Version 2.18.0-103.0.dev
Merge commit '063ee76dc7bdf43bf25f3f1fbb2885c48f3037ae' into 'dev'
diff --git a/DEPS b/DEPS
index b6d3a6b..2075bbb 100644
--- a/DEPS
+++ b/DEPS
@@ -54,7 +54,7 @@
# Checkout Android dependencies only on Mac and Linux.
"download_android_deps":
- "(host_os == mac or host_os == linux) and host_cpu == x64",
+ "host_os == mac or (host_os == linux and host_cpu == x64)",
# Checkout extra javascript engines for testing or benchmarking.
# d8, the V8 shell, is always checked out.
@@ -528,7 +528,7 @@
Var("dart_root") + "/third_party/android_tools/ndk": {
"packages": [
{
- "package": "flutter/android/ndk/${{platform}}",
+ "package": "flutter/android/ndk/${{os}}-amd64",
"version": "version:r21.0.6113669"
}
],
@@ -539,7 +539,7 @@
Var("dart_root") + "/third_party/android_tools/sdk/build-tools": {
"packages": [
{
- "package": "flutter/android/sdk/build-tools/${{platform}}",
+ "package": "flutter/android/sdk/build-tools/${{os}}-amd64",
"version": "version:30.0.1"
}
],
@@ -550,7 +550,7 @@
Var("dart_root") + "/third_party/android_tools/sdk/platform-tools": {
"packages": [
{
- "package": "flutter/android/sdk/platform-tools/${{platform}}",
+ "package": "flutter/android/sdk/platform-tools/${{os}}-amd64",
"version": "version:29.0.2"
}
],
@@ -572,7 +572,7 @@
Var("dart_root") + "/third_party/android_tools/sdk/tools": {
"packages": [
{
- "package": "flutter/android/sdk/tools/${{platform}}",
+ "package": "flutter/android/sdk/tools/${{os}}-amd64",
"version": "version:26.1.1"
}
],
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index c61d41a..f5def03 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -26,6 +26,9 @@
# architecture, which is different than the names GN uses.
if (host_cpu == "x64" || host_cpu == "x86") {
android_host_arch = "x86_64"
+ } else if (host_cpu == "arm64") {
+ # Run existing Android toolchain via Rosetta.
+ android_host_arch = "x86_64"
} else {
assert(false, "Need Android toolchain support for your build CPU arch.")
}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_key_to_constructors.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_key_to_constructors.dart
index c308c1d..7ebfe8c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_key_to_constructors.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_key_to_constructors.dart
@@ -175,15 +175,26 @@
argument is NamedExpression && argument.name.label.name == 'key');
if (existing == null) {
// There is no 'key' argument, so add it.
- if (arguments.isEmpty) {
- builder.addSimpleInsertion(
- argumentList.leftParenthesis.end, 'key: key');
- } else {
- // This case should never happen because 'key' is the only parameter
- // in the constructors for both `StatelessWidget` and `StatefulWidget`.
- builder.addSimpleInsertion(
- argumentList.leftParenthesis.end, 'key: key, ');
- }
+ var namedArguments = arguments.whereType<NamedExpression>();
+ var firstNamed = namedArguments.firstOrNull;
+ var token = firstNamed?.beginToken ?? argumentList.endToken;
+ var comma = token.previous?.type == TokenType.COMMA;
+
+ builder.addInsertion(token.offset, (builder) {
+ if (arguments.length != namedArguments.length) {
+ // there are unnamed arguments
+ if (!comma) {
+ builder.write(',');
+ }
+ builder.write(' ');
+ }
+ builder.write('key: key');
+ if (firstNamed != null) {
+ builder.write(', ');
+ } else if (comma) {
+ builder.write(',');
+ }
+ });
} else {
// There is an existing 'key' argument, so we leave it alone.
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_key_to_constructors_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_key_to_constructors_test.dart
index 834a76c..1d48dd5 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_key_to_constructors_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_key_to_constructors_test.dart
@@ -13,6 +13,8 @@
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(AddKeyToConstructorsTest);
+ defineReflectiveTests(
+ AddKeyToConstructorsWithoutNamedArgumentsAnywhereTest);
});
}
@@ -169,19 +171,93 @@
await resolveTestCode('''
import 'package:flutter/material.dart';
-class MyWidget extends StatelessWidget {
+class A extends StatelessWidget {
+ const A({required this.text, Key? key}) : super(key: key);
+
+ final String text;
+}
+
+class MyWidget extends A {
MyWidget() : super(text: '');
}
''');
await assertHasFix('''
import 'package:flutter/material.dart';
-class MyWidget extends StatelessWidget {
+class A extends StatelessWidget {
+ const A({required this.text, Key? key}) : super(key: key);
+
+ final String text;
+}
+
+class MyWidget extends A {
MyWidget({Key? key}) : super(key: key, text: '');
}
''', errorFilter: (error) => error.errorCode is LintCode);
}
+ Future<void>
+ test_constructor_noParameters_withSuper_nonEmpty_tailingComma() async {
+ await resolveTestCode('''
+import 'package:flutter/material.dart';
+
+class A extends StatelessWidget {
+ const A({required this.text, Key? key}) : super(key: key);
+
+ final String text;
+}
+
+class MyWidget extends A {
+ MyWidget() : super(text: '',);
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/material.dart';
+
+class A extends StatelessWidget {
+ const A({required this.text, Key? key}) : super(key: key);
+
+ final String text;
+}
+
+class MyWidget extends A {
+ MyWidget({Key? key}) : super(key: key, text: '',);
+}
+''', errorFilter: (error) => error.errorCode is LintCode);
+ }
+
+ Future<void>
+ test_constructor_noParameters_withSuper_nonNamed_trailingComma() async {
+ await resolveTestCode('''
+import 'package:flutter/material.dart';
+
+class A extends StatelessWidget {
+ const A(this.widget, {Key? key}) : super(key: key);
+
+ final Widget widget;
+}
+
+class B extends A {
+ B() : super(const Text(''),);
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/material.dart';
+
+class A extends StatelessWidget {
+ const A(this.widget, {Key? key}) : super(key: key);
+
+ final Widget widget;
+}
+
+class B extends A {
+ B({Key? key}) : super(const Text(''), key: key,);
+}
+''',
+ //TODO(asashour) there should be no other errors
+ errorFilter: (error) => error.errorCode is LintCode);
+ }
+
Future<void> test_initializer_final_constant() async {
await resolveTestCode('''
import 'package:flutter/material.dart';
@@ -311,3 +387,55 @@
''', errorFilter: (error) => error.errorCode is LintCode);
}
}
+
+@reflectiveTest
+class AddKeyToConstructorsWithoutNamedArgumentsAnywhereTest
+ extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_KEY_TO_CONSTRUCTORS;
+
+ @override
+ String get lintCode => LintNames.use_key_in_widget_constructors;
+
+ @override
+ String get testPackageLanguageVersion => '2.16';
+
+ @override
+ void setUp() {
+ super.setUp();
+ writeTestPackageConfig(
+ flutter: true,
+ );
+ }
+
+ Future<void> test_constructor_noParameters_withSuper_nonEmpty() async {
+ await resolveTestCode('''
+import 'package:flutter/material.dart';
+
+class A extends StatelessWidget {
+ const A(this.widget, {Key? key}) : super(key: key);
+
+ final Widget widget;
+}
+
+class B extends A {
+ B() : super(const Text(''));
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/material.dart';
+
+class A extends StatelessWidget {
+ const A(this.widget, {Key? key}) : super(key: key);
+
+ final Widget widget;
+}
+
+class B extends A {
+ B({Key? key}) : super(const Text(''), key: key);
+}
+''',
+ //TODO(asashour) there should be no other errors
+ errorFilter: (error) => error.errorCode is LintCode);
+ }
+}
diff --git a/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart b/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
index 9451d5c..4cebed9 100644
--- a/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
+++ b/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
@@ -22,6 +22,7 @@
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/package_bundle_format.dart';
import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:yaml/yaml.dart';
@@ -106,7 +107,11 @@
Reference.root(),
);
- var linkResult = await link(elementFactory, inputLibraries);
+ var linkResult = await link2(
+ elementFactory: elementFactory,
+ inputLibraries: inputLibraries,
+ performance: OperationPerformanceImpl('link'),
+ );
var bundleBuilder = PackageBundleBuilder();
for (var library in inputLibraries) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 311c3b0..ea279e3 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -26,6 +26,7 @@
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/macro.dart';
import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:path/src/context.dart';
/// Context information necessary to analyze one or more libraries within an
@@ -203,8 +204,12 @@
LinkResult linkResult;
try {
- linkResult = await link(elementFactory, inputLibraries,
- macroExecutor: macroExecutor);
+ linkResult = await link2(
+ elementFactory: elementFactory,
+ performance: OperationPerformanceImpl('link'),
+ inputLibraries: inputLibraries,
+ macroExecutor: macroExecutor,
+ );
librariesLinked += cycle.libraries.length;
} catch (exception, stackTrace) {
_throwLibraryCycleLinkException(cycle, exception, stackTrace);
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index e333fc8..efb1059 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -916,7 +916,17 @@
}
inputsTimer.stop();
- var linkResult = await link(elementFactory, inputLibraries);
+ var linkResult = await performance.runAsync(
+ 'link',
+ (performance) async {
+ return await link2(
+ elementFactory: elementFactory,
+ performance: performance,
+ inputLibraries: inputLibraries,
+ );
+ },
+ );
+
librariesLinked += cycle.libraries.length;
resolutionBytes = linkResult.resolutionBytes;
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index acef1f4..7594b79 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -24,6 +24,7 @@
import 'package:analyzer/src/summary2/reference_resolver.dart';
import 'package:analyzer/src/summary2/scope.dart';
import 'package:analyzer/src/summary2/types_builder.dart';
+import 'package:analyzer/src/util/performance/operation_performance.dart';
class ImplicitEnumNodes {
final EnumElementImpl element;
@@ -275,14 +276,30 @@
];
}
- Future<void> executeMacroTypesPhase() async {
+ Future<void> executeMacroTypesPhase({
+ required OperationPerformanceImpl performance,
+ }) async {
final macroApplier = _macroApplier;
if (macroApplier == null) {
return;
}
- await macroApplier.buildApplications();
- var augmentationLibrary = await macroApplier.executeTypesPhase();
+ await performance.runAsync(
+ 'buildApplications',
+ (performance) async {
+ await macroApplier.buildApplications(
+ performance: performance,
+ );
+ },
+ );
+
+ final augmentationLibrary = await performance.runAsync(
+ 'executeTypesPhase',
+ (performance) async {
+ return await macroApplier.executeTypesPhase();
+ },
+ );
+
if (augmentationLibrary == null) {
return;
}
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 31000d1..f6e224f 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -25,15 +25,35 @@
import 'package:analyzer/src/summary2/type_alias.dart';
import 'package:analyzer/src/summary2/types_builder.dart';
import 'package:analyzer/src/summary2/variance_builder.dart';
+import 'package:analyzer/src/util/performance/operation_performance.dart';
/// Note that AST units and tokens of [inputLibraries] will be damaged.
+@Deprecated('Use link2() instead')
Future<LinkResult> link(
LinkedElementFactory elementFactory,
List<LinkInputLibrary> inputLibraries, {
macro.MultiMacroExecutor? macroExecutor,
+ OperationPerformanceImpl? performance,
}) async {
- var linker = Linker(elementFactory, macroExecutor);
- await linker.link(inputLibraries);
+ return await link2(
+ elementFactory: elementFactory,
+ inputLibraries: inputLibraries,
+ performance: OperationPerformanceImpl('<root>'),
+ );
+}
+
+/// Note that AST units and tokens of [inputLibraries] will be damaged.
+Future<LinkResult> link2({
+ required LinkedElementFactory elementFactory,
+ required OperationPerformanceImpl performance,
+ required List<LinkInputLibrary> inputLibraries,
+ macro.MultiMacroExecutor? macroExecutor,
+}) async {
+ final linker = Linker(elementFactory, macroExecutor);
+ await linker.link(
+ performance: performance,
+ inputLibraries: inputLibraries,
+ );
return LinkResult(
resolutionBytes: linker.resolutionBytes,
macroGeneratedUnits: linker.macroGeneratedUnits,
@@ -79,12 +99,18 @@
return elementNodes[element];
}
- Future<void> link(List<LinkInputLibrary> inputLibraries) async {
+ Future<void> link({
+ required OperationPerformanceImpl performance,
+ required List<LinkInputLibrary> inputLibraries,
+ }) async {
for (var inputLibrary in inputLibraries) {
LibraryBuilder.build(this, inputLibrary);
}
- await _buildOutlines();
+ await _buildOutlines(
+ performance: performance,
+ );
+
_writeLibraries();
}
@@ -94,13 +120,31 @@
}
}
- Future<void> _buildOutlines() async {
+ Future<void> _buildOutlines({
+ required OperationPerformanceImpl performance,
+ }) async {
_createTypeSystemIfNotLinkingDartCore();
- await _computeLibraryScopes();
+
+ await performance.runAsync(
+ 'computeLibraryScopes',
+ (performance) async {
+ await _computeLibraryScopes(
+ performance: performance,
+ );
+ },
+ );
+
_createTypeSystem();
_resolveTypes();
_buildEnumChildren();
- await _executeMacroDeclarationsPhase();
+
+ await performance.runAsync(
+ 'executeMacroDeclarationsPhase',
+ (_) async {
+ await _executeMacroDeclarationsPhase();
+ },
+ );
+
SuperConstructorResolver(this).perform();
_performTopLevelInference();
_resolveConstructors();
@@ -117,14 +161,23 @@
}
}
- Future<void> _computeLibraryScopes() async {
+ Future<void> _computeLibraryScopes({
+ required OperationPerformanceImpl performance,
+ }) async {
for (var library in builders.values) {
library.buildElements();
}
- for (var library in builders.values) {
- await library.executeMacroTypesPhase();
- }
+ await performance.runAsync(
+ 'executeMacroTypesPhase',
+ (performance) async {
+ for (var library in builders.values) {
+ await library.executeMacroTypesPhase(
+ performance: performance,
+ );
+ }
+ },
+ );
macroDeclarationBuilder.transferToElements();
diff --git a/pkg/analyzer/lib/src/summary2/macro_application.dart b/pkg/analyzer/lib/src/summary2/macro_application.dart
index 8ca3caf..24e180b 100644
--- a/pkg/analyzer/lib/src/summary2/macro_application.dart
+++ b/pkg/analyzer/lib/src/summary2/macro_application.dart
@@ -20,6 +20,7 @@
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/macro_application_error.dart';
import 'package:analyzer/src/summary2/macro_declarations.dart';
+import 'package:analyzer/src/util/performance/operation_performance.dart';
class LibraryMacroApplier {
final MultiMacroExecutor macroExecutor;
@@ -47,7 +48,9 @@
Linker get _linker => libraryBuilder.linker;
/// Fill [_targets]s with macro applications.
- Future<void> buildApplications() async {
+ Future<void> buildApplications({
+ required OperationPerformanceImpl performance,
+ }) async {
final collector = _MacroTargetElementCollector();
libraryBuilder.element.accept(collector);
@@ -55,11 +58,17 @@
final targetNode = _linker.elementNodes[targetElement];
// TODO(scheglov) support other declarations
if (targetNode is ClassDeclaration) {
- await _buildApplications(
- targetElement,
- targetNode.metadata,
- macro.DeclarationKind.clazz,
- () => declarationBuilder.fromNode.classDeclaration(targetNode),
+ await performance.runAsync(
+ 'forClassDeclaration',
+ (performance) async {
+ await _buildApplications(
+ targetElement,
+ targetNode.metadata,
+ macro.DeclarationKind.clazz,
+ () => declarationBuilder.fromNode.classDeclaration(targetNode),
+ performance: performance,
+ );
+ },
);
}
}
@@ -117,8 +126,9 @@
MacroTargetElement targetElement,
List<Annotation> annotations,
macro.DeclarationKind declarationKind,
- macro.DeclarationImpl Function() getDeclaration,
- ) async {
+ macro.DeclarationImpl Function() getDeclaration, {
+ required OperationPerformanceImpl performance,
+ }) async {
final applications = <_MacroApplication>[];
for (var i = 0; i < annotations.length; i++) {
@@ -136,12 +146,14 @@
annotationIndex: i,
node: argumentsNode,
);
- return await macroExecutor.instantiate(
- libraryUri: macroClass.librarySource.uri,
- className: macroClass.name,
- constructorName: constructorName,
- arguments: arguments,
- );
+ return await performance.runAsync('instantiate', (_) {
+ return macroExecutor.instantiate(
+ libraryUri: macroClass.librarySource.uri,
+ className: macroClass.name,
+ constructorName: constructorName,
+ arguments: arguments,
+ );
+ });
},
annotationIndex: i,
onError: (error) {
diff --git a/pkg/analyzer/lib/src/util/performance/operation_performance.dart b/pkg/analyzer/lib/src/util/performance/operation_performance.dart
index 3d5ac61b..b3f6b38 100644
--- a/pkg/analyzer/lib/src/util/performance/operation_performance.dart
+++ b/pkg/analyzer/lib/src/util/performance/operation_performance.dart
@@ -105,6 +105,12 @@
);
}
+ /// Collapse any children into this operation, making [elapsedSelf] equal
+ /// to [elapsed].
+ void collapse() {
+ _children.clear();
+ }
+
@override
OperationPerformanceImpl? getChild(String name) {
return _children.firstWhereOrNull(
diff --git a/pkg/analyzer/test/src/summary/elements_base.dart b/pkg/analyzer/test/src/summary/elements_base.dart
index 16267e1..3fd14b1 100644
--- a/pkg/analyzer/test/src/summary/elements_base.dart
+++ b/pkg/analyzer/test/src/summary/elements_base.dart
@@ -31,6 +31,7 @@
import 'package:analyzer/src/summary2/reference.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/util/uri.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as package_path;
@@ -103,7 +104,11 @@
Reference.root(),
);
- var sdkLinkResult = await link(elementFactory, inputLibraries);
+ var sdkLinkResult = await link2(
+ elementFactory: elementFactory,
+ inputLibraries: inputLibraries,
+ performance: OperationPerformanceImpl('link'),
+ );
return _sdkBundle = _SdkBundle(
resolutionBytes: sdkLinkResult.resolutionBytes,
@@ -128,75 +133,99 @@
bool dumpSummaries = false,
List<Set<String>>? preBuildSequence,
}) async {
- _buildSourceFactory();
+ final performance = OperationPerformanceImpl('<root>');
+ final result = await performance.runAsync(
+ 'buildLibrary',
+ (performance) async {
+ _buildSourceFactory();
- var testFile = newFile(testFilePath, text);
- var testUri = sourceFactory.pathToUri(testFile.path)!;
- var testSource = sourceFactory.forUri2(testUri)!;
+ var testFile = newFile(testFilePath, text);
+ var testUri = sourceFactory.pathToUri(testFile.path)!;
+ var testSource = sourceFactory.forUri2(testUri)!;
- var inputLibraries = <LinkInputLibrary>[];
- _addNonDartLibraries({}, inputLibraries, testSource);
+ var inputLibraries = <LinkInputLibrary>[];
+ _addNonDartLibraries({}, inputLibraries, testSource);
- var unitsInformativeBytes = <Uri, Uint8List>{};
- for (var inputLibrary in inputLibraries) {
- for (var inputUnit in inputLibrary.units) {
- var informativeBytes = writeUnitInformative(inputUnit.unit);
- unitsInformativeBytes[inputUnit.uri] = informativeBytes;
- }
- }
+ var unitsInformativeBytes = <Uri, Uint8List>{};
+ for (var inputLibrary in inputLibraries) {
+ for (var inputUnit in inputLibrary.units) {
+ var informativeBytes = writeUnitInformative(inputUnit.unit);
+ unitsInformativeBytes[inputUnit.uri] = informativeBytes;
+ }
+ }
- var analysisContext = AnalysisContextImpl(
- SynchronousSession(
- AnalysisOptionsImpl()..contextFeatures = featureSet,
- declaredVariables,
- ),
- sourceFactory,
+ var analysisContext = AnalysisContextImpl(
+ SynchronousSession(
+ AnalysisOptionsImpl()..contextFeatures = featureSet,
+ declaredVariables,
+ ),
+ sourceFactory,
+ );
+
+ var elementFactory = LinkedElementFactory(
+ analysisContext,
+ _AnalysisSessionForLinking(),
+ Reference.root(),
+ );
+ elementFactory.addBundle(
+ BundleReader(
+ elementFactory: elementFactory,
+ unitsInformativeBytes: {},
+ resolutionBytes: (await sdkBundle).resolutionBytes,
+ ),
+ );
+
+ await performance.runAsync(
+ 'linkConfiguredLibraries',
+ (performance) async {
+ await _linkConfiguredLibraries(
+ elementFactory,
+ inputLibraries,
+ preBuildSequence,
+ performance,
+ );
+ },
+ );
+
+ var linkResult = await performance.runAsync(
+ 'link',
+ (performance) async {
+ return await link2(
+ elementFactory: elementFactory,
+ inputLibraries: inputLibraries,
+ macroExecutor: _macroExecutor,
+ performance: performance,
+ );
+ },
+ );
+
+ for (var macroUnit in linkResult.macroGeneratedUnits) {
+ var informativeBytes = writeUnitInformative(macroUnit.unit);
+ unitsInformativeBytes[macroUnit.uri] = informativeBytes;
+ }
+
+ if (!keepLinkingLibraries) {
+ elementFactory.removeBundle(
+ inputLibraries.map((e) => e.uriStr).toSet(),
+ );
+ elementFactory.addBundle(
+ BundleReader(
+ elementFactory: elementFactory,
+ unitsInformativeBytes: unitsInformativeBytes,
+ resolutionBytes: linkResult.resolutionBytes,
+ ),
+ );
+ }
+
+ return elementFactory.libraryOfUri2('$testUri');
+ },
);
- var elementFactory = LinkedElementFactory(
- analysisContext,
- _AnalysisSessionForLinking(),
- Reference.root(),
- );
- elementFactory.addBundle(
- BundleReader(
- elementFactory: elementFactory,
- unitsInformativeBytes: {},
- resolutionBytes: (await sdkBundle).resolutionBytes,
- ),
- );
+ // final performanceBuffer = StringBuffer();
+ // performance.children.single.write(buffer: performanceBuffer);
+ // print(performanceBuffer);
- await _linkConfiguredLibraries(
- elementFactory,
- inputLibraries,
- preBuildSequence,
- );
-
- var linkResult = await link(
- elementFactory,
- inputLibraries,
- macroExecutor: _macroExecutor,
- );
-
- for (var macroUnit in linkResult.macroGeneratedUnits) {
- var informativeBytes = writeUnitInformative(macroUnit.unit);
- unitsInformativeBytes[macroUnit.uri] = informativeBytes;
- }
-
- if (!keepLinkingLibraries) {
- elementFactory.removeBundle(
- inputLibraries.map((e) => e.uriStr).toSet(),
- );
- elementFactory.addBundle(
- BundleReader(
- elementFactory: elementFactory,
- unitsInformativeBytes: unitsInformativeBytes,
- resolutionBytes: linkResult.resolutionBytes,
- ),
- );
- }
-
- return elementFactory.libraryOfUri2('$testUri');
+ return result;
}
@mustCallSuper
@@ -366,6 +395,7 @@
LinkedElementFactory elementFactory,
List<LinkInputLibrary> inputLibraries,
List<Set<String>>? uriStrSetList,
+ OperationPerformanceImpl performance,
) async {
if (uriStrSetList == null) {
return;
@@ -381,13 +411,19 @@
}
}
- await link(
- elementFactory,
- cycleInputLibraries,
- macroExecutor: _macroExecutor,
- );
+ await performance.runAsync('link', (performance) async {
+ await link2(
+ elementFactory: elementFactory,
+ inputLibraries: cycleInputLibraries,
+ macroExecutor: _macroExecutor,
+ performance: performance,
+ );
+ performance.collapse();
+ });
- await _buildMacroLibraries(elementFactory, macroLibraries);
+ await performance.runAsync('buildMacroLibraries', (_) async {
+ await _buildMacroLibraries(elementFactory, macroLibraries);
+ });
// Remove libraries that we just linked.
cycleInputLibraries.forEach(inputLibraries.remove);
diff --git a/pkg/dart2native/lib/macho.dart b/pkg/dart2native/lib/macho.dart
index e0d8f93..9294483 100644
--- a/pkg/dart2native/lib/macho.dart
+++ b/pkg/dart2native/lib/macho.dart
@@ -6,6 +6,8 @@
// part of the Apple system headers. All comments, which detail the format of
// Mach-O files, have been reproduced from the orginal header.
+// ignore_for_file: non_constant_identifier_names, constant_identifier_names
+
import 'dart:io';
import 'dart:typed_data';
@@ -87,6 +89,7 @@
return _data > other;
}
+ @override
bool operator ==(other) {
if (other is Uint64) {
return _data == other._data;
@@ -94,6 +97,9 @@
return false;
}
}
+
+ @override
+ int get hashCode => _data.hashCode;
}
class Int32 extends IntLike {
@@ -103,6 +109,7 @@
return Int32(_data | other._data);
}
+ @override
bool operator ==(other) {
if (other is Int32) {
return _data == other._data;
@@ -110,6 +117,9 @@
return false;
}
}
+
+ @override
+ int get hashCode => _data.hashCode;
}
class Uint16 extends IntLike {
@@ -147,6 +157,7 @@
return _data >= other;
}
+ @override
bool operator ==(other) {
if (other is Uint32) {
return _data == other._data;
@@ -155,6 +166,9 @@
}
}
+ @override
+ int get hashCode => _data.hashCode;
+
Uint64 asUint64() {
return Uint64(_data);
}
@@ -420,9 +434,9 @@
stream.writeUint32(nsects);
stream.writeUint32(flags);
- sections.forEach((section) {
+ for (final section in sections) {
section.writeContentsSync(stream);
- });
+ }
}
}
diff --git a/pkg/dart2native/lib/macho_parser.dart b/pkg/dart2native/lib/macho_parser.dart
index 20deb1d..99dce1a 100644
--- a/pkg/dart2native/lib/macho_parser.dart
+++ b/pkg/dart2native/lib/macho_parser.dart
@@ -261,9 +261,9 @@
}
// Write all of the commands.
- commands.forEach((command) {
+ for (var command in commands) {
writeLoadCommandToStream(command, stream);
- });
+ }
// Pad the header according to the offset.
final int paddingAmount = headerMaxOffset - stream.positionSync();
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index e71c21bf..6debbc9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -2030,23 +2030,15 @@
}
TypeConstraintGatherer? gatherer;
if (inferenceNeeded) {
- inferredTypes = [const UnknownType()];
gatherer = inferrer.typeSchemaEnvironment.setupGenericTypeInference(
listType,
listClass.typeParameters,
typeContext,
inferrer.libraryBuilder.library,
isConst: node.isConst);
- inferrer.typeSchemaEnvironment.partialInfer(
- gatherer,
- listClass.typeParameters,
- inferredTypes,
- inferrer.libraryBuilder.library);
+ inferredTypes = inferrer.typeSchemaEnvironment.partialInfer(gatherer,
+ listClass.typeParameters, null, inferrer.libraryBuilder.library);
inferredTypeArgument = inferredTypes[0];
- if (inferrer.dataForTesting != null) {
- inferrer.dataForTesting!.typeInferenceResult
- .inferredTypeArguments[node] = inferredTypes;
- }
} else {
inferredTypeArgument = node.typeArgument;
}
@@ -2068,11 +2060,15 @@
}
if (inferenceNeeded) {
gatherer!.constrainArguments(formalTypes!, actualTypes!);
- inferrer.typeSchemaEnvironment.upwardsInfer(
+ inferredTypes = inferrer.typeSchemaEnvironment.upwardsInfer(
gatherer,
listClass.typeParameters,
inferredTypes!,
inferrer.libraryBuilder.library);
+ if (inferrer.dataForTesting != null) {
+ inferrer.dataForTesting!.typeInferenceResult
+ .inferredTypeArguments[node] = inferredTypes;
+ }
inferredTypeArgument = inferredTypes[0];
inferrer.instrumentation?.record(
inferrer.uriForInstrumentation,
@@ -2715,24 +2711,16 @@
}
TypeConstraintGatherer? gatherer;
if (inferenceNeeded) {
- inferredTypes = [noInferredType, noInferredType];
gatherer = inferrer.typeSchemaEnvironment.setupGenericTypeInference(
mapType,
mapClass.typeParameters,
typeContext,
inferrer.libraryBuilder.library,
isConst: node.isConst);
- inferrer.typeSchemaEnvironment.partialInfer(
- gatherer,
- mapClass.typeParameters,
- inferredTypes,
- inferrer.libraryBuilder.library);
+ inferredTypes = inferrer.typeSchemaEnvironment.partialInfer(gatherer,
+ mapClass.typeParameters, null, inferrer.libraryBuilder.library);
inferredKeyType = inferredTypes[0];
inferredValueType = inferredTypes[1];
- if (inferrer.dataForTesting != null) {
- inferrer.dataForTesting!.typeInferenceResult
- .inferredTypeArguments[node] = inferredTypes;
- }
} else {
inferredKeyType = node.keyType;
inferredValueType = node.valueType;
@@ -2796,7 +2784,6 @@
formalTypesForSet.add(setType.typeArguments[0]);
}
- List<DartType> inferredTypesForSet = <DartType>[noInferredType];
// Note: we don't use the previously created gatherer because it was set
// up presuming that the literal would be a map; we now know that it
// needs to be a set.
@@ -2807,13 +2794,11 @@
typeContext,
inferrer.libraryBuilder.library,
isConst: node.isConst);
- inferrer.typeSchemaEnvironment.partialInfer(
- gatherer,
- inferrer.coreTypes.setClass.typeParameters,
- inferredTypesForSet,
- inferrer.libraryBuilder.library);
+ List<DartType> inferredTypesForSet = inferrer.typeSchemaEnvironment
+ .partialInfer(gatherer, inferrer.coreTypes.setClass.typeParameters,
+ null, inferrer.libraryBuilder.library);
gatherer.constrainArguments(formalTypesForSet, actualTypesForSet!);
- inferrer.typeSchemaEnvironment.upwardsInfer(
+ inferredTypesForSet = inferrer.typeSchemaEnvironment.upwardsInfer(
gatherer,
inferrer.coreTypes.setClass.typeParameters,
inferredTypesForSet,
@@ -2864,11 +2849,15 @@
replacement);
}
gatherer!.constrainArguments(formalTypes!, actualTypes!);
- inferrer.typeSchemaEnvironment.upwardsInfer(
+ inferredTypes = inferrer.typeSchemaEnvironment.upwardsInfer(
gatherer,
mapClass.typeParameters,
inferredTypes!,
inferrer.libraryBuilder.library);
+ if (inferrer.dataForTesting != null) {
+ inferrer.dataForTesting!.typeInferenceResult
+ .inferredTypeArguments[node] = inferredTypes;
+ }
inferredKeyType = inferredTypes[0];
inferredValueType = inferredTypes[1];
inferrer.instrumentation?.record(
@@ -5985,23 +5974,15 @@
}
TypeConstraintGatherer? gatherer;
if (inferenceNeeded) {
- inferredTypes = [const UnknownType()];
gatherer = inferrer.typeSchemaEnvironment.setupGenericTypeInference(
setType,
setClass.typeParameters,
typeContext,
inferrer.libraryBuilder.library,
isConst: node.isConst);
- inferrer.typeSchemaEnvironment.partialInfer(
- gatherer,
- setClass.typeParameters,
- inferredTypes,
- inferrer.libraryBuilder.library);
+ inferredTypes = inferrer.typeSchemaEnvironment.partialInfer(gatherer,
+ setClass.typeParameters, null, inferrer.libraryBuilder.library);
inferredTypeArgument = inferredTypes[0];
- if (inferrer.dataForTesting != null) {
- inferrer.dataForTesting!.typeInferenceResult
- .inferredTypeArguments[node] = inferredTypes;
- }
} else {
inferredTypeArgument = node.typeArgument;
}
@@ -6023,11 +6004,15 @@
}
if (inferenceNeeded) {
gatherer!.constrainArguments(formalTypes!, actualTypes!);
- inferrer.typeSchemaEnvironment.upwardsInfer(
+ inferredTypes = inferrer.typeSchemaEnvironment.upwardsInfer(
gatherer,
setClass.typeParameters,
inferredTypes!,
inferrer.libraryBuilder.library);
+ if (inferrer.dataForTesting != null) {
+ inferrer.dataForTesting!.typeInferenceResult
+ .inferredTypeArguments[node] = inferredTypes;
+ }
inferredTypeArgument = inferredTypes[0];
inferrer.instrumentation?.record(
inferrer.uriForInstrumentation,
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 4f37948..609515e 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -128,6 +128,8 @@
for (_DeferredParamInfo functionLiteral in deferredFunctionLiterals)
functionLiteral.evaluationOrderIndex
};
+ assert(evaluationOrderIndicesAlreadyCovered
+ .every((i) => 0 <= i && i < formalTypes.length));
return [
for (int i = 0; i < formalTypes.length; i++)
if (!evaluationOrderIndicesAlreadyCovered.contains(i))
@@ -976,7 +978,7 @@
typeSchemaEnvironment.setupGenericTypeInference(
null, typeParameters, null, libraryBuilder.library);
gatherer.constrainArguments([onType], [receiverType]);
- typeSchemaEnvironment.upwardsInfer(
+ inferredTypes = typeSchemaEnvironment.upwardsInfer(
gatherer, typeParameters, inferredTypes, libraryBuilder.library);
return inferredTypes;
}
@@ -2376,8 +2378,6 @@
: coreTypes.objectLegacyRawType)
.substituteType(typeContext);
}
- inferredTypes = new List<DartType>.filled(
- calleeTypeParameters.length, const UnknownType());
gatherer = typeSchemaEnvironment.setupGenericTypeInference(
isNonNullableByDefault
? calleeType.returnType
@@ -2385,8 +2385,8 @@
calleeTypeParameters,
typeContext,
libraryBuilder.library);
- typeSchemaEnvironment.partialInfer(gatherer, calleeTypeParameters,
- inferredTypes, libraryBuilder.library);
+ inferredTypes = typeSchemaEnvironment.partialInfer(
+ gatherer, calleeTypeParameters, null, libraryBuilder.library);
substitution =
Substitution.fromPairs(calleeTypeParameters, inferredTypes);
} else if (explicitTypeArguments != null &&
@@ -2527,7 +2527,9 @@
argumentExpression: argumentExpression,
unparenthesizedExpression: unparenthesizedExpression,
isNamed: !isExpression,
- evaluationOrderIndex: evaluationOrderIndex,
+ evaluationOrderIndex: isImplicitExtensionMember
+ ? evaluationOrderIndex - 1
+ : evaluationOrderIndex,
index: index));
// We don't have `identical` info yet, so fill it in with `null` for
// now. Later, when we visit the function literal, we'll replace it.
@@ -2575,8 +2577,8 @@
: const [])
.planReconciliationStages()) {
if (gatherer != null && !isFirstStage) {
- typeSchemaEnvironment.partialInfer(gatherer, calleeTypeParameters,
- inferredTypes!, libraryBuilder.library);
+ inferredTypes = typeSchemaEnvironment.partialInfer(gatherer,
+ calleeTypeParameters, inferredTypes, libraryBuilder.library);
substitution =
Substitution.fromPairs(calleeTypeParameters, inferredTypes);
}
@@ -2702,8 +2704,8 @@
}
if (inferenceNeeded) {
- typeSchemaEnvironment.upwardsInfer(gatherer!, calleeTypeParameters,
- inferredTypes!, libraryBuilder.library);
+ inferredTypes = typeSchemaEnvironment.upwardsInfer(gatherer!,
+ calleeTypeParameters, inferredTypes!, libraryBuilder.library);
assert(inferredTypes.every((type) => isKnown(type)),
"Unknown type(s) in inferred types: $inferredTypes.");
assert(inferredTypes.every((type) => !hasPromotedTypeVariable(type)),
@@ -4251,7 +4253,7 @@
TypeConstraintGatherer gatherer =
typeSchemaEnvironment.setupGenericTypeInference(instantiatedType,
typeParameters, context, libraryBuilder.library);
- typeSchemaEnvironment.upwardsInfer(
+ inferredTypes = typeSchemaEnvironment.upwardsInfer(
gatherer, typeParameters, inferredTypes, libraryBuilder.library);
Substitution substitution =
Substitution.fromPairs(typeParameters, inferredTypes);
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index 86cc5da..dd2f233 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -130,14 +130,14 @@
/// Performs partial (either downwards or horizontal) inference, producing a
/// set of inferred types that may contain references to the "unknown type".
- void partialInfer(
+ List<DartType> partialInfer(
TypeConstraintGatherer gatherer,
List<TypeParameter> typeParametersToInfer,
- List<DartType> inferredTypes,
+ List<DartType>? previouslyInferredTypes,
Library clientLibrary) =>
- _chooseTypes(
- gatherer, typeParametersToInfer, inferredTypes, clientLibrary,
- downwardsInferPhase: true);
+ _chooseTypes(gatherer, typeParametersToInfer, previouslyInferredTypes,
+ clientLibrary,
+ partial: true);
@override
DartType getTypeOfSpecialCasedBinaryOperator(DartType type1, DartType type2,
@@ -255,26 +255,24 @@
/// Use the given [constraints] to substitute for type variables.
///
/// [typeParametersToInfer] is the set of type parameters that should be
- /// substituted for. [inferredTypes] should be a list of the same length.
+ /// substituted for. [previouslyInferredTypes], if present, should be the set
+ /// of types inferred by the last call to this method; it should be a list of
+ /// the same length.
///
- /// If [downwardsInferPhase] is `true`, then we are in the first pass of
- /// inference, pushing context types down. This means we are allowed to push
- /// down `?` to precisely represent an unknown type. [inferredTypes] should
- /// be initially populated with `?`. These `?`s will be replaced, if
- /// appropriate, with the types that were inferred by downwards inference.
+ /// If [partial] is `true`, then we not in the final pass of inference. This
+ /// means we are allowed to return `?` to precisely represent an unknown type.
///
- /// If [downwardsInferPhase] is `false`, then we are in the second pass of
- /// inference, and must not conclude `?` for any type formal. In this pass,
- /// [inferredTypes] should contain the values from the first pass. They will
- /// be replaced with the final inferred types.
- void inferTypeFromConstraints(
+ /// If [partial] is `false`, then we are in the final pass of inference, and
+ /// must not conclude `?` for any type formal.
+ List<DartType> inferTypeFromConstraints(
Map<TypeParameter, TypeConstraint> constraints,
List<TypeParameter> typeParametersToInfer,
- List<DartType> inferredTypes,
+ List<DartType>? previouslyInferredTypes,
Library clientLibrary,
- {bool downwardsInferPhase: false}) {
- List<DartType>? typesFromDownwardsInference =
- downwardsInferPhase ? null : inferredTypes.toList(growable: false);
+ {bool partial: false}) {
+ List<DartType> inferredTypes =
+ previouslyInferredTypes?.toList(growable: false) ??
+ new List.filled(typeParametersToInfer.length, const UnknownType());
for (int i = 0; i < typeParametersToInfer.length; i++) {
TypeParameter typeParam = typeParametersToInfer[i];
@@ -288,21 +286,25 @@
}
TypeConstraint constraint = constraints[typeParam]!;
- if (downwardsInferPhase) {
+ if (partial) {
inferredTypes[i] = _inferTypeParameterFromContext(
- constraint, extendsConstraint, clientLibrary);
+ previouslyInferredTypes?[i],
+ constraint,
+ extendsConstraint,
+ clientLibrary,
+ isLegacyCovariant: typeParam.isLegacyCovariant);
} else {
inferredTypes[i] = _inferTypeParameterFromAll(
- typesFromDownwardsInference![i],
+ previouslyInferredTypes![i],
constraint,
extendsConstraint,
clientLibrary,
isContravariant: typeParam.variance == Variance.contravariant,
- preferUpwardsInference: !typeParam.isLegacyCovariant);
+ isLegacyCovariant: typeParam.isLegacyCovariant);
}
}
- if (!downwardsInferPhase) {
+ if (!partial) {
assert(typeParametersToInfer.length == inferredTypes.length);
FreshTypeParameters freshTypeParameters =
getFreshTypeParameters(typeParametersToInfer);
@@ -337,6 +339,8 @@
}
}
}
+
+ return inferredTypes;
}
@override
@@ -502,44 +506,48 @@
/// Performs upwards inference, producing a final set of inferred types that
/// does not contain references to the "unknown type".
- void upwardsInfer(
+ List<DartType> upwardsInfer(
TypeConstraintGatherer gatherer,
List<TypeParameter> typeParametersToInfer,
- List<DartType> inferredTypes,
+ List<DartType> previouslyInferredTypes,
Library clientLibrary) =>
- _chooseTypes(
- gatherer, typeParametersToInfer, inferredTypes, clientLibrary,
- downwardsInferPhase: false);
+ _chooseTypes(gatherer, typeParametersToInfer, previouslyInferredTypes,
+ clientLibrary,
+ partial: false);
/// Computes (or recomputes) a set of [inferredTypes] based on the constraints
/// that have been recorded so far.
- void _chooseTypes(
+ List<DartType> _chooseTypes(
TypeConstraintGatherer gatherer,
List<TypeParameter> typeParametersToInfer,
- List<DartType> inferredTypes,
+ List<DartType>? previouslyInferredTypes,
Library clientLibrary,
- {required bool downwardsInferPhase}) {
- inferTypeFromConstraints(gatherer.computeConstraints(clientLibrary),
- typeParametersToInfer, inferredTypes, clientLibrary,
- downwardsInferPhase: downwardsInferPhase);
+ {required bool partial}) {
+ List<DartType> inferredTypes = inferTypeFromConstraints(
+ gatherer.computeConstraints(clientLibrary),
+ typeParametersToInfer,
+ previouslyInferredTypes,
+ clientLibrary,
+ partial: partial);
for (int i = 0; i < inferredTypes.length; i++) {
inferredTypes[i] = demoteTypeInLibrary(inferredTypes[i], clientLibrary);
}
+ return inferredTypes;
}
DartType _inferTypeParameterFromAll(
- DartType typeFromContextInference,
+ DartType typeFromPreviousInference,
TypeConstraint constraint,
DartType? extendsConstraint,
Library clientLibrary,
{bool isContravariant: false,
- bool preferUpwardsInference: false}) {
- // See if we already fixed this type from downwards inference.
- // If so, then we aren't allowed to change it based on argument types unless
- // [preferUpwardsInference] is true.
- if (!preferUpwardsInference && isKnown(typeFromContextInference)) {
- return typeFromContextInference;
+ bool isLegacyCovariant: true}) {
+ // See if we already fixed this type in a previous inference step.
+ // If so, then we aren't allowed to change it unless [isLegacyCovariant] is
+ // false.
+ if (isLegacyCovariant && isKnown(typeFromPreviousInference)) {
+ return typeFromPreviousInference;
}
if (extendsConstraint != null) {
@@ -559,8 +567,21 @@
isContravariant: isContravariant);
}
- DartType _inferTypeParameterFromContext(TypeConstraint constraint,
- DartType? extendsConstraint, Library clientLibrary) {
+ DartType _inferTypeParameterFromContext(
+ DartType? typeFromPreviousInference,
+ TypeConstraint constraint,
+ DartType? extendsConstraint,
+ Library clientLibrary,
+ {bool isLegacyCovariant: true}) {
+ // See if we already fixed this type in a previous inference step.
+ // If so, then we aren't allowed to change it unless [isLegacyCovariant] is
+ // false.
+ if (isLegacyCovariant &&
+ typeFromPreviousInference != null &&
+ isKnown(typeFromPreviousInference)) {
+ return typeFromPreviousInference;
+ }
+
DartType t = solveTypeConstraint(
constraint,
clientLibrary.isNonNullableByDefault
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test_base.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test_base.dart
index 3309b0b..dfb95a3 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test_base.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test_base.dart
@@ -156,10 +156,9 @@
? null
: functionTypeNode.positionalParameters;
- List<DartType> inferredTypeNodes;
+ List<DartType>? inferredTypeNodes;
if (inferredTypesFromDownwardPhase == null) {
- inferredTypeNodes = new List<DartType>.generate(
- typeParameterNodesToInfer.length, (_) => new UnknownType());
+ inferredTypeNodes = null;
} else {
inferredTypeNodes = parseTypes(inferredTypesFromDownwardPhase);
}
@@ -171,12 +170,12 @@
returnContextTypeNode,
testLibrary);
if (formalTypeNodes == null) {
- typeSchemaEnvironment.partialInfer(gatherer, typeParameterNodesToInfer,
- inferredTypeNodes, testLibrary);
+ inferredTypeNodes = typeSchemaEnvironment.partialInfer(gatherer,
+ typeParameterNodesToInfer, inferredTypeNodes, testLibrary);
} else {
gatherer.constrainArguments(formalTypeNodes, actualTypeNodes!);
- typeSchemaEnvironment.upwardsInfer(gatherer, typeParameterNodesToInfer,
- inferredTypeNodes, testLibrary);
+ inferredTypeNodes = typeSchemaEnvironment.upwardsInfer(gatherer,
+ typeParameterNodesToInfer, inferredTypeNodes!, testLibrary);
}
assert(
@@ -204,18 +203,15 @@
TypeConstraint typeConstraint = parseConstraint(constraints);
DartType expectedTypeNode = parseType(expected);
TypeParameter typeParameterNode = typeParameterNodes.single;
- List<DartType> inferredTypeNodes = <DartType>[
- inferredTypeFromDownwardPhase == null
- ? new UnknownType()
- : parseType(inferredTypeFromDownwardPhase)
- ];
+ List<DartType>? inferredTypeNodes = inferredTypeFromDownwardPhase == null
+ ? null
+ : <DartType>[parseType(inferredTypeFromDownwardPhase)];
- typeSchemaEnvironment.inferTypeFromConstraints(
- {typeParameterNode: typeConstraint},
- [typeParameterNode],
- inferredTypeNodes,
- testLibrary,
- downwardsInferPhase: downwardsInferPhase);
+ inferredTypeNodes = typeSchemaEnvironment.inferTypeFromConstraints({
+ typeParameterNode: typeConstraint
+ }, [
+ typeParameterNode
+ ], inferredTypeNodes, testLibrary, partial: downwardsInferPhase);
expect(inferredTypeNodes.single, expectedTypeNode);
});
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 83bb81c..0b2a65c 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -444,6 +444,7 @@
nottest
null'ed
numerator
+nums
ob
obool
observable
diff --git a/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart
new file mode 100644
index 0000000..7896c7a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that when the feature is enabled, types supplied by downward inference
+// are preferred over those available via horizontal inference.
+//
+// The way this happens is that the type parameter is "fixed" after the downward
+// inference phase and is not changed in further inference phases.
+
+testProductOfNums(List<num> values) {
+ num a = values.fold(1, (p, v) => p * v);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.textual_outline.expect b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.textual_outline.expect
new file mode 100644
index 0000000..67376a5
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+testProductOfNums(List<num> values) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9079d6c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+testProductOfNums(List<num> values) {}
diff --git a/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.weak.expect b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.weak.expect
new file mode 100644
index 0000000..e07090c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.weak.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method testProductOfNums(core::List<core::num> values) → dynamic {
+ core::num a = values.{core::Iterable::fold}<core::num>(1, (core::num p, core::num v) → core::num => p.{core::num::*}(v){(core::num) → core::num}){(core::num, (core::num, core::num) → core::num) → core::num};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.weak.modular.expect b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.weak.modular.expect
new file mode 100644
index 0000000..e07090c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.weak.modular.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method testProductOfNums(core::List<core::num> values) → dynamic {
+ core::num a = values.{core::Iterable::fold}<core::num>(1, (core::num p, core::num v) → core::num => p.{core::num::*}(v){(core::num) → core::num}){(core::num, (core::num, core::num) → core::num) → core::num};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.weak.outline.expect b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.weak.outline.expect
new file mode 100644
index 0000000..f885afa
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.weak.outline.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method testProductOfNums(core::List<core::num> values) → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.weak.transformed.expect b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.weak.transformed.expect
new file mode 100644
index 0000000..e07090c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/downward_inference_preferred_over_horizontal.dart.weak.transformed.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method testProductOfNums(core::List<core::num> values) → dynamic {
+ core::num a = values.{core::Iterable::fold}<core::num>(1, (core::num p, core::num v) → core::num => p.{core::num::*}(v){(core::num) → core::num}){(core::num, (core::num, core::num) → core::num) → core::num};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart
new file mode 100644
index 0000000..d6220a0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart
@@ -0,0 +1,173 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that horizontal inference works properly when the invocation is an
+// extension member. This is an important corner case because the front end
+// adds an implicit `this` argument to extension members as part of the lowering
+// process. We need to make sure that the dependency tracking logic properly
+// accounts for this extra argument.
+
+// SharedOptions=--enable-experiment=inference-update-1
+
+testLaterUnnamedParameter(int i) {
+ i._laterUnnamedParameter(0, (x) {
+ x;
+ });
+}
+
+/// This special case verifies that the implementations correctly associate the
+/// zeroth positional parameter with the corresponding argument (even if that
+/// argument isn't in the zeroth position at the call site).
+testLaterUnnamedParameterDependsOnNamedParameter(int i) {
+ i._laterUnnamedParameterDependsOnNamedParameter(a: 0, (x) {
+ x;
+ });
+}
+
+testEarlierUnnamedParameter(int i) {
+ i._earlierUnnamedParameter((x) {
+ x;
+ }, 0);
+}
+
+testLaterNamedParameter(int i) {
+ i._laterNamedParameter(
+ a: 0,
+ b: (x) {
+ x;
+ });
+}
+
+testEarlierNamedParameter(int i) {
+ i._earlierNamedParameter(
+ a: (x) {
+ x;
+ },
+ b: 0);
+}
+
+/// This special case verifies that the implementations correctly associate the
+/// zeroth positional parameter with the corresponding argument (even if that
+/// argument isn't in the zeroth position at the call site).
+testEarlierNamedParameterDependsOnUnnamedParameter(int i) {
+ i._earlierNamedParameterDependsOnUnnamedParameter(a: (x) {
+ x;
+ }, 0);
+}
+
+testPropagateToReturnType(int i) {
+ i._propagateToReturnType(0, (x) => [x]);
+}
+
+// The test cases below exercise situations where there are multiple closures in
+// the invocation, and they need to be inferred in the right order.
+
+testClosureAsParameterType(int i) {
+ i._closureAsParameterType(() => 0, (h) => [h()])
+ ;
+}
+
+testPropagateToEarlierClosure(int i) {
+ i._propagateToEarlierClosure((x) => [x], () => 0)
+ ;
+}
+
+testPropagateToLaterClosure(int i) {
+ i._propagateToLaterClosure(() => 0, (x) => [x])
+ ;
+}
+
+testLongDependencyChain(int i) {
+ i._longDependencyChain(() => [0], (x) => x.single,
+ (y) => {y})
+ ;
+}
+
+testDependencyCycle(int i) {
+ i._dependencyCycle((x) => [x],
+ (y) => {y})
+ ;
+}
+
+testPropagateFromContravariantReturnType(int i) {
+ i._propagateFromContravariantReturnType(() => (int i) {}, (x) => [x])
+ ;
+}
+
+testPropagateToContravariantParameterType(int i) {
+ i._propagateToContravariantParameterType(() => 0, (x) => [x])
+ ;
+}
+
+testReturnTypeRefersToMultipleTypeVars(int i) {
+ i._returnTypeRefersToMultipleTypeVars(() => {0: ''}, (k) {
+ k;
+ }, (v) {
+ v;
+ });
+}
+
+testUnnecessaryDueToNoDependency(int i) {
+ i._unnecessaryDueToNoDependency(() => 0, null);
+}
+
+testUnnecessaryDueToExplicitParameterTypeNamed(int i) {
+ var a = i._unnecessaryDueToExplicitParameterTypeNamed(null, ({int? x, required y}) => (x ?? 0) + y);
+ a;
+}
+
+testParenthesized(int i) {
+ i._parenthesized(0, ((x) {
+ x;
+ }));
+}
+
+testParenthesizedNamed(int i) {
+ i._parenthesizedNamed(
+ a: 0,
+ b: ((x) {
+ x;
+ }));
+}
+
+testParenthesizedTwice(int i) {
+ i._parenthesizedTwice(0, (((x) {
+ x;
+ })));
+}
+
+testParenthesizedTwiceNamed(int i) {
+ i._parenthesizedTwiceNamed(
+ a: 0,
+ b: (((x) {
+ x;
+ })));
+}
+
+extension on int {
+ T _laterUnnamedParameter<T>(T x, void Function(T) y) => throw '';
+ void _laterUnnamedParameterDependsOnNamedParameter<T>(void Function(T) x, {required T a}) => throw '';
+ void _earlierUnnamedParameter<T>(void Function(T) x, T y) => throw '';
+ void _laterNamedParameter<T>({required T a, required void Function(T) b}) => throw '';
+ void _earlierNamedParameter<T>({required void Function(T) a, required T b}) => throw '';
+ void _earlierNamedParameterDependsOnUnnamedParameter<T>(T b, {required void Function(T) a}) => throw '';
+ U _propagateToReturnType<T, U>(T x, U Function(T) y) => throw '';
+ U _closureAsParameterType<T, U>(T x, U Function(T) y) => throw '';
+ U _propagateToEarlierClosure<T, U>(U Function(T) x, T Function() y) => throw '';
+ U _propagateToLaterClosure<T, U>(T Function() x, U Function(T) y) => throw '';
+ V _longDependencyChain<T, U, V>(T Function() x, U Function(T) y, V Function(U) z) => throw '';
+ Map<T, U> _dependencyCycle<T, U>(T Function(U) x, U Function(T) y) => throw '';
+ U _propagateFromContravariantReturnType<T, U>(void Function(T) Function() x, U Function(T) y) => throw '';
+ U _propagateToContravariantParameterType<T, U>(T Function() x, U Function(void Function(T)) y) => throw '';
+ void _returnTypeRefersToMultipleTypeVars<T, U>(
+ Map<T, U> Function() x, void Function(T) y, void Function(U) z) => throw '';
+ T _unnecessaryDueToNoDependency<T>(T Function() x, T y) => throw '';
+ T _unnecessaryDueToExplicitParameterTypeNamed<T>(T x, T Function({required T x, required int y}) y) => throw '';
+ void _parenthesized<T>(T x, void Function(T) y) => throw '';
+ void _parenthesizedNamed<T>({required T a, required void Function(T) b}) => throw '';
+ void _parenthesizedTwice<T>(T x, void Function(T) y) => throw '';
+ void _parenthesizedTwiceNamed<T>({required T a, required void Function(T) b}) => throw '';
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.textual_outline.expect b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.textual_outline.expect
new file mode 100644
index 0000000..3732332
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.textual_outline.expect
@@ -0,0 +1,68 @@
+testLaterUnnamedParameter(int i) {}
+testLaterUnnamedParameterDependsOnNamedParameter(int i) {}
+testEarlierUnnamedParameter(int i) {}
+testLaterNamedParameter(int i) {}
+testEarlierNamedParameter(int i) {}
+testEarlierNamedParameterDependsOnUnnamedParameter(int i) {}
+testPropagateToReturnType(int i) {}
+testClosureAsParameterType(int i) {}
+testPropagateToEarlierClosure(int i) {}
+testPropagateToLaterClosure(int i) {}
+testLongDependencyChain(int i) {}
+testDependencyCycle(int i) {}
+testPropagateFromContravariantReturnType(int i) {}
+testPropagateToContravariantParameterType(int i) {}
+testReturnTypeRefersToMultipleTypeVars(int i) {}
+testUnnecessaryDueToNoDependency(int i) {}
+testUnnecessaryDueToExplicitParameterTypeNamed(int i) {}
+testParenthesized(int i) {}
+testParenthesizedNamed(int i) {}
+testParenthesizedTwice(int i) {}
+testParenthesizedTwiceNamed(int i) {}
+
+extension on int {
+ T _laterUnnamedParameter<T>(T x, void Function(T) y) => throw '';
+ void _laterUnnamedParameterDependsOnNamedParameter<T>(void Function(T) x,
+ {required T a}) =>
+ throw '';
+ void _earlierUnnamedParameter<T>(void Function(T) x, T y) => throw '';
+ void _laterNamedParameter<T>({required T a, required void Function(T) b}) =>
+ throw '';
+ void _earlierNamedParameter<T>({required void Function(T) a, required T b}) =>
+ throw '';
+ void _earlierNamedParameterDependsOnUnnamedParameter<T>(T b,
+ {required void Function(T) a}) =>
+ throw '';
+ U _propagateToReturnType<T, U>(T x, U Function(T) y) => throw '';
+ U _closureAsParameterType<T, U>(T x, U Function(T) y) => throw '';
+ U _propagateToEarlierClosure<T, U>(U Function(T) x, T Function() y) =>
+ throw '';
+ U _propagateToLaterClosure<T, U>(T Function() x, U Function(T) y) => throw '';
+ V _longDependencyChain<T, U, V>(
+ T Function() x, U Function(T) y, V Function(U) z) =>
+ throw '';
+ Map<T, U> _dependencyCycle<T, U>(T Function(U) x, U Function(T) y) =>
+ throw '';
+ U _propagateFromContravariantReturnType<T, U>(
+ void Function(T) Function() x, U Function(T) y) =>
+ throw '';
+ U _propagateToContravariantParameterType<T, U>(
+ T Function() x, U Function(void Function(T)) y) =>
+ throw '';
+ void _returnTypeRefersToMultipleTypeVars<T, U>(
+ Map<T, U> Function() x, void Function(T) y, void Function(U) z) =>
+ throw '';
+ T _unnecessaryDueToNoDependency<T>(T Function() x, T y) => throw '';
+ T _unnecessaryDueToExplicitParameterTypeNamed<T>(
+ T x, T Function({required T x, required int y}) y) =>
+ throw '';
+ void _parenthesized<T>(T x, void Function(T) y) => throw '';
+ void _parenthesizedNamed<T>({required T a, required void Function(T) b}) =>
+ throw '';
+ void _parenthesizedTwice<T>(T x, void Function(T) y) => throw '';
+ void _parenthesizedTwiceNamed<T>(
+ {required T a, required void Function(T) b}) =>
+ throw '';
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5b33e9f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,67 @@
+extension on int {
+ Map<T, U> _dependencyCycle<T, U>(T Function(U) x, U Function(T) y) =>
+ throw '';
+ T _laterUnnamedParameter<T>(T x, void Function(T) y) => throw '';
+ T _unnecessaryDueToExplicitParameterTypeNamed<T>(
+ T x, T Function({required T x, required int y}) y) =>
+ throw '';
+ T _unnecessaryDueToNoDependency<T>(T Function() x, T y) => throw '';
+ U _closureAsParameterType<T, U>(T x, U Function(T) y) => throw '';
+ U _propagateFromContravariantReturnType<T, U>(
+ void Function(T) Function() x, U Function(T) y) =>
+ throw '';
+ U _propagateToContravariantParameterType<T, U>(
+ T Function() x, U Function(void Function(T)) y) =>
+ throw '';
+ U _propagateToEarlierClosure<T, U>(U Function(T) x, T Function() y) =>
+ throw '';
+ U _propagateToLaterClosure<T, U>(T Function() x, U Function(T) y) => throw '';
+ U _propagateToReturnType<T, U>(T x, U Function(T) y) => throw '';
+ V _longDependencyChain<T, U, V>(
+ T Function() x, U Function(T) y, V Function(U) z) =>
+ throw '';
+ void _earlierNamedParameter<T>({required void Function(T) a, required T b}) =>
+ throw '';
+ void _earlierNamedParameterDependsOnUnnamedParameter<T>(T b,
+ {required void Function(T) a}) =>
+ throw '';
+ void _earlierUnnamedParameter<T>(void Function(T) x, T y) => throw '';
+ void _laterNamedParameter<T>({required T a, required void Function(T) b}) =>
+ throw '';
+ void _laterUnnamedParameterDependsOnNamedParameter<T>(void Function(T) x,
+ {required T a}) =>
+ throw '';
+ void _parenthesized<T>(T x, void Function(T) y) => throw '';
+ void _parenthesizedNamed<T>({required T a, required void Function(T) b}) =>
+ throw '';
+ void _parenthesizedTwice<T>(T x, void Function(T) y) => throw '';
+ void _parenthesizedTwiceNamed<T>(
+ {required T a, required void Function(T) b}) =>
+ throw '';
+ void _returnTypeRefersToMultipleTypeVars<T, U>(
+ Map<T, U> Function() x, void Function(T) y, void Function(U) z) =>
+ throw '';
+}
+
+main() {}
+testClosureAsParameterType(int i) {}
+testDependencyCycle(int i) {}
+testEarlierNamedParameter(int i) {}
+testEarlierNamedParameterDependsOnUnnamedParameter(int i) {}
+testEarlierUnnamedParameter(int i) {}
+testLaterNamedParameter(int i) {}
+testLaterUnnamedParameter(int i) {}
+testLaterUnnamedParameterDependsOnNamedParameter(int i) {}
+testLongDependencyChain(int i) {}
+testParenthesized(int i) {}
+testParenthesizedNamed(int i) {}
+testParenthesizedTwice(int i) {}
+testParenthesizedTwiceNamed(int i) {}
+testPropagateFromContravariantReturnType(int i) {}
+testPropagateToContravariantParameterType(int i) {}
+testPropagateToEarlierClosure(int i) {}
+testPropagateToLaterClosure(int i) {}
+testPropagateToReturnType(int i) {}
+testReturnTypeRefersToMultipleTypeVars(int i) {}
+testUnnecessaryDueToExplicitParameterTypeNamed(int i) {}
+testUnnecessaryDueToNoDependency(int i) {}
diff --git a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.expect b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.expect
new file mode 100644
index 0000000..e09a14c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.expect
@@ -0,0 +1,232 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+extension _extension#0 on core::int {
+ method _laterUnnamedParameter = self::_extension#0|_laterUnnamedParameter;
+ tearoff _laterUnnamedParameter = self::_extension#0|get#_laterUnnamedParameter;
+ method _laterUnnamedParameterDependsOnNamedParameter = self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter;
+ tearoff _laterUnnamedParameterDependsOnNamedParameter = self::_extension#0|get#_laterUnnamedParameterDependsOnNamedParameter;
+ method _earlierUnnamedParameter = self::_extension#0|_earlierUnnamedParameter;
+ tearoff _earlierUnnamedParameter = self::_extension#0|get#_earlierUnnamedParameter;
+ method _laterNamedParameter = self::_extension#0|_laterNamedParameter;
+ tearoff _laterNamedParameter = self::_extension#0|get#_laterNamedParameter;
+ method _earlierNamedParameter = self::_extension#0|_earlierNamedParameter;
+ tearoff _earlierNamedParameter = self::_extension#0|get#_earlierNamedParameter;
+ method _earlierNamedParameterDependsOnUnnamedParameter = self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter;
+ tearoff _earlierNamedParameterDependsOnUnnamedParameter = self::_extension#0|get#_earlierNamedParameterDependsOnUnnamedParameter;
+ method _propagateToReturnType = self::_extension#0|_propagateToReturnType;
+ tearoff _propagateToReturnType = self::_extension#0|get#_propagateToReturnType;
+ method _closureAsParameterType = self::_extension#0|_closureAsParameterType;
+ tearoff _closureAsParameterType = self::_extension#0|get#_closureAsParameterType;
+ method _propagateToEarlierClosure = self::_extension#0|_propagateToEarlierClosure;
+ tearoff _propagateToEarlierClosure = self::_extension#0|get#_propagateToEarlierClosure;
+ method _propagateToLaterClosure = self::_extension#0|_propagateToLaterClosure;
+ tearoff _propagateToLaterClosure = self::_extension#0|get#_propagateToLaterClosure;
+ method _longDependencyChain = self::_extension#0|_longDependencyChain;
+ tearoff _longDependencyChain = self::_extension#0|get#_longDependencyChain;
+ method _dependencyCycle = self::_extension#0|_dependencyCycle;
+ tearoff _dependencyCycle = self::_extension#0|get#_dependencyCycle;
+ method _propagateFromContravariantReturnType = self::_extension#0|_propagateFromContravariantReturnType;
+ tearoff _propagateFromContravariantReturnType = self::_extension#0|get#_propagateFromContravariantReturnType;
+ method _propagateToContravariantParameterType = self::_extension#0|_propagateToContravariantParameterType;
+ tearoff _propagateToContravariantParameterType = self::_extension#0|get#_propagateToContravariantParameterType;
+ method _returnTypeRefersToMultipleTypeVars = self::_extension#0|_returnTypeRefersToMultipleTypeVars;
+ tearoff _returnTypeRefersToMultipleTypeVars = self::_extension#0|get#_returnTypeRefersToMultipleTypeVars;
+ method _unnecessaryDueToNoDependency = self::_extension#0|_unnecessaryDueToNoDependency;
+ tearoff _unnecessaryDueToNoDependency = self::_extension#0|get#_unnecessaryDueToNoDependency;
+ method _unnecessaryDueToExplicitParameterTypeNamed = self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed;
+ tearoff _unnecessaryDueToExplicitParameterTypeNamed = self::_extension#0|get#_unnecessaryDueToExplicitParameterTypeNamed;
+ method _parenthesized = self::_extension#0|_parenthesized;
+ tearoff _parenthesized = self::_extension#0|get#_parenthesized;
+ method _parenthesizedNamed = self::_extension#0|_parenthesizedNamed;
+ tearoff _parenthesizedNamed = self::_extension#0|get#_parenthesizedNamed;
+ method _parenthesizedTwice = self::_extension#0|_parenthesizedTwice;
+ tearoff _parenthesizedTwice = self::_extension#0|get#_parenthesizedTwice;
+ method _parenthesizedTwiceNamed = self::_extension#0|_parenthesizedTwiceNamed;
+ tearoff _parenthesizedTwiceNamed = self::_extension#0|get#_parenthesizedTwiceNamed;
+}
+static method testLaterUnnamedParameter(core::int i) → dynamic {
+ self::_extension#0|_laterUnnamedParameter<core::int>(i, 0, (core::int x) → void {
+ x;
+ });
+}
+static method testLaterUnnamedParameterDependsOnNamedParameter(core::int i) → dynamic {
+ self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter<core::int>(i, (core::int x) → void {
+ x;
+ }, a: 0);
+}
+static method testEarlierUnnamedParameter(core::int i) → dynamic {
+ self::_extension#0|_earlierUnnamedParameter<core::int>(i, (core::int x) → void {
+ x;
+ }, 0);
+}
+static method testLaterNamedParameter(core::int i) → dynamic {
+ self::_extension#0|_laterNamedParameter<core::int>(i, a: 0, b: (core::int x) → void {
+ x;
+ });
+}
+static method testEarlierNamedParameter(core::int i) → dynamic {
+ self::_extension#0|_earlierNamedParameter<core::int>(i, a: (core::int x) → void {
+ x;
+ }, b: 0);
+}
+static method testEarlierNamedParameterDependsOnUnnamedParameter(core::int i) → dynamic {
+ self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter<core::int>(i, 0, a: (core::int x) → void {
+ x;
+ });
+}
+static method testPropagateToReturnType(core::int i) → dynamic {
+ self::_extension#0|_propagateToReturnType<core::int, core::List<core::int>>(i, 0, (core::int x) → core::List<core::int> => <core::int>[x]);
+}
+static method testClosureAsParameterType(core::int i) → dynamic {
+ self::_extension#0|_closureAsParameterType<() → core::int, core::List<core::int>>(i, () → core::int => 0, (() → core::int h) → core::List<core::int> => <core::int>[h(){() → core::int}]);
+}
+static method testPropagateToEarlierClosure(core::int i) → dynamic {
+ self::_extension#0|_propagateToEarlierClosure<core::int, core::List<core::int>>(i, (core::int x) → core::List<core::int> => <core::int>[x], () → core::int => 0);
+}
+static method testPropagateToLaterClosure(core::int i) → dynamic {
+ self::_extension#0|_propagateToLaterClosure<core::int, core::List<core::int>>(i, () → core::int => 0, (core::int x) → core::List<core::int> => <core::int>[x]);
+}
+static method testLongDependencyChain(core::int i) → dynamic {
+ self::_extension#0|_longDependencyChain<core::List<core::int>, core::int, core::Set<core::int>>(i, () → core::List<core::int> => <core::int>[0], (core::List<core::int> x) → core::int => x.{core::Iterable::single}{core::int}, (core::int y) → core::Set<core::int> => block {
+ final core::Set<core::int> #t1 = col::LinkedHashSet::•<core::int>();
+ #t1.{core::Set::add}{Invariant}(y){(core::int) → core::bool};
+ } =>#t1);
+}
+static method testDependencyCycle(core::int i) → dynamic {
+ self::_extension#0|_dependencyCycle<core::List<core::Object?>, core::Set<core::Object?>>(i, (core::Object? x) → core::List<core::Object?> => <core::Object?>[x], (core::Object? y) → core::Set<core::Object?> => block {
+ final core::Set<core::Object?> #t2 = col::LinkedHashSet::•<core::Object?>();
+ #t2.{core::Set::add}{Invariant}(y){(core::Object?) → core::bool};
+ } =>#t2);
+}
+static method testPropagateFromContravariantReturnType(core::int i) → dynamic {
+ self::_extension#0|_propagateFromContravariantReturnType<core::int, core::List<core::int>>(i, () → (core::int) → void => (core::int i) → void {}, (core::int x) → core::List<core::int> => <core::int>[x]);
+}
+static method testPropagateToContravariantParameterType(core::int i) → dynamic {
+ self::_extension#0|_propagateToContravariantParameterType<core::int, core::List<(core::int) → void>>(i, () → core::int => 0, ((core::int) → void x) → core::List<(core::int) → void> => <(core::int) → void>[x]);
+}
+static method testReturnTypeRefersToMultipleTypeVars(core::int i) → dynamic {
+ self::_extension#0|_returnTypeRefersToMultipleTypeVars<core::int, core::String>(i, () → core::Map<core::int, core::String> => <core::int, core::String>{0: ""}, (core::int k) → void {
+ k;
+ }, (core::String v) → void {
+ v;
+ });
+}
+static method testUnnecessaryDueToNoDependency(core::int i) → dynamic {
+ self::_extension#0|_unnecessaryDueToNoDependency<core::int?>(i, () → core::int => 0, null);
+}
+static method testUnnecessaryDueToExplicitParameterTypeNamed(core::int i) → dynamic {
+ core::int? a = self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed<core::int?>(i, null, ({core::int? x = #C1, required core::int y = #C1}) → core::int => (let final core::int? #t3 = x in #t3 == null ?{core::int} 0 : #t3{core::int}).{core::num::+}(y){(core::num) → core::int});
+ a;
+}
+static method testParenthesized(core::int i) → dynamic {
+ self::_extension#0|_parenthesized<core::int>(i, 0, (core::int x) → void {
+ x;
+ });
+}
+static method testParenthesizedNamed(core::int i) → dynamic {
+ self::_extension#0|_parenthesizedNamed<core::int>(i, a: 0, b: (core::int x) → void {
+ x;
+ });
+}
+static method testParenthesizedTwice(core::int i) → dynamic {
+ self::_extension#0|_parenthesizedTwice<core::int>(i, 0, (core::int x) → void {
+ x;
+ });
+}
+static method testParenthesizedTwiceNamed(core::int i) → dynamic {
+ self::_extension#0|_parenthesizedTwiceNamed<core::int>(i, a: 0, b: (core::int x) → void {
+ x;
+ });
+}
+static method _extension#0|_laterUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_laterUnnamedParameter::T% x, (self::_extension#0|_laterUnnamedParameter::T%) → void y) → self::_extension#0|_laterUnnamedParameter::T%
+ return throw "";
+static method _extension#0|get#_laterUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, (T%) → void) → T%
+ return <T extends core::Object? = dynamic>(T% x, (T%) → void y) → T% => self::_extension#0|_laterUnnamedParameter<T%>(#this, x, y);
+static method _extension#0|_laterUnnamedParameterDependsOnNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter::T%) → void x, {required self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter::T% a = #C1}) → void
+ return throw "";
+static method _extension#0|get#_laterUnnamedParameterDependsOnNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>((T%) → void, {a: T%}) → void
+ return <T extends core::Object? = dynamic>((T%) → void x, {T% a = #C1}) → void => self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter<T%>(#this, x, a: a);
+static method _extension#0|_earlierUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_earlierUnnamedParameter::T%) → void x, self::_extension#0|_earlierUnnamedParameter::T% y) → void
+ return throw "";
+static method _extension#0|get#_earlierUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>((T%) → void, T%) → void
+ return <T extends core::Object? = dynamic>((T%) → void x, T% y) → void => self::_extension#0|_earlierUnnamedParameter<T%>(#this, x, y);
+static method _extension#0|_laterNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_laterNamedParameter::T% a = #C1, required (self::_extension#0|_laterNamedParameter::T%) → void b = #C1}) → void
+ return throw "";
+static method _extension#0|get#_laterNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>({T% a = #C1, (T%) → void b = #C1}) → void => self::_extension#0|_laterNamedParameter<T%>(#this, a: a, b: b);
+static method _extension#0|_earlierNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required (self::_extension#0|_earlierNamedParameter::T%) → void a = #C1, required self::_extension#0|_earlierNamedParameter::T% b = #C1}) → void
+ return throw "";
+static method _extension#0|get#_earlierNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: (T%) → void, b: T%}) → void
+ return <T extends core::Object? = dynamic>({(T%) → void a = #C1, T% b = #C1}) → void => self::_extension#0|_earlierNamedParameter<T%>(#this, a: a, b: b);
+static method _extension#0|_earlierNamedParameterDependsOnUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T% b, {required (self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T%) → void a = #C1}) → void
+ return throw "";
+static method _extension#0|get#_earlierNamedParameterDependsOnUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, {a: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>(T% b, {(T%) → void a = #C1}) → void => self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter<T%>(#this, b, a: a);
+static method _extension#0|_propagateToReturnType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_propagateToReturnType::T% x, (self::_extension#0|_propagateToReturnType::T%) → self::_extension#0|_propagateToReturnType::U% y) → self::_extension#0|_propagateToReturnType::U%
+ return throw "";
+static method _extension#0|get#_propagateToReturnType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T%, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T% x, (T%) → U% y) → U% => self::_extension#0|_propagateToReturnType<T%, U%>(#this, x, y);
+static method _extension#0|_closureAsParameterType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_closureAsParameterType::T% x, (self::_extension#0|_closureAsParameterType::T%) → self::_extension#0|_closureAsParameterType::U% y) → self::_extension#0|_closureAsParameterType::U%
+ return throw "";
+static method _extension#0|get#_closureAsParameterType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T%, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T% x, (T%) → U% y) → U% => self::_extension#0|_closureAsParameterType<T%, U%>(#this, x, y);
+static method _extension#0|_propagateToEarlierClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_propagateToEarlierClosure::T%) → self::_extension#0|_propagateToEarlierClosure::U% x, () → self::_extension#0|_propagateToEarlierClosure::T% y) → self::_extension#0|_propagateToEarlierClosure::U%
+ return throw "";
+static method _extension#0|get#_propagateToEarlierClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U%, () → T%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U% x, () → T% y) → U% => self::_extension#0|_propagateToEarlierClosure<T%, U%>(#this, x, y);
+static method _extension#0|_propagateToLaterClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToLaterClosure::T% x, (self::_extension#0|_propagateToLaterClosure::T%) → self::_extension#0|_propagateToLaterClosure::U% y) → self::_extension#0|_propagateToLaterClosure::U%
+ return throw "";
+static method _extension#0|get#_propagateToLaterClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T%, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T% x, (T%) → U% y) → U% => self::_extension#0|_propagateToLaterClosure<T%, U%>(#this, x, y);
+static method _extension#0|get#_longDependencyChain(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T%, (T%) → U%, (U%) → V%) → V%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T% x, (T%) → U% y, (U%) → V% z) → V% => self::_extension#0|_longDependencyChain<T%, U%, V%>(#this, x, y, z);
+static method _extension#0|_longDependencyChain<T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_longDependencyChain::T% x, (self::_extension#0|_longDependencyChain::T%) → self::_extension#0|_longDependencyChain::U% y, (self::_extension#0|_longDependencyChain::U%) → self::_extension#0|_longDependencyChain::V% z) → self::_extension#0|_longDependencyChain::V%
+ return throw "";
+static method _extension#0|_dependencyCycle<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_dependencyCycle::U%) → self::_extension#0|_dependencyCycle::T% x, (self::_extension#0|_dependencyCycle::T%) → self::_extension#0|_dependencyCycle::U% y) → core::Map<self::_extension#0|_dependencyCycle::T%, self::_extension#0|_dependencyCycle::U%>
+ return throw "";
+static method _extension#0|get#_dependencyCycle(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((U%) → T%, (T%) → U%) → core::Map<T%, U%>
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((U%) → T% x, (T%) → U% y) → core::Map<T%, U%> => self::_extension#0|_dependencyCycle<T%, U%>(#this, x, y);
+static method _extension#0|_propagateFromContravariantReturnType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → (self::_extension#0|_propagateFromContravariantReturnType::T%) → void x, (self::_extension#0|_propagateFromContravariantReturnType::T%) → self::_extension#0|_propagateFromContravariantReturnType::U% y) → self::_extension#0|_propagateFromContravariantReturnType::U%
+ return throw "";
+static method _extension#0|get#_propagateFromContravariantReturnType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → (T%) → void, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → (T%) → void x, (T%) → U% y) → U% => self::_extension#0|_propagateFromContravariantReturnType<T%, U%>(#this, x, y);
+static method _extension#0|_propagateToContravariantParameterType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToContravariantParameterType::T% x, ((self::_extension#0|_propagateToContravariantParameterType::T%) → void) → self::_extension#0|_propagateToContravariantParameterType::U% y) → self::_extension#0|_propagateToContravariantParameterType::U%
+ return throw "";
+static method _extension#0|get#_propagateToContravariantParameterType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T%, ((T%) → void) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T% x, ((T%) → void) → U% y) → U% => self::_extension#0|_propagateToContravariantParameterType<T%, U%>(#this, x, y);
+static method _extension#0|_returnTypeRefersToMultipleTypeVars<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → core::Map<self::_extension#0|_returnTypeRefersToMultipleTypeVars::T%, self::_extension#0|_returnTypeRefersToMultipleTypeVars::U%> x, (self::_extension#0|_returnTypeRefersToMultipleTypeVars::T%) → void y, (self::_extension#0|_returnTypeRefersToMultipleTypeVars::U%) → void z) → void
+ return throw "";
+static method _extension#0|get#_returnTypeRefersToMultipleTypeVars(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → core::Map<T%, U%>, (T%) → void, (U%) → void) → void
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → core::Map<T%, U%> x, (T%) → void y, (U%) → void z) → void => self::_extension#0|_returnTypeRefersToMultipleTypeVars<T%, U%>(#this, x, y, z);
+static method _extension#0|_unnecessaryDueToNoDependency<T extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_unnecessaryDueToNoDependency::T% x, self::_extension#0|_unnecessaryDueToNoDependency::T% y) → self::_extension#0|_unnecessaryDueToNoDependency::T%
+ return throw "";
+static method _extension#0|get#_unnecessaryDueToNoDependency(lowered final core::int #this) → <T extends core::Object? = dynamic>(() → T%, T%) → T%
+ return <T extends core::Object? = dynamic>(() → T% x, T% y) → T% => self::_extension#0|_unnecessaryDueToNoDependency<T%>(#this, x, y);
+static method _extension#0|_unnecessaryDueToExplicitParameterTypeNamed<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T% x, ({required x: self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T%, required y: core::int}) → self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T% y) → self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T%
+ return throw "";
+static method _extension#0|get#_unnecessaryDueToExplicitParameterTypeNamed(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, ({required x: T%, required y: core::int}) → T%) → T%
+ return <T extends core::Object? = dynamic>(T% x, ({required x: T%, required y: core::int}) → T% y) → T% => self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed<T%>(#this, x, y);
+static method _extension#0|_parenthesized<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_parenthesized::T% x, (self::_extension#0|_parenthesized::T%) → void y) → void
+ return throw "";
+static method _extension#0|get#_parenthesized(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, (T%) → void) → void
+ return <T extends core::Object? = dynamic>(T% x, (T%) → void y) → void => self::_extension#0|_parenthesized<T%>(#this, x, y);
+static method _extension#0|_parenthesizedNamed<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_parenthesizedNamed::T% a = #C1, required (self::_extension#0|_parenthesizedNamed::T%) → void b = #C1}) → void
+ return throw "";
+static method _extension#0|get#_parenthesizedNamed(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>({T% a = #C1, (T%) → void b = #C1}) → void => self::_extension#0|_parenthesizedNamed<T%>(#this, a: a, b: b);
+static method _extension#0|_parenthesizedTwice<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_parenthesizedTwice::T% x, (self::_extension#0|_parenthesizedTwice::T%) → void y) → void
+ return throw "";
+static method _extension#0|get#_parenthesizedTwice(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, (T%) → void) → void
+ return <T extends core::Object? = dynamic>(T% x, (T%) → void y) → void => self::_extension#0|_parenthesizedTwice<T%>(#this, x, y);
+static method _extension#0|_parenthesizedTwiceNamed<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_parenthesizedTwiceNamed::T% a = #C1, required (self::_extension#0|_parenthesizedTwiceNamed::T%) → void b = #C1}) → void
+ return throw "";
+static method _extension#0|get#_parenthesizedTwiceNamed(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>({T% a = #C1, (T%) → void b = #C1}) → void => self::_extension#0|_parenthesizedTwiceNamed<T%>(#this, a: a, b: b);
+static method main() → dynamic {}
+
+constants {
+ #C1 = null
+}
diff --git a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.modular.expect b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.modular.expect
new file mode 100644
index 0000000..e09a14c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.modular.expect
@@ -0,0 +1,232 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+extension _extension#0 on core::int {
+ method _laterUnnamedParameter = self::_extension#0|_laterUnnamedParameter;
+ tearoff _laterUnnamedParameter = self::_extension#0|get#_laterUnnamedParameter;
+ method _laterUnnamedParameterDependsOnNamedParameter = self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter;
+ tearoff _laterUnnamedParameterDependsOnNamedParameter = self::_extension#0|get#_laterUnnamedParameterDependsOnNamedParameter;
+ method _earlierUnnamedParameter = self::_extension#0|_earlierUnnamedParameter;
+ tearoff _earlierUnnamedParameter = self::_extension#0|get#_earlierUnnamedParameter;
+ method _laterNamedParameter = self::_extension#0|_laterNamedParameter;
+ tearoff _laterNamedParameter = self::_extension#0|get#_laterNamedParameter;
+ method _earlierNamedParameter = self::_extension#0|_earlierNamedParameter;
+ tearoff _earlierNamedParameter = self::_extension#0|get#_earlierNamedParameter;
+ method _earlierNamedParameterDependsOnUnnamedParameter = self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter;
+ tearoff _earlierNamedParameterDependsOnUnnamedParameter = self::_extension#0|get#_earlierNamedParameterDependsOnUnnamedParameter;
+ method _propagateToReturnType = self::_extension#0|_propagateToReturnType;
+ tearoff _propagateToReturnType = self::_extension#0|get#_propagateToReturnType;
+ method _closureAsParameterType = self::_extension#0|_closureAsParameterType;
+ tearoff _closureAsParameterType = self::_extension#0|get#_closureAsParameterType;
+ method _propagateToEarlierClosure = self::_extension#0|_propagateToEarlierClosure;
+ tearoff _propagateToEarlierClosure = self::_extension#0|get#_propagateToEarlierClosure;
+ method _propagateToLaterClosure = self::_extension#0|_propagateToLaterClosure;
+ tearoff _propagateToLaterClosure = self::_extension#0|get#_propagateToLaterClosure;
+ method _longDependencyChain = self::_extension#0|_longDependencyChain;
+ tearoff _longDependencyChain = self::_extension#0|get#_longDependencyChain;
+ method _dependencyCycle = self::_extension#0|_dependencyCycle;
+ tearoff _dependencyCycle = self::_extension#0|get#_dependencyCycle;
+ method _propagateFromContravariantReturnType = self::_extension#0|_propagateFromContravariantReturnType;
+ tearoff _propagateFromContravariantReturnType = self::_extension#0|get#_propagateFromContravariantReturnType;
+ method _propagateToContravariantParameterType = self::_extension#0|_propagateToContravariantParameterType;
+ tearoff _propagateToContravariantParameterType = self::_extension#0|get#_propagateToContravariantParameterType;
+ method _returnTypeRefersToMultipleTypeVars = self::_extension#0|_returnTypeRefersToMultipleTypeVars;
+ tearoff _returnTypeRefersToMultipleTypeVars = self::_extension#0|get#_returnTypeRefersToMultipleTypeVars;
+ method _unnecessaryDueToNoDependency = self::_extension#0|_unnecessaryDueToNoDependency;
+ tearoff _unnecessaryDueToNoDependency = self::_extension#0|get#_unnecessaryDueToNoDependency;
+ method _unnecessaryDueToExplicitParameterTypeNamed = self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed;
+ tearoff _unnecessaryDueToExplicitParameterTypeNamed = self::_extension#0|get#_unnecessaryDueToExplicitParameterTypeNamed;
+ method _parenthesized = self::_extension#0|_parenthesized;
+ tearoff _parenthesized = self::_extension#0|get#_parenthesized;
+ method _parenthesizedNamed = self::_extension#0|_parenthesizedNamed;
+ tearoff _parenthesizedNamed = self::_extension#0|get#_parenthesizedNamed;
+ method _parenthesizedTwice = self::_extension#0|_parenthesizedTwice;
+ tearoff _parenthesizedTwice = self::_extension#0|get#_parenthesizedTwice;
+ method _parenthesizedTwiceNamed = self::_extension#0|_parenthesizedTwiceNamed;
+ tearoff _parenthesizedTwiceNamed = self::_extension#0|get#_parenthesizedTwiceNamed;
+}
+static method testLaterUnnamedParameter(core::int i) → dynamic {
+ self::_extension#0|_laterUnnamedParameter<core::int>(i, 0, (core::int x) → void {
+ x;
+ });
+}
+static method testLaterUnnamedParameterDependsOnNamedParameter(core::int i) → dynamic {
+ self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter<core::int>(i, (core::int x) → void {
+ x;
+ }, a: 0);
+}
+static method testEarlierUnnamedParameter(core::int i) → dynamic {
+ self::_extension#0|_earlierUnnamedParameter<core::int>(i, (core::int x) → void {
+ x;
+ }, 0);
+}
+static method testLaterNamedParameter(core::int i) → dynamic {
+ self::_extension#0|_laterNamedParameter<core::int>(i, a: 0, b: (core::int x) → void {
+ x;
+ });
+}
+static method testEarlierNamedParameter(core::int i) → dynamic {
+ self::_extension#0|_earlierNamedParameter<core::int>(i, a: (core::int x) → void {
+ x;
+ }, b: 0);
+}
+static method testEarlierNamedParameterDependsOnUnnamedParameter(core::int i) → dynamic {
+ self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter<core::int>(i, 0, a: (core::int x) → void {
+ x;
+ });
+}
+static method testPropagateToReturnType(core::int i) → dynamic {
+ self::_extension#0|_propagateToReturnType<core::int, core::List<core::int>>(i, 0, (core::int x) → core::List<core::int> => <core::int>[x]);
+}
+static method testClosureAsParameterType(core::int i) → dynamic {
+ self::_extension#0|_closureAsParameterType<() → core::int, core::List<core::int>>(i, () → core::int => 0, (() → core::int h) → core::List<core::int> => <core::int>[h(){() → core::int}]);
+}
+static method testPropagateToEarlierClosure(core::int i) → dynamic {
+ self::_extension#0|_propagateToEarlierClosure<core::int, core::List<core::int>>(i, (core::int x) → core::List<core::int> => <core::int>[x], () → core::int => 0);
+}
+static method testPropagateToLaterClosure(core::int i) → dynamic {
+ self::_extension#0|_propagateToLaterClosure<core::int, core::List<core::int>>(i, () → core::int => 0, (core::int x) → core::List<core::int> => <core::int>[x]);
+}
+static method testLongDependencyChain(core::int i) → dynamic {
+ self::_extension#0|_longDependencyChain<core::List<core::int>, core::int, core::Set<core::int>>(i, () → core::List<core::int> => <core::int>[0], (core::List<core::int> x) → core::int => x.{core::Iterable::single}{core::int}, (core::int y) → core::Set<core::int> => block {
+ final core::Set<core::int> #t1 = col::LinkedHashSet::•<core::int>();
+ #t1.{core::Set::add}{Invariant}(y){(core::int) → core::bool};
+ } =>#t1);
+}
+static method testDependencyCycle(core::int i) → dynamic {
+ self::_extension#0|_dependencyCycle<core::List<core::Object?>, core::Set<core::Object?>>(i, (core::Object? x) → core::List<core::Object?> => <core::Object?>[x], (core::Object? y) → core::Set<core::Object?> => block {
+ final core::Set<core::Object?> #t2 = col::LinkedHashSet::•<core::Object?>();
+ #t2.{core::Set::add}{Invariant}(y){(core::Object?) → core::bool};
+ } =>#t2);
+}
+static method testPropagateFromContravariantReturnType(core::int i) → dynamic {
+ self::_extension#0|_propagateFromContravariantReturnType<core::int, core::List<core::int>>(i, () → (core::int) → void => (core::int i) → void {}, (core::int x) → core::List<core::int> => <core::int>[x]);
+}
+static method testPropagateToContravariantParameterType(core::int i) → dynamic {
+ self::_extension#0|_propagateToContravariantParameterType<core::int, core::List<(core::int) → void>>(i, () → core::int => 0, ((core::int) → void x) → core::List<(core::int) → void> => <(core::int) → void>[x]);
+}
+static method testReturnTypeRefersToMultipleTypeVars(core::int i) → dynamic {
+ self::_extension#0|_returnTypeRefersToMultipleTypeVars<core::int, core::String>(i, () → core::Map<core::int, core::String> => <core::int, core::String>{0: ""}, (core::int k) → void {
+ k;
+ }, (core::String v) → void {
+ v;
+ });
+}
+static method testUnnecessaryDueToNoDependency(core::int i) → dynamic {
+ self::_extension#0|_unnecessaryDueToNoDependency<core::int?>(i, () → core::int => 0, null);
+}
+static method testUnnecessaryDueToExplicitParameterTypeNamed(core::int i) → dynamic {
+ core::int? a = self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed<core::int?>(i, null, ({core::int? x = #C1, required core::int y = #C1}) → core::int => (let final core::int? #t3 = x in #t3 == null ?{core::int} 0 : #t3{core::int}).{core::num::+}(y){(core::num) → core::int});
+ a;
+}
+static method testParenthesized(core::int i) → dynamic {
+ self::_extension#0|_parenthesized<core::int>(i, 0, (core::int x) → void {
+ x;
+ });
+}
+static method testParenthesizedNamed(core::int i) → dynamic {
+ self::_extension#0|_parenthesizedNamed<core::int>(i, a: 0, b: (core::int x) → void {
+ x;
+ });
+}
+static method testParenthesizedTwice(core::int i) → dynamic {
+ self::_extension#0|_parenthesizedTwice<core::int>(i, 0, (core::int x) → void {
+ x;
+ });
+}
+static method testParenthesizedTwiceNamed(core::int i) → dynamic {
+ self::_extension#0|_parenthesizedTwiceNamed<core::int>(i, a: 0, b: (core::int x) → void {
+ x;
+ });
+}
+static method _extension#0|_laterUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_laterUnnamedParameter::T% x, (self::_extension#0|_laterUnnamedParameter::T%) → void y) → self::_extension#0|_laterUnnamedParameter::T%
+ return throw "";
+static method _extension#0|get#_laterUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, (T%) → void) → T%
+ return <T extends core::Object? = dynamic>(T% x, (T%) → void y) → T% => self::_extension#0|_laterUnnamedParameter<T%>(#this, x, y);
+static method _extension#0|_laterUnnamedParameterDependsOnNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter::T%) → void x, {required self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter::T% a = #C1}) → void
+ return throw "";
+static method _extension#0|get#_laterUnnamedParameterDependsOnNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>((T%) → void, {a: T%}) → void
+ return <T extends core::Object? = dynamic>((T%) → void x, {T% a = #C1}) → void => self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter<T%>(#this, x, a: a);
+static method _extension#0|_earlierUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_earlierUnnamedParameter::T%) → void x, self::_extension#0|_earlierUnnamedParameter::T% y) → void
+ return throw "";
+static method _extension#0|get#_earlierUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>((T%) → void, T%) → void
+ return <T extends core::Object? = dynamic>((T%) → void x, T% y) → void => self::_extension#0|_earlierUnnamedParameter<T%>(#this, x, y);
+static method _extension#0|_laterNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_laterNamedParameter::T% a = #C1, required (self::_extension#0|_laterNamedParameter::T%) → void b = #C1}) → void
+ return throw "";
+static method _extension#0|get#_laterNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>({T% a = #C1, (T%) → void b = #C1}) → void => self::_extension#0|_laterNamedParameter<T%>(#this, a: a, b: b);
+static method _extension#0|_earlierNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required (self::_extension#0|_earlierNamedParameter::T%) → void a = #C1, required self::_extension#0|_earlierNamedParameter::T% b = #C1}) → void
+ return throw "";
+static method _extension#0|get#_earlierNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: (T%) → void, b: T%}) → void
+ return <T extends core::Object? = dynamic>({(T%) → void a = #C1, T% b = #C1}) → void => self::_extension#0|_earlierNamedParameter<T%>(#this, a: a, b: b);
+static method _extension#0|_earlierNamedParameterDependsOnUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T% b, {required (self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T%) → void a = #C1}) → void
+ return throw "";
+static method _extension#0|get#_earlierNamedParameterDependsOnUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, {a: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>(T% b, {(T%) → void a = #C1}) → void => self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter<T%>(#this, b, a: a);
+static method _extension#0|_propagateToReturnType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_propagateToReturnType::T% x, (self::_extension#0|_propagateToReturnType::T%) → self::_extension#0|_propagateToReturnType::U% y) → self::_extension#0|_propagateToReturnType::U%
+ return throw "";
+static method _extension#0|get#_propagateToReturnType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T%, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T% x, (T%) → U% y) → U% => self::_extension#0|_propagateToReturnType<T%, U%>(#this, x, y);
+static method _extension#0|_closureAsParameterType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_closureAsParameterType::T% x, (self::_extension#0|_closureAsParameterType::T%) → self::_extension#0|_closureAsParameterType::U% y) → self::_extension#0|_closureAsParameterType::U%
+ return throw "";
+static method _extension#0|get#_closureAsParameterType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T%, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T% x, (T%) → U% y) → U% => self::_extension#0|_closureAsParameterType<T%, U%>(#this, x, y);
+static method _extension#0|_propagateToEarlierClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_propagateToEarlierClosure::T%) → self::_extension#0|_propagateToEarlierClosure::U% x, () → self::_extension#0|_propagateToEarlierClosure::T% y) → self::_extension#0|_propagateToEarlierClosure::U%
+ return throw "";
+static method _extension#0|get#_propagateToEarlierClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U%, () → T%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U% x, () → T% y) → U% => self::_extension#0|_propagateToEarlierClosure<T%, U%>(#this, x, y);
+static method _extension#0|_propagateToLaterClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToLaterClosure::T% x, (self::_extension#0|_propagateToLaterClosure::T%) → self::_extension#0|_propagateToLaterClosure::U% y) → self::_extension#0|_propagateToLaterClosure::U%
+ return throw "";
+static method _extension#0|get#_propagateToLaterClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T%, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T% x, (T%) → U% y) → U% => self::_extension#0|_propagateToLaterClosure<T%, U%>(#this, x, y);
+static method _extension#0|get#_longDependencyChain(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T%, (T%) → U%, (U%) → V%) → V%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T% x, (T%) → U% y, (U%) → V% z) → V% => self::_extension#0|_longDependencyChain<T%, U%, V%>(#this, x, y, z);
+static method _extension#0|_longDependencyChain<T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_longDependencyChain::T% x, (self::_extension#0|_longDependencyChain::T%) → self::_extension#0|_longDependencyChain::U% y, (self::_extension#0|_longDependencyChain::U%) → self::_extension#0|_longDependencyChain::V% z) → self::_extension#0|_longDependencyChain::V%
+ return throw "";
+static method _extension#0|_dependencyCycle<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_dependencyCycle::U%) → self::_extension#0|_dependencyCycle::T% x, (self::_extension#0|_dependencyCycle::T%) → self::_extension#0|_dependencyCycle::U% y) → core::Map<self::_extension#0|_dependencyCycle::T%, self::_extension#0|_dependencyCycle::U%>
+ return throw "";
+static method _extension#0|get#_dependencyCycle(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((U%) → T%, (T%) → U%) → core::Map<T%, U%>
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((U%) → T% x, (T%) → U% y) → core::Map<T%, U%> => self::_extension#0|_dependencyCycle<T%, U%>(#this, x, y);
+static method _extension#0|_propagateFromContravariantReturnType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → (self::_extension#0|_propagateFromContravariantReturnType::T%) → void x, (self::_extension#0|_propagateFromContravariantReturnType::T%) → self::_extension#0|_propagateFromContravariantReturnType::U% y) → self::_extension#0|_propagateFromContravariantReturnType::U%
+ return throw "";
+static method _extension#0|get#_propagateFromContravariantReturnType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → (T%) → void, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → (T%) → void x, (T%) → U% y) → U% => self::_extension#0|_propagateFromContravariantReturnType<T%, U%>(#this, x, y);
+static method _extension#0|_propagateToContravariantParameterType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToContravariantParameterType::T% x, ((self::_extension#0|_propagateToContravariantParameterType::T%) → void) → self::_extension#0|_propagateToContravariantParameterType::U% y) → self::_extension#0|_propagateToContravariantParameterType::U%
+ return throw "";
+static method _extension#0|get#_propagateToContravariantParameterType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T%, ((T%) → void) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T% x, ((T%) → void) → U% y) → U% => self::_extension#0|_propagateToContravariantParameterType<T%, U%>(#this, x, y);
+static method _extension#0|_returnTypeRefersToMultipleTypeVars<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → core::Map<self::_extension#0|_returnTypeRefersToMultipleTypeVars::T%, self::_extension#0|_returnTypeRefersToMultipleTypeVars::U%> x, (self::_extension#0|_returnTypeRefersToMultipleTypeVars::T%) → void y, (self::_extension#0|_returnTypeRefersToMultipleTypeVars::U%) → void z) → void
+ return throw "";
+static method _extension#0|get#_returnTypeRefersToMultipleTypeVars(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → core::Map<T%, U%>, (T%) → void, (U%) → void) → void
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → core::Map<T%, U%> x, (T%) → void y, (U%) → void z) → void => self::_extension#0|_returnTypeRefersToMultipleTypeVars<T%, U%>(#this, x, y, z);
+static method _extension#0|_unnecessaryDueToNoDependency<T extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_unnecessaryDueToNoDependency::T% x, self::_extension#0|_unnecessaryDueToNoDependency::T% y) → self::_extension#0|_unnecessaryDueToNoDependency::T%
+ return throw "";
+static method _extension#0|get#_unnecessaryDueToNoDependency(lowered final core::int #this) → <T extends core::Object? = dynamic>(() → T%, T%) → T%
+ return <T extends core::Object? = dynamic>(() → T% x, T% y) → T% => self::_extension#0|_unnecessaryDueToNoDependency<T%>(#this, x, y);
+static method _extension#0|_unnecessaryDueToExplicitParameterTypeNamed<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T% x, ({required x: self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T%, required y: core::int}) → self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T% y) → self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T%
+ return throw "";
+static method _extension#0|get#_unnecessaryDueToExplicitParameterTypeNamed(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, ({required x: T%, required y: core::int}) → T%) → T%
+ return <T extends core::Object? = dynamic>(T% x, ({required x: T%, required y: core::int}) → T% y) → T% => self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed<T%>(#this, x, y);
+static method _extension#0|_parenthesized<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_parenthesized::T% x, (self::_extension#0|_parenthesized::T%) → void y) → void
+ return throw "";
+static method _extension#0|get#_parenthesized(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, (T%) → void) → void
+ return <T extends core::Object? = dynamic>(T% x, (T%) → void y) → void => self::_extension#0|_parenthesized<T%>(#this, x, y);
+static method _extension#0|_parenthesizedNamed<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_parenthesizedNamed::T% a = #C1, required (self::_extension#0|_parenthesizedNamed::T%) → void b = #C1}) → void
+ return throw "";
+static method _extension#0|get#_parenthesizedNamed(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>({T% a = #C1, (T%) → void b = #C1}) → void => self::_extension#0|_parenthesizedNamed<T%>(#this, a: a, b: b);
+static method _extension#0|_parenthesizedTwice<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_parenthesizedTwice::T% x, (self::_extension#0|_parenthesizedTwice::T%) → void y) → void
+ return throw "";
+static method _extension#0|get#_parenthesizedTwice(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, (T%) → void) → void
+ return <T extends core::Object? = dynamic>(T% x, (T%) → void y) → void => self::_extension#0|_parenthesizedTwice<T%>(#this, x, y);
+static method _extension#0|_parenthesizedTwiceNamed<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_parenthesizedTwiceNamed::T% a = #C1, required (self::_extension#0|_parenthesizedTwiceNamed::T%) → void b = #C1}) → void
+ return throw "";
+static method _extension#0|get#_parenthesizedTwiceNamed(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>({T% a = #C1, (T%) → void b = #C1}) → void => self::_extension#0|_parenthesizedTwiceNamed<T%>(#this, a: a, b: b);
+static method main() → dynamic {}
+
+constants {
+ #C1 = null
+}
diff --git a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.outline.expect b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.outline.expect
new file mode 100644
index 0000000..dae2ab4
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.outline.expect
@@ -0,0 +1,176 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+extension _extension#0 on core::int {
+ method _laterUnnamedParameter = self::_extension#0|_laterUnnamedParameter;
+ tearoff _laterUnnamedParameter = self::_extension#0|get#_laterUnnamedParameter;
+ method _laterUnnamedParameterDependsOnNamedParameter = self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter;
+ tearoff _laterUnnamedParameterDependsOnNamedParameter = self::_extension#0|get#_laterUnnamedParameterDependsOnNamedParameter;
+ method _earlierUnnamedParameter = self::_extension#0|_earlierUnnamedParameter;
+ tearoff _earlierUnnamedParameter = self::_extension#0|get#_earlierUnnamedParameter;
+ method _laterNamedParameter = self::_extension#0|_laterNamedParameter;
+ tearoff _laterNamedParameter = self::_extension#0|get#_laterNamedParameter;
+ method _earlierNamedParameter = self::_extension#0|_earlierNamedParameter;
+ tearoff _earlierNamedParameter = self::_extension#0|get#_earlierNamedParameter;
+ method _earlierNamedParameterDependsOnUnnamedParameter = self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter;
+ tearoff _earlierNamedParameterDependsOnUnnamedParameter = self::_extension#0|get#_earlierNamedParameterDependsOnUnnamedParameter;
+ method _propagateToReturnType = self::_extension#0|_propagateToReturnType;
+ tearoff _propagateToReturnType = self::_extension#0|get#_propagateToReturnType;
+ method _closureAsParameterType = self::_extension#0|_closureAsParameterType;
+ tearoff _closureAsParameterType = self::_extension#0|get#_closureAsParameterType;
+ method _propagateToEarlierClosure = self::_extension#0|_propagateToEarlierClosure;
+ tearoff _propagateToEarlierClosure = self::_extension#0|get#_propagateToEarlierClosure;
+ method _propagateToLaterClosure = self::_extension#0|_propagateToLaterClosure;
+ tearoff _propagateToLaterClosure = self::_extension#0|get#_propagateToLaterClosure;
+ method _longDependencyChain = self::_extension#0|_longDependencyChain;
+ tearoff _longDependencyChain = self::_extension#0|get#_longDependencyChain;
+ method _dependencyCycle = self::_extension#0|_dependencyCycle;
+ tearoff _dependencyCycle = self::_extension#0|get#_dependencyCycle;
+ method _propagateFromContravariantReturnType = self::_extension#0|_propagateFromContravariantReturnType;
+ tearoff _propagateFromContravariantReturnType = self::_extension#0|get#_propagateFromContravariantReturnType;
+ method _propagateToContravariantParameterType = self::_extension#0|_propagateToContravariantParameterType;
+ tearoff _propagateToContravariantParameterType = self::_extension#0|get#_propagateToContravariantParameterType;
+ method _returnTypeRefersToMultipleTypeVars = self::_extension#0|_returnTypeRefersToMultipleTypeVars;
+ tearoff _returnTypeRefersToMultipleTypeVars = self::_extension#0|get#_returnTypeRefersToMultipleTypeVars;
+ method _unnecessaryDueToNoDependency = self::_extension#0|_unnecessaryDueToNoDependency;
+ tearoff _unnecessaryDueToNoDependency = self::_extension#0|get#_unnecessaryDueToNoDependency;
+ method _unnecessaryDueToExplicitParameterTypeNamed = self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed;
+ tearoff _unnecessaryDueToExplicitParameterTypeNamed = self::_extension#0|get#_unnecessaryDueToExplicitParameterTypeNamed;
+ method _parenthesized = self::_extension#0|_parenthesized;
+ tearoff _parenthesized = self::_extension#0|get#_parenthesized;
+ method _parenthesizedNamed = self::_extension#0|_parenthesizedNamed;
+ tearoff _parenthesizedNamed = self::_extension#0|get#_parenthesizedNamed;
+ method _parenthesizedTwice = self::_extension#0|_parenthesizedTwice;
+ tearoff _parenthesizedTwice = self::_extension#0|get#_parenthesizedTwice;
+ method _parenthesizedTwiceNamed = self::_extension#0|_parenthesizedTwiceNamed;
+ tearoff _parenthesizedTwiceNamed = self::_extension#0|get#_parenthesizedTwiceNamed;
+}
+static method testLaterUnnamedParameter(core::int i) → dynamic
+ ;
+static method testLaterUnnamedParameterDependsOnNamedParameter(core::int i) → dynamic
+ ;
+static method testEarlierUnnamedParameter(core::int i) → dynamic
+ ;
+static method testLaterNamedParameter(core::int i) → dynamic
+ ;
+static method testEarlierNamedParameter(core::int i) → dynamic
+ ;
+static method testEarlierNamedParameterDependsOnUnnamedParameter(core::int i) → dynamic
+ ;
+static method testPropagateToReturnType(core::int i) → dynamic
+ ;
+static method testClosureAsParameterType(core::int i) → dynamic
+ ;
+static method testPropagateToEarlierClosure(core::int i) → dynamic
+ ;
+static method testPropagateToLaterClosure(core::int i) → dynamic
+ ;
+static method testLongDependencyChain(core::int i) → dynamic
+ ;
+static method testDependencyCycle(core::int i) → dynamic
+ ;
+static method testPropagateFromContravariantReturnType(core::int i) → dynamic
+ ;
+static method testPropagateToContravariantParameterType(core::int i) → dynamic
+ ;
+static method testReturnTypeRefersToMultipleTypeVars(core::int i) → dynamic
+ ;
+static method testUnnecessaryDueToNoDependency(core::int i) → dynamic
+ ;
+static method testUnnecessaryDueToExplicitParameterTypeNamed(core::int i) → dynamic
+ ;
+static method testParenthesized(core::int i) → dynamic
+ ;
+static method testParenthesizedNamed(core::int i) → dynamic
+ ;
+static method testParenthesizedTwice(core::int i) → dynamic
+ ;
+static method testParenthesizedTwiceNamed(core::int i) → dynamic
+ ;
+static method _extension#0|_laterUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_laterUnnamedParameter::T% x, (self::_extension#0|_laterUnnamedParameter::T%) → void y) → self::_extension#0|_laterUnnamedParameter::T%
+ ;
+static method _extension#0|get#_laterUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, (T%) → void) → T%
+ return <T extends core::Object? = dynamic>(T% x, (T%) → void y) → T% => self::_extension#0|_laterUnnamedParameter<T%>(#this, x, y);
+static method _extension#0|_laterUnnamedParameterDependsOnNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter::T%) → void x, {required self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter::T% a}) → void
+ ;
+static method _extension#0|get#_laterUnnamedParameterDependsOnNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>((T%) → void, {a: T%}) → void
+ return <T extends core::Object? = dynamic>((T%) → void x, {T% a}) → void => self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter<T%>(#this, x, a: a);
+static method _extension#0|_earlierUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_earlierUnnamedParameter::T%) → void x, self::_extension#0|_earlierUnnamedParameter::T% y) → void
+ ;
+static method _extension#0|get#_earlierUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>((T%) → void, T%) → void
+ return <T extends core::Object? = dynamic>((T%) → void x, T% y) → void => self::_extension#0|_earlierUnnamedParameter<T%>(#this, x, y);
+static method _extension#0|_laterNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_laterNamedParameter::T% a, required (self::_extension#0|_laterNamedParameter::T%) → void b}) → void
+ ;
+static method _extension#0|get#_laterNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>({T% a, (T%) → void b}) → void => self::_extension#0|_laterNamedParameter<T%>(#this, a: a, b: b);
+static method _extension#0|_earlierNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required (self::_extension#0|_earlierNamedParameter::T%) → void a, required self::_extension#0|_earlierNamedParameter::T% b}) → void
+ ;
+static method _extension#0|get#_earlierNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: (T%) → void, b: T%}) → void
+ return <T extends core::Object? = dynamic>({(T%) → void a, T% b}) → void => self::_extension#0|_earlierNamedParameter<T%>(#this, a: a, b: b);
+static method _extension#0|_earlierNamedParameterDependsOnUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T% b, {required (self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T%) → void a}) → void
+ ;
+static method _extension#0|get#_earlierNamedParameterDependsOnUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, {a: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>(T% b, {(T%) → void a}) → void => self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter<T%>(#this, b, a: a);
+static method _extension#0|_propagateToReturnType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_propagateToReturnType::T% x, (self::_extension#0|_propagateToReturnType::T%) → self::_extension#0|_propagateToReturnType::U% y) → self::_extension#0|_propagateToReturnType::U%
+ ;
+static method _extension#0|get#_propagateToReturnType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T%, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T% x, (T%) → U% y) → U% => self::_extension#0|_propagateToReturnType<T%, U%>(#this, x, y);
+static method _extension#0|_closureAsParameterType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_closureAsParameterType::T% x, (self::_extension#0|_closureAsParameterType::T%) → self::_extension#0|_closureAsParameterType::U% y) → self::_extension#0|_closureAsParameterType::U%
+ ;
+static method _extension#0|get#_closureAsParameterType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T%, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T% x, (T%) → U% y) → U% => self::_extension#0|_closureAsParameterType<T%, U%>(#this, x, y);
+static method _extension#0|_propagateToEarlierClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_propagateToEarlierClosure::T%) → self::_extension#0|_propagateToEarlierClosure::U% x, () → self::_extension#0|_propagateToEarlierClosure::T% y) → self::_extension#0|_propagateToEarlierClosure::U%
+ ;
+static method _extension#0|get#_propagateToEarlierClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U%, () → T%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U% x, () → T% y) → U% => self::_extension#0|_propagateToEarlierClosure<T%, U%>(#this, x, y);
+static method _extension#0|_propagateToLaterClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToLaterClosure::T% x, (self::_extension#0|_propagateToLaterClosure::T%) → self::_extension#0|_propagateToLaterClosure::U% y) → self::_extension#0|_propagateToLaterClosure::U%
+ ;
+static method _extension#0|get#_propagateToLaterClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T%, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T% x, (T%) → U% y) → U% => self::_extension#0|_propagateToLaterClosure<T%, U%>(#this, x, y);
+static method _extension#0|get#_longDependencyChain(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T%, (T%) → U%, (U%) → V%) → V%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T% x, (T%) → U% y, (U%) → V% z) → V% => self::_extension#0|_longDependencyChain<T%, U%, V%>(#this, x, y, z);
+static method _extension#0|_longDependencyChain<T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_longDependencyChain::T% x, (self::_extension#0|_longDependencyChain::T%) → self::_extension#0|_longDependencyChain::U% y, (self::_extension#0|_longDependencyChain::U%) → self::_extension#0|_longDependencyChain::V% z) → self::_extension#0|_longDependencyChain::V%
+ ;
+static method _extension#0|_dependencyCycle<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_dependencyCycle::U%) → self::_extension#0|_dependencyCycle::T% x, (self::_extension#0|_dependencyCycle::T%) → self::_extension#0|_dependencyCycle::U% y) → core::Map<self::_extension#0|_dependencyCycle::T%, self::_extension#0|_dependencyCycle::U%>
+ ;
+static method _extension#0|get#_dependencyCycle(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((U%) → T%, (T%) → U%) → core::Map<T%, U%>
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((U%) → T% x, (T%) → U% y) → core::Map<T%, U%> => self::_extension#0|_dependencyCycle<T%, U%>(#this, x, y);
+static method _extension#0|_propagateFromContravariantReturnType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → (self::_extension#0|_propagateFromContravariantReturnType::T%) → void x, (self::_extension#0|_propagateFromContravariantReturnType::T%) → self::_extension#0|_propagateFromContravariantReturnType::U% y) → self::_extension#0|_propagateFromContravariantReturnType::U%
+ ;
+static method _extension#0|get#_propagateFromContravariantReturnType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → (T%) → void, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → (T%) → void x, (T%) → U% y) → U% => self::_extension#0|_propagateFromContravariantReturnType<T%, U%>(#this, x, y);
+static method _extension#0|_propagateToContravariantParameterType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToContravariantParameterType::T% x, ((self::_extension#0|_propagateToContravariantParameterType::T%) → void) → self::_extension#0|_propagateToContravariantParameterType::U% y) → self::_extension#0|_propagateToContravariantParameterType::U%
+ ;
+static method _extension#0|get#_propagateToContravariantParameterType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T%, ((T%) → void) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T% x, ((T%) → void) → U% y) → U% => self::_extension#0|_propagateToContravariantParameterType<T%, U%>(#this, x, y);
+static method _extension#0|_returnTypeRefersToMultipleTypeVars<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → core::Map<self::_extension#0|_returnTypeRefersToMultipleTypeVars::T%, self::_extension#0|_returnTypeRefersToMultipleTypeVars::U%> x, (self::_extension#0|_returnTypeRefersToMultipleTypeVars::T%) → void y, (self::_extension#0|_returnTypeRefersToMultipleTypeVars::U%) → void z) → void
+ ;
+static method _extension#0|get#_returnTypeRefersToMultipleTypeVars(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → core::Map<T%, U%>, (T%) → void, (U%) → void) → void
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → core::Map<T%, U%> x, (T%) → void y, (U%) → void z) → void => self::_extension#0|_returnTypeRefersToMultipleTypeVars<T%, U%>(#this, x, y, z);
+static method _extension#0|_unnecessaryDueToNoDependency<T extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_unnecessaryDueToNoDependency::T% x, self::_extension#0|_unnecessaryDueToNoDependency::T% y) → self::_extension#0|_unnecessaryDueToNoDependency::T%
+ ;
+static method _extension#0|get#_unnecessaryDueToNoDependency(lowered final core::int #this) → <T extends core::Object? = dynamic>(() → T%, T%) → T%
+ return <T extends core::Object? = dynamic>(() → T% x, T% y) → T% => self::_extension#0|_unnecessaryDueToNoDependency<T%>(#this, x, y);
+static method _extension#0|_unnecessaryDueToExplicitParameterTypeNamed<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T% x, ({required x: self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T%, required y: core::int}) → self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T% y) → self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T%
+ ;
+static method _extension#0|get#_unnecessaryDueToExplicitParameterTypeNamed(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, ({required x: T%, required y: core::int}) → T%) → T%
+ return <T extends core::Object? = dynamic>(T% x, ({required x: T%, required y: core::int}) → T% y) → T% => self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed<T%>(#this, x, y);
+static method _extension#0|_parenthesized<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_parenthesized::T% x, (self::_extension#0|_parenthesized::T%) → void y) → void
+ ;
+static method _extension#0|get#_parenthesized(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, (T%) → void) → void
+ return <T extends core::Object? = dynamic>(T% x, (T%) → void y) → void => self::_extension#0|_parenthesized<T%>(#this, x, y);
+static method _extension#0|_parenthesizedNamed<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_parenthesizedNamed::T% a, required (self::_extension#0|_parenthesizedNamed::T%) → void b}) → void
+ ;
+static method _extension#0|get#_parenthesizedNamed(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>({T% a, (T%) → void b}) → void => self::_extension#0|_parenthesizedNamed<T%>(#this, a: a, b: b);
+static method _extension#0|_parenthesizedTwice<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_parenthesizedTwice::T% x, (self::_extension#0|_parenthesizedTwice::T%) → void y) → void
+ ;
+static method _extension#0|get#_parenthesizedTwice(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, (T%) → void) → void
+ return <T extends core::Object? = dynamic>(T% x, (T%) → void y) → void => self::_extension#0|_parenthesizedTwice<T%>(#this, x, y);
+static method _extension#0|_parenthesizedTwiceNamed<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_parenthesizedTwiceNamed::T% a, required (self::_extension#0|_parenthesizedTwiceNamed::T%) → void b}) → void
+ ;
+static method _extension#0|get#_parenthesizedTwiceNamed(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>({T% a, (T%) → void b}) → void => self::_extension#0|_parenthesizedTwiceNamed<T%>(#this, a: a, b: b);
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.transformed.expect b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.transformed.expect
new file mode 100644
index 0000000..af2047a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.transformed.expect
@@ -0,0 +1,232 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+extension _extension#0 on core::int {
+ method _laterUnnamedParameter = self::_extension#0|_laterUnnamedParameter;
+ tearoff _laterUnnamedParameter = self::_extension#0|get#_laterUnnamedParameter;
+ method _laterUnnamedParameterDependsOnNamedParameter = self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter;
+ tearoff _laterUnnamedParameterDependsOnNamedParameter = self::_extension#0|get#_laterUnnamedParameterDependsOnNamedParameter;
+ method _earlierUnnamedParameter = self::_extension#0|_earlierUnnamedParameter;
+ tearoff _earlierUnnamedParameter = self::_extension#0|get#_earlierUnnamedParameter;
+ method _laterNamedParameter = self::_extension#0|_laterNamedParameter;
+ tearoff _laterNamedParameter = self::_extension#0|get#_laterNamedParameter;
+ method _earlierNamedParameter = self::_extension#0|_earlierNamedParameter;
+ tearoff _earlierNamedParameter = self::_extension#0|get#_earlierNamedParameter;
+ method _earlierNamedParameterDependsOnUnnamedParameter = self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter;
+ tearoff _earlierNamedParameterDependsOnUnnamedParameter = self::_extension#0|get#_earlierNamedParameterDependsOnUnnamedParameter;
+ method _propagateToReturnType = self::_extension#0|_propagateToReturnType;
+ tearoff _propagateToReturnType = self::_extension#0|get#_propagateToReturnType;
+ method _closureAsParameterType = self::_extension#0|_closureAsParameterType;
+ tearoff _closureAsParameterType = self::_extension#0|get#_closureAsParameterType;
+ method _propagateToEarlierClosure = self::_extension#0|_propagateToEarlierClosure;
+ tearoff _propagateToEarlierClosure = self::_extension#0|get#_propagateToEarlierClosure;
+ method _propagateToLaterClosure = self::_extension#0|_propagateToLaterClosure;
+ tearoff _propagateToLaterClosure = self::_extension#0|get#_propagateToLaterClosure;
+ method _longDependencyChain = self::_extension#0|_longDependencyChain;
+ tearoff _longDependencyChain = self::_extension#0|get#_longDependencyChain;
+ method _dependencyCycle = self::_extension#0|_dependencyCycle;
+ tearoff _dependencyCycle = self::_extension#0|get#_dependencyCycle;
+ method _propagateFromContravariantReturnType = self::_extension#0|_propagateFromContravariantReturnType;
+ tearoff _propagateFromContravariantReturnType = self::_extension#0|get#_propagateFromContravariantReturnType;
+ method _propagateToContravariantParameterType = self::_extension#0|_propagateToContravariantParameterType;
+ tearoff _propagateToContravariantParameterType = self::_extension#0|get#_propagateToContravariantParameterType;
+ method _returnTypeRefersToMultipleTypeVars = self::_extension#0|_returnTypeRefersToMultipleTypeVars;
+ tearoff _returnTypeRefersToMultipleTypeVars = self::_extension#0|get#_returnTypeRefersToMultipleTypeVars;
+ method _unnecessaryDueToNoDependency = self::_extension#0|_unnecessaryDueToNoDependency;
+ tearoff _unnecessaryDueToNoDependency = self::_extension#0|get#_unnecessaryDueToNoDependency;
+ method _unnecessaryDueToExplicitParameterTypeNamed = self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed;
+ tearoff _unnecessaryDueToExplicitParameterTypeNamed = self::_extension#0|get#_unnecessaryDueToExplicitParameterTypeNamed;
+ method _parenthesized = self::_extension#0|_parenthesized;
+ tearoff _parenthesized = self::_extension#0|get#_parenthesized;
+ method _parenthesizedNamed = self::_extension#0|_parenthesizedNamed;
+ tearoff _parenthesizedNamed = self::_extension#0|get#_parenthesizedNamed;
+ method _parenthesizedTwice = self::_extension#0|_parenthesizedTwice;
+ tearoff _parenthesizedTwice = self::_extension#0|get#_parenthesizedTwice;
+ method _parenthesizedTwiceNamed = self::_extension#0|_parenthesizedTwiceNamed;
+ tearoff _parenthesizedTwiceNamed = self::_extension#0|get#_parenthesizedTwiceNamed;
+}
+static method testLaterUnnamedParameter(core::int i) → dynamic {
+ self::_extension#0|_laterUnnamedParameter<core::int>(i, 0, (core::int x) → void {
+ x;
+ });
+}
+static method testLaterUnnamedParameterDependsOnNamedParameter(core::int i) → dynamic {
+ self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter<core::int>(i, (core::int x) → void {
+ x;
+ }, a: 0);
+}
+static method testEarlierUnnamedParameter(core::int i) → dynamic {
+ self::_extension#0|_earlierUnnamedParameter<core::int>(i, (core::int x) → void {
+ x;
+ }, 0);
+}
+static method testLaterNamedParameter(core::int i) → dynamic {
+ self::_extension#0|_laterNamedParameter<core::int>(i, a: 0, b: (core::int x) → void {
+ x;
+ });
+}
+static method testEarlierNamedParameter(core::int i) → dynamic {
+ self::_extension#0|_earlierNamedParameter<core::int>(i, a: (core::int x) → void {
+ x;
+ }, b: 0);
+}
+static method testEarlierNamedParameterDependsOnUnnamedParameter(core::int i) → dynamic {
+ self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter<core::int>(i, 0, a: (core::int x) → void {
+ x;
+ });
+}
+static method testPropagateToReturnType(core::int i) → dynamic {
+ self::_extension#0|_propagateToReturnType<core::int, core::List<core::int>>(i, 0, (core::int x) → core::List<core::int> => core::_GrowableList::_literal1<core::int>(x));
+}
+static method testClosureAsParameterType(core::int i) → dynamic {
+ self::_extension#0|_closureAsParameterType<() → core::int, core::List<core::int>>(i, () → core::int => 0, (() → core::int h) → core::List<core::int> => core::_GrowableList::_literal1<core::int>(h(){() → core::int}));
+}
+static method testPropagateToEarlierClosure(core::int i) → dynamic {
+ self::_extension#0|_propagateToEarlierClosure<core::int, core::List<core::int>>(i, (core::int x) → core::List<core::int> => core::_GrowableList::_literal1<core::int>(x), () → core::int => 0);
+}
+static method testPropagateToLaterClosure(core::int i) → dynamic {
+ self::_extension#0|_propagateToLaterClosure<core::int, core::List<core::int>>(i, () → core::int => 0, (core::int x) → core::List<core::int> => core::_GrowableList::_literal1<core::int>(x));
+}
+static method testLongDependencyChain(core::int i) → dynamic {
+ self::_extension#0|_longDependencyChain<core::List<core::int>, core::int, core::Set<core::int>>(i, () → core::List<core::int> => core::_GrowableList::_literal1<core::int>(0), (core::List<core::int> x) → core::int => x.{core::Iterable::single}{core::int}, (core::int y) → core::Set<core::int> => block {
+ final core::Set<core::int> #t1 = new col::_CompactLinkedHashSet::•<core::int>();
+ #t1.{core::Set::add}{Invariant}(y){(core::int) → core::bool};
+ } =>#t1);
+}
+static method testDependencyCycle(core::int i) → dynamic {
+ self::_extension#0|_dependencyCycle<core::List<core::Object?>, core::Set<core::Object?>>(i, (core::Object? x) → core::List<core::Object?> => core::_GrowableList::_literal1<core::Object?>(x), (core::Object? y) → core::Set<core::Object?> => block {
+ final core::Set<core::Object?> #t2 = new col::_CompactLinkedHashSet::•<core::Object?>();
+ #t2.{core::Set::add}{Invariant}(y){(core::Object?) → core::bool};
+ } =>#t2);
+}
+static method testPropagateFromContravariantReturnType(core::int i) → dynamic {
+ self::_extension#0|_propagateFromContravariantReturnType<core::int, core::List<core::int>>(i, () → (core::int) → void => (core::int i) → void {}, (core::int x) → core::List<core::int> => core::_GrowableList::_literal1<core::int>(x));
+}
+static method testPropagateToContravariantParameterType(core::int i) → dynamic {
+ self::_extension#0|_propagateToContravariantParameterType<core::int, core::List<(core::int) → void>>(i, () → core::int => 0, ((core::int) → void x) → core::List<(core::int) → void> => core::_GrowableList::_literal1<(core::int) → void>(x));
+}
+static method testReturnTypeRefersToMultipleTypeVars(core::int i) → dynamic {
+ self::_extension#0|_returnTypeRefersToMultipleTypeVars<core::int, core::String>(i, () → core::Map<core::int, core::String> => <core::int, core::String>{0: ""}, (core::int k) → void {
+ k;
+ }, (core::String v) → void {
+ v;
+ });
+}
+static method testUnnecessaryDueToNoDependency(core::int i) → dynamic {
+ self::_extension#0|_unnecessaryDueToNoDependency<core::int?>(i, () → core::int => 0, null);
+}
+static method testUnnecessaryDueToExplicitParameterTypeNamed(core::int i) → dynamic {
+ core::int? a = self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed<core::int?>(i, null, ({core::int? x = #C1, required core::int y = #C1}) → core::int => (let final core::int? #t3 = x in #t3 == null ?{core::int} 0 : #t3{core::int}).{core::num::+}(y){(core::num) → core::int});
+ a;
+}
+static method testParenthesized(core::int i) → dynamic {
+ self::_extension#0|_parenthesized<core::int>(i, 0, (core::int x) → void {
+ x;
+ });
+}
+static method testParenthesizedNamed(core::int i) → dynamic {
+ self::_extension#0|_parenthesizedNamed<core::int>(i, a: 0, b: (core::int x) → void {
+ x;
+ });
+}
+static method testParenthesizedTwice(core::int i) → dynamic {
+ self::_extension#0|_parenthesizedTwice<core::int>(i, 0, (core::int x) → void {
+ x;
+ });
+}
+static method testParenthesizedTwiceNamed(core::int i) → dynamic {
+ self::_extension#0|_parenthesizedTwiceNamed<core::int>(i, a: 0, b: (core::int x) → void {
+ x;
+ });
+}
+static method _extension#0|_laterUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_laterUnnamedParameter::T% x, (self::_extension#0|_laterUnnamedParameter::T%) → void y) → self::_extension#0|_laterUnnamedParameter::T%
+ return throw "";
+static method _extension#0|get#_laterUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, (T%) → void) → T%
+ return <T extends core::Object? = dynamic>(T% x, (T%) → void y) → T% => self::_extension#0|_laterUnnamedParameter<T%>(#this, x, y);
+static method _extension#0|_laterUnnamedParameterDependsOnNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter::T%) → void x, {required self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter::T% a = #C1}) → void
+ return throw "";
+static method _extension#0|get#_laterUnnamedParameterDependsOnNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>((T%) → void, {a: T%}) → void
+ return <T extends core::Object? = dynamic>((T%) → void x, {T% a = #C1}) → void => self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter<T%>(#this, x, a: a);
+static method _extension#0|_earlierUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_earlierUnnamedParameter::T%) → void x, self::_extension#0|_earlierUnnamedParameter::T% y) → void
+ return throw "";
+static method _extension#0|get#_earlierUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>((T%) → void, T%) → void
+ return <T extends core::Object? = dynamic>((T%) → void x, T% y) → void => self::_extension#0|_earlierUnnamedParameter<T%>(#this, x, y);
+static method _extension#0|_laterNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_laterNamedParameter::T% a = #C1, required (self::_extension#0|_laterNamedParameter::T%) → void b = #C1}) → void
+ return throw "";
+static method _extension#0|get#_laterNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>({T% a = #C1, (T%) → void b = #C1}) → void => self::_extension#0|_laterNamedParameter<T%>(#this, a: a, b: b);
+static method _extension#0|_earlierNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required (self::_extension#0|_earlierNamedParameter::T%) → void a = #C1, required self::_extension#0|_earlierNamedParameter::T% b = #C1}) → void
+ return throw "";
+static method _extension#0|get#_earlierNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: (T%) → void, b: T%}) → void
+ return <T extends core::Object? = dynamic>({(T%) → void a = #C1, T% b = #C1}) → void => self::_extension#0|_earlierNamedParameter<T%>(#this, a: a, b: b);
+static method _extension#0|_earlierNamedParameterDependsOnUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T% b, {required (self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T%) → void a = #C1}) → void
+ return throw "";
+static method _extension#0|get#_earlierNamedParameterDependsOnUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, {a: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>(T% b, {(T%) → void a = #C1}) → void => self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter<T%>(#this, b, a: a);
+static method _extension#0|_propagateToReturnType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_propagateToReturnType::T% x, (self::_extension#0|_propagateToReturnType::T%) → self::_extension#0|_propagateToReturnType::U% y) → self::_extension#0|_propagateToReturnType::U%
+ return throw "";
+static method _extension#0|get#_propagateToReturnType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T%, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T% x, (T%) → U% y) → U% => self::_extension#0|_propagateToReturnType<T%, U%>(#this, x, y);
+static method _extension#0|_closureAsParameterType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_closureAsParameterType::T% x, (self::_extension#0|_closureAsParameterType::T%) → self::_extension#0|_closureAsParameterType::U% y) → self::_extension#0|_closureAsParameterType::U%
+ return throw "";
+static method _extension#0|get#_closureAsParameterType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T%, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(T% x, (T%) → U% y) → U% => self::_extension#0|_closureAsParameterType<T%, U%>(#this, x, y);
+static method _extension#0|_propagateToEarlierClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_propagateToEarlierClosure::T%) → self::_extension#0|_propagateToEarlierClosure::U% x, () → self::_extension#0|_propagateToEarlierClosure::T% y) → self::_extension#0|_propagateToEarlierClosure::U%
+ return throw "";
+static method _extension#0|get#_propagateToEarlierClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U%, () → T%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U% x, () → T% y) → U% => self::_extension#0|_propagateToEarlierClosure<T%, U%>(#this, x, y);
+static method _extension#0|_propagateToLaterClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToLaterClosure::T% x, (self::_extension#0|_propagateToLaterClosure::T%) → self::_extension#0|_propagateToLaterClosure::U% y) → self::_extension#0|_propagateToLaterClosure::U%
+ return throw "";
+static method _extension#0|get#_propagateToLaterClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T%, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T% x, (T%) → U% y) → U% => self::_extension#0|_propagateToLaterClosure<T%, U%>(#this, x, y);
+static method _extension#0|get#_longDependencyChain(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T%, (T%) → U%, (U%) → V%) → V%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T% x, (T%) → U% y, (U%) → V% z) → V% => self::_extension#0|_longDependencyChain<T%, U%, V%>(#this, x, y, z);
+static method _extension#0|_longDependencyChain<T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_longDependencyChain::T% x, (self::_extension#0|_longDependencyChain::T%) → self::_extension#0|_longDependencyChain::U% y, (self::_extension#0|_longDependencyChain::U%) → self::_extension#0|_longDependencyChain::V% z) → self::_extension#0|_longDependencyChain::V%
+ return throw "";
+static method _extension#0|_dependencyCycle<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_dependencyCycle::U%) → self::_extension#0|_dependencyCycle::T% x, (self::_extension#0|_dependencyCycle::T%) → self::_extension#0|_dependencyCycle::U% y) → core::Map<self::_extension#0|_dependencyCycle::T%, self::_extension#0|_dependencyCycle::U%>
+ return throw "";
+static method _extension#0|get#_dependencyCycle(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((U%) → T%, (T%) → U%) → core::Map<T%, U%>
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((U%) → T% x, (T%) → U% y) → core::Map<T%, U%> => self::_extension#0|_dependencyCycle<T%, U%>(#this, x, y);
+static method _extension#0|_propagateFromContravariantReturnType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → (self::_extension#0|_propagateFromContravariantReturnType::T%) → void x, (self::_extension#0|_propagateFromContravariantReturnType::T%) → self::_extension#0|_propagateFromContravariantReturnType::U% y) → self::_extension#0|_propagateFromContravariantReturnType::U%
+ return throw "";
+static method _extension#0|get#_propagateFromContravariantReturnType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → (T%) → void, (T%) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → (T%) → void x, (T%) → U% y) → U% => self::_extension#0|_propagateFromContravariantReturnType<T%, U%>(#this, x, y);
+static method _extension#0|_propagateToContravariantParameterType<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToContravariantParameterType::T% x, ((self::_extension#0|_propagateToContravariantParameterType::T%) → void) → self::_extension#0|_propagateToContravariantParameterType::U% y) → self::_extension#0|_propagateToContravariantParameterType::U%
+ return throw "";
+static method _extension#0|get#_propagateToContravariantParameterType(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T%, ((T%) → void) → U%) → U%
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T% x, ((T%) → void) → U% y) → U% => self::_extension#0|_propagateToContravariantParameterType<T%, U%>(#this, x, y);
+static method _extension#0|_returnTypeRefersToMultipleTypeVars<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → core::Map<self::_extension#0|_returnTypeRefersToMultipleTypeVars::T%, self::_extension#0|_returnTypeRefersToMultipleTypeVars::U%> x, (self::_extension#0|_returnTypeRefersToMultipleTypeVars::T%) → void y, (self::_extension#0|_returnTypeRefersToMultipleTypeVars::U%) → void z) → void
+ return throw "";
+static method _extension#0|get#_returnTypeRefersToMultipleTypeVars(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → core::Map<T%, U%>, (T%) → void, (U%) → void) → void
+ return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → core::Map<T%, U%> x, (T%) → void y, (U%) → void z) → void => self::_extension#0|_returnTypeRefersToMultipleTypeVars<T%, U%>(#this, x, y, z);
+static method _extension#0|_unnecessaryDueToNoDependency<T extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_unnecessaryDueToNoDependency::T% x, self::_extension#0|_unnecessaryDueToNoDependency::T% y) → self::_extension#0|_unnecessaryDueToNoDependency::T%
+ return throw "";
+static method _extension#0|get#_unnecessaryDueToNoDependency(lowered final core::int #this) → <T extends core::Object? = dynamic>(() → T%, T%) → T%
+ return <T extends core::Object? = dynamic>(() → T% x, T% y) → T% => self::_extension#0|_unnecessaryDueToNoDependency<T%>(#this, x, y);
+static method _extension#0|_unnecessaryDueToExplicitParameterTypeNamed<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T% x, ({required x: self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T%, required y: core::int}) → self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T% y) → self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed::T%
+ return throw "";
+static method _extension#0|get#_unnecessaryDueToExplicitParameterTypeNamed(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, ({required x: T%, required y: core::int}) → T%) → T%
+ return <T extends core::Object? = dynamic>(T% x, ({required x: T%, required y: core::int}) → T% y) → T% => self::_extension#0|_unnecessaryDueToExplicitParameterTypeNamed<T%>(#this, x, y);
+static method _extension#0|_parenthesized<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_parenthesized::T% x, (self::_extension#0|_parenthesized::T%) → void y) → void
+ return throw "";
+static method _extension#0|get#_parenthesized(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, (T%) → void) → void
+ return <T extends core::Object? = dynamic>(T% x, (T%) → void y) → void => self::_extension#0|_parenthesized<T%>(#this, x, y);
+static method _extension#0|_parenthesizedNamed<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_parenthesizedNamed::T% a = #C1, required (self::_extension#0|_parenthesizedNamed::T%) → void b = #C1}) → void
+ return throw "";
+static method _extension#0|get#_parenthesizedNamed(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>({T% a = #C1, (T%) → void b = #C1}) → void => self::_extension#0|_parenthesizedNamed<T%>(#this, a: a, b: b);
+static method _extension#0|_parenthesizedTwice<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_parenthesizedTwice::T% x, (self::_extension#0|_parenthesizedTwice::T%) → void y) → void
+ return throw "";
+static method _extension#0|get#_parenthesizedTwice(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, (T%) → void) → void
+ return <T extends core::Object? = dynamic>(T% x, (T%) → void y) → void => self::_extension#0|_parenthesizedTwice<T%>(#this, x, y);
+static method _extension#0|_parenthesizedTwiceNamed<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_parenthesizedTwiceNamed::T% a = #C1, required (self::_extension#0|_parenthesizedTwiceNamed::T%) → void b = #C1}) → void
+ return throw "";
+static method _extension#0|get#_parenthesizedTwiceNamed(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
+ return <T extends core::Object? = dynamic>({T% a = #C1, (T%) → void b = #C1}) → void => self::_extension#0|_parenthesizedTwiceNamed<T%>(#this, a: a, b: b);
+static method main() → dynamic {}
+
+constants {
+ #C1 = null
+}
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 0f8cabf..d71457b 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -339,10 +339,10 @@
#endif // !defined(ARCH_IS_64_BIT) && !defined(FFI_UNIT_TESTS)
#elif defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) || \
defined(TARGET_ARCH_RISCV32)
-#if defined(HOST_ARCH_X64) && defined(TARGET_ARCH_ARM)
-// This is simarm_x64, which is the only case where host/target architecture
-// mismatch is allowed. Unless, we're running FFI unit tests.
-#define IS_SIMARM_X64 1
+#if defined(ARCH_IS_64_BIT) && defined(TARGET_ARCH_ARM)
+// This is simarm_x64 or simarm_arm64, which is the only case where host/target
+// architecture mismatch is allowed. Unless, we're running FFI unit tests.
+#define IS_SIMARM_HOST64 1
#elif !defined(ARCH_IS_32_BIT) && !defined(FFI_UNIT_TESTS)
#error Mismatched Host/Target architectures.
#endif // !defined(ARCH_IS_32_BIT) && !defined(FFI_UNIT_TESTS)
@@ -360,7 +360,7 @@
#elif defined(TARGET_ARCH_ARM)
#if !defined(HOST_ARCH_ARM)
#define TARGET_HOST_MISMATCH 1
-#if !defined(IS_SIMARM_X64)
+#if !defined(IS_SIMARM_HOST64)
#define USING_SIMULATOR 1
#endif
#endif
diff --git a/runtime/vm/compiler/assembler/disassembler_arm.cc b/runtime/vm/compiler/assembler/disassembler_arm.cc
index 51bb568..4d860a5 100644
--- a/runtime/vm/compiler/assembler/disassembler_arm.cc
+++ b/runtime/vm/compiler/assembler/disassembler_arm.cc
@@ -1512,14 +1512,14 @@
*object = NULL;
// TODO(36839): Make DecodeLoadObjectFromPoolOrThread work on simarm_x64.
-#if !defined(IS_SIMARM_X64)
+#if !defined(IS_SIMARM_HOST64)
if (!code.IsNull()) {
*object = &Object::Handle();
if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) {
*object = NULL;
}
}
-#endif // !defined(IS_SIMARM_X64)
+#endif // !defined(IS_SIMARM_HOST64)
}
#endif // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index bf4c995..2ccf215 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -155,7 +155,7 @@
static DartInitializationState init_state_;
static void CheckOffsets() {
-#if !defined(IS_SIMARM_X64)
+#if !defined(IS_SIMARM_HOST64)
// These offsets are embedded in precompiled instructions. We need the
// compiler and the runtime to agree.
bool ok = true;
@@ -241,7 +241,7 @@
#undef CHECK_CONSTANT
#undef CHECK_OFFSET
#undef CHECK_PAYLOAD_SIZEOF
-#endif // !defined(IS_SIMARM_X64)
+#endif // !defined(IS_SIMARM_HOST64)
}
char* Dart::DartInit(const Dart_InitializeParams* params) {
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index c564a48..559dc44 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -112,7 +112,7 @@
#define SUPPORT_TIMELINE 1
#endif
-#if defined(ARCH_IS_64_BIT) && !defined(IS_SIMARM_X64)
+#if defined(ARCH_IS_64_BIT) && !defined(IS_SIMARM_HOST64)
#define HASH_IN_OBJECT_HEADER 1
#endif
diff --git a/tests/language/inference_update_1/downward_inference_preferred_over_horizontal_test.dart b/tests/language/inference_update_1/downward_inference_preferred_over_horizontal_test.dart
new file mode 100644
index 0000000..704d642
--- /dev/null
+++ b/tests/language/inference_update_1/downward_inference_preferred_over_horizontal_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that when the feature is enabled, types supplied by downward inference
+// are preferred over those available via horizontal inference.
+//
+// The way this happens is that the type parameter is "fixed" after the downward
+// inference phase and is not changed in further inference phases.
+
+// SharedOptions=--enable-experiment=inference-update-1
+
+import '../static_type_helper.dart';
+
+testProductOfNums(List<num> values) {
+ num a = values.fold(
+ 1,
+ (p, v) =>
+ (p..expectStaticType<Exactly<num>>()) *
+ (v..expectStaticType<Exactly<num>>()))
+ ..expectStaticType<Exactly<num>>();
+}
+
+main() {}
diff --git a/tests/language/inference_update_1/horizontal_inference_extension_method_test.dart b/tests/language/inference_update_1/horizontal_inference_extension_method_test.dart
new file mode 100644
index 0000000..346be23
--- /dev/null
+++ b/tests/language/inference_update_1/horizontal_inference_extension_method_test.dart
@@ -0,0 +1,214 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that horizontal inference works properly when the invocation is an
+// extension member. This is an important corner case because the front end
+// adds an implicit `this` argument to extension members as part of the lowering
+// process. We need to make sure that the dependency tracking logic properly
+// accounts for this extra argument.
+
+// SharedOptions=--enable-experiment=inference-update-1
+
+import '../static_type_helper.dart';
+
+testLaterUnnamedParameter(int i) {
+ i._laterUnnamedParameter(0, (x) {
+ x.expectStaticType<Exactly<int>>();
+ });
+}
+
+/// This special case verifies that the implementations correctly associate the
+/// zeroth positional parameter with the corresponding argument (even if that
+/// argument isn't in the zeroth position at the call site).
+testLaterUnnamedParameterDependsOnNamedParameter(int i) {
+ i._laterUnnamedParameterDependsOnNamedParameter(a: 0, (x) {
+ x.expectStaticType<Exactly<int>>();
+ });
+}
+
+testEarlierUnnamedParameter(int i) {
+ i._earlierUnnamedParameter((x) {
+ x.expectStaticType<Exactly<int>>();
+ }, 0);
+}
+
+testLaterNamedParameter(int i) {
+ i._laterNamedParameter(
+ a: 0,
+ b: (x) {
+ x.expectStaticType<Exactly<int>>();
+ });
+}
+
+testEarlierNamedParameter(int i) {
+ i._earlierNamedParameter(
+ a: (x) {
+ x.expectStaticType<Exactly<int>>();
+ },
+ b: 0);
+}
+
+/// This special case verifies that the implementations correctly associate the
+/// zeroth positional parameter with the corresponding argument (even if that
+/// argument isn't in the zeroth position at the call site).
+testEarlierNamedParameterDependsOnUnnamedParameter(int i) {
+ i._earlierNamedParameterDependsOnUnnamedParameter(a: (x) {
+ x.expectStaticType<Exactly<int>>();
+ }, 0);
+}
+
+testPropagateToReturnType(int i) {
+ i
+ ._propagateToReturnType(0, (x) => [x])
+ .expectStaticType<Exactly<List<int>>>();
+}
+
+// The test cases below exercise situations where there are multiple closures in
+// the invocation, and they need to be inferred in the right order.
+
+testClosureAsParameterType(int i) {
+ i
+ ._closureAsParameterType(
+ () => 0, (h) => [h()]..expectStaticType<Exactly<List<int>>>())
+ .expectStaticType<Exactly<List<int>>>();
+}
+
+testPropagateToEarlierClosure(int i) {
+ i
+ ._propagateToEarlierClosure(
+ (x) => [x]..expectStaticType<Exactly<List<int>>>(), () => 0)
+ .expectStaticType<Exactly<List<int>>>();
+}
+
+testPropagateToLaterClosure(int i) {
+ i
+ ._propagateToLaterClosure(
+ () => 0, (x) => [x]..expectStaticType<Exactly<List<int>>>())
+ .expectStaticType<Exactly<List<int>>>();
+}
+
+testLongDependencyChain(int i) {
+ i
+ ._longDependencyChain(
+ () => [0],
+ (x) => x.single..expectStaticType<Exactly<int>>(),
+ (y) => {y}..expectStaticType<Exactly<Set<int>>>())
+ .expectStaticType<Exactly<Set<int>>>();
+}
+
+testDependencyCycle(int i) {
+ i
+ ._dependencyCycle((x) => [x]..expectStaticType<Exactly<List<Object?>>>(),
+ (y) => {y}..expectStaticType<Exactly<Set<Object?>>>())
+ .expectStaticType<Exactly<Map<List<Object?>, Set<Object?>>>>();
+}
+
+testPropagateFromContravariantReturnType(int i) {
+ i
+ ._propagateFromContravariantReturnType(
+ () => (int i) {}, (x) => [x]..expectStaticType<Exactly<List<int>>>())
+ .expectStaticType<Exactly<List<int>>>();
+}
+
+testPropagateToContravariantParameterType(int i) {
+ i
+ ._propagateToContravariantParameterType(() => 0,
+ (x) => [x]..expectStaticType<Exactly<List<void Function(int)>>>())
+ .expectStaticType<Exactly<List<void Function(int)>>>();
+}
+
+testReturnTypeRefersToMultipleTypeVars(int i) {
+ i._returnTypeRefersToMultipleTypeVars(() => {0: ''}, (k) {
+ k.expectStaticType<Exactly<int>>();
+ }, (v) {
+ v.expectStaticType<Exactly<String>>();
+ });
+}
+
+testUnnecessaryDueToNoDependency(int i) {
+ i
+ ._unnecessaryDueToNoDependency(() => 0, null)
+ .expectStaticType<Exactly<int?>>();
+}
+
+testUnnecessaryDueToExplicitParameterTypeNamed(int i) {
+ var a = i._unnecessaryDueToExplicitParameterTypeNamed(
+ null, ({int? x, required y}) => (x ?? 0) + y);
+ a.expectStaticType<Exactly<int?>>();
+}
+
+testParenthesized(int i) {
+ i._parenthesized(0, ((x) {
+ x.expectStaticType<Exactly<int>>();
+ }));
+}
+
+testParenthesizedNamed(int i) {
+ i._parenthesizedNamed(
+ a: 0,
+ b: ((x) {
+ x.expectStaticType<Exactly<int>>();
+ }));
+}
+
+testParenthesizedTwice(int i) {
+ i._parenthesizedTwice(0, (((x) {
+ x.expectStaticType<Exactly<int>>();
+ })));
+}
+
+testParenthesizedTwiceNamed(int i) {
+ i._parenthesizedTwiceNamed(
+ a: 0,
+ b: (((x) {
+ x.expectStaticType<Exactly<int>>();
+ })));
+}
+
+extension on int {
+ T _laterUnnamedParameter<T>(T x, void Function(T) y) => throw '';
+ void _laterUnnamedParameterDependsOnNamedParameter<T>(void Function(T) x,
+ {required T a}) =>
+ throw '';
+ void _earlierUnnamedParameter<T>(void Function(T) x, T y) => throw '';
+ void _laterNamedParameter<T>({required T a, required void Function(T) b}) =>
+ throw '';
+ void _earlierNamedParameter<T>({required void Function(T) a, required T b}) =>
+ throw '';
+ void _earlierNamedParameterDependsOnUnnamedParameter<T>(T b,
+ {required void Function(T) a}) =>
+ throw '';
+ U _propagateToReturnType<T, U>(T x, U Function(T) y) => throw '';
+ U _closureAsParameterType<T, U>(T x, U Function(T) y) => throw '';
+ U _propagateToEarlierClosure<T, U>(U Function(T) x, T Function() y) =>
+ throw '';
+ U _propagateToLaterClosure<T, U>(T Function() x, U Function(T) y) => throw '';
+ V _longDependencyChain<T, U, V>(
+ T Function() x, U Function(T) y, V Function(U) z) =>
+ throw '';
+ Map<T, U> _dependencyCycle<T, U>(T Function(U) x, U Function(T) y) =>
+ throw '';
+ U _propagateFromContravariantReturnType<T, U>(
+ void Function(T) Function() x, U Function(T) y) =>
+ throw '';
+ U _propagateToContravariantParameterType<T, U>(
+ T Function() x, U Function(void Function(T)) y) =>
+ throw '';
+ void _returnTypeRefersToMultipleTypeVars<T, U>(
+ Map<T, U> Function() x, void Function(T) y, void Function(U) z) =>
+ throw '';
+ T _unnecessaryDueToNoDependency<T>(T Function() x, T y) => throw '';
+ T _unnecessaryDueToExplicitParameterTypeNamed<T>(
+ T x, T Function({required T x, required int y}) y) =>
+ throw '';
+ void _parenthesized<T>(T x, void Function(T) y) => throw '';
+ void _parenthesizedNamed<T>({required T a, required void Function(T) b}) =>
+ throw '';
+ void _parenthesizedTwice<T>(T x, void Function(T) y) => throw '';
+ void _parenthesizedTwiceNamed<T>(
+ {required T a, required void Function(T) b}) =>
+ throw '';
+}
+
+main() {}
diff --git a/tools/VERSION b/tools/VERSION
index 65f3e26..2d8ba76 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 102
+PRERELEASE 103
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index c7bcc68..53e919c 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -3402,6 +3402,15 @@
]
},
{
+ "name": "analyze pkg/dart2native",
+ "script": "out/ReleaseX64/dart-sdk/bin/dart",
+ "arguments": [
+ "analyze",
+ "--fatal-infos",
+ "pkg/dart2native"
+ ]
+ },
+ {
"name": "analyze pkg/dartdev",
"script": "out/ReleaseX64/dart-sdk/bin/dart",
"arguments": [
diff --git a/tools/gn.py b/tools/gn.py
index a89e8a3..647f045 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -67,61 +67,82 @@
return [merge(x, y) for x, y in gn_args.items()]
-# Runs true if the currently executing python interpreter is running under
-# Rosetta. I.e., python3 is an x64 executable and we're on an arm64 Mac.
-def IsRosetta():
- if platform.system() == 'Darwin':
- p = subprocess.Popen(['sysctl', '-in', 'sysctl.proc_translated'],
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- output, _ = p.communicate()
- return output.decode('utf-8').strip() == '1'
- return False
-
-
+# The C compiler's host.
def HostCpuForArch(arch):
- # Check for Rosetta before checking platform.machine(), as the latter
- # returns 'x86_64' when running under Rosetta.
- if IsRosetta():
- if arch in ['x64', 'x64c']:
- # Without this case, we would try to build with
- # host_cpu="arm64"
- # target_cpu="x64"
- # dart_target_arch="x64"
- # Which requires the VM to use an x64 simulator in the host
- # arm64 binaries, and this simulator is unimplemented.
- return 'x64'
- else:
- return 'arm64'
-
- m = platform.machine()
- if m == 'aarch64' or m == 'arm64':
- return 'arm64'
- if m == 'armv7l':
- return 'arm'
-
- if arch in ['ia32', 'arm', 'simarm', 'simarm_x64', 'riscv32', 'simriscv32']:
- return 'x86'
- if arch in [
- 'x64', 'arm64', 'simarm64', 'arm_x64', 'x64c', 'arm64c',
- 'simarm64c', 'riscv64', 'simriscv64'
- ]:
+ if arch.endswith('_x64'):
return 'x64'
+ if arch.endswith('_arm64'):
+ return 'arm64'
+ if arch.endswith('_riscv64'):
+ return 'riscv64'
+
+ # For each target architecture, we prefer in descending order
+ # - using the same architecture for the host (supports all architectures)
+ # - using a host architecture with the same word size (supports arm and riscv, which have simulators)
+ # - using a host architecture with a different word size (supports only AOT and only 32-bit target on 64-bit host)
+ if arch in ['ia32']:
+ candidates = ['x86']
+ elif arch in ['x64', 'x64c']:
+ candidates = ['x64']
+ elif arch in ['arm', 'simarm']:
+ candidates = ['arm', 'x86', 'riscv32', 'arm64', 'x64', 'riscv64']
+ elif arch in ['arm64', 'arm64c', 'simarm64', 'simarm64c']:
+ candidates = ['arm64', 'x64', 'riscv64']
+ elif arch in ['riscv32', 'simriscv32']:
+ candidates = ['riscv32', 'arm', 'x86', 'riscv64', 'arm64', 'x64']
+ elif arch in ['riscv64', 'simriscv64']:
+ candidates = ['riscv64', 'arm64', 'x64']
+ else:
+ raise Exception("Unknown Dart architecture: %s" % arch)
+
+ available = utils.HostArchitectures()
+ for candidate in candidates:
+ if candidate in available:
+ return candidate
+
+ raise Exception(
+ "Failed to find a C host architecture for %s. Need one of %s but only %s are available."
+ % (arch, candidates, available))
# The C compiler's target.
def TargetCpuForArch(arch, target_os):
- if arch in ['ia32', 'simarm', 'simriscv32']:
+ # Real target architectures
+ if arch in ['ia32']:
return 'x86'
- if arch in [
- 'x64', 'simarm64', 'simarm_x64', 'simriscv64', 'x64c', 'simarm64c'
- ]:
+ elif arch in ['x64', 'x64c']:
return 'x64'
- if arch == 'arm_x64':
+ elif arch in ['arm', 'arm_x64', 'arm_arm64', 'arm_riscv64']:
return 'arm'
- if arch == 'arm64c':
+ elif arch in ['arm64', 'arm64c']:
return 'arm64'
- return arch
+ elif arch in ['riscv32', 'riscv32_x64', 'riscv32_arm64', 'riscv32_riscv64']:
+ return 'riscv32'
+ elif arch in ['riscv64']:
+ return 'riscv64'
+
+ # Simulators
+ if arch in ['simarm_x64', 'simriscv32_x64']:
+ return 'x64'
+ elif arch in ['simarm_arm64', 'simriscv32_arm64']:
+ return 'arm64'
+ elif arch in ['simarm_riscv64', 'simriscv32_riscv64']:
+ return 'riscv64'
+ elif arch in ['simarm', 'simriscv32']:
+ candidates = ['arm', 'riscv32', 'x86']
+ elif arch in ['simarm64', 'simarm64c', 'simriscv64']:
+ candidates = ['arm64', 'riscv64', 'x64']
+ else:
+ raise Exception("Unknown Dart architecture: %s" % arch)
+
+ available = utils.HostArchitectures()
+ for candidate in candidates:
+ if candidate in available:
+ return candidate
+
+ raise Exception(
+ "Failed to find a C target architecture for %s. Need one of %s but only %s are available."
+ % (arch, candidates, available))
# The Dart compiler's target.
@@ -130,7 +151,10 @@
return 'ia32'
if arch in ['x64', 'x64c']:
return 'x64'
- if arch in ['arm', 'simarm', 'simarm_x64', 'arm_x64']:
+ if arch in [
+ 'arm', 'simarm', 'simarm_x64', 'arm_x64', 'simarm_arm64',
+ 'arm_arm64'
+ ]:
return 'arm'
if arch in ['arm64', 'simarm64', 'arm64c', 'simarm64c']:
return 'arm64'
diff --git a/tools/utils.py b/tools/utils.py
index 2f42263..d3401f1 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -67,9 +67,11 @@
'arm': 'arm',
'arm64': 'arm',
'arm_x64': 'arm',
+ 'arm_arm64': 'arm',
'simarm': 'ia32',
'simarm64': 'ia32',
'simarm_x64': 'ia32',
+ 'simarm_arm64': 'arm',
'x64c': 'ia32',
'arm64c': 'arm',
'simarm64c': 'ia32',
@@ -149,27 +151,44 @@
return None
+# Runs true if the currently executing python interpreter is running under
+# Rosetta. I.e., python3 is an x64 executable and we're on an arm64 Mac.
+def IsRosetta():
+ if platform.system() == 'Darwin':
+ p = subprocess.Popen(['sysctl', '-in', 'sysctl.proc_translated'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ output, _ = p.communicate()
+ return output.decode('utf-8').strip() == '1'
+ return False
+
+
+# Returns the architectures that can run on the current machine.
+def HostArchitectures():
+ m = platform.machine()
+ if platform.system() == 'Darwin':
+ if m == 'arm64' or IsRosetta():
+ # ARM64 Macs also support X64.
+ return ['arm64', 'x64']
+ if m == 'x86_64':
+ # X64 Macs no longer support IA32.
+ return ['x64']
+ else:
+ if m in ['aarch64', 'arm64', 'arm64e']:
+ return ['arm64']
+ if m in ['armv7l']:
+ return ['arm']
+ if m in ['i386', 'i686', 'ia32', 'x86']:
+ return ['x86', 'ia32']
+ if m in ['x64', 'x86-64', 'x86_64', 'AMD64']:
+ return ['x64', 'x86', 'ia32']
+ raise Exception('Failed to determine host architectures for %s %s',
+ platform.machine(), platform.system())
+
+
# Try to guess the host architecture.
def GuessArchitecture():
- os_id = platform.machine()
- if os_id.startswith('aarch64') or os_id == 'arm64':
- return 'arm64'
- elif os_id.startswith('arm'):
- return 'arm'
- elif '64' in os_id:
- return 'x64'
- elif (not os_id) or (not re.match('(x|i[3-6])86', os_id) is None):
- return 'ia32'
- elif os_id == 'i86pc':
- return 'ia32'
-
- guess_os = GuessOS()
- print('Warning: Guessing architecture {} based on os {}\n'.format(
- os_id, guess_os))
- if guess_os == 'win32':
- return 'ia32'
- return None
-
+ return HostArchitectures()[0]
# Try to guess the number of cpus on this machine.
def GuessCpus():
@@ -242,9 +261,13 @@
def IsCrossBuild(target_os, arch):
- host_arch = GuessArchitecture()
- return ((GetArchFamily(host_arch) != GetArchFamily(arch)) or
- (target_os != GuessOS()))
+ if (target_os not in [None, 'host']) and (target_os != GuessOS()):
+ return True
+ if arch.startswith('sim'):
+ return False
+ if arch in HostArchitectures():
+ return False
+ return True
def GetBuildConf(mode, arch, conf_os=None, sanitizer=None):
@@ -253,9 +276,8 @@
arch.upper())
# Ask for a cross build if the host and target architectures don't match.
- host_arch = GuessArchitecture()
cross_build = ''
- if GetArchFamily(host_arch) != GetArchFamily(arch):
+ if IsCrossBuild(conf_os, arch):
cross_build = 'X'
return '{}{}{}{}'.format(GetBuildMode(mode), GetBuildSanitizer(sanitizer),
cross_build, arch.upper())