Version 2.14.0-349.0.dev
Merge commit '8a0aeb678631252ece307d4dbd804329818d3524' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 1a0cb9e..e05af29 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -142,7 +142,7 @@
"name": "browser_launcher",
"rootUri": "../third_party/pkg/browser_launcher",
"packageUri": "lib/",
- "languageVersion": "2.2"
+ "languageVersion": "2.12"
},
{
"name": "build_integration",
@@ -800,4 +800,4 @@
"languageVersion": "2.12"
}
]
-}
+}
\ No newline at end of file
diff --git a/DEPS b/DEPS
index d1df738..f31a4bf 100644
--- a/DEPS
+++ b/DEPS
@@ -72,7 +72,7 @@
"gperftools_revision": "180bfa10d7cb38e8b3784d60943d50e8fcef0dcb",
# Revisions of /third_party/* dependencies.
- "args_rev": "0329844afcf3efa9e92a1dc55d7d10226b0fa932",
+ "args_rev": "bf4c8796881b62fd5d3f6d86ab43014f9651eb20",
"async_rev": "25a7e2ec39c03622b86918cb9ce3e7d00dd283d1",
"bazel_worker_rev": "0885637b037979afbf5bcd05fd748b309fd669c0",
"benchmark_harness_rev": "c546dbd9f639f75cd2f75de8df2eb9f8ea15e8e7",
@@ -80,13 +80,13 @@
"boringssl_gen_rev": "7322fc15cc065d8d2957fccce6b62a509dc4d641",
"boringssl_rev" : "1607f54fed72c6589d560254626909a64124f091",
"browser-compat-data_tag": "v1.0.22",
- "browser_launcher_rev": "12ab9f351a44ac803de9bc17bb2180bb312a9dd7",
+ "browser_launcher_rev": "c6cc1025d6901926cf022e144ba109677e3548f1",
"charcode_rev": "84ea427711e24abf3b832923959caa7dd9a8514b",
"chrome_rev" : "19997",
"cli_util_rev" : "8c504de5deb08fe32ecf51f9662bb37d8c708e57",
"clock_rev" : "a494269254ba978e7ef8f192c5f7fec3fc05b9d3",
"collection_rev": "75a7a5510979a3cd70143af85bcc1667ee233674",
- "convert_rev": "413f591577419d8a8b95d445094a82c926650bd1",
+ "convert_rev": "e063fdca4bebffecbb5e6aa5525995120982d9ce",
"crypto_rev": "b5024e4de2b1c474dd558bef593ddbf0bfade152",
"csslib_rev": "e411d862fd8cc50415c1badf2632e017373b3f47",
"dart2js_info_rev" : "e0acfeb5affdf94c53067e68bd836adf589628fd",
@@ -125,10 +125,10 @@
"json_rpc_2_rev": "7e00f893440a72de0637970325e4ea44bd1e8c8e",
"linter_tag": "422981ffb2fbd4010aa52381676cf745e2844dd9",
"lints_tag": "f9670df2a66e0ec12eb51554e70c1cbf56c8f5d0",
- "logging_rev": "e2f633b543ef89c54688554b15ca3d7e425b86a2",
+ "logging_rev": "575781ef196e4fed4fb737e38fb4b73d62727187",
"markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
"markdown_rev": "9c4beaac96d8f008078e00b027915f81b665d2de",
- "matcher_rev": "1f7b6f0cb15eb6659a1de0513571575a5c8a51d0",
+ "matcher_rev": "b411b22ec2437ba206c7a3006bbaeb519bd343d1",
"mime_rev": "c931f4bed87221beaece356494b43731445ce7b8",
"mockito_rev": "d39ac507483b9891165e422ec98d9fb480037c8b",
"oauth2_rev": "7cd3284049fe5badbec9f2bea2afc41d14c01057",
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 7c40e38..017468a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -80,7 +80,7 @@
/// TODO(scheglov) Clean up the list of implicitly analyzed files.
class AnalysisDriver implements AnalysisDriverGeneric {
/// The version of data format, should be incremented on every format change.
- static const int DATA_VERSION = 163;
+ static const int DATA_VERSION = 164;
/// The number of exception contexts allowed to write. Once this field is
/// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 41a201a..d466919 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -2715,6 +2715,17 @@
}
}
+/// Information about a macro-produced [Element].
+class ElementMacro {
+ /// The sequential id of this macro-produced element.
+ final int id;
+
+ /// The code that for produced by the macro.
+ final String code;
+
+ ElementMacro(this.id, this.code);
+}
+
/// An [AbstractClassElementImpl] which is an enum.
class EnumElementImpl extends AbstractClassElementImpl {
ElementLinkedData? linkedData;
@@ -3480,6 +3491,13 @@
}
}
+/// This interface is implemented by [Element]s that can be added by macros.
+abstract class HasElementMacro {
+ /// If this element was added by a macro, the code of a declaration that
+ /// was produced by the macro.
+ ElementMacro? macro;
+}
+
/// A concrete implementation of a [HideElementCombinator].
class HideElementCombinatorImpl implements HideElementCombinator {
@override
@@ -4912,11 +4930,14 @@
/// A concrete implementation of a [PropertyAccessorElement].
class PropertyAccessorElementImpl extends ExecutableElementImpl
- implements PropertyAccessorElement {
+ implements PropertyAccessorElement, HasElementMacro {
/// The variable associated with this accessor.
@override
late PropertyInducingElement variable;
+ @override
+ ElementMacro? macro;
+
/// Initialize a newly created property accessor element to have the given
/// [name] and [offset].
PropertyAccessorElementImpl(String name, int offset) : super(name, offset);
diff --git a/pkg/analyzer/lib/src/macro/impl/macro.dart b/pkg/analyzer/lib/src/macro/impl/macro.dart
index 6459a6c..85f0223 100644
--- a/pkg/analyzer/lib/src/macro/impl/macro.dart
+++ b/pkg/analyzer/lib/src/macro/impl/macro.dart
@@ -6,14 +6,16 @@
import 'package:analyzer/dart/ast/ast.dart' as ast;
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/ast.dart' as ast;
+import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/macro/api/code.dart';
import 'package:analyzer/src/macro/api/macro.dart';
class ClassDeclarationBuilderImpl extends DeclarationBuilderImpl
implements ClassDeclarationBuilder {
+ final DeclarationCollector _collector;
final ast.ClassDeclarationImpl node;
- ClassDeclarationBuilderImpl(this.node);
+ ClassDeclarationBuilderImpl(this._collector, this.node);
@override
void addToClass(Declaration declaration) {
@@ -28,6 +30,7 @@
_resetOffsets(parsedMember);
node.members.add(parsedMember);
+ _collector._add(parsedMember, declaration);
}
/// We parsed [node] in the context of some synthetic code string, its
@@ -52,3 +55,36 @@
return Fragment(node.toSource());
}
}
+
+class DeclarationCollector {
+ final Map<ast.AstNode, _CollectedDeclaration> _declarations = {};
+ int _nextId = 0;
+
+ /// Elements for nodes in [_declarations] were built.
+ /// Move information from [_CollectedDeclaration] into elements.
+ void updateElements() {
+ for (var entry in _declarations.entries) {
+ var node = entry.key;
+ if (node is ast.Declaration) {
+ var element = node.declaredElement;
+ if (element is HasElementMacro) {
+ (element as HasElementMacro).macro = ElementMacro(
+ entry.value.id,
+ entry.value.declaration.code,
+ );
+ }
+ }
+ }
+ }
+
+ void _add(ast.AstNode node, Declaration declaration) {
+ _declarations[node] = _CollectedDeclaration(_nextId++, declaration);
+ }
+}
+
+class _CollectedDeclaration {
+ final int id;
+ final Declaration declaration;
+
+ _CollectedDeclaration(this.id, this.declaration);
+}
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index 4448606..94e46ae 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -850,6 +850,15 @@
return LibraryLanguageVersion(package: package, override: override);
}
+ ElementMacro? _readMacro() {
+ var hasData = _reader.readBool();
+ if (hasData) {
+ var id = _reader.readUInt30();
+ var code = _reader.readStringUtf8();
+ return ElementMacro(id, code);
+ }
+ }
+
List<MethodElementImpl> _readMethods(
CompilationUnitElementImpl unitElement,
ElementImpl enclosingElement,
@@ -986,6 +995,7 @@
var element = PropertyAccessorElementImpl(name, -1);
PropertyAccessorElementFlags.read(_reader, element);
+ element.macro = _readMacro();
var reference = classReference
.getChild(element.isGetter ? '@getter' : '@setter')
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index a88940b..a112b46 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -280,6 +280,14 @@
}
}
+ void _writeMacro(ElementMacro? macro) {
+ _sink.writeBool(macro != null);
+ if (macro != null) {
+ _sink.writeUInt30(macro.id);
+ _sink.writeStringUtf8(macro.code);
+ }
+ }
+
void _writeMethodElement(MethodElement element) {
element as MethodElementImpl;
_sink.writeUInt30(_resolutionSink.offset);
@@ -364,6 +372,7 @@
_sink.writeUInt30(_resolutionSink.offset);
_sink._writeStringReference(element.displayName);
PropertyAccessorElementFlags.write(_sink, element);
+ _writeMacro(element.macro);
_resolutionSink._writeAnnotationList(element.metadata);
_resolutionSink.writeType(element.returnType);
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 9548d6e..8e1064e 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -198,16 +198,21 @@
TypesBuilder(linker).build(nodesToBuildType);
}
+ var collector = macro.DeclarationCollector();
for (var linkingUnit in units) {
for (var declaration in linkingUnit.node.declarations) {
if (declaration is ast.ClassDeclarationImpl) {
var members = declaration.members.toList();
+ var classBuilder = macro.ClassDeclarationBuilderImpl(
+ collector,
+ declaration,
+ );
for (var member in members) {
if (member is ast.FieldDeclarationImpl) {
if (hasMacroAnnotation(member, 'observable')) {
macro.ObservableMacro().visitFieldDeclaration(
member,
- macro.ClassDeclarationBuilderImpl(declaration),
+ classBuilder,
);
}
}
@@ -227,6 +232,7 @@
}
}
}
+ collector.updateElements();
}
void storeExportScope() {
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index e7884a5..8e2ebe9 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -402,10 +402,7 @@
void _writeDocumentation(Element element) {
var documentation = element.documentationComment;
if (documentation != null) {
- var str = documentation;
- str = str.replaceAll('\n', r'\n');
- str = str.replaceAll('\r', r'\r');
- _writelnWithIndent('documentationComment: $str');
+ _writelnMultiLineWithIndent('documentationComment: $documentation');
}
}
@@ -521,11 +518,30 @@
buffer.writeln();
}
+ void _writelnMultiLineWithIndent(String str) {
+ str = str.replaceAll('\n', r'\n');
+ str = str.replaceAll('\r', r'\r');
+ _writelnWithIndent(str);
+ }
+
void _writelnWithIndent(String line) {
buffer.write(indent);
buffer.writeln(line);
}
+ void _writeMacro(Element e) {
+ if (e is HasElementMacro) {
+ var macro = (e as HasElementMacro).macro;
+ if (macro != null) {
+ _writelnWithIndent('macro');
+ _withIndent(() {
+ _writelnWithIndent('id: ${macro.id}');
+ _writelnMultiLineWithIndent('code: ${macro.code}');
+ });
+ }
+ }
+ }
+
void _writeMetadata(Element element) {
var annotations = element.metadata;
if (annotations.isNotEmpty) {
@@ -693,6 +709,7 @@
});
_withIndent(() {
+ _writeMacro(e);
_writeDocumentation(e);
_writeMetadata(e);
_writeCodeRange(e);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 814a92b..7c789a4f 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -21289,8 +21289,14 @@
type: int
returnType: void
get f @-1
+ macro
+ id: 0
+ code: int get f => _f;
returnType: int
set f @-1
+ macro
+ id: 1
+ code: set f(int val) {\n print('Setting f to ${val}');\n _f = val;\n}
parameters
requiredPositional val @-1
type: int
@@ -21344,8 +21350,14 @@
type: T
returnType: void
get f @-1
+ macro
+ id: 0
+ code: T get f => _f;
returnType: T
set f @-1
+ macro
+ id: 1
+ code: set f(T val) {\n print('Setting f to ${val}');\n _f = val;\n}
parameters
requiredPositional val @-1
type: T
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 4495763..6f7e3fd 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -360,6 +360,8 @@
flavor.write(', lax runtime type');
}
if (_options.useContentSecurityPolicy) flavor.write(', CSP');
+ var featureString = _options.features.flavorString();
+ if (featureString.isNotEmpty) flavor.write(', $featureString');
return js.Comment(generatedBy(_options, flavor: '$flavor'));
}
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index a710db6..3598ad3 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -81,6 +81,21 @@
}
}
+ /// Returns a list of enabled features as a comma separated string.
+ String flavorString() {
+ bool _shouldPrint(FeatureOption feature) {
+ return feature.isNegativeFlag ? feature.isDisabled : feature.isEnabled;
+ }
+ String _toString(FeatureOption feature) {
+ return feature.isNegativeFlag ? 'no-${feature.flag}' : feature.flag;
+ }
+ Iterable<String> _listToString(List<FeatureOption> options) {
+ return options.where(_shouldPrint).map(_toString);
+ }
+ return _listToString(shipping).followedBy(_listToString(canary)).join(', ');
+ }
+
+ /// Parses a [List<String>] and enables / disables features as necessary.
void parse(List<String> options) {
_extractFeatures(options, shipping, FeatureStatus.shipping);
_extractFeatures(options, canary, FeatureStatus.canary);
diff --git a/pkg/compiler/test/end_to_end/feature_options_test.dart b/pkg/compiler/test/end_to_end/feature_options_test.dart
index 3481941..d4f3908 100644
--- a/pkg/compiler/test/end_to_end/feature_options_test.dart
+++ b/pkg/compiler/test/end_to_end/feature_options_test.dart
@@ -128,7 +128,26 @@
Expect.throwsArgumentError(() => test(['--cf1', '--no-cf1']));
}
+void flavorStringTest(List<String> options, String expectedFlavorString) {
+ var tfo = test(options);
+ Expect.equals(expectedFlavorString, tfo.flavorString());
+}
+
+void flavorStringTests() {
+ flavorStringTest([], 'sf1, sf2, no-sf3, no-sf4');
+ flavorStringTest(['--no-sf1', '--no-sf2', '--sf3', '--sf4'], '');
+ flavorStringTest(['--no-sf1', '--no-sf2', '--sf3'], 'no-sf4');
+ flavorStringTest(['--no-sf1', '--sf3', '--sf4'], 'sf2');
+ flavorStringTest(['--no-sf1', '--no-sf2', '--sf3', '--sf4', '--cf1'], 'cf1');
+ flavorStringTest(['--cf1'], 'sf1, sf2, no-sf3, no-sf4, cf1');
+ flavorStringTest(['--no-sf1', '--no-sf2', '--sf3', '--sf4', '--no-cf3'], 'no-cf3');
+ flavorStringTest(['--no-cf3'], 'sf1, sf2, no-sf3, no-sf4, no-cf3');
+ flavorStringTest(['--no-sf1', '--no-sf2', '--sf3', '--sf4', '--cf1',
+ '--no-cf3'], 'cf1, no-cf3');
+}
+
void main() {
+ // Test feature options functionality.
testShipping();
testNoShipping();
testCanary();
@@ -138,4 +157,7 @@
testNoCanaryEnabled();
testNoShippingEnabled();
testFlagCollision();
+
+ // Supplemental tests.
+ flavorStringTests();
}
diff --git a/pkg/dev_compiler/pubspec.yaml b/pkg/dev_compiler/pubspec.yaml
index 2c8bf7f..41826b5 100644
--- a/pkg/dev_compiler/pubspec.yaml
+++ b/pkg/dev_compiler/pubspec.yaml
@@ -28,7 +28,7 @@
source_span: any
dev_dependencies:
- browser_launcher: ^0.1.9
+ browser_launcher: ^1.0.0
expect:
path: ../expect
http_multi_server:
@@ -48,5 +48,5 @@
path: ../testing
vm:
path: ../vm
- webkit_inspection_protocol: ^0.7.4
+ webkit_inspection_protocol: ^1.0.0
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index 716a5a2..4de08b9 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -42,7 +42,7 @@
import '../fasta_codes.dart';
-import '../kernel/kernel_target.dart';
+import '../kernel/kernel_helper.dart';
import '../loader.dart';
diff --git a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
index e49c0c7..98068cb 100644
--- a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
@@ -20,7 +20,7 @@
show ExpressionGeneratorHelper;
import '../kernel/kernel_builder.dart'
show isRedirectingGenerativeConstructorImplementation;
-import '../kernel/kernel_target.dart' show SynthesizedFunctionNode;
+import '../kernel/kernel_helper.dart' show SynthesizedFunctionNode;
import '../loader.dart' show Loader;
@@ -229,8 +229,8 @@
library == libraryBuilder,
"Unexpected library builder ${libraryBuilder} for"
" constructor $this in ${library}.");
- libraryBuilder.loader.typeInferenceEngine.toBeInferred[_constructor] =
- this;
+ libraryBuilder.loader
+ .registerConstructorToBeInferred(_constructor, this);
}
}
return _constructor;
@@ -266,10 +266,6 @@
bodyBuilder.parseInitializers(beginInitializers!);
bodyBuilder.resolveRedirectingFactoryTargets();
}
- if (_constructorTearOff != null) {
- buildConstructorTearOffOutline(
- _constructorTearOff!, constructor, classBuilder!.cls);
- }
beginInitializers = null;
}
diff --git a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart b/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
index 463174c..a9a0b74 100644
--- a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
@@ -42,7 +42,7 @@
templateDuplicatedDeclarationSyntheticCause,
templateEnumConstantSameNameAsEnclosing;
-import '../kernel/kernel_target.dart';
+import '../kernel/kernel_helper.dart';
import '../util/helpers.dart';
diff --git a/pkg/front_end/lib/src/fasta/builder/extension_builder.dart b/pkg/front_end/lib/src/fasta/builder/extension_builder.dart
index 9435193..d0250bf 100644
--- a/pkg/front_end/lib/src/fasta/builder/extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/extension_builder.dart
@@ -7,7 +7,7 @@
import '../fasta_codes.dart'
show templateInternalProblemNotFoundIn, templateTypeArgumentMismatch;
-import '../kernel/kernel_target.dart';
+import '../kernel/kernel_helper.dart';
import '../scope.dart';
import '../source/source_library_builder.dart';
import '../problems.dart';
diff --git a/pkg/front_end/lib/src/fasta/builder/factory_builder.dart b/pkg/front_end/lib/src/fasta/builder/factory_builder.dart
index 2725aac..8b6c13e 100644
--- a/pkg/front_end/lib/src/fasta/builder/factory_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/factory_builder.dart
@@ -12,7 +12,7 @@
import '../kernel/forest.dart';
import '../kernel/internal_ast.dart';
import '../kernel/kernel_api.dart';
-import '../kernel/kernel_target.dart';
+import '../kernel/kernel_helper.dart';
import '../kernel/redirecting_factory_body.dart'
show getRedirectingFactoryBody, RedirectingFactoryBody;
@@ -342,7 +342,7 @@
if (_factoryTearOff != null) {
_tearOffTypeParameters =
buildRedirectingFactoryTearOffProcedureParameters(
- _factoryTearOff!, _procedure, library);
+ _factoryTearOff!, _procedureInternal, libraryBuilder);
}
return _procedureInternal;
}
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index 4fd424a..1a7c9bc 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -17,7 +17,7 @@
import '../kernel/body_builder.dart' show BodyBuilder;
import '../kernel/class_hierarchy_builder.dart';
import '../kernel/kernel_builder.dart' show ImplicitFieldType;
-import '../kernel/kernel_target.dart';
+import '../kernel/kernel_helper.dart';
import '../kernel/late_lowering.dart' as late_lowering;
import '../kernel/member_covariance.dart';
diff --git a/pkg/front_end/lib/src/fasta/builder/function_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
index e4cab78..71dc58a 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
@@ -13,7 +13,7 @@
import '../scope.dart';
import '../kernel/internal_ast.dart' show VariableDeclarationImpl;
-import '../kernel/kernel_target.dart';
+import '../kernel/kernel_helper.dart';
import '../loader.dart' show Loader;
diff --git a/pkg/front_end/lib/src/fasta/builder/member_builder.dart b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
index 87167ef..bae23b9 100644
--- a/pkg/front_end/lib/src/fasta/builder/member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
@@ -10,7 +10,7 @@
import '../../base/common.dart';
import '../kernel/class_hierarchy_builder.dart';
-import '../kernel/kernel_target.dart';
+import '../kernel/kernel_helper.dart';
import '../modifier.dart';
import '../problems.dart' show unsupported;
import '../source/source_library_builder.dart';
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_extension_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_extension_builder.dart
index c9aba98..1a1857b 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_extension_builder.dart
@@ -11,7 +11,7 @@
import '../builder/type_builder.dart';
import '../builder/type_variable_builder.dart';
-import '../kernel/kernel_target.dart';
+import '../kernel/kernel_helper.dart';
import '../scope.dart';
diff --git a/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
index 6cf584a..ae3a7d3 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
@@ -4,11 +4,10 @@
import 'package:kernel/ast.dart';
import 'package:kernel/type_algebra.dart';
-import '../builder/library_builder.dart';
import '../builder/member_builder.dart';
import '../source/source_library_builder.dart';
import 'kernel_api.dart';
-import 'kernel_target.dart';
+import 'kernel_helper.dart';
const String _tearOffNamePrefix = '_#';
const String _tearOffNameSuffix = '#tearOff';
@@ -155,7 +154,7 @@
List<DartType> typeArguments = freshTypeParameters.freshTypeArguments;
Substitution substitution = freshTypeParameters.substitution;
- _createParameters(tearOff, function, substitution);
+ _createParameters(tearOff, constructor, substitution, libraryBuilder);
Arguments arguments = _createArguments(tearOff, typeArguments, fileOffset);
_createTearOffBody(tearOff, constructor, arguments);
tearOff.function.fileOffset = tearOff.fileOffset;
@@ -206,8 +205,11 @@
(int index) => substitution.substituteType(typeArguments[index]));
}
}
- _createParameters(tearOff, function,
- Substitution.fromPairs(classTypeParameters, typeArguments));
+ _createParameters(
+ tearOff,
+ constructor,
+ Substitution.fromPairs(classTypeParameters, typeArguments),
+ libraryBuilder);
Arguments arguments = _createArguments(tearOff, typeArguments, fileOffset);
_createTearOffBody(tearOff, constructor, arguments);
tearOff.function.fileOffset = tearOff.fileOffset;
@@ -215,52 +217,19 @@
updatePrivateMemberName(tearOff, libraryBuilder);
}
-/// Copies the parameter types from [constructor] to [tearOff].
-///
-/// These might have been inferred and therefore not available when the
-/// parameters were created.
-// TODO(johnniwinther): Avoid doing this when parameter types are not inferred.
-void buildConstructorTearOffOutline(
- Procedure tearOff, Constructor constructor, Class enclosingClass) {
- List<TypeParameter> classTypeParameters = enclosingClass.typeParameters;
- Substitution substitution = Substitution.empty;
- if (classTypeParameters.isNotEmpty) {
- List<DartType> typeArguments = [];
- for (TypeParameter typeParameter in tearOff.function.typeParameters) {
- typeArguments.add(new TypeParameterType(typeParameter,
- TypeParameterType.computeNullabilityFromBound(typeParameter)));
- }
- substitution = Substitution.fromPairs(classTypeParameters, typeArguments);
- }
- for (int i = 0; i < constructor.function.positionalParameters.length; i++) {
- VariableDeclaration tearOffParameter =
- tearOff.function.positionalParameters[i];
- VariableDeclaration constructorParameter =
- constructor.function.positionalParameters[i];
- tearOffParameter.type =
- substitution.substituteType(constructorParameter.type);
- }
- for (int i = 0; i < constructor.function.namedParameters.length; i++) {
- VariableDeclaration tearOffParameter = tearOff.function.namedParameters[i];
- VariableDeclaration constructorParameter =
- constructor.function.namedParameters[i];
- tearOffParameter.type =
- substitution.substituteType(constructorParameter.type);
- }
-}
-
/// Creates the parameters for the redirecting factory [tearOff] based on the
/// [redirectingConstructor] declaration.
FreshTypeParameters buildRedirectingFactoryTearOffProcedureParameters(
Procedure tearOff,
Procedure redirectingConstructor,
- LibraryBuilder libraryBuilder) {
+ SourceLibraryBuilder libraryBuilder) {
assert(redirectingConstructor.isRedirectingFactory);
FunctionNode function = redirectingConstructor.function;
FreshTypeParameters freshTypeParameters =
_createFreshTypeParameters(function.typeParameters, tearOff.function);
Substitution substitution = freshTypeParameters.substitution;
- _createParameters(tearOff, function, substitution);
+ _createParameters(
+ tearOff, redirectingConstructor, substitution, libraryBuilder);
tearOff.function.fileOffset = tearOff.fileOffset;
tearOff.function.fileEndOffset = tearOff.fileOffset;
updatePrivateMemberName(tearOff, libraryBuilder);
@@ -330,10 +299,11 @@
}
/// Creates the parameters for the [tearOff] lowering based of the parameters
-/// in [function] and using the [substitution] to compute the parameter and
+/// in [constructor] and using the [substitution] to compute the parameter and
/// return types.
-void _createParameters(
- Procedure tearOff, FunctionNode function, Substitution substitution) {
+void _createParameters(Procedure tearOff, Member constructor,
+ Substitution substitution, SourceLibraryBuilder libraryBuilder) {
+ FunctionNode function = constructor.function!;
for (VariableDeclaration constructorParameter
in function.positionalParameters) {
VariableDeclaration tearOffParameter = new VariableDeclaration(
@@ -355,6 +325,8 @@
tearOff.function.returnType =
substitution.substituteType(function.returnType);
tearOff.function.requiredParameterCount = function.requiredParameterCount;
+ libraryBuilder.loader.registerTypeDependency(
+ tearOff, new TypeDependency(tearOff, constructor, substitution));
}
/// Creates the [Arguments] for passing the parameters from [tearOff] to its
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 104b239..e08aaf2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -191,6 +191,7 @@
@override
ExpressionInferenceResult visitStaticTearOff(
StaticTearOff node, DartType typeContext) {
+ inferrer.ensureMemberType(node.target);
DartType type =
node.target.function.computeFunctionType(inferrer.library.nonNullable);
return inferrer.instantiateTearOff(type, typeContext, node);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart
new file mode 100644
index 0000000..71176e5
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart
@@ -0,0 +1,120 @@
+// Copyright (c) 2016, 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.
+
+library fasta.kernel_target;
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
+import 'package:kernel/type_algebra.dart' show Substitution;
+
+/// Data for clone default values for synthesized function nodes once the
+/// original default values have been computed.
+///
+/// This is used for constructors in unnamed mixin application, which are
+/// created from the constructors in the superclass, and for tear off lowerings
+/// for redirecting factories, which are created from the effective target
+/// constructor.
+class SynthesizedFunctionNode {
+ /// Type parameter map from type parameters in scope [_original] to types
+ /// in scope of [_synthesized].
+ // TODO(johnniwinther): Is this ever needed? Should occurrence of type
+ // variable types in default values be a compile time error?
+ final Map<TypeParameter, DartType> _typeSubstitution;
+
+ /// The original function node.
+ final FunctionNode _original;
+
+ /// The synthesized function node.
+ final FunctionNode _synthesized;
+
+ /// If `true`, the [_synthesized] is guaranteed to have the same parameters in
+ /// the same order as [_original]. Otherwise [_original] is only guaranteed to
+ /// be callable from [_synthesized], meaning that is has at most the same
+ /// number of positional parameters and a, possibly reordered, subset of the
+ /// named parameters.
+ final bool identicalSignatures;
+
+ SynthesizedFunctionNode(
+ this._typeSubstitution, this._original, this._synthesized,
+ {this.identicalSignatures: true});
+
+ void cloneDefaultValues() {
+ // TODO(ahe): It is unclear if it is legal to use type variables in
+ // default values, but Fasta is currently allowing it, and the VM
+ // accepts it. If it isn't legal, the we can speed this up by using a
+ // single cloner without substitution.
+ CloneVisitorNotMembers? cloner;
+
+ void cloneInitializer(VariableDeclaration originalParameter,
+ VariableDeclaration clonedParameter) {
+ if (originalParameter.initializer != null) {
+ cloner ??=
+ new CloneVisitorNotMembers(typeSubstitution: _typeSubstitution);
+ clonedParameter.initializer = cloner!
+ .clone(originalParameter.initializer!)
+ ..parent = clonedParameter;
+ }
+ }
+
+ // For mixin application constructors, the argument count is the same, but
+ // for redirecting tear off lowerings, the argument count of the tear off
+ // can be less than that of the redirection target.
+
+ assert(_synthesized.positionalParameters.length <=
+ _original.positionalParameters.length);
+ for (int i = 0; i < _synthesized.positionalParameters.length; i++) {
+ cloneInitializer(_original.positionalParameters[i],
+ _synthesized.positionalParameters[i]);
+ }
+
+ if (identicalSignatures) {
+ assert(_synthesized.namedParameters.length ==
+ _original.namedParameters.length);
+ for (int i = 0; i < _synthesized.namedParameters.length; i++) {
+ cloneInitializer(
+ _original.namedParameters[i], _synthesized.namedParameters[i]);
+ }
+ } else if (_synthesized.namedParameters.isNotEmpty) {
+ Map<String, VariableDeclaration> originalParameters = {};
+ for (int i = 0; i < _original.namedParameters.length; i++) {
+ originalParameters[_original.namedParameters[i].name!] =
+ _original.namedParameters[i];
+ }
+ for (int i = 0; i < _synthesized.namedParameters.length; i++) {
+ cloneInitializer(
+ originalParameters[_synthesized.namedParameters[i].name!]!,
+ _synthesized.namedParameters[i]);
+ }
+ }
+ }
+}
+
+class TypeDependency {
+ final Member synthesized;
+ final Member original;
+ final Substitution substitution;
+
+ TypeDependency(this.synthesized, this.original, this.substitution);
+
+ void copyInferred() {
+ for (int i = 0; i < original.function!.positionalParameters.length; i++) {
+ VariableDeclaration synthesizedParameter =
+ synthesized.function!.positionalParameters[i];
+ VariableDeclaration constructorParameter =
+ original.function!.positionalParameters[i];
+ synthesizedParameter.type =
+ substitution.substituteType(constructorParameter.type);
+ }
+ for (int i = 0; i < original.function!.namedParameters.length; i++) {
+ VariableDeclaration synthesizedParameter =
+ synthesized.function!.namedParameters[i];
+ VariableDeclaration originalParameter =
+ original.function!.namedParameters[i];
+ synthesizedParameter.type =
+ substitution.substituteType(originalParameter.type);
+ }
+ synthesized.function!.returnType =
+ substitution.substituteType(original.function!.returnType);
+ }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 00e445c..0d35d0f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -6,7 +6,6 @@
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
-import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
import 'package:kernel/core_types.dart';
import 'package:kernel/reference_from_index.dart' show IndexedClass;
import 'package:kernel/target/changed_structure_notifier.dart'
@@ -82,6 +81,7 @@
transformProcedure,
ConstantCoverage;
import 'kernel_constants.dart' show KernelConstantErrorReporter;
+import 'kernel_helper.dart';
import 'verifier.dart' show verifyComponent, verifyGetStaticType;
class KernelTarget extends TargetImplementation {
@@ -364,7 +364,7 @@
return withCrashReporting<Component?>(() async {
ticker.logMs("Building component");
await loader.buildBodies();
- finishClonedParameters();
+ finishSynthesizedParameters();
loader.finishDeferredLoadTearoffs();
loader.finishNoSuchMethodForwarders();
List<SourceClassBuilder> myClasses = collectMyClasses();
@@ -792,7 +792,7 @@
synthesizedFunctionNode: isConst ? synthesizedFunctionNode : null);
}
- void finishClonedParameters() {
+ void finishSynthesizedParameters() {
for (SynthesizedFunctionNode synthesizedFunctionNode
in synthesizedFunctionNodes) {
synthesizedFunctionNode.cloneDefaultValues();
@@ -1428,85 +1428,3 @@
target.type = substitute(source.type, substitutionMap);
}
}
-
-/// Data for clone default values for synthesized function nodes once the
-/// original default values have been computed.
-///
-/// This is used for constructors in unnamed mixin application, which are
-/// created from the constructors in the superclass, and for tear off lowerings
-/// for redirecting factories, which are created from the effective target
-/// constructor.
-class SynthesizedFunctionNode {
- /// Type parameter map from type parameters in scope [_original] to types
- /// in scope of [_synthesized].
- // TODO(johnniwinther): Is this ever needed? Should occurrence of type
- // variable types in default values be a compile time error?
- final Map<TypeParameter, DartType> _typeSubstitution;
-
- /// The original function node.
- final FunctionNode _original;
-
- /// The synthesized function node.
- final FunctionNode _synthesized;
-
- /// If `true`, the [_synthesized] is guaranteed to have the same parameters in
- /// the same order as [_original]. Otherwise [_original] is only guaranteed to
- /// be callable from [_synthesized], meaning that is has at most the same
- /// number of positional parameters and a, possibly reordered, subset of the
- /// named parameters.
- final bool identicalSignatures;
-
- SynthesizedFunctionNode(
- this._typeSubstitution, this._original, this._synthesized,
- {this.identicalSignatures: true});
-
- void cloneDefaultValues() {
- // TODO(ahe): It is unclear if it is legal to use type variables in
- // default values, but Fasta is currently allowing it, and the VM
- // accepts it. If it isn't legal, the we can speed this up by using a
- // single cloner without substitution.
- CloneVisitorNotMembers? cloner;
-
- void cloneInitializer(VariableDeclaration originalParameter,
- VariableDeclaration clonedParameter) {
- if (originalParameter.initializer != null) {
- cloner ??=
- new CloneVisitorNotMembers(typeSubstitution: _typeSubstitution);
- clonedParameter.initializer = cloner!
- .clone(originalParameter.initializer!)
- ..parent = clonedParameter;
- }
- }
-
- // For mixin application constructors, the argument count is the same, but
- // for redirecting tear off lowerings, the argument count of the tear off
- // can be less than that of the redirection target.
-
- assert(_synthesized.positionalParameters.length <=
- _original.positionalParameters.length);
- for (int i = 0; i < _synthesized.positionalParameters.length; i++) {
- cloneInitializer(_original.positionalParameters[i],
- _synthesized.positionalParameters[i]);
- }
-
- if (identicalSignatures) {
- assert(_synthesized.namedParameters.length ==
- _original.namedParameters.length);
- for (int i = 0; i < _synthesized.namedParameters.length; i++) {
- cloneInitializer(
- _original.namedParameters[i], _synthesized.namedParameters[i]);
- }
- } else if (_synthesized.namedParameters.isNotEmpty) {
- Map<String, VariableDeclaration> originalParameters = {};
- for (int i = 0; i < _original.namedParameters.length; i++) {
- originalParameters[_original.namedParameters[i].name!] =
- _original.namedParameters[i];
- }
- for (int i = 0; i < _synthesized.namedParameters.length; i++) {
- cloneInitializer(
- originalParameters[_synthesized.namedParameters[i].name!]!,
- _synthesized.namedParameters[i]);
- }
- }
- }
-}
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index 4027001..34849e8 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -15,7 +15,7 @@
import 'builder/type_variable_builder.dart';
import 'kernel/body_builder.dart' show JumpTarget;
import 'kernel/class_hierarchy_builder.dart' show ClassMember;
-import 'kernel/kernel_target.dart';
+import 'kernel/kernel_helper.dart';
import 'util/helpers.dart' show DelayedActionPerformer;
import 'fasta_codes.dart'
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
index d6a21ef..5ffcb20 100644
--- a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
@@ -26,7 +26,7 @@
noLength,
templateExtensionMemberConflictsWithObjectMember;
-import '../kernel/kernel_target.dart';
+import '../kernel/kernel_helper.dart';
import '../problems.dart';
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index ed43189..538d6cc 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -30,12 +30,14 @@
AsyncMarker,
Class,
Component,
+ Constructor,
DartType,
Expression,
FunctionNode,
InterfaceType,
Library,
LibraryDependency,
+ Member,
NeverType,
Nullability,
Procedure,
@@ -70,6 +72,7 @@
import '../builder/builder.dart';
import '../builder/class_builder.dart';
+import '../builder/constructor_builder.dart';
import '../builder/dynamic_type_declaration_builder.dart';
import '../builder/enum_builder.dart';
import '../builder/extension_builder.dart';
@@ -89,18 +92,14 @@
import '../fasta_codes.dart';
+import '../kernel/body_builder.dart' show BodyBuilder;
import '../kernel/kernel_builder.dart'
show ClassHierarchyBuilder, ClassMember, DelayedCheck;
-
-import '../kernel/kernel_target.dart'
- show SynthesizedFunctionNode, KernelTarget;
-
-import '../kernel/body_builder.dart' show BodyBuilder;
-
+import '../kernel/kernel_helper.dart'
+ show SynthesizedFunctionNode, TypeDependency;
+import '../kernel/kernel_target.dart' show KernelTarget;
import '../kernel/transform_collections.dart' show CollectionTransformer;
-
import '../kernel/transform_set_literals.dart' show SetLiteralTransformer;
-
import '../kernel/type_builder_computer.dart' show TypeBuilderComputer;
import '../loader.dart' show Loader, untranslatableUriScheme;
@@ -110,19 +109,14 @@
import '../source/stack_listener_impl.dart' show offsetForToken;
import '../type_inference/type_inference_engine.dart';
-
import '../type_inference/type_inferrer.dart';
import '../util/helpers.dart';
import 'diet_listener.dart' show DietListener;
-
import 'diet_parser.dart' show DietParser;
-
import 'outline_builder.dart' show OutlineBuilder;
-
import 'source_class_builder.dart' show SourceClassBuilder;
-
import 'source_library_builder.dart' show SourceLibraryBuilder;
import 'source_type_alias_builder.dart';
@@ -368,6 +362,15 @@
hasInvalidNnbdModeLibrary = true;
}
+ void registerConstructorToBeInferred(
+ Constructor constructor, ConstructorBuilder builder) {
+ _typeInferenceEngine!.toBeInferred[constructor] = builder;
+ }
+
+ void registerTypeDependency(Member member, TypeDependency typeDependency) {
+ _typeInferenceEngine!.typeDependencies[member] = typeDependency;
+ }
+
@override
Future<Null> buildOutlines() async {
await super.buildOutlines();
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index 9961217..ed04394 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -32,7 +32,7 @@
import '../builder/type_variable_builder.dart';
import '../kernel/constructor_tearoff_lowering.dart';
-import '../kernel/kernel_target.dart';
+import '../kernel/kernel_helper.dart';
import '../util/helpers.dart';
@@ -264,8 +264,6 @@
}
_tearOffDependencies?.forEach((Procedure tearOff, Member target) {
InterfaceType targetType = typedef.type as InterfaceType;
- buildTypedefTearOffProcedure(tearOff, target, target.enclosingClass!,
- typedef.typeParameters, targetType.typeArguments, library);
synthesizedFunctionNodes.add(new SynthesizedFunctionNode(
new Map<TypeParameter, DartType>.fromIterables(
target.enclosingClass!.typeParameters, targetType.typeArguments),
@@ -295,6 +293,9 @@
createTypedefTearOffProcedure(
name, constructorName, library, fileUri, charOffset);
_tearOffDependencies![tearOff] = target;
+ InterfaceType targetType = typedef.type as InterfaceType;
+ buildTypedefTearOffProcedure(tearOff, target, declaration.cls,
+ typedef.typeParameters, targetType.typeArguments, library);
f(tearOff);
}
});
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index 407fbfb..5ba0cfa 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE.md file.
import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
-import 'package:front_end/src/fasta/kernel/internal_ast.dart';
import 'package:kernel/ast.dart';
@@ -18,9 +17,10 @@
import '../builder/constructor_builder.dart';
import '../kernel/forest.dart';
-
+import '../kernel/internal_ast.dart';
import '../kernel/kernel_builder.dart'
show ClassHierarchyBuilder, ImplicitFieldType;
+import '../kernel/kernel_helper.dart';
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
@@ -128,6 +128,8 @@
/// is used to report errors.
final Map<Constructor, ConstructorBuilder> beingInferred = {};
+ final Map<Member, TypeDependency> typeDependencies = {};
+
final Instrumentation? instrumentation;
TypeInferenceEngine(this.instrumentation);
@@ -152,6 +154,10 @@
builder.inferFormalTypes();
}
toBeInferred.clear();
+ for (TypeDependency typeDependency in typeDependencies.values) {
+ typeDependency.copyInferred();
+ }
+ typeDependencies.clear();
}
/// Gets ready to do top level type inference for the component having the
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 a0be20e..db042b3 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
@@ -37,6 +37,7 @@
import '../fasta_codes.dart';
import '../kernel/class_hierarchy_builder.dart' show ClassMember;
+import '../kernel/kernel_helper.dart';
import '../kernel/inference_visitor.dart';
import '../kernel/internal_ast.dart';
import '../kernel/invalid_type.dart';
@@ -210,14 +211,8 @@
/// inside a closure.
ClosureContext? closureContext;
- TypeInferrerImpl(
- this.engine,
- this.uriForInstrumentation,
- bool topLevel,
- this.thisType,
- this.library,
- this.assignedVariables,
- this.dataForTesting)
+ TypeInferrerImpl(this.engine, this.uriForInstrumentation, bool topLevel,
+ this.thisType, this.library, this.assignedVariables, this.dataForTesting)
// ignore: unnecessary_null_comparison
: assert(library != null),
unknownFunction = new FunctionType(
@@ -369,6 +364,11 @@
if (member is Constructor) {
inferConstructorParameterTypes(member);
}
+ TypeDependency? typeDependency = engine.typeDependencies.remove(member);
+ if (typeDependency != null) {
+ ensureMemberType(typeDependency.original);
+ typeDependency.copyInferred();
+ }
}
@override
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.expect
index 8770854..fa85f71 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.expect
@@ -2,16 +2,6 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:28:18: Error: A value of type 'Class1 Function(int)' can't be assigned to a variable of type 'Class1 Function(dynamic)'.
-// - 'Class1' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-// var Class1_new = Class1.new;
-// ^
-//
-// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:29:18: Error: A value of type 'Class2 Function(int)' can't be assigned to a variable of type 'Class2 Function(dynamic)'.
-// - 'Class2' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-// var Class2_new = Class2.new;
-// ^
-//
// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:38:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
// f1a(''); // error
// ^
@@ -46,14 +36,8 @@
return new self::Class2::•(field);
}
static final field core::bool inSoundMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
-static field (dynamic) → self::Class1 Class1_new = let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:28:18: Error: A value of type 'Class1 Function(int)' can't be assigned to a variable of type 'Class1 Function(dynamic)'.
- - 'Class1' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-var Class1_new = Class1.new;
- ^" in (#C1) as{TypeError,ForNonNullableByDefault} (dynamic) → self::Class1;
-static field (dynamic) → self::Class2 Class2_new = let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:29:18: Error: A value of type 'Class2 Function(int)' can't be assigned to a variable of type 'Class2 Function(dynamic)'.
- - 'Class2' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-var Class2_new = Class2.new;
- ^" in (#C2) as{TypeError,ForNonNullableByDefault} (dynamic) → self::Class2;
+static field (core::int) → self::Class1 Class1_new = #C1;
+static field (core::int) → self::Class2 Class2_new = #C2;
static method main() → dynamic {
core::print("inSoundMode: ${self::inSoundMode}");
self::testInferred();
@@ -65,7 +49,7 @@
self::Class1 c1a = f1a(0){(core::int) → self::Class1};
self::expect(true, c1a is{ForNonNullableByDefault} self::Class1);
() → Null {
- f1a(let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:38:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+ f1a(let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:38:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
f1a(''); // error
^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class1};
};
@@ -79,7 +63,7 @@
self::Class2 c2a = f2a(0){(core::int) → self::Class2};
self::expect(true, c2a is{ForNonNullableByDefault} self::Class2);
() → Null {
- f2a(let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:52:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+ f2a(let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:52:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
f2a(''); // error
^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class2};
};
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.transformed.expect
index 2d658941..2664cf0 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.transformed.expect
@@ -2,16 +2,6 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:28:18: Error: A value of type 'Class1 Function(int)' can't be assigned to a variable of type 'Class1 Function(dynamic)'.
-// - 'Class1' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-// var Class1_new = Class1.new;
-// ^
-//
-// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:29:18: Error: A value of type 'Class2 Function(int)' can't be assigned to a variable of type 'Class2 Function(dynamic)'.
-// - 'Class2' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-// var Class2_new = Class2.new;
-// ^
-//
// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:38:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
// f1a(''); // error
// ^
@@ -46,14 +36,8 @@
return new self::Class2::•(field);
}
static final field core::bool inSoundMode = !(core::_GrowableList::•<core::int?>(0) is{ForNonNullableByDefault} core::List<core::int>);
-static field (dynamic) → self::Class1 Class1_new = let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:28:18: Error: A value of type 'Class1 Function(int)' can't be assigned to a variable of type 'Class1 Function(dynamic)'.
- - 'Class1' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-var Class1_new = Class1.new;
- ^" in (#C1) as{TypeError,ForNonNullableByDefault} (dynamic) → self::Class1;
-static field (dynamic) → self::Class2 Class2_new = let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:29:18: Error: A value of type 'Class2 Function(int)' can't be assigned to a variable of type 'Class2 Function(dynamic)'.
- - 'Class2' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-var Class2_new = Class2.new;
- ^" in (#C2) as{TypeError,ForNonNullableByDefault} (dynamic) → self::Class2;
+static field (core::int) → self::Class1 Class1_new = #C1;
+static field (core::int) → self::Class2 Class2_new = #C2;
static method main() → dynamic {
core::print("inSoundMode: ${self::inSoundMode}");
self::testInferred();
@@ -65,7 +49,7 @@
self::Class1 c1a = f1a(0){(core::int) → self::Class1};
self::expect(true, c1a is{ForNonNullableByDefault} self::Class1);
() → Null {
- f1a(let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:38:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+ f1a(let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:38:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
f1a(''); // error
^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class1};
};
@@ -79,7 +63,7 @@
self::Class2 c2a = f2a(0){(core::int) → self::Class2};
self::expect(true, c2a is{ForNonNullableByDefault} self::Class2);
() → Null {
- f2a(let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:52:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+ f2a(let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:52:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
f2a(''); // error
^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class2};
};
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.expect
index 8770854..fa85f71 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.expect
@@ -2,16 +2,6 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:28:18: Error: A value of type 'Class1 Function(int)' can't be assigned to a variable of type 'Class1 Function(dynamic)'.
-// - 'Class1' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-// var Class1_new = Class1.new;
-// ^
-//
-// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:29:18: Error: A value of type 'Class2 Function(int)' can't be assigned to a variable of type 'Class2 Function(dynamic)'.
-// - 'Class2' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-// var Class2_new = Class2.new;
-// ^
-//
// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:38:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
// f1a(''); // error
// ^
@@ -46,14 +36,8 @@
return new self::Class2::•(field);
}
static final field core::bool inSoundMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
-static field (dynamic) → self::Class1 Class1_new = let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:28:18: Error: A value of type 'Class1 Function(int)' can't be assigned to a variable of type 'Class1 Function(dynamic)'.
- - 'Class1' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-var Class1_new = Class1.new;
- ^" in (#C1) as{TypeError,ForNonNullableByDefault} (dynamic) → self::Class1;
-static field (dynamic) → self::Class2 Class2_new = let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:29:18: Error: A value of type 'Class2 Function(int)' can't be assigned to a variable of type 'Class2 Function(dynamic)'.
- - 'Class2' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-var Class2_new = Class2.new;
- ^" in (#C2) as{TypeError,ForNonNullableByDefault} (dynamic) → self::Class2;
+static field (core::int) → self::Class1 Class1_new = #C1;
+static field (core::int) → self::Class2 Class2_new = #C2;
static method main() → dynamic {
core::print("inSoundMode: ${self::inSoundMode}");
self::testInferred();
@@ -65,7 +49,7 @@
self::Class1 c1a = f1a(0){(core::int) → self::Class1};
self::expect(true, c1a is{ForNonNullableByDefault} self::Class1);
() → Null {
- f1a(let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:38:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+ f1a(let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:38:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
f1a(''); // error
^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class1};
};
@@ -79,7 +63,7 @@
self::Class2 c2a = f2a(0){(core::int) → self::Class2};
self::expect(true, c2a is{ForNonNullableByDefault} self::Class2);
() → Null {
- f2a(let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:52:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+ f2a(let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:52:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
f2a(''); // error
^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class2};
};
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.outline.expect
index a9eb8a4..cc60ae4 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.outline.expect
@@ -22,8 +22,8 @@
return new self::Class2::•(field);
}
static final field core::bool inSoundMode;
-static field (dynamic) → self::Class1 Class1_new;
-static field (dynamic) → self::Class2 Class2_new;
+static field (core::int) → self::Class1 Class1_new;
+static field (core::int) → self::Class2 Class2_new;
static method main() → dynamic
;
static method testInferred() → dynamic
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.transformed.expect
index 2d658941..2664cf0 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.transformed.expect
@@ -2,16 +2,6 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:28:18: Error: A value of type 'Class1 Function(int)' can't be assigned to a variable of type 'Class1 Function(dynamic)'.
-// - 'Class1' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-// var Class1_new = Class1.new;
-// ^
-//
-// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:29:18: Error: A value of type 'Class2 Function(int)' can't be assigned to a variable of type 'Class2 Function(dynamic)'.
-// - 'Class2' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-// var Class2_new = Class2.new;
-// ^
-//
// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:38:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
// f1a(''); // error
// ^
@@ -46,14 +36,8 @@
return new self::Class2::•(field);
}
static final field core::bool inSoundMode = !(core::_GrowableList::•<core::int?>(0) is{ForNonNullableByDefault} core::List<core::int>);
-static field (dynamic) → self::Class1 Class1_new = let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:28:18: Error: A value of type 'Class1 Function(int)' can't be assigned to a variable of type 'Class1 Function(dynamic)'.
- - 'Class1' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-var Class1_new = Class1.new;
- ^" in (#C1) as{TypeError,ForNonNullableByDefault} (dynamic) → self::Class1;
-static field (dynamic) → self::Class2 Class2_new = let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:29:18: Error: A value of type 'Class2 Function(int)' can't be assigned to a variable of type 'Class2 Function(dynamic)'.
- - 'Class2' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart'.
-var Class2_new = Class2.new;
- ^" in (#C2) as{TypeError,ForNonNullableByDefault} (dynamic) → self::Class2;
+static field (core::int) → self::Class1 Class1_new = #C1;
+static field (core::int) → self::Class2 Class2_new = #C2;
static method main() → dynamic {
core::print("inSoundMode: ${self::inSoundMode}");
self::testInferred();
@@ -65,7 +49,7 @@
self::Class1 c1a = f1a(0){(core::int) → self::Class1};
self::expect(true, c1a is{ForNonNullableByDefault} self::Class1);
() → Null {
- f1a(let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:38:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+ f1a(let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:38:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
f1a(''); // error
^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class1};
};
@@ -79,7 +63,7 @@
self::Class2 c2a = f2a(0){(core::int) → self::Class2};
self::expect(true, c2a is{ForNonNullableByDefault} self::Class2);
() → Null {
- f2a(let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:52:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+ f2a(let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:52:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
f2a(''); // error
^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class2};
};
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart
new file mode 100644
index 0000000..e923b7a
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2021, 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.
+
+var A_new = A.new;
+var B_new = B.new;
+var F_new = F.new;
+var G_new = G.new;
+
+class A {
+ int field1 = 0;
+
+ A(this.field1);
+ A.named(this.field1);
+}
+
+class B<T> implements A {
+ var field1;
+ T field2;
+
+ B(this.field1, this.field2);
+ B.named(this.field1, this.field2);
+}
+
+typedef F<T> = A;
+typedef G<T extends num> = B;
+
+var A_named = A.named;
+var B_named = B<int>.named;
+var F_named = F.named;
+var G_named = G<int>.named;
+
+main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.strong.expect
new file mode 100644
index 0000000..d952a09
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.strong.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::A;
+typedef G<unrelated T extends core::num> = self::B<dynamic>;
+class A extends core::Object {
+ field core::int field1 = 0;
+ constructor •(core::int field1) → self::A
+ : self::A::field1 = field1, super core::Object::•()
+ ;
+ constructor named(core::int field1) → self::A
+ : self::A::field1 = field1, super core::Object::•()
+ ;
+ static method _#new#tearOff(core::int field1) → self::A
+ return new self::A::•(field1);
+ static method _#named#tearOff(core::int field1) → self::A
+ return new self::A::named(field1);
+}
+class B<T extends core::Object? = dynamic> extends core::Object implements self::A {
+ field core::int field1;
+ generic-covariant-impl field self::B::T% field2;
+ constructor •(core::int field1, self::B::T% field2) → self::B<self::B::T%>
+ : self::B::field1 = field1, self::B::field2 = field2, super core::Object::•()
+ ;
+ constructor named(core::int field1, self::B::T% field2) → self::B<self::B::T%>
+ : self::B::field1 = field1, self::B::field2 = field2, super core::Object::•()
+ ;
+ static method _#new#tearOff<T extends core::Object? = dynamic>(core::int field1, self::B::_#new#tearOff::T% field2) → self::B<self::B::_#new#tearOff::T%>
+ return new self::B::•<self::B::_#new#tearOff::T%>(field1, field2);
+ static method _#named#tearOff<T extends core::Object? = dynamic>(core::int field1, self::B::_#named#tearOff::T% field2) → self::B<self::B::_#named#tearOff::T%>
+ return new self::B::named<self::B::_#named#tearOff::T%>(field1, field2);
+}
+static field (core::int) → self::A A_new = #C1;
+static field <T extends core::Object? = dynamic>(core::int, T%) → self::B<T%> B_new = #C2;
+static field <unrelated T extends core::Object? = dynamic>(core::int) → self::A F_new = #C3;
+static field <unrelated T extends core::num>(core::int, dynamic) → self::B<dynamic> G_new = #C4;
+static field (core::int) → self::A A_named = #C5;
+static field (core::int, core::int) → self::B<core::int> B_named = #C7;
+static field <unrelated T extends core::Object? = dynamic>(core::int) → self::A F_named = #C8;
+static field (core::int, dynamic) → self::B<dynamic> G_named = #C9;
+static method main() → dynamic {}
+static method _#F#new#tearOff<unrelated T extends core::Object? = dynamic>(core::int field1) → self::A
+ return new self::A::•(field1);
+static method _#F#named#tearOff<unrelated T extends core::Object? = dynamic>(core::int field1) → self::A
+ return new self::A::named(field1);
+static method _#G#new#tearOff<unrelated T extends core::num>(core::int field1, dynamic field2) → self::B<dynamic>
+ return new self::B::•<dynamic>(field1, field2);
+static method _#G#named#tearOff<unrelated T extends core::num>(core::int field1, dynamic field2) → self::B<dynamic>
+ return new self::B::named<dynamic>(field1, field2);
+
+constants {
+ #C1 = static-tearoff self::A::_#new#tearOff
+ #C2 = static-tearoff self::B::_#new#tearOff
+ #C3 = static-tearoff self::_#F#new#tearOff
+ #C4 = static-tearoff self::_#G#new#tearOff
+ #C5 = static-tearoff self::A::_#named#tearOff
+ #C6 = static-tearoff self::B::_#named#tearOff
+ #C7 = instantiation self::B::_#named#tearOff <core::int>
+ #C8 = static-tearoff self::_#F#named#tearOff
+ #C9 = instantiation self::B::_#named#tearOff <dynamic>
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..d952a09
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::A;
+typedef G<unrelated T extends core::num> = self::B<dynamic>;
+class A extends core::Object {
+ field core::int field1 = 0;
+ constructor •(core::int field1) → self::A
+ : self::A::field1 = field1, super core::Object::•()
+ ;
+ constructor named(core::int field1) → self::A
+ : self::A::field1 = field1, super core::Object::•()
+ ;
+ static method _#new#tearOff(core::int field1) → self::A
+ return new self::A::•(field1);
+ static method _#named#tearOff(core::int field1) → self::A
+ return new self::A::named(field1);
+}
+class B<T extends core::Object? = dynamic> extends core::Object implements self::A {
+ field core::int field1;
+ generic-covariant-impl field self::B::T% field2;
+ constructor •(core::int field1, self::B::T% field2) → self::B<self::B::T%>
+ : self::B::field1 = field1, self::B::field2 = field2, super core::Object::•()
+ ;
+ constructor named(core::int field1, self::B::T% field2) → self::B<self::B::T%>
+ : self::B::field1 = field1, self::B::field2 = field2, super core::Object::•()
+ ;
+ static method _#new#tearOff<T extends core::Object? = dynamic>(core::int field1, self::B::_#new#tearOff::T% field2) → self::B<self::B::_#new#tearOff::T%>
+ return new self::B::•<self::B::_#new#tearOff::T%>(field1, field2);
+ static method _#named#tearOff<T extends core::Object? = dynamic>(core::int field1, self::B::_#named#tearOff::T% field2) → self::B<self::B::_#named#tearOff::T%>
+ return new self::B::named<self::B::_#named#tearOff::T%>(field1, field2);
+}
+static field (core::int) → self::A A_new = #C1;
+static field <T extends core::Object? = dynamic>(core::int, T%) → self::B<T%> B_new = #C2;
+static field <unrelated T extends core::Object? = dynamic>(core::int) → self::A F_new = #C3;
+static field <unrelated T extends core::num>(core::int, dynamic) → self::B<dynamic> G_new = #C4;
+static field (core::int) → self::A A_named = #C5;
+static field (core::int, core::int) → self::B<core::int> B_named = #C7;
+static field <unrelated T extends core::Object? = dynamic>(core::int) → self::A F_named = #C8;
+static field (core::int, dynamic) → self::B<dynamic> G_named = #C9;
+static method main() → dynamic {}
+static method _#F#new#tearOff<unrelated T extends core::Object? = dynamic>(core::int field1) → self::A
+ return new self::A::•(field1);
+static method _#F#named#tearOff<unrelated T extends core::Object? = dynamic>(core::int field1) → self::A
+ return new self::A::named(field1);
+static method _#G#new#tearOff<unrelated T extends core::num>(core::int field1, dynamic field2) → self::B<dynamic>
+ return new self::B::•<dynamic>(field1, field2);
+static method _#G#named#tearOff<unrelated T extends core::num>(core::int field1, dynamic field2) → self::B<dynamic>
+ return new self::B::named<dynamic>(field1, field2);
+
+constants {
+ #C1 = static-tearoff self::A::_#new#tearOff
+ #C2 = static-tearoff self::B::_#new#tearOff
+ #C3 = static-tearoff self::_#F#new#tearOff
+ #C4 = static-tearoff self::_#G#new#tearOff
+ #C5 = static-tearoff self::A::_#named#tearOff
+ #C6 = static-tearoff self::B::_#named#tearOff
+ #C7 = instantiation self::B::_#named#tearOff <core::int>
+ #C8 = static-tearoff self::_#F#named#tearOff
+ #C9 = instantiation self::B::_#named#tearOff <dynamic>
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..12bef00
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+var A_new = A.new;
+var B_new = B.new;
+var F_new = F.new;
+var G_new = G.new;
+class A {
+ int field1 = 0;
+ A(this.field1);
+ A.named(this.field1);
+}
+class B<T> implements A {
+ var field1;
+ T field2;
+ B(this.field1, this.field2);
+ B.named(this.field1, this.field2);
+}
+typedef F<T> = A;
+typedef G<T extends num> = B;
+var A_named = A.named;
+var B_named = B<int>.named;
+var F_named = F.named;
+var G_named = G<int>.named;
+main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.weak.expect
new file mode 100644
index 0000000..9294ac3
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.weak.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::A;
+typedef G<unrelated T extends core::num> = self::B<dynamic>;
+class A extends core::Object {
+ field core::int field1 = 0;
+ constructor •(core::int field1) → self::A
+ : self::A::field1 = field1, super core::Object::•()
+ ;
+ constructor named(core::int field1) → self::A
+ : self::A::field1 = field1, super core::Object::•()
+ ;
+ static method _#new#tearOff(core::int field1) → self::A
+ return new self::A::•(field1);
+ static method _#named#tearOff(core::int field1) → self::A
+ return new self::A::named(field1);
+}
+class B<T extends core::Object? = dynamic> extends core::Object implements self::A {
+ field core::int field1;
+ generic-covariant-impl field self::B::T% field2;
+ constructor •(core::int field1, self::B::T% field2) → self::B<self::B::T%>
+ : self::B::field1 = field1, self::B::field2 = field2, super core::Object::•()
+ ;
+ constructor named(core::int field1, self::B::T% field2) → self::B<self::B::T%>
+ : self::B::field1 = field1, self::B::field2 = field2, super core::Object::•()
+ ;
+ static method _#new#tearOff<T extends core::Object? = dynamic>(core::int field1, self::B::_#new#tearOff::T% field2) → self::B<self::B::_#new#tearOff::T%>
+ return new self::B::•<self::B::_#new#tearOff::T%>(field1, field2);
+ static method _#named#tearOff<T extends core::Object? = dynamic>(core::int field1, self::B::_#named#tearOff::T% field2) → self::B<self::B::_#named#tearOff::T%>
+ return new self::B::named<self::B::_#named#tearOff::T%>(field1, field2);
+}
+static field (core::int) → self::A A_new = #C1;
+static field <T extends core::Object? = dynamic>(core::int, T%) → self::B<T%> B_new = #C2;
+static field <unrelated T extends core::Object? = dynamic>(core::int) → self::A F_new = #C3;
+static field <unrelated T extends core::num>(core::int, dynamic) → self::B<dynamic> G_new = #C4;
+static field (core::int) → self::A A_named = #C5;
+static field (core::int, core::int) → self::B<core::int> B_named = #C7;
+static field <unrelated T extends core::Object? = dynamic>(core::int) → self::A F_named = #C8;
+static field (core::int, dynamic) → self::B<dynamic> G_named = #C9;
+static method main() → dynamic {}
+static method _#F#new#tearOff<unrelated T extends core::Object? = dynamic>(core::int field1) → self::A
+ return new self::A::•(field1);
+static method _#F#named#tearOff<unrelated T extends core::Object? = dynamic>(core::int field1) → self::A
+ return new self::A::named(field1);
+static method _#G#new#tearOff<unrelated T extends core::num>(core::int field1, dynamic field2) → self::B<dynamic>
+ return new self::B::•<dynamic>(field1, field2);
+static method _#G#named#tearOff<unrelated T extends core::num>(core::int field1, dynamic field2) → self::B<dynamic>
+ return new self::B::named<dynamic>(field1, field2);
+
+constants {
+ #C1 = static-tearoff self::A::_#new#tearOff
+ #C2 = static-tearoff self::B::_#new#tearOff
+ #C3 = static-tearoff self::_#F#new#tearOff
+ #C4 = static-tearoff self::_#G#new#tearOff
+ #C5 = static-tearoff self::A::_#named#tearOff
+ #C6 = static-tearoff self::B::_#named#tearOff
+ #C7 = instantiation self::B::_#named#tearOff <core::int*>
+ #C8 = static-tearoff self::_#F#named#tearOff
+ #C9 = instantiation self::B::_#named#tearOff <dynamic>
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.weak.outline.expect
new file mode 100644
index 0000000..c32ee60
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.weak.outline.expect
@@ -0,0 +1,47 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::A;
+typedef G<unrelated T extends core::num> = self::B<dynamic>;
+class A extends core::Object {
+ field core::int field1;
+ constructor •(core::int field1) → self::A
+ ;
+ constructor named(core::int field1) → self::A
+ ;
+ static method _#new#tearOff(core::int field1) → self::A
+ return new self::A::•(field1);
+ static method _#named#tearOff(core::int field1) → self::A
+ return new self::A::named(field1);
+}
+class B<T extends core::Object? = dynamic> extends core::Object implements self::A {
+ field core::int field1;
+ generic-covariant-impl field self::B::T% field2;
+ constructor •(core::int field1, self::B::T% field2) → self::B<self::B::T%>
+ ;
+ constructor named(core::int field1, self::B::T% field2) → self::B<self::B::T%>
+ ;
+ static method _#new#tearOff<T extends core::Object? = dynamic>(core::int field1, self::B::_#new#tearOff::T% field2) → self::B<self::B::_#new#tearOff::T%>
+ return new self::B::•<self::B::_#new#tearOff::T%>(field1, field2);
+ static method _#named#tearOff<T extends core::Object? = dynamic>(core::int field1, self::B::_#named#tearOff::T% field2) → self::B<self::B::_#named#tearOff::T%>
+ return new self::B::named<self::B::_#named#tearOff::T%>(field1, field2);
+}
+static field (core::int) → self::A A_new;
+static field <T extends core::Object? = dynamic>(core::int, T%) → self::B<T%> B_new;
+static field <unrelated T extends core::Object? = dynamic>(core::int) → self::A F_new;
+static field <unrelated T extends core::num>(core::int, dynamic) → self::B<dynamic> G_new;
+static field (core::int) → self::A A_named;
+static field (core::int, core::int) → self::B<core::int> B_named;
+static field <unrelated T extends core::Object? = dynamic>(core::int) → self::A F_named;
+static field (core::int, dynamic) → self::B<dynamic> G_named;
+static method main() → dynamic
+ ;
+static method _#F#new#tearOff<unrelated T extends core::Object? = dynamic>(core::int field1) → self::A
+ return new self::A::•(field1);
+static method _#F#named#tearOff<unrelated T extends core::Object? = dynamic>(core::int field1) → self::A
+ return new self::A::named(field1);
+static method _#G#new#tearOff<unrelated T extends core::num>(core::int field1, dynamic field2) → self::B<dynamic>
+ return new self::B::•<dynamic>(field1, field2);
+static method _#G#named#tearOff<unrelated T extends core::num>(core::int field1, dynamic field2) → self::B<dynamic>
+ return new self::B::named<dynamic>(field1, field2);
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.weak.transformed.expect
new file mode 100644
index 0000000..9294ac3
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_tear_off.dart.weak.transformed.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::A;
+typedef G<unrelated T extends core::num> = self::B<dynamic>;
+class A extends core::Object {
+ field core::int field1 = 0;
+ constructor •(core::int field1) → self::A
+ : self::A::field1 = field1, super core::Object::•()
+ ;
+ constructor named(core::int field1) → self::A
+ : self::A::field1 = field1, super core::Object::•()
+ ;
+ static method _#new#tearOff(core::int field1) → self::A
+ return new self::A::•(field1);
+ static method _#named#tearOff(core::int field1) → self::A
+ return new self::A::named(field1);
+}
+class B<T extends core::Object? = dynamic> extends core::Object implements self::A {
+ field core::int field1;
+ generic-covariant-impl field self::B::T% field2;
+ constructor •(core::int field1, self::B::T% field2) → self::B<self::B::T%>
+ : self::B::field1 = field1, self::B::field2 = field2, super core::Object::•()
+ ;
+ constructor named(core::int field1, self::B::T% field2) → self::B<self::B::T%>
+ : self::B::field1 = field1, self::B::field2 = field2, super core::Object::•()
+ ;
+ static method _#new#tearOff<T extends core::Object? = dynamic>(core::int field1, self::B::_#new#tearOff::T% field2) → self::B<self::B::_#new#tearOff::T%>
+ return new self::B::•<self::B::_#new#tearOff::T%>(field1, field2);
+ static method _#named#tearOff<T extends core::Object? = dynamic>(core::int field1, self::B::_#named#tearOff::T% field2) → self::B<self::B::_#named#tearOff::T%>
+ return new self::B::named<self::B::_#named#tearOff::T%>(field1, field2);
+}
+static field (core::int) → self::A A_new = #C1;
+static field <T extends core::Object? = dynamic>(core::int, T%) → self::B<T%> B_new = #C2;
+static field <unrelated T extends core::Object? = dynamic>(core::int) → self::A F_new = #C3;
+static field <unrelated T extends core::num>(core::int, dynamic) → self::B<dynamic> G_new = #C4;
+static field (core::int) → self::A A_named = #C5;
+static field (core::int, core::int) → self::B<core::int> B_named = #C7;
+static field <unrelated T extends core::Object? = dynamic>(core::int) → self::A F_named = #C8;
+static field (core::int, dynamic) → self::B<dynamic> G_named = #C9;
+static method main() → dynamic {}
+static method _#F#new#tearOff<unrelated T extends core::Object? = dynamic>(core::int field1) → self::A
+ return new self::A::•(field1);
+static method _#F#named#tearOff<unrelated T extends core::Object? = dynamic>(core::int field1) → self::A
+ return new self::A::named(field1);
+static method _#G#new#tearOff<unrelated T extends core::num>(core::int field1, dynamic field2) → self::B<dynamic>
+ return new self::B::•<dynamic>(field1, field2);
+static method _#G#named#tearOff<unrelated T extends core::num>(core::int field1, dynamic field2) → self::B<dynamic>
+ return new self::B::named<dynamic>(field1, field2);
+
+constants {
+ #C1 = static-tearoff self::A::_#new#tearOff
+ #C2 = static-tearoff self::B::_#new#tearOff
+ #C3 = static-tearoff self::_#F#new#tearOff
+ #C4 = static-tearoff self::_#G#new#tearOff
+ #C5 = static-tearoff self::A::_#named#tearOff
+ #C6 = static-tearoff self::B::_#named#tearOff
+ #C7 = instantiation self::B::_#named#tearOff <core::int*>
+ #C8 = static-tearoff self::_#F#named#tearOff
+ #C9 = instantiation self::B::_#named#tearOff <dynamic>
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart
index 8bd470e..33453f6 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart
@@ -6,17 +6,15 @@
typedef H<X, Y> = A<Y>;
-// TODO(johnniwinther): Use 'var' here when dependency on inferred parameter
-// types is handled.
-dynamic H_new = H.new;
-dynamic H_named = H.named;
-dynamic H_fact = H.fact;
-dynamic H_redirect = H.redirect;
+var H_new = H.new;
+var H_named = H.named;
+var H_fact = H.fact;
+var H_redirect = H.redirect;
-dynamic F_new = F.new;
-dynamic F_named = F.named;
-dynamic F_fact = F.fact;
-dynamic F_redirect = F.redirect;
+var F_new = F.new;
+var F_named = F.named;
+var F_fact = F.fact;
+var F_redirect = F.redirect;
main() {
expect(true, identical(F_new, F_new_lib));
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.strong.expect
index 98b8997..3e82a43 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.strong.expect
@@ -6,14 +6,14 @@
import "org-dartlang-testcase:///typedef_identical_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
-static field dynamic H_new = #C1;
-static field dynamic H_named = #C2;
-static field dynamic H_fact = #C3;
-static field dynamic H_redirect = #C4;
-static field dynamic F_new = #C5;
-static field dynamic F_named = #C6;
-static field dynamic F_fact = #C7;
-static field dynamic F_redirect = #C8;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> H_new = #C1;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> H_named = #C2;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> H_fact = #C3;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> H_redirect = #C4;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_new = #C5;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> F_named = #C6;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> F_fact = #C7;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_redirect = #C8;
static method main() → dynamic {
self::expect(true, core::identical(self::F_new, typ::F_new_lib));
self::expect(false, core::identical(self::F_new, typ::F_named_lib));
@@ -104,14 +104,14 @@
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#redirect#tearOff::T%>
return new typ::A::•<typ::A::_#redirect#tearOff::T%>();
}
-static field dynamic F_new_lib = #C5;
-static field dynamic F_named_lib = #C6;
-static field dynamic F_fact_lib = #C7;
-static field dynamic F_redirect_lib = #C8;
-static field dynamic G_new_lib = #C11;
-static field dynamic G_named_lib = #C12;
-static field dynamic G_fact_lib = #C13;
-static field dynamic G_redirect_lib = #C14;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_new_lib = #C5;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> F_named_lib = #C6;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> F_fact_lib = #C7;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_redirect_lib = #C8;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> G_new_lib = #C11;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> G_named_lib = #C12;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> G_fact_lib = #C13;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> G_redirect_lib = #C14;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#new#tearOff::Y%>
return new typ::A::•<typ::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<typ::_#F#named#tearOff::Y%>
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.strong.transformed.expect
index b956c9c..f7eae91 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.strong.transformed.expect
@@ -6,14 +6,14 @@
import "org-dartlang-testcase:///typedef_identical_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
-static field dynamic H_new = #C1;
-static field dynamic H_named = #C2;
-static field dynamic H_fact = #C3;
-static field dynamic H_redirect = #C4;
-static field dynamic F_new = #C5;
-static field dynamic F_named = #C6;
-static field dynamic F_fact = #C7;
-static field dynamic F_redirect = #C8;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> H_new = #C1;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> H_named = #C2;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> H_fact = #C3;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> H_redirect = #C4;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_new = #C5;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> F_named = #C6;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> F_fact = #C7;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_redirect = #C8;
static method main() → dynamic {
self::expect(true, core::identical(self::F_new, typ::F_new_lib));
self::expect(false, core::identical(self::F_new, typ::F_named_lib));
@@ -104,14 +104,14 @@
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#redirect#tearOff::T%>
return new typ::A::•<typ::A::_#redirect#tearOff::T%>();
}
-static field dynamic F_new_lib = #C5;
-static field dynamic F_named_lib = #C6;
-static field dynamic F_fact_lib = #C7;
-static field dynamic F_redirect_lib = #C8;
-static field dynamic G_new_lib = #C11;
-static field dynamic G_named_lib = #C12;
-static field dynamic G_fact_lib = #C13;
-static field dynamic G_redirect_lib = #C14;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_new_lib = #C5;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> F_named_lib = #C6;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> F_fact_lib = #C7;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_redirect_lib = #C8;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> G_new_lib = #C11;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> G_named_lib = #C12;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> G_fact_lib = #C13;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> G_redirect_lib = #C14;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#new#tearOff::Y%>
return new typ::A::•<typ::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<typ::_#F#named#tearOff::Y%>
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.textual_outline.expect
index 0f1bd66..8ca6604 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.textual_outline.expect
@@ -1,12 +1,12 @@
import 'typedef_identical_lib.dart';
typedef H<X, Y> = A<Y>;
-dynamic H_new = H.new;
-dynamic H_named = H.named;
-dynamic H_fact = H.fact;
-dynamic H_redirect = H.redirect;
-dynamic F_new = F.new;
-dynamic F_named = F.named;
-dynamic F_fact = F.fact;
-dynamic F_redirect = F.redirect;
+var H_new = H.new;
+var H_named = H.named;
+var H_fact = H.fact;
+var H_redirect = H.redirect;
+var F_new = F.new;
+var F_named = F.named;
+var F_fact = F.fact;
+var F_redirect = F.redirect;
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.weak.expect
index 98b8997..3e82a43 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.weak.expect
@@ -6,14 +6,14 @@
import "org-dartlang-testcase:///typedef_identical_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
-static field dynamic H_new = #C1;
-static field dynamic H_named = #C2;
-static field dynamic H_fact = #C3;
-static field dynamic H_redirect = #C4;
-static field dynamic F_new = #C5;
-static field dynamic F_named = #C6;
-static field dynamic F_fact = #C7;
-static field dynamic F_redirect = #C8;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> H_new = #C1;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> H_named = #C2;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> H_fact = #C3;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> H_redirect = #C4;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_new = #C5;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> F_named = #C6;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> F_fact = #C7;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_redirect = #C8;
static method main() → dynamic {
self::expect(true, core::identical(self::F_new, typ::F_new_lib));
self::expect(false, core::identical(self::F_new, typ::F_named_lib));
@@ -104,14 +104,14 @@
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#redirect#tearOff::T%>
return new typ::A::•<typ::A::_#redirect#tearOff::T%>();
}
-static field dynamic F_new_lib = #C5;
-static field dynamic F_named_lib = #C6;
-static field dynamic F_fact_lib = #C7;
-static field dynamic F_redirect_lib = #C8;
-static field dynamic G_new_lib = #C11;
-static field dynamic G_named_lib = #C12;
-static field dynamic G_fact_lib = #C13;
-static field dynamic G_redirect_lib = #C14;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_new_lib = #C5;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> F_named_lib = #C6;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> F_fact_lib = #C7;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_redirect_lib = #C8;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> G_new_lib = #C11;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> G_named_lib = #C12;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> G_fact_lib = #C13;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> G_redirect_lib = #C14;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#new#tearOff::Y%>
return new typ::A::•<typ::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<typ::_#F#named#tearOff::Y%>
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.weak.outline.expect
index 7f142cf..feafdc3 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.weak.outline.expect
@@ -6,14 +6,14 @@
import "org-dartlang-testcase:///typedef_identical_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
-static field dynamic H_new;
-static field dynamic H_named;
-static field dynamic H_fact;
-static field dynamic H_redirect;
-static field dynamic F_new;
-static field dynamic F_named;
-static field dynamic F_fact;
-static field dynamic F_redirect;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> H_new;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> H_named;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> H_fact;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> H_redirect;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_new;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> F_named;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> F_fact;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_redirect;
static method main() → dynamic
;
static method expect(dynamic expected, dynamic actual) → dynamic
@@ -52,14 +52,14 @@
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#redirect#tearOff::T%>
return new typ::A::•<typ::A::_#redirect#tearOff::T%>();
}
-static field dynamic F_new_lib;
-static field dynamic F_named_lib;
-static field dynamic F_fact_lib;
-static field dynamic F_redirect_lib;
-static field dynamic G_new_lib;
-static field dynamic G_named_lib;
-static field dynamic G_fact_lib;
-static field dynamic G_redirect_lib;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_new_lib;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> F_named_lib;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> F_fact_lib;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_redirect_lib;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> G_new_lib;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> G_named_lib;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> G_fact_lib;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> G_redirect_lib;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#new#tearOff::Y%>
return new typ::A::•<typ::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#named#tearOff::Y% a, [core::int? b]) → typ::A<typ::_#F#named#tearOff::Y%>
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.weak.transformed.expect
index b956c9c..f7eae91 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical.dart.weak.transformed.expect
@@ -6,14 +6,14 @@
import "org-dartlang-testcase:///typedef_identical_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
-static field dynamic H_new = #C1;
-static field dynamic H_named = #C2;
-static field dynamic H_fact = #C3;
-static field dynamic H_redirect = #C4;
-static field dynamic F_new = #C5;
-static field dynamic F_named = #C6;
-static field dynamic F_fact = #C7;
-static field dynamic F_redirect = #C8;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> H_new = #C1;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> H_named = #C2;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> H_fact = #C3;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> H_redirect = #C4;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_new = #C5;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> F_named = #C6;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> F_fact = #C7;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_redirect = #C8;
static method main() → dynamic {
self::expect(true, core::identical(self::F_new, typ::F_new_lib));
self::expect(false, core::identical(self::F_new, typ::F_named_lib));
@@ -104,14 +104,14 @@
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#redirect#tearOff::T%>
return new typ::A::•<typ::A::_#redirect#tearOff::T%>();
}
-static field dynamic F_new_lib = #C5;
-static field dynamic F_named_lib = #C6;
-static field dynamic F_fact_lib = #C7;
-static field dynamic F_redirect_lib = #C8;
-static field dynamic G_new_lib = #C11;
-static field dynamic G_named_lib = #C12;
-static field dynamic G_fact_lib = #C13;
-static field dynamic G_redirect_lib = #C14;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_new_lib = #C5;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> F_named_lib = #C6;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> F_fact_lib = #C7;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> F_redirect_lib = #C8;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> G_new_lib = #C11;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, [core::int?]) → typ::A<Y%> G_named_lib = #C12;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(Y%, {b: core::int?, c: core::int}) → typ::A<Y%> G_fact_lib = #C13;
+static field <unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<Y%> G_redirect_lib = #C14;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#new#tearOff::Y%>
return new typ::A::•<typ::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<typ::_#F#named#tearOff::Y%>
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical_lib.dart b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical_lib.dart
index a57b86b..e21df56 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical_lib.dart
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_identical_lib.dart
@@ -12,12 +12,12 @@
typedef F<X, Y> = A<Y>;
typedef G<X, Y> = A<Y>;
-dynamic F_new_lib = F.new;
-dynamic F_named_lib = F.named;
-dynamic F_fact_lib = F.fact;
-dynamic F_redirect_lib = F.redirect;
+var F_new_lib = F.new;
+var F_named_lib = F.named;
+var F_fact_lib = F.fact;
+var F_redirect_lib = F.redirect;
-dynamic G_new_lib = G.new;
-dynamic G_named_lib = G.named;
-dynamic G_fact_lib = G.fact;
-dynamic G_redirect_lib = G.redirect;
\ No newline at end of file
+var G_new_lib = G.new;
+var G_named_lib = G.named;
+var G_fact_lib = G.fact;
+var G_redirect_lib = G.redirect;
\ No newline at end of file
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 8082cff..e8cae1b 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -32,6 +32,7 @@
constructor_tearoffs/inferred_constructor_tear_off: FormatterCrash
constructor_tearoffs/instantiation: FormatterCrash
constructor_tearoffs/lowering/inferred_constructor_tear_off: FormatterCrash
+constructor_tearoffs/lowering/inferred_tear_off: FormatterCrash
constructor_tearoffs/lowering/typedef_from_dill/main: FormatterCrash
constructor_tearoffs/lowering/typedef_identical: FormatterCrash
constructor_tearoffs/nongeneric_tearoff_with_context: FormatterCrash
diff --git a/tools/VERSION b/tools/VERSION
index 778bf10..1633d98 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 348
+PRERELEASE 349
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/flutter/analyze_flutter_plugins.sh b/tools/bots/flutter/analyze_flutter_plugins.sh
index 9696c74..3616faa 100755
--- a/tools/bots/flutter/analyze_flutter_plugins.sh
+++ b/tools/bots/flutter/analyze_flutter_plugins.sh
@@ -36,4 +36,6 @@
(cd script/tool; dart analyze --fatal-infos)
# Invoke the repo's analysis script.
-./script/tool_runner.sh analyze --analysis-sdk $sdk
+./script/tool_runner.sh analyze \
+ --analysis-sdk $sdk \
+ --custom-analysis=script/configs/custom_analysis.yaml