From 77073f79923eebc8159b48db70d95df90c1cdacd Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Tue, 6 Jan 2026 02:30:12 -0800 Subject: [PATCH] [cfe][InternalNodes] Add Argument nodes This adds the sealed class Argument with subclasses PositionalArgument and NamedArgument to the internal AST and uses these through out compilation. This cleans up a lot of the handling of arguments during inference. Change-Id: If604895ee578d45874d4760e5ead2426b19b96ff Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/469621 Commit-Queue: Johnni Winther Reviewed-by: Chloe Stefantsova --- .../lib/src/dill/dill_library_builder.dart | 2 - .../src/fragment/constructor/encoding.dart | 6 +- .../lib/src/fragment/enum_element.dart | 5 +- .../lib/src/kernel/body_builder.dart | 221 ++--- .../lib/src/kernel/body_builder_context.dart | 8 +- .../lib/src/kernel/body_builder_helpers.dart | 2 +- .../lib/src/kernel/expression_generator.dart | 125 ++- .../kernel/expression_generator_helper.dart | 18 +- pkg/front_end/lib/src/kernel/forest.dart | 37 +- .../lib/src/kernel/internal_ast.dart | 208 +++-- .../lib/src/kernel/kernel_target.dart | 7 +- .../lib/src/kernel/load_library_builder.dart | 2 +- pkg/front_end/lib/src/kernel/resolver.dart | 420 +++------ .../lib/src/kernel/resolver_helpers.dart | 15 + pkg/front_end/lib/src/kernel/utils.dart | 3 + .../lib/src/source/check_helper.dart | 76 +- pkg/front_end/lib/src/source/value_kinds.dart | 5 +- .../src/type_inference/inference_results.dart | 38 +- .../src/type_inference/inference_visitor.dart | 103 ++- .../inference_visitor_base.dart | 862 ++++++++---------- .../type_inference/object_access_target.dart | 21 +- .../lib/src/type_inference/type_inferrer.dart | 21 +- pkg/front_end/test/compile_and_lint_impl.dart | 2 +- .../test/generator_to_string_test.dart | 7 +- ...internal_ast_text_representation_test.dart | 262 ++++-- ...arameters_super_and_not.dart.strong.expect | 2 +- ...s_super_and_not.dart.strong.modular.expect | 2 +- ...per_and_not.dart.strong.transformed.expect | 2 +- .../trailing_comma1.dart.strong.expect | 20 +- ...trailing_comma1.dart.strong.modular.expect | 20 +- ...ling_comma1.dart.strong.transformed.expect | 20 +- .../issue48642.dart.strong.expect | 32 +- .../issue48642.dart.strong.modular.expect | 32 +- .../issue48642.dart.strong.outline.expect | 16 +- .../issue48642.dart.strong.transformed.expect | 32 +- .../no_coercions.dart.strong.expect | 4 +- .../no_coercions.dart.strong.modular.expect | 4 +- ...o_coercions.dart.strong.transformed.expect | 4 +- .../opt_out.dart.strong.expect | 10 +- .../opt_out.dart.strong.modular.expect | 10 +- .../opt_out.dart.strong.transformed.expect | 10 +- ..._named_super_parameters.dart.strong.expect | 10 +- ...uper_parameters.dart.strong.modular.expect | 10 +- ..._parameters.dart.strong.transformed.expect | 10 +- 44 files changed, 1449 insertions(+), 1277 deletions(-) diff --git a/pkg/front_end/lib/src/dill/dill_library_builder.dart b/pkg/front_end/lib/src/dill/dill_library_builder.dart index a987a6641eb..6e1f88a0ecb 100644 --- a/pkg/front_end/lib/src/dill/dill_library_builder.dart +++ b/pkg/front_end/lib/src/dill/dill_library_builder.dart @@ -106,7 +106,6 @@ class DillCompilationUnitImpl extends DillCompilationUnit { _dillLibraryBuilder.conditionalImportSupported; @override - // Coverage-ignore(suite): Not run. Importability get importability => _dillLibraryBuilder.importability; @override @@ -396,7 +395,6 @@ class DillLibraryBuilder extends LibraryBuilderImpl { bool get conditionalImportSupported => library.conditionalImportSupported; @override - // Coverage-ignore(suite): Not run. Importability get importability => library.importability; @override diff --git a/pkg/front_end/lib/src/fragment/constructor/encoding.dart b/pkg/front_end/lib/src/fragment/constructor/encoding.dart index a14b2823bf5..4e3b2b0838a 100644 --- a/pkg/front_end/lib/src/fragment/constructor/encoding.dart +++ b/pkg/front_end/lib/src/fragment/constructor/encoding.dart @@ -813,7 +813,11 @@ class _ExtensionTypeInitializerToStatementConverter thisVariable, new StaticInvocation( node.target, - node.arguments.toArguments(node.inferredTypeArguments), + node.arguments.toArguments( + node.inferredTypeArguments, + node.positional, + node.named, + ), )..fileOffset = node.fileOffset, )..fileOffset = node.fileOffset, )..fileOffset = node.fileOffset, diff --git a/pkg/front_end/lib/src/fragment/enum_element.dart b/pkg/front_end/lib/src/fragment/enum_element.dart index aec195f7117..e67090eb0f0 100644 --- a/pkg/front_end/lib/src/fragment/enum_element.dart +++ b/pkg/front_end/lib/src/fragment/enum_element.dart @@ -360,7 +360,10 @@ class EnumElementDeclaration extensionScope: _fragment.enclosingCompilationUnit.extensionScope, scope: _fragment.enclosingScope, token: token, - enumSyntheticArguments: enumSyntheticArguments, + enumSyntheticArguments: [ + new PositionalArgument(enumSyntheticArguments[0]), + new PositionalArgument(enumSyntheticArguments[1]), + ], enumTypeParameterCount: sourceEnumBuilder.typeParametersCount, typeArguments: typeArguments, constructorBuilder: constructorBuilder, diff --git a/pkg/front_end/lib/src/kernel/body_builder.dart b/pkg/front_end/lib/src/kernel/body_builder.dart index 1b9a1c2ce70..e81e0ff1020 100644 --- a/pkg/front_end/lib/src/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/kernel/body_builder.dart @@ -914,7 +914,7 @@ class BodyBuilderImpl extends StackListenerImpl ]), ); debugEvent("Metadata"); - ArgumentsImpl? arguments = pop() as ArgumentsImpl?; + ActualArguments? arguments = pop() as ActualArguments?; pushQualifiedReference( beginToken.next!, periodBeforeName, @@ -1335,14 +1335,14 @@ class BodyBuilderImpl extends StackListenerImpl return annotation; } - ArgumentsImpl parseArguments(Token token) { + ActualArguments parseArguments(Token token) { Parser parser = new Parser( this, useImplicitCreationExpression: useImplicitCreationExpressionInCfe, experimentalFeatures: new LibraryExperimentalFeatures(libraryFeatures), ); token = parser.parseArgumentsRest(token); - ArgumentsImpl arguments = pop() as ArgumentsImpl; + ActualArguments arguments = pop() as ActualArguments; checkEmpty(token.charOffset); return arguments; } @@ -1366,104 +1366,71 @@ class BodyBuilderImpl extends StackListenerImpl @override void endArguments(int count, Token beginToken, Token endToken) { debugEvent("Arguments"); - List? arguments = count == 0 - ? [] - : const FixedNullableList().pop(stack, count); + assert( + checkState( + beginToken, + repeatedKind( + unionOfKinds([ValueKinds.Argument, ValueKinds.ParserRecovery]), + count, + ), + ), + ); + + List? arguments = count == 0 + ? [] + : const FixedNullableList().popNonNullable( + stack, + count, + dummyArgument, + ); if (arguments == null) { push(new ParserRecovery(beginToken.charOffset)); return; } - List? argumentsOriginalOrder; - if (libraryFeatures.namedArgumentsAnywhere.isEnabled) { - argumentsOriginalOrder = new List.of(arguments); - } + List argumentsOriginalOrder = new List.of(arguments); int firstNamedArgumentIndex = arguments.length; int positionalCount = 0; bool hasNamedBeforePositional = false; for (int i = 0; i < arguments.length; i++) { - Object? node = arguments[i]; - if (node is NamedExpression) { - firstNamedArgumentIndex = i < firstNamedArgumentIndex - ? i - : firstNamedArgumentIndex; - } else { - positionalCount++; - Expression argument = toValue(node); - arguments[i] = argument; - argumentsOriginalOrder?[i] = argument; - if (i > firstNamedArgumentIndex) { - hasNamedBeforePositional = true; - if (!libraryFeatures.namedArgumentsAnywhere.isEnabled) { - arguments[i] = new NamedExpression( - "#$i", - buildProblem( - message: cfe.codeExpectedNamedArgument, - fileUri: uri, - fileOffset: argument.fileOffset, - length: noLength, - ), - )..fileOffset = beginToken.charOffset; + Argument argument = arguments[i]; + switch (argument) { + case NamedArgument(): + firstNamedArgumentIndex = i < firstNamedArgumentIndex + ? i + : firstNamedArgumentIndex; + case PositionalArgument(): + positionalCount++; + if (i > firstNamedArgumentIndex) { + hasNamedBeforePositional = true; + if (!libraryFeatures.namedArgumentsAnywhere.isEnabled) { + addProblem( + cfe.codeExpectedNamedArgument, + argument.expression.fileOffset, + noLength, + ); + } } - } } } - if (!hasNamedBeforePositional) { - argumentsOriginalOrder = null; - } if (firstNamedArgumentIndex < arguments.length) { - List positional; - List named; - if (libraryFeatures.namedArgumentsAnywhere.isEnabled) { - positional = new List.filled( - positionalCount, - dummyExpression, - growable: true, - ); - named = new List.filled( - arguments.length - positionalCount, - dummyNamedExpression, - growable: true, - ); - int positionalIndex = 0; - int namedIndex = 0; - for (int i = 0; i < arguments.length; i++) { - if (arguments[i] is NamedExpression) { - named[namedIndex++] = arguments[i] as NamedExpression; - } else { - positional[positionalIndex++] = arguments[i] as Expression; - } - } - assert( - positionalIndex == positional.length && namedIndex == named.length, - ); - } else { - // arguments have non-null Expression entries after the initial loop. - positional = new List.from( - arguments.getRange(0, firstNamedArgumentIndex), - ); - named = new List.from( - arguments.getRange(firstNamedArgumentIndex, arguments.length), - ); - } - push( forest.createArguments( beginToken.offset, - positional, - named: named, - argumentsOriginalOrder: argumentsOriginalOrder, + arguments: argumentsOriginalOrder, + hasNamedBeforePositional: hasNamedBeforePositional, + positionalCount: positionalCount, ), ); } else { // TODO(kmillikin): Find a way to avoid allocating a second list in the // case where there were no named arguments, which is a common one. - // arguments have non-null Expression entries after the initial loop. push( forest.createArguments( beginToken.offset, - new List.from(arguments), - argumentsOriginalOrder: argumentsOriginalOrder, + arguments: argumentsOriginalOrder, + hasNamedBeforePositional: hasNamedBeforePositional, + positionalCount: argumentsOriginalOrder.length, ), ); } @@ -1592,7 +1559,7 @@ class BodyBuilderImpl extends StackListenerImpl // Delay adding [typeArgumentBuilders] to [forest] for type aliases: They // must be unaliased to the type arguments of the denoted type. bool isInForest = - arguments is ArgumentsImpl && + arguments is ActualArguments && typeArgumentBuilders != null && (receiver is! TypeUseGenerator || receiver.declaration is! TypeAliasBuilder); @@ -1625,7 +1592,7 @@ class BodyBuilderImpl extends StackListenerImpl name, typeArgumentBuilders, typeArguments, - arguments as ArgumentsImpl, + arguments as ActualArguments, isTypeArgumentsInForest: isInForest, ), ); @@ -1638,7 +1605,7 @@ class BodyBuilderImpl extends StackListenerImpl receiver, typeArgumentBuilders, typeArguments, - arguments as ArgumentsImpl, + arguments as ActualArguments, beginToken.charOffset, isTypeArgumentsInForest: isInForest, ), @@ -1661,7 +1628,7 @@ class BodyBuilderImpl extends StackListenerImpl Object receiver, List? typeArgumentBuilders, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, int charOffset, { bool isTypeArgumentsInForest = false, }) { @@ -4347,7 +4314,6 @@ class BodyBuilderImpl extends StackListenerImpl token, repeatedKind( unionOfKinds([ - ValueKinds.Generator, ValueKinds.Expression, ValueKinds.NamedExpression, ValueKinds.ParserRecovery, @@ -6234,7 +6200,7 @@ class BodyBuilderImpl extends StackListenerImpl Expression _buildConstructorInvocation( Member target, TypeArguments? typeArguments, - ArgumentsImpl arguments, { + ActualArguments arguments, { Constness constness = Constness.implicit, required TypeAliasBuilder? typeAliasBuilder, required int fileOffset, @@ -6370,7 +6336,7 @@ class BodyBuilderImpl extends StackListenerImpl Expression buildStaticInvocation({ required Procedure target, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required int fileOffset, }) { Expression? result = problemReporting.checkStaticArguments( @@ -6496,9 +6462,9 @@ class BodyBuilderImpl extends StackListenerImpl ConstantContext savedConstantContext = pop() as ConstantContext; - if (arguments is! ArgumentsImpl) { + if (arguments is! ActualArguments) { push(new ParserErrorGenerator(this, nameToken, cfe.codeSyntheticToken)); - arguments = forest.createArguments(offset, []); + arguments = forest.createArgumentsEmpty(offset); } else if (type is Generator) { push( type.invokeConstructor( @@ -6555,7 +6521,7 @@ class BodyBuilderImpl extends StackListenerImpl List? typeArgumentBuilders, String className, String constructorName, - ArgumentsImpl arguments, { + ActualArguments arguments, { required int instantiationOffset, required int invocationOffset, required bool inImplicitCreationContext, @@ -6627,7 +6593,7 @@ class BodyBuilderImpl extends StackListenerImpl TypeDeclarationBuilder? typeDeclarationBuilder, Token nameToken, Token nameLastToken, - ArgumentsImpl arguments, + ActualArguments arguments, String name, List? typeArgumentBuilders, TypeArguments? typeArguments, @@ -7651,8 +7617,10 @@ class BodyBuilderImpl extends StackListenerImpl Object? identifier = pop(); if (identifier is Identifier) { push( - new NamedExpression(identifier.name, value) - ..fileOffset = identifier.nameOffset, + new NamedArgument( + new NamedExpression(identifier.name, value) + ..fileOffset = identifier.nameOffset, + ), ); } else { assert( @@ -7665,8 +7633,54 @@ class BodyBuilderImpl extends StackListenerImpl } @override - // TODO: Handle directly. - void handleNamedRecordField(Token colon) => handleNamedArgument(colon); + void handlePositionalArgument(Token token) { + debugEvent("NamedArgument"); + assert( + checkState(token, [ + unionOfKinds([ValueKinds.Expression, ValueKinds.Generator]), + ]), + ); + Expression value = popForValue(); + push(new PositionalArgument(value)); + } + + @override + void handleNamedRecordField(Token colon) { + debugEvent("handleNamedRecordField"); + assert( + checkState(colon, [ + unionOfKinds([ValueKinds.Expression, ValueKinds.Generator]), + unionOfKinds([ValueKinds.Identifier, ValueKinds.ParserRecovery]), + ]), + ); + Expression value = popForValue(); + Object? identifier = pop(); + if (identifier is Identifier) { + push( + new NamedExpression(identifier.name, value) + ..fileOffset = identifier.nameOffset, + ); + } else { + assert( + identifier is ParserRecovery, + "Unexpected record field name: " + "${identifier} (${identifier.runtimeType})", + ); + push(identifier); + } + } + + @override + void handlePositionalRecordField(Token token) { + debugEvent("handlePositionalRecordField"); + assert( + checkState(token, [ + unionOfKinds([ValueKinds.Expression, ValueKinds.Generator]), + ]), + ); + Expression value = popForValue(); + push(value); + } @override void endFunctionName( @@ -10010,7 +10024,7 @@ class BodyBuilderImpl extends StackListenerImpl Initializer buildSuperInitializer( bool isSynthetic, Constructor constructor, - ArgumentsImpl arguments, [ + ActualArguments arguments, [ int charOffset = -1, ]) { if (_context.isConstConstructor && !constructor.isConst) { @@ -10031,7 +10045,7 @@ class BodyBuilderImpl extends StackListenerImpl @override Initializer buildRedirectingInitializer( Name name, - ArgumentsImpl arguments, { + ActualArguments arguments, { required int fileOffset, }) { Builder? constructorBuilder = _context.lookupConstructor(name); @@ -10283,21 +10297,14 @@ class BodyBuilderImpl extends StackListenerImpl @override Expression evaluateArgumentsBefore( - ArgumentsImpl? arguments, + ActualArguments? arguments, Expression expression, ) { if (arguments == null) return expression; - List expressions = new List.of( - arguments.positional, - ); - for (NamedExpression named in arguments.named) { - // Coverage-ignore-block(suite): Not run. - expressions.add(named.value); - } - for (Expression argument in expressions.reversed) { + for (Argument argument in arguments.argumentList.reversed) { expression = new Let( new VariableDeclaration.forValue( - argument, + argument.expression, isFinal: true, type: coreTypes.objectRawType(Nullability.nullable), ), @@ -10315,7 +10322,7 @@ class BodyBuilderImpl extends StackListenerImpl Expression receiver, Name name, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, int offset, { bool isConstantExpression = false, bool isNullAware = false, @@ -10346,7 +10353,7 @@ class BodyBuilderImpl extends StackListenerImpl Expression buildSuperInvocation( Name name, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, int offset, { bool isConstantExpression = false, bool isNullAware = false, @@ -11341,7 +11348,7 @@ class BodyBuilderImpl extends StackListenerImpl @override BuildEnumConstantResult buildEnumConstant({required Token token}) { - ArgumentsImpl arguments = parseArguments(token); + ActualArguments arguments = parseArguments(token); return new BuildEnumConstantResult(arguments, _takePendingAnnotations()); } diff --git a/pkg/front_end/lib/src/kernel/body_builder_context.dart b/pkg/front_end/lib/src/kernel/body_builder_context.dart index 90d571e0ccd..62e49690fe4 100644 --- a/pkg/front_end/lib/src/kernel/body_builder_context.dart +++ b/pkg/front_end/lib/src/kernel/body_builder_context.dart @@ -102,7 +102,7 @@ abstract class BodyBuilderContext { /// in the same class. Initializer buildRedirectingInitializer( Builder constructorBuilder, - ArgumentsImpl arguments, { + ActualArguments arguments, { required int fileOffset, }) { return declarationContext.buildRedirectingInitializer( @@ -453,7 +453,7 @@ abstract class BodyBuilderDeclarationContext { Initializer buildRedirectingInitializer( Builder constructorBuilder, - ArgumentsImpl arguments, { + ActualArguments arguments, { required int fileOffset, }) { throw new UnsupportedError('${runtimeType}.buildRedirectingInitializer'); @@ -563,7 +563,7 @@ class _SourceClassBodyBuilderDeclarationContext @override Initializer buildRedirectingInitializer( covariant SourceConstructorBuilder constructorBuilder, - ArgumentsImpl arguments, { + ActualArguments arguments, { required int fileOffset, }) { return new InternalRedirectingInitializer( @@ -668,7 +668,7 @@ class _SourceExtensionTypeDeclarationBodyBuilderDeclarationContext @override Initializer buildRedirectingInitializer( covariant SourceConstructorBuilder constructorBuilder, - ArgumentsImpl arguments, { + ActualArguments arguments, { required int fileOffset, }) { return new ExtensionTypeRedirectingInitializer( diff --git a/pkg/front_end/lib/src/kernel/body_builder_helpers.dart b/pkg/front_end/lib/src/kernel/body_builder_helpers.dart index 856fc7ab587..8d8147b6ac6 100644 --- a/pkg/front_end/lib/src/kernel/body_builder_helpers.dart +++ b/pkg/front_end/lib/src/kernel/body_builder_helpers.dart @@ -565,7 +565,7 @@ class BuildFieldInitializerResult { } class BuildEnumConstantResult { - final ArgumentsImpl arguments; + final ActualArguments arguments; final PendingAnnotations? annotations; BuildEnumConstantResult(this.arguments, this.annotations); diff --git a/pkg/front_end/lib/src/kernel/expression_generator.dart b/pkg/front_end/lib/src/kernel/expression_generator.dart index d9d0969f092..0d6dd6d13f2 100644 --- a/pkg/front_end/lib/src/kernel/expression_generator.dart +++ b/pkg/front_end/lib/src/kernel/expression_generator.dart @@ -234,7 +234,7 @@ abstract class Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }); @@ -360,7 +360,7 @@ abstract class Generator { required String name, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required Token nameToken, required Token nameLastToken, required Constness constness, @@ -540,7 +540,7 @@ class VariableUseGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return _helper.forest.createExpressionInvocation( @@ -668,7 +668,7 @@ class PropertyAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return _helper.buildMethodInvocation( @@ -1020,7 +1020,7 @@ class ThisPropertyAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return _helper.buildMethodInvocation( @@ -1192,7 +1192,7 @@ class NullAwarePropertyAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return unsupported("doInvocation", offset, _fileUri); @@ -1387,7 +1387,7 @@ class SuperPropertyAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { if (_helper.constantContext != ConstantContext.none) { @@ -1561,7 +1561,7 @@ class IndexedAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return _helper.forest.createExpressionInvocation( @@ -1739,7 +1739,7 @@ class ThisIndexedAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return _helper.forest.createExpressionInvocation( @@ -1814,7 +1814,12 @@ class SuperIndexedAccessGenerator extends Generator { indexGetName, getter, null, - _helper.forest.createArguments(fileOffset, [index]), + _helper.forest.createArguments( + fileOffset, + arguments: [new PositionalArgument(index)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), ); } } @@ -1837,10 +1842,15 @@ class SuperIndexedAccessGenerator extends Generator { indexSetName, setter, null, - _helper.forest.createArguments(fileOffset, [ - index, - value, - ]), + _helper.forest.createArguments( + fileOffset, + arguments: [ + new PositionalArgument(index), + new PositionalArgument(value), + ], + hasNamedBeforePositional: false, + positionalCount: 2, + ), ); } else { return new SuperIndexSet(setter, index, value)..fileOffset = fileOffset; @@ -1919,7 +1929,7 @@ class SuperIndexedAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return _helper.forest.createExpressionInvocation( @@ -2200,7 +2210,7 @@ class StaticAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { if (_helper.constantContext != ConstantContext.none && @@ -2606,7 +2616,7 @@ class ExtensionInstanceAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { Procedure? method = invokeTarget; @@ -3053,7 +3063,7 @@ class ExplicitExtensionInstanceAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { Procedure? method = invokeTarget; @@ -3349,7 +3359,7 @@ class ExplicitExtensionIndexedAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return _helper.forest.createExpressionInvocation( @@ -3576,7 +3586,12 @@ class ExplicitExtensionAccessGenerator extends Generator { offset: fileOffset, typeArgumentBuilders: null, typeArguments: null, - arguments: _forest.createArguments(fileOffset, [right]), + arguments: _forest.createArguments( + fileOffset, + arguments: [new PositionalArgument(right)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), ); } @@ -3597,7 +3612,7 @@ class ExplicitExtensionAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { Generator generator = _createInstanceAccess(token, callName); @@ -3770,10 +3785,10 @@ class LoadLibraryGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { - if (arguments.positional.length > 0 || arguments.named.length > 0) { + if (arguments.positionalCount > 0 || arguments.namedCount > 0) { _helper.addProblemErrorIfConst( codeLoadLibraryTakesNoArguments, offset, @@ -3998,7 +4013,7 @@ class DeferredAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { Object suffix = suffixGenerator.doInvocation( @@ -4029,7 +4044,7 @@ class DeferredAccessGenerator extends Generator { required String name, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required Token nameToken, required Token nameLastToken, required Constness constness, @@ -4148,7 +4163,7 @@ class TypeUseGenerator extends AbstractReadOnlyAccessGenerator { required String name, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required Token nameToken, required Token nameLastToken, required Constness constness, @@ -4241,7 +4256,7 @@ class TypeUseGenerator extends AbstractReadOnlyAccessGenerator { ) { int nameOffset = offsetForToken(send.token); Name name = send.name; - ArgumentsImpl? arguments = send.arguments; + ActualArguments? arguments = send.arguments; TypeDeclarationBuilder? declarationBuilder = declaration; TypeAliasBuilder? aliasBuilder; @@ -4696,12 +4711,12 @@ class TypeUseGenerator extends AbstractReadOnlyAccessGenerator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { if (declaration is ExtensionBuilder) { ExtensionBuilder extensionBuilder = declaration as ExtensionBuilder; - if (arguments.positional.length != 1 || arguments.named.isNotEmpty) { + if (arguments.positionalCount != 1 || arguments.namedCount > 0) { return _helper.buildProblem( message: codeExplicitExtensionArgumentMismatch, fileUri: _helper.uri, @@ -4731,7 +4746,7 @@ class TypeUseGenerator extends AbstractReadOnlyAccessGenerator { helper: _helper, token: token, extensionBuilder: declaration as ExtensionBuilder, - receiver: arguments.positional.single, + receiver: arguments.argumentList.single.expression, explicitTypeArguments: typeArguments, extensionTypeArgumentOffset: extensionTypeArgumentOffset, ); @@ -4948,7 +4963,7 @@ abstract class AbstractReadOnlyAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return _helper.forest.createExpressionInvocation( @@ -5016,7 +5031,7 @@ abstract class ErroneousExpressionGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return buildError(charOffset: offset, kind: UnresolvedKind.Method); @@ -5113,7 +5128,7 @@ abstract class ErroneousExpressionGenerator extends Generator { required String name, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required Token nameToken, required Token nameLastToken, required Constness constness, @@ -5239,7 +5254,7 @@ class DuplicateDeclarationGenerator extends ErroneousExpressionGenerator { required String name, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required Token nameToken, required Token nameLastToken, required Constness constness, @@ -5300,7 +5315,7 @@ class UnresolvedNameGenerator extends ErroneousExpressionGenerator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return buildError( @@ -5414,7 +5429,7 @@ abstract class ContextAwareGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return unhandled("${runtimeType}", "doInvocation", offset, _fileUri); @@ -5806,7 +5821,7 @@ class PrefixUseGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return problemReporting.wrapInLocatedProblem( @@ -5985,7 +6000,7 @@ class UnexpectedQualifiedUseGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return _helper.buildUnresolvedError( @@ -6031,7 +6046,7 @@ class UnexpectedQualifiedUseGenerator extends Generator { required String name, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required Token nameToken, required Token nameLastToken, required Constness constness, @@ -6186,7 +6201,7 @@ class ParserErrorGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { return buildProblem(); @@ -6238,7 +6253,7 @@ class ParserErrorGenerator extends Generator { required String name, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required Token nameToken, required Token nameLastToken, required Constness constness, @@ -6392,7 +6407,7 @@ class ThisAccessGenerator extends Generator { bool isNullAware, ) { Name name = selector.name; - ArgumentsImpl? arguments = selector.arguments; + ActualArguments? arguments = selector.arguments; int offset = offsetForToken(selector.token); if (isInitializer && selector is InvocationSelector) { if (isNullAware) { @@ -6459,7 +6474,7 @@ class ThisAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { if (isInitializer) { @@ -6493,7 +6508,12 @@ class ThisAccessGenerator extends Generator { Expression result = _helper.buildSuperInvocation( equalsName, null, - _forest.createArguments(offset, [right]), + _forest.createArguments( + offset, + arguments: [new PositionalArgument(right)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), offset, ); if (isNot) { @@ -6516,7 +6536,12 @@ class ThisAccessGenerator extends Generator { return _helper.buildSuperInvocation( binaryName, null, - _forest.createArguments(offset, [right]), + _forest.createArguments( + offset, + arguments: [new PositionalArgument(right)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), offset, ); } @@ -6542,7 +6567,7 @@ class ThisAccessGenerator extends Generator { Expression_Initializer buildConstructorInitializer( int offset, Name name, - ArgumentsImpl arguments, + ActualArguments arguments, ) { if (isSuper) { MemberLookupResult? result = _helper.lookupSuperConstructor( @@ -6746,7 +6771,7 @@ class IncompleteErrorGenerator extends ErroneousExpressionGenerator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) => this; @@ -6895,7 +6920,7 @@ abstract class Selector { // Coverage-ignore(suite): Not run. TypeArguments? get typeArguments => null; - ArgumentsImpl? get arguments => null; + ActualArguments? get arguments => null; /// Internal name used for debugging. String get _debugName; @@ -6951,7 +6976,7 @@ class InvocationSelector extends Selector { final bool isTypeArgumentsInForest; @override - final ArgumentsImpl arguments; + final ActualArguments arguments; final bool isPotentiallyConstant; @@ -7186,7 +7211,7 @@ class AugmentSuperAccessGenerator extends Generator { required int offset, required List? typeArgumentBuilders, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, bool isTypeArgumentsInForest = false, }) { Member? invokeTarget = augmentSuperTarget.invokeTarget; diff --git a/pkg/front_end/lib/src/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/kernel/expression_generator_helper.dart index 416ceff4ff3..7159e5b0e15 100644 --- a/pkg/front_end/lib/src/kernel/expression_generator_helper.dart +++ b/pkg/front_end/lib/src/kernel/expression_generator_helper.dart @@ -101,7 +101,7 @@ abstract class ExpressionGeneratorHelper { Object receiver, List? typeArgumentBuilders, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, int offset, { bool isTypeArgumentsInForest = false, }); @@ -119,20 +119,20 @@ abstract class ExpressionGeneratorHelper { Initializer buildSuperInitializer( bool isSynthetic, Constructor constructor, - ArgumentsImpl arguments, [ + ActualArguments arguments, [ int offset = TreeNode.noOffset, ]); Initializer buildRedirectingInitializer( Name name, - ArgumentsImpl arguments, { + ActualArguments arguments, { required int fileOffset, }); Expression buildStaticInvocation({ required Procedure target, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required int fileOffset, }); @@ -157,7 +157,7 @@ abstract class ExpressionGeneratorHelper { Expression receiver, Name name, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, int offset, { bool isConstantExpression = false, bool isNullAware = false, @@ -166,7 +166,7 @@ abstract class ExpressionGeneratorHelper { Expression buildSuperInvocation( Name name, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, int offset, { bool isConstantExpression = false, bool isNullAware = false, @@ -177,7 +177,7 @@ abstract class ExpressionGeneratorHelper { TypeDeclarationBuilder type, Token nameToken, Token nameLastToken, - ArgumentsImpl arguments, + ActualArguments arguments, String name, List? typeArgumentBuilders, TypeArguments? typeArguments, @@ -202,7 +202,7 @@ abstract class ExpressionGeneratorHelper { ); Expression evaluateArgumentsBefore( - ArgumentsImpl arguments, + ActualArguments arguments, Expression expression, ); @@ -269,7 +269,7 @@ abstract class ExpressionGeneratorHelper { List? typeArguments, String className, String constructorName, - ArgumentsImpl arguments, { + ActualArguments arguments, { required int instantiationOffset, required int invocationOffset, required bool inImplicitCreationContext, diff --git a/pkg/front_end/lib/src/kernel/forest.dart b/pkg/front_end/lib/src/kernel/forest.dart index efccf8fa1a5..890795ff41b 100644 --- a/pkg/front_end/lib/src/kernel/forest.dart +++ b/pkg/front_end/lib/src/kernel/forest.dart @@ -28,21 +28,26 @@ import 'internal_ast.dart'; class Forest { const Forest(); - ArgumentsImpl createArguments( - int fileOffset, - List positional, { - List? named, - List? argumentsOriginalOrder, + ActualArguments createArguments( + int fileOffset, { + required List arguments, + required bool hasNamedBeforePositional, + required int positionalCount, }) { - return new ArgumentsImpl( - positional, - named: named, - argumentsOriginalOrder: argumentsOriginalOrder, + return new ActualArguments( + argumentList: arguments, + hasNamedBeforePositional: hasNamedBeforePositional, + positionalCount: positionalCount, )..fileOffset = fileOffset; } - ArgumentsImpl createArgumentsEmpty(int fileOffset) { - return createArguments(fileOffset, []); + ActualArguments createArgumentsEmpty(int fileOffset) { + return createArguments( + fileOffset, + arguments: [], + hasNamedBeforePositional: false, + positionalCount: 0, + ); } /// Return a representation of a boolean literal at the given [fileOffset]. @@ -192,7 +197,7 @@ class Forest { LoadLibrary createLoadLibrary( int fileOffset, LibraryDependency dependency, - ArgumentsImpl? arguments, + ActualArguments? arguments, ) { return new LoadLibraryImpl(dependency, arguments)..fileOffset = fileOffset; } @@ -752,7 +757,7 @@ class Forest { int fileOffset, Expression expression, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, ) { return new ExpressionInvocation(expression, typeArguments, arguments) ..fileOffset = fileOffset; @@ -763,7 +768,7 @@ class Forest { Expression expression, Name name, TypeArguments? typeArguments, - ArgumentsImpl arguments, { + ActualArguments arguments, { required bool isNullAware, }) { return new MethodInvocation( @@ -780,7 +785,7 @@ class Forest { Name name, Procedure procedure, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, ) { return new InternalSuperMethodInvocation( name, @@ -1156,7 +1161,7 @@ class Forest { int fileOffset, Name name, TypeArguments? typeArguments, - ArgumentsImpl arguments, { + ActualArguments arguments, { required int nameOffset, required bool isConst, }) { diff --git a/pkg/front_end/lib/src/kernel/internal_ast.dart b/pkg/front_end/lib/src/kernel/internal_ast.dart index 046189ad121..ed553501a75 100644 --- a/pkg/front_end/lib/src/kernel/internal_ast.dart +++ b/pkg/front_end/lib/src/kernel/internal_ast.dart @@ -287,68 +287,137 @@ class TypeArguments { } } -/// Front end specific implementation of [Argument]. -class ArgumentsImpl extends TreeNode with InternalTreeNode { - final List positional; - List named; +sealed class Argument { + TreeNode get node; - bool _hasExplicitTypeArguments; + abstract Expression expression; - List? argumentsOriginalOrder; + bool get isSuperParameter => false; - /// True if the arguments are passed to the super-constructor in a - /// super-initializer, and the positional parameters are super-initializer - /// parameters. It is true that either all of the positional parameters are - /// super-initializer parameters or none of them, so a simple boolean - /// accurately reflects the state. - bool positionalAreSuperParameters = false; + void toTextInternal(AstPrinter printer); +} - /// Names of the named positional parameters. If none of the parameters are - /// super-positional, the field is null. - Set? namedSuperParameterNames; +class PositionalArgument extends Argument { + @override + Expression expression; - ArgumentsImpl( - this.positional, { - List? types, - List? named, - this.argumentsOriginalOrder, - }) : _hasExplicitTypeArguments = false, - this.named = named ?? []; + PositionalArgument(this.expression); - ArgumentsImpl.empty() - : _hasExplicitTypeArguments = false, - this.positional = [], - this.named = []; - - @deprecated + @override // Coverage-ignore(suite): Not run. - bool get hasExplicitTypeArguments => _hasExplicitTypeArguments; + TreeNode get node => expression; - Arguments toArguments(List typeArguments) { - return new Arguments(positional, types: typeArguments, named: named) - ..fileOffset = fileOffset; + @override + // Coverage-ignore(suite): Not run. + void toTextInternal(AstPrinter printer) { + expression.toTextInternal(printer); + } + + @override + String toString() => 'PositionalArgument($expression)'; +} + +class SuperPositionalArgument extends PositionalArgument { + SuperPositionalArgument(super.expression); + + @override + bool get isSuperParameter => true; +} + +class NamedArgument extends Argument { + NamedExpression namedExpression; + + NamedArgument(this.namedExpression); + + @override + // Coverage-ignore(suite): Not run. + TreeNode get node => namedExpression; + + String get name => namedExpression.name; + + @override + Expression get expression => namedExpression.value; + + @override + void set expression(Expression value) { + namedExpression.value = value..parent = namedExpression; + } + + @override + // Coverage-ignore(suite): Not run. + void toTextInternal(AstPrinter printer) { + namedExpression.toTextInternal(printer); + } + + @override + String toString() => 'NamedArgument($namedExpression)'; +} + +class SuperNamedArgument extends NamedArgument { + SuperNamedArgument(super.expression); + + @override + bool get isSuperParameter => true; +} + +/// Front end specific implementation of [Argument]. +class ActualArguments extends TreeNode with InternalTreeNode { + final List argumentList; + + bool _hasNamedBeforePositional; + int _positionalCount; + + ActualArguments({ + required this.argumentList, + required bool hasNamedBeforePositional, + required int positionalCount, + }) : _hasNamedBeforePositional = hasNamedBeforePositional, + _positionalCount = positionalCount; + + // Coverage-ignore(suite): Not run. + ActualArguments.empty() + : this.argumentList = [], + this._hasNamedBeforePositional = false, + this._positionalCount = 0; + + int get positionalCount => _positionalCount; + + int get namedCount => argumentList.length - positionalCount; + + bool get hasNamedBeforePositional => _hasNamedBeforePositional; + + void prependArguments(List list, {required int positionalCount}) { + assert(list.whereType().length == positionalCount); + argumentList.insertAll(0, list); + if (!_hasNamedBeforePositional && + _positionalCount > 0 && + positionalCount < list.length) { + _hasNamedBeforePositional = true; + } + _positionalCount += positionalCount; + } + + Arguments toArguments( + List typeArguments, + List positionalArguments, + List namedArguments, + ) { + return new Arguments( + positionalArguments, + types: typeArguments, + named: namedArguments, + )..fileOffset = fileOffset; } @override // Coverage-ignore(suite): Not run. void toTextInternal(AstPrinter printer) { printer.write('('); - for (int index = 0; index < positional.length; index++) { + for (int index = 0; index < argumentList.length; index++) { if (index > 0) { printer.write(', '); } - printer.writeExpression(positional[index]); - } - if (named.isNotEmpty) { - if (positional.isNotEmpty) { - printer.write(', '); - } - for (int index = 0; index < named.length; index++) { - if (index > 0) { - printer.write(', '); - } - printer.writeNamedExpression(named[index]); - } + argumentList[index].toTextInternal(printer); } printer.write(')'); } @@ -492,7 +561,7 @@ class FactoryConstructorInvocation extends InternalExpression { bool hasBeenInferred = false; final Procedure target; final TypeArguments? typeArguments; - ArgumentsImpl arguments; + ActualArguments arguments; /// If `true`, this invocation is constant, either explicit or inferred. final bool isConst; @@ -543,7 +612,7 @@ class TypeAliasedConstructorInvocation extends InternalExpression { final TypeAliasBuilder typeAliasBuilder; final Constructor target; final TypeArguments? typeArguments; - ArgumentsImpl arguments; + ActualArguments arguments; final bool isConst; TypeAliasedConstructorInvocation( @@ -593,7 +662,7 @@ class TypeAliasedFactoryInvocation extends InternalExpression { final TypeAliasBuilder typeAliasBuilder; final Procedure target; final TypeArguments? typeArguments; - ArgumentsImpl arguments; + ActualArguments arguments; /// If `true`, this invocation is constant, either explicit or inferred. final bool isConst; @@ -796,7 +865,7 @@ class ShadowLargeIntLiteral extends IntLiteral implements ExpressionJudgment { class ExpressionInvocation extends InternalExpression { Expression expression; final TypeArguments? typeArguments; - ArgumentsImpl arguments; + ActualArguments arguments; ExpressionInvocation(this.expression, this.typeArguments, this.arguments) { expression.parent = this; @@ -1427,7 +1496,7 @@ mixin InternalExpressionVariableMixin on TreeNode /// Front end specific implementation of [LoadLibrary]. class LoadLibraryImpl extends LoadLibrary { - final ArgumentsImpl? arguments; + final ActualArguments? arguments; LoadLibraryImpl(LibraryDependency import, this.arguments) : super(import); @@ -3865,7 +3934,7 @@ class ExtensionMethodInvocation extends InternalExpression { final TypeArguments? typeArguments; /// The arguments provided to the method. - ArgumentsImpl arguments; + ActualArguments arguments; /// `true` if the extension access is explicit, i.e. `E(o).a()` and /// not implicit like `a()` inside the extension `E`. @@ -3885,7 +3954,7 @@ class ExtensionMethodInvocation extends InternalExpression { required Name name, required Procedure target, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, }) : this._( extension, thisAccess, @@ -3905,7 +3974,7 @@ class ExtensionMethodInvocation extends InternalExpression { required Name name, required Procedure target, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required List? explicitTypeArguments, required int? extensionTypeArgumentOffset, required bool isNullAware, @@ -4012,7 +4081,7 @@ class ExtensionGetterInvocation extends InternalExpression { final TypeArguments? typeArguments; /// The arguments provided to the getter. - ArgumentsImpl arguments; + ActualArguments arguments; /// `true` if the extension access is explicit, i.e. `E(o).a()` and /// not implicit like `a()` inside the extension `E`. @@ -4032,7 +4101,7 @@ class ExtensionGetterInvocation extends InternalExpression { required Name name, required Procedure target, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, }) : this._( extension, thisAccess, @@ -4052,7 +4121,7 @@ class ExtensionGetterInvocation extends InternalExpression { required Name name, required Procedure target, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required List? explicitTypeArguments, required int? extensionTypeArgumentOffset, required bool isNullAware, @@ -4449,7 +4518,7 @@ class MethodInvocation extends InternalExpression { final TypeArguments? typeArguments; /// The arguments applied at the invocation. - ArgumentsImpl arguments; + ActualArguments arguments; /// `true` if the access is null-aware, i.e. of the form `o?.a()`. final bool isNullAware; @@ -4618,7 +4687,7 @@ class AugmentSuperInvocation extends InternalExpression { final TypeArguments? typeArguments; - ArgumentsImpl arguments; + ActualArguments arguments; AugmentSuperInvocation( this.target, @@ -4808,14 +4877,19 @@ class ObjectPatternInternal extends ObjectPattern { class ExtensionTypeRedirectingInitializer extends InternalInitializer { Reference targetReference; - ArgumentsImpl arguments; + ActualArguments arguments; /// Redirecting initializers are encoded as calls to top-level functions. /// The type arguments for this call are inferred. List inferredTypeArguments = []; - ExtensionTypeRedirectingInitializer(Procedure target, ArgumentsImpl arguments) - : this.byReference( + List positional = []; + List named = []; + + ExtensionTypeRedirectingInitializer( + Procedure target, + ActualArguments arguments, + ) : this.byReference( // Getter vs setter doesn't matter for procedures. getNonNullableMemberReferenceGetter(target), arguments, @@ -4935,7 +5009,7 @@ class DotShorthandInvocation extends InternalExpression { final Name name; final int nameOffset; final TypeArguments? typeArguments; - final ArgumentsImpl arguments; + final ActualArguments arguments; /// If `true`, this invocation is constant, either explicit or inferred. final bool isConst; @@ -5018,7 +5092,7 @@ class DotShorthandPropertyGet extends InternalExpression { class InternalConstructorInvocation extends InternalExpression { final Constructor target; final TypeArguments? typeArguments; - final ArgumentsImpl arguments; + final ActualArguments arguments; final bool isConst; InternalConstructorInvocation( @@ -5065,7 +5139,7 @@ class InternalStaticInvocation extends InternalExpression { final Name name; final Procedure target; final TypeArguments? typeArguments; - final ArgumentsImpl arguments; + final ActualArguments arguments; InternalStaticInvocation( this.name, @@ -5102,7 +5176,7 @@ class InternalSuperMethodInvocation extends InternalExpression { final Name name; final Procedure target; final TypeArguments? typeArguments; - final ArgumentsImpl arguments; + final ActualArguments arguments; InternalSuperMethodInvocation( this.name, @@ -5138,7 +5212,7 @@ class InternalSuperMethodInvocation extends InternalExpression { class InternalRedirectingInitializer extends InternalInitializer { final Constructor target; - ArgumentsImpl arguments; + ActualArguments arguments; InternalRedirectingInitializer(this.target, this.arguments) { arguments.parent = this; @@ -5168,7 +5242,7 @@ class InternalRedirectingInitializer extends InternalInitializer { class InternalSuperInitializer extends InternalInitializer { final Constructor target; - ArgumentsImpl arguments; + ActualArguments arguments; @override final bool isSynthetic; diff --git a/pkg/front_end/lib/src/kernel/kernel_target.dart b/pkg/front_end/lib/src/kernel/kernel_target.dart index f75a85ae08e..389047710d8 100644 --- a/pkg/front_end/lib/src/kernel/kernel_target.dart +++ b/pkg/front_end/lib/src/kernel/kernel_target.dart @@ -1843,17 +1843,16 @@ class KernelTarget { final Importability importability = compilationUnit.importability; final bool importableWithFlag = (importability == Importability.withFlag && - // Coverage-ignore(suite): Not run. flags.includeUnsupportedPlatformLibraryStubs); if (!dartLibrarySupport.computeDartLibrarySupport( importUri.path, isSupportedBySpec: (importability == Importability.always || importableWithFlag), )) { - // Coverage-ignore-block(suite): Not run. diagnostic = codeUnavailableDartLibrary.withArguments(uri: importUri); - } else if (importableWithFlag) { - // Coverage-ignore-block(suite): Not run. + } + // Coverage-ignore(suite): Not run. + else if (importableWithFlag) { // Display a warning for each import of an unsupported library. diagnostic = codeUnsupportedPlatformDartLibraryImport.withArguments( uri: importUri, diff --git a/pkg/front_end/lib/src/kernel/load_library_builder.dart b/pkg/front_end/lib/src/kernel/load_library_builder.dart index a12414e35c2..c2bd52139fd 100644 --- a/pkg/front_end/lib/src/kernel/load_library_builder.dart +++ b/pkg/front_end/lib/src/kernel/load_library_builder.dart @@ -71,7 +71,7 @@ class LoadLibraryBuilder extends NamedBuilderImpl { LoadLibrary createLoadLibrary( int charOffset, Forest forest, - ArgumentsImpl? arguments, + ActualArguments? arguments, ) { return forest.createLoadLibrary(charOffset, importDependency, arguments); } diff --git a/pkg/front_end/lib/src/kernel/resolver.dart b/pkg/front_end/lib/src/kernel/resolver.dart index 6c7f48574a7..91ee4ac8509 100644 --- a/pkg/front_end/lib/src/kernel/resolver.dart +++ b/pkg/front_end/lib/src/kernel/resolver.dart @@ -144,7 +144,7 @@ class Resolver { required ExtensionScope extensionScope, required LookupScope scope, required Token? token, - required List enumSyntheticArguments, + required List enumSyntheticArguments, required int enumTypeParameterCount, required TypeArguments? typeArguments, required MemberBuilder? constructorBuilder, @@ -178,16 +178,21 @@ class Resolver { constantContext: constantContext, ); BuildEnumConstantResult? result; - ArgumentsImpl arguments; + ActualArguments arguments; if (token != null) { result = bodyBuilder.buildEnumConstant(token: token); arguments = result.arguments; - arguments.positional.insertAll(0, enumSyntheticArguments); - arguments.argumentsOriginalOrder?.insertAll(0, enumSyntheticArguments); + arguments.prependArguments( + enumSyntheticArguments, + positionalCount: enumSyntheticArguments.length, + ); } else { - arguments = new ArgumentsImpl(enumSyntheticArguments); + arguments = new ActualArguments( + argumentList: enumSyntheticArguments, + hasNamedBeforePositional: false, + positionalCount: enumSyntheticArguments.length, + ); } - setParents(enumSyntheticArguments, arguments); Expression initializer; DartType? fieldType; if (constructorBuilder == null || @@ -431,12 +436,11 @@ class Resolver { bool needsImplicitSuperInitializer = result.needsImplicitSuperInitializer; if (isConst) { List? formals = bodyBuilderContext.formals; - List? superParametersAsArguments = formals != null - ? _createSuperParametersAsArguments( - assignedVariables: context.typeInferrer.assignedVariables, - formals: formals, - ) - : null; + _SuperParameterArguments? superParameterArguments = + _createSuperParameterArguments( + assignedVariables: context.typeInferrer.assignedVariables, + formals: formals, + ); _declareFormals( typeInferrer: context.typeInferrer, bodyBuilderContext: bodyBuilderContext, @@ -451,7 +455,7 @@ class Resolver { bodyBuilderContext: bodyBuilderContext, asyncModifier: AsyncMarker.Sync, body: null, - superParametersAsArguments: superParametersAsArguments, + superParameterArguments: superParameterArguments, fileUri: fileUri, needsImplicitSuperInitializer: needsImplicitSuperInitializer, constantContext: constantContext, @@ -820,7 +824,7 @@ class Resolver { required TypeEnvironment typeEnvironment, required Member target, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required Uri fileUri, required int fileOffset, required bool hasInferredTypeArguments, @@ -976,37 +980,55 @@ class Resolver { ); } - List? _createSuperParametersAsArguments({ + _SuperParameterArguments? _createSuperParameterArguments({ required AssignedVariables assignedVariables, - required List formals, + required List? formals, }) { - List? superParametersAsArguments; + if (formals == null) { + return null; + } + List? superParametersAsArguments; + int positionalCount = 0; + int? firstPositionalOffset; for (int i = 0; i < formals.length; i++) { FormalParameterBuilder formal = formals[i]; if (formal.isSuperInitializingFormal) { if (formal.isNamed) { - (superParametersAsArguments ??= []).add( - new NamedExpression( - formal.name, + (superParametersAsArguments ??= []).add( + new SuperNamedArgument( + new NamedExpression( + formal.name, + _createVariableGet( + assignedVariables: assignedVariables, + variable: formal.variable as VariableDeclarationImpl, + fileOffset: formal.fileOffset, + ), + )..fileOffset = formal.fileOffset, + ), + ); + } else { + positionalCount++; + firstPositionalOffset ??= formal.fileOffset; + (superParametersAsArguments ??= []).add( + new SuperPositionalArgument( _createVariableGet( assignedVariables: assignedVariables, variable: formal.variable as VariableDeclarationImpl, fileOffset: formal.fileOffset, ), - )..fileOffset = formal.fileOffset, - ); - } else { - (superParametersAsArguments ??= []).add( - _createVariableGet( - assignedVariables: assignedVariables, - variable: formal.variable as VariableDeclarationImpl, - fileOffset: formal.fileOffset, ), ); } } } - return superParametersAsArguments; + if (superParametersAsArguments == null) { + return null; + } + return new _SuperParameterArguments( + superParametersAsArguments, + positionalCount: positionalCount, + firstPositionalOffset: firstPositionalOffset ?? -1, + ); } /// Helper method to create a [VariableGet] of the [variable] using @@ -1059,10 +1081,7 @@ class Resolver { required TypeInferrer typeInferrer, required Uri fileUri, required List initializers, - required Set? namedSuperParameterNames, - required List? positionalSuperParametersAsArguments, - required List? namedSuperParametersAsArguments, - required List? superParametersAsArguments, + required _SuperParameterArguments? superParameterArguments, required bool needsImplicitSuperInitializer, required AsyncMarker asyncModifier, required int? asyncModifierFileOffset, @@ -1097,10 +1116,11 @@ class Resolver { ), )..parent = last.parent; needsImplicitSuperInitializer = false; - } else if (libraryFeatures.superParameters.isEnabled) { - ArgumentsImpl arguments = last.arguments; - if (positionalSuperParametersAsArguments != null) { - if (arguments.positional.isNotEmpty) { + } else if (superParameterArguments != null) { + bool insertNamedOnly = false; + ActualArguments arguments = last.arguments; + if (superParameterArguments.positionalCount > 0) { + if (arguments.positionalCount > 0) { problemReporting.addProblem( codePositionalSuperParametersAndArguments, arguments.fileOffset, @@ -1109,47 +1129,44 @@ class Resolver { context: [ codeSuperInitializerParameter.withLocation( fileUri, - (positionalSuperParametersAsArguments.first as VariableGet) - .variable - .fileOffset, + superParameterArguments.firstPositionalOffset, noLength, ), ], ); - } else { - arguments.positional.addAll(positionalSuperParametersAsArguments); - setParents(positionalSuperParametersAsArguments, arguments); - arguments.positionalAreSuperParameters = true; + insertNamedOnly = true; } } - if (namedSuperParametersAsArguments != null) { - // TODO(cstefantsova): Report name conflicts. - arguments.named.addAll(namedSuperParametersAsArguments); - setParents(namedSuperParametersAsArguments, arguments); - arguments.namedSuperParameterNames = namedSuperParameterNames; - } - if (superParametersAsArguments != null) { - arguments.argumentsOriginalOrder?.insertAll( - 0, - superParametersAsArguments, + if (insertNamedOnly) { + /// Error case: Don't insert positional argument when positional + /// arguments already exist. + arguments.prependArguments( + superParameterArguments.arguments + .whereType() + .toList(), + positionalCount: 0, + ); + } else { + arguments.prependArguments( + superParameterArguments.arguments, + positionalCount: superParameterArguments.positionalCount, ); } } } else if (last is InternalRedirectingInitializer) { if (bodyBuilderContext.isEnumClass && libraryFeatures.enhancedEnums.isEnabled) { - ArgumentsImpl arguments = last.arguments; + ActualArguments arguments = last.arguments; List enumSyntheticArguments = [ new VariableGet(function.positionalParameters[0]) ..parent = last.arguments, new VariableGet(function.positionalParameters[1]) ..parent = last.arguments, ]; - arguments.positional.insertAll(0, enumSyntheticArguments); - arguments.argumentsOriginalOrder?.insertAll( - 0, - enumSyntheticArguments, - ); + arguments.prependArguments([ + new PositionalArgument(enumSyntheticArguments[0]), + new PositionalArgument(enumSyntheticArguments[1]), + ], positionalCount: 2); } } @@ -1199,12 +1216,12 @@ class Resolver { /// >of the form super() is added at the end of the constructor's /// >initializer list, unless the enclosing class is class Object. Initializer? initializer; - ArgumentsImpl arguments; - List? positionalArguments; - List? namedArguments; - if (libraryFeatures.superParameters.isEnabled) { - positionalArguments = positionalSuperParametersAsArguments; - namedArguments = namedSuperParametersAsArguments; + ActualArguments arguments; + List? argumentsOriginalOrder; + int positionalCount = 0; + if (superParameterArguments != null) { + argumentsOriginalOrder = superParameterArguments.arguments; + positionalCount += superParameterArguments.positionalCount; } if (bodyBuilderContext.isEnumClass) { assert( @@ -1212,22 +1229,23 @@ class Resolver { function.positionalParameters[0].name == "#index" && function.positionalParameters[1].name == "#name", ); - (positionalArguments ??= []).insertAll(0, [ - new VariableGet(function.positionalParameters[0]), - new VariableGet(function.positionalParameters[1]), + Expression indexExpression = new VariableGet( + function.positionalParameters[0], + ); + Expression nameExpression = new VariableGet( + function.positionalParameters[1], + ); + (argumentsOriginalOrder ??= []).insertAll(0, [ + new PositionalArgument(indexExpression), + new PositionalArgument(nameExpression), ]); + positionalCount += 2; } int argumentsOffset = -1; - if (superParametersAsArguments != null) { - for (Object argument in superParametersAsArguments) { - assert(argument is Expression || argument is NamedExpression); - int currentArgumentOffset; - if (argument is Expression) { - currentArgumentOffset = argument.fileOffset; - } else { - currentArgumentOffset = (argument as NamedExpression).fileOffset; - } + if (superParameterArguments != null) { + for (Argument argument in superParameterArguments.arguments) { + int currentArgumentOffset = argument.expression.fileOffset; argumentsOffset = argumentsOffset <= currentArgumentOffset ? argumentsOffset : currentArgumentOffset; @@ -1246,20 +1264,17 @@ class Resolver { } const Forest forest = const Forest(); - if (positionalArguments != null || namedArguments != null) { + if (argumentsOriginalOrder != null) { arguments = forest.createArguments( argumentsOffset, - positionalArguments ?? [], - named: namedArguments, + arguments: argumentsOriginalOrder, + hasNamedBeforePositional: false, + positionalCount: positionalCount, ); } else { arguments = forest.createArgumentsEmpty(argumentsOffset); } - arguments.positionalAreSuperParameters = - positionalSuperParametersAsArguments != null; - arguments.namedSuperParameterNames = namedSuperParameterNames; - MemberLookupResult? result = bodyBuilderContext.lookupSuperConstructor( '', libraryBuilder.nameOriginBuilder, @@ -1318,79 +1333,56 @@ class Resolver { typeParameters: const [], ) case LocatedMessage argumentIssue) { - List? positionalSuperParametersIssueOffsets; - if (positionalSuperParametersAsArguments != null) { - for ( - int positionalSuperParameterIndex = - superTarget.function.positionalParameters.length; - positionalSuperParameterIndex < - positionalSuperParametersAsArguments.length; - positionalSuperParameterIndex++ - ) { - (positionalSuperParametersIssueOffsets ??= []).add( - positionalSuperParametersAsArguments[ // force line break - positionalSuperParameterIndex] - .fileOffset, - ); - } - } - - List? namedSuperParametersIssueOffsets; - if (namedSuperParametersAsArguments != null) { + Initializer? errorMessageInitializer; + if (superParameterArguments != null) { + int positionalSuperParameterCount = + superTarget.function.positionalParameters.length; Set superTargetNamedParameterNames = { for (VariableDeclaration namedParameter in superTarget.function.namedParameters) - if (namedParameter // Coverage-ignore(suite): Not run. - .name != - null) - // Coverage-ignore(suite): Not run. - namedParameter.name!, + ?namedParameter // Coverage-ignore(suite): Not run. + .name, }; - for (NamedExpression namedSuperParameter - in namedSuperParametersAsArguments) { - if (!superTargetNamedParameterNames.contains( - namedSuperParameter.name, - )) { - (namedSuperParametersIssueOffsets ??= []).add( - namedSuperParameter.fileOffset, - ); + int positionalIndex = 0; + for (Argument argument in superParameterArguments.arguments) { + switch (argument) { + case PositionalArgument(): + if (positionalIndex >= positionalSuperParameterCount) { + InvalidExpression errorMessageExpression = problemReporting + .buildProblem( + compilerContext: compilerContext, + message: + codeMissingPositionalSuperConstructorParameter, + fileUri: fileUri, + fileOffset: argument.expression.fileOffset, + length: noLength, + ); + errorMessageInitializer ??= _buildInvalidInitializer( + errorMessageExpression, + ); + needsImplicitSuperInitializer = false; + } + positionalIndex++; + case NamedArgument(): + if (!superTargetNamedParameterNames.contains( + argument.namedExpression.name, + )) { + InvalidExpression errorMessageExpression = problemReporting + .buildProblem( + compilerContext: compilerContext, + message: codeMissingNamedSuperConstructorParameter, + fileUri: fileUri, + fileOffset: argument.namedExpression.fileOffset, + length: noLength, + ); + errorMessageInitializer ??= _buildInvalidInitializer( + errorMessageExpression, + ); + needsImplicitSuperInitializer = false; + } } } } - - Initializer? errorMessageInitializer; - if (positionalSuperParametersIssueOffsets != null) { - for (int issueOffset in positionalSuperParametersIssueOffsets) { - InvalidExpression errorMessageExpression = problemReporting - .buildProblem( - compilerContext: compilerContext, - message: codeMissingPositionalSuperConstructorParameter, - fileUri: fileUri, - fileOffset: issueOffset, - length: noLength, - ); - errorMessageInitializer ??= _buildInvalidInitializer( - errorMessageExpression, - ); - needsImplicitSuperInitializer = false; - } - } - if (namedSuperParametersIssueOffsets != null) { - for (int issueOffset in namedSuperParametersIssueOffsets) { - InvalidExpression errorMessageExpression = problemReporting - .buildProblem( - compilerContext: compilerContext, - message: codeMissingNamedSuperConstructorParameter, - fileUri: fileUri, - fileOffset: issueOffset, - length: noLength, - ); - errorMessageInitializer ??= _buildInvalidInitializer( - errorMessageExpression, - ); - needsImplicitSuperInitializer = false; - } - } if (explicitSuperInitializer == null) { errorMessageInitializer ??= _buildInvalidInitializer( problemReporting.buildProblem( @@ -1462,117 +1454,12 @@ class Resolver { required BodyBuilderContext bodyBuilderContext, required AsyncMarker asyncModifier, required Statement? body, - required List? - superParametersAsArguments, + required _SuperParameterArguments? superParameterArguments, required Uri fileUri, required bool needsImplicitSuperInitializer, required ConstantContext constantContext, required List initializers, }) { - AssignedVariables assignedVariables = context.assignedVariables; - - /// Quotes below are from [Dart Programming Language Specification, 4th - /// Edition]( - /// https://ecma-international.org/publications/files/ECMA-ST/ECMA-408.pdf). - assert( - () { - if (superParametersAsArguments == null) { - return true; - } - for (Object superParameterAsArgument in superParametersAsArguments) { - if (superParameterAsArgument is! Expression && - superParameterAsArgument is! NamedExpression) { - return false; - } - } - return true; - }(), - "Expected 'superParametersAsArguments' " - "to contain nothing but Expressions and NamedExpressions.", - ); - assert( - () { - if (superParametersAsArguments == null) { - return true; - } - int previousOffset = -1; - for (Object superParameterAsArgument in superParametersAsArguments) { - int offset; - if (superParameterAsArgument is Expression) { - offset = superParameterAsArgument.fileOffset; - } else if (superParameterAsArgument is NamedExpression) { - offset = superParameterAsArgument.value.fileOffset; - } else { - return false; - } - if (previousOffset > offset) { - return false; - } - previousOffset = offset; - } - return true; - }(), - "Expected 'superParametersAsArguments' " - "to be sorted by occurrence in file.", - ); - - Set? namedSuperParameterNames; - List? positionalSuperParametersAsArguments; - List? namedSuperParametersAsArguments; - List? formals = bodyBuilderContext.formals; - if (superParametersAsArguments != null) { - for (Object superParameterAsArgument in superParametersAsArguments) { - if (superParameterAsArgument is Expression) { - (positionalSuperParametersAsArguments ??= []).add( - superParameterAsArgument, - ); - } else { - NamedExpression namedSuperParameterAsArgument = - superParameterAsArgument as NamedExpression; - (namedSuperParametersAsArguments ??= []).add( - namedSuperParameterAsArgument, - ); - (namedSuperParameterNames ??= {}).add( - namedSuperParameterAsArgument.name, - ); - } - } - } else if (formals != null) { - for (FormalParameterBuilder formal in formals) { - if (formal.isSuperInitializingFormal) { - // Coverage-ignore-block(suite): Not run. - if (formal.isNamed) { - NamedExpression superParameterAsArgument = new NamedExpression( - formal.name, - _createVariableGet( - assignedVariables: assignedVariables, - variable: formal.variable as VariableDeclarationImpl, - fileOffset: formal.fileOffset, - ), - )..fileOffset = formal.fileOffset; - (namedSuperParametersAsArguments ??= []).add( - superParameterAsArgument, - ); - (namedSuperParameterNames ??= {}).add(formal.name); - (superParametersAsArguments ??= []).add( - superParameterAsArgument, - ); - } else { - Expression superParameterAsArgument = _createVariableGet( - assignedVariables: assignedVariables, - variable: formal.variable as VariableDeclarationImpl, - fileOffset: formal.fileOffset, - ); - (positionalSuperParametersAsArguments ??= []).add( - superParameterAsArgument, - ); - (superParametersAsArguments ??= []).add( - superParameterAsArgument, - ); - } - } - } - } _finishInitializers( compilerContext: compilerContext, problemReporting: problemReporting, @@ -1582,11 +1469,7 @@ class Resolver { typeInferrer: context.typeInferrer, fileUri: fileUri, initializers: initializers, - namedSuperParameterNames: namedSuperParameterNames, - positionalSuperParametersAsArguments: - positionalSuperParametersAsArguments, - namedSuperParametersAsArguments: namedSuperParametersAsArguments, - superParametersAsArguments: superParametersAsArguments, + superParameterArguments: superParameterArguments, needsImplicitSuperInitializer: needsImplicitSuperInitializer, asyncModifier: asyncModifier, asyncModifierFileOffset: body?.fileOffset, @@ -1636,16 +1519,11 @@ class Resolver { // Create variable get expressions for super parameters before finishing // the analysis of the assigned variables. Creating the expressions later // that point results in a flow analysis error. - List? superParametersAsArguments; - if (formals != null) { - List? formalParameters = formals.parameters; - if (formalParameters != null) { - superParametersAsArguments = _createSuperParametersAsArguments( + _SuperParameterArguments? superParameterArguments = + _createSuperParameterArguments( assignedVariables: assignedVariables, - formals: formalParameters, + formals: formals?.parameters, ); - } - } assignedVariables.finish(); FunctionNode function = bodyBuilderContext.function; @@ -1715,7 +1593,7 @@ class Resolver { bodyBuilderContext: bodyBuilderContext, asyncModifier: asyncModifier, body: body, - superParametersAsArguments: superParametersAsArguments, + superParameterArguments: superParameterArguments, fileUri: fileUri, needsImplicitSuperInitializer: needsImplicitSuperInitializer, constantContext: constantContext, diff --git a/pkg/front_end/lib/src/kernel/resolver_helpers.dart b/pkg/front_end/lib/src/kernel/resolver_helpers.dart index a8f83b49bfd..7945d464d41 100644 --- a/pkg/front_end/lib/src/kernel/resolver_helpers.dart +++ b/pkg/front_end/lib/src/kernel/resolver_helpers.dart @@ -327,3 +327,18 @@ class _InitializerBuilder { List get initializers => _initializers; } + +class _SuperParameterArguments { + final List arguments; + final int positionalCount; + final int firstPositionalOffset; + + _SuperParameterArguments( + this.arguments, { + required this.positionalCount, + required this.firstPositionalOffset, + }); + + // Coverage-ignore(suite): Not run. + int get namedCount => arguments.length - positionalCount; +} diff --git a/pkg/front_end/lib/src/kernel/utils.dart b/pkg/front_end/lib/src/kernel/utils.dart index 155dba8c918..e7ac33e1a0a 100644 --- a/pkg/front_end/lib/src/kernel/utils.dart +++ b/pkg/front_end/lib/src/kernel/utils.dart @@ -34,6 +34,7 @@ import '../fragment/fragment.dart'; import '../source/fragment_factory.dart'; import '../source/source_type_parameter_builder.dart'; import 'body_builder.dart'; +import 'internal_ast.dart'; /// The name for the synthesized field used to store information of /// unserializable exports in a [Library]. @@ -364,3 +365,5 @@ class _DummyExtensionScope implements ExtensionScope { @override void forEachExtension(void Function(ExtensionBuilder) f) {} } + +final Argument dummyArgument = new PositionalArgument(dummyExpression); diff --git a/pkg/front_end/lib/src/source/check_helper.dart b/pkg/front_end/lib/src/source/check_helper.dart index 50e10f17827..58882f24442 100644 --- a/pkg/front_end/lib/src/source/check_helper.dart +++ b/pkg/front_end/lib/src/source/check_helper.dart @@ -113,7 +113,7 @@ extension CheckHelper on ProblemReporting { LocatedMessage? checkArgumentsForFunction({ required FunctionNode function, required TypeArguments? explicitTypeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required int fileOffset, required Uri fileUri, required List typeParameters, @@ -122,7 +122,7 @@ extension CheckHelper on ProblemReporting { int typeParameterCount = typeParameters.length; int requiredParameterCount = function.requiredParameterCount; int positionalParameterCount = function.positionalParameters.length; - int positionalArgumentsCount = arguments.positional.length; + int positionalArgumentsCount = arguments.positionalCount; if (extension != null) { // Extension member invocations have additional synthetic parameter for // `this`. @@ -140,22 +140,32 @@ extension CheckHelper on ProblemReporting { .withArgumentsOld(positionalParameterCount, positionalArgumentsCount) .withLocation(fileUri, arguments.fileOffset, noLength); } - List named = arguments.named; - if (named.isNotEmpty) { + Set argumentNames = {}; + if (arguments.namedCount > 0) { Set parameterNames = new Set.of( function.namedParameters.map((a) => a.name), ); - for (int i = 0; i < named.length; i++) { - NamedExpression argument = named[i]; - if (!parameterNames.contains(argument.name)) { - return codeNoSuchNamedParameter - .withArgumentsOld(argument.name) - .withLocation(fileUri, argument.fileOffset, argument.name.length); + for (Argument argument in arguments.argumentList) { + switch (argument) { + case NamedArgument(): + NamedExpression namedExpression = argument.namedExpression; + String name = namedExpression.name; + argumentNames.add(name); + if (!parameterNames.contains(name)) { + return codeNoSuchNamedParameter + .withArgumentsOld(name) + .withLocation( + fileUri, + namedExpression.fileOffset, + name.length, + ); + } + case PositionalArgument(): + break; } } } if (function.namedParameters.isNotEmpty) { - Set argumentNames = new Set.of(named.map((a) => a.name)); for (int i = 0; i < function.namedParameters.length; i++) { VariableDeclaration parameter = function.namedParameters[i]; if (parameter.isRequired && !argumentNames.contains(parameter.name)) { @@ -165,6 +175,7 @@ extension CheckHelper on ProblemReporting { } } } + if (explicitTypeArguments != null) { if (typeParameterCount != explicitTypeArguments.types.length) { // A wrong (non-zero) amount of type arguments given. That's an error. @@ -181,15 +192,15 @@ extension CheckHelper on ProblemReporting { LocatedMessage? checkArgumentsForType({ required FunctionType function, required TypeArguments? explicitTypeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required Uri fileUri, required int fileOffset, }) { int requiredPositionalParameterCountToReport = function.requiredParameterCount; int positionalParameterCountToReport = function.positionalParameters.length; - int positionalArgumentCountToReport = arguments.positional.length; - if (arguments.positional.length < function.requiredParameterCount) { + int positionalArgumentCountToReport = arguments.positionalCount; + if (positionalArgumentCountToReport < function.requiredParameterCount) { return codeTooFewArguments .withArgumentsOld( requiredPositionalParameterCountToReport, @@ -197,7 +208,8 @@ extension CheckHelper on ProblemReporting { ) .withLocation(fileUri, arguments.fileOffset, noLength); } - if (arguments.positional.length > function.positionalParameters.length) { + if (positionalArgumentCountToReport > + function.positionalParameters.length) { return codeTooManyArguments .withArgumentsOld( positionalParameterCountToReport, @@ -205,22 +217,32 @@ extension CheckHelper on ProblemReporting { ) .withLocation(fileUri, arguments.fileOffset, noLength); } - List named = arguments.named; - if (named.isNotEmpty) { + Set argumentNames = {}; + if (arguments.namedCount > 0) { Set names = new Set.of( function.namedParameters.map((a) => a.name), ); - for (int i = 0; i < named.length; i++) { - NamedExpression argument = named[i]; - if (!names.contains(argument.name)) { - return codeNoSuchNamedParameter - .withArgumentsOld(argument.name) - .withLocation(fileUri, argument.fileOffset, argument.name.length); + for (Argument argument in arguments.argumentList) { + switch (argument) { + case NamedArgument(): + NamedExpression namedExpression = argument.namedExpression; + String name = namedExpression.name; + argumentNames.add(name); + if (!names.contains(name)) { + return codeNoSuchNamedParameter + .withArgumentsOld(name) + .withLocation( + fileUri, + namedExpression.fileOffset, + name.length, + ); + } + case PositionalArgument(): + break; } } } if (function.namedParameters.isNotEmpty) { - Set argumentNames = new Set.of(named.map((a) => a.name)); for (int i = 0; i < function.namedParameters.length; i++) { NamedType parameter = function.namedParameters[i]; if (parameter.isRequired && !argumentNames.contains(parameter.name)) { @@ -364,7 +386,7 @@ extension CheckHelper on ProblemReporting { required FunctionType functionType, required String? localName, required List explicitOrInferredTypeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required Uri fileUri, required int fileOffset, required bool hasInferredTypeArguments, @@ -462,7 +484,7 @@ extension CheckHelper on ProblemReporting { required Name name, required Member? interfaceTarget, required List explicitOrInferredTypeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required Uri fileUri, required int fileOffset, required bool hasInferredTypeArguments, @@ -718,7 +740,7 @@ extension CheckHelper on ProblemReporting { required CompilerContext compilerContext, required Member target, required TypeArguments? explicitTypeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required int fileOffset, required Uri fileUri, }) { diff --git a/pkg/front_end/lib/src/source/value_kinds.dart b/pkg/front_end/lib/src/source/value_kinds.dart index 5a493e426ee..1c9f3dc0760 100644 --- a/pkg/front_end/lib/src/source/value_kinds.dart +++ b/pkg/front_end/lib/src/source/value_kinds.dart @@ -45,10 +45,11 @@ class ValueKinds { const SingleValueKind>(); static const ValueKind AnnotationListOrNull = const SingleValueKind>(NullValues.Metadata); + static const ValueKind Argument = const SingleValueKind(); static const ValueKind Arguments = - const SingleValueKind(); + const SingleValueKind(); static const ValueKind ArgumentsOrNull = - const SingleValueKind(NullValues.Arguments); + const SingleValueKind(NullValues.Arguments); static const ValueKind ArgumentsTokenOrNull = const SingleValueKind(NullValues.Arguments); static const ValueKind AssignedVariablesNodeInfo = diff --git a/pkg/front_end/lib/src/type_inference/inference_results.dart b/pkg/front_end/lib/src/type_inference/inference_results.dart index f06b30a369a..288f0bd85b0 100644 --- a/pkg/front_end/lib/src/type_inference/inference_results.dart +++ b/pkg/front_end/lib/src/type_inference/inference_results.dart @@ -114,6 +114,12 @@ abstract class InvocationInferenceResult { /// The explicit or inferred type arguments. List get typeArguments; + /// The positional arguments. + List get positional; + + /// The named arguments. + List get named; + /// Applies the result of the inference to the expression being inferred. /// /// A successful result leaves [expression] intact, and an error detected @@ -160,12 +166,20 @@ class SuccessfulInferenceResult implements InvocationInferenceResult { final List? hoistedArguments; + @override + final List positional; + + @override + final List named; + final DartType? inferredReceiverType; - SuccessfulInferenceResult( - this.inferredType, - this.functionType, - this.typeArguments, { + SuccessfulInferenceResult({ + required this.inferredType, + required this.functionType, + required this.typeArguments, + required this.positional, + required this.named, required this.hoistedArguments, this.inferredReceiverType, }); @@ -296,12 +310,20 @@ class WrapInProblemInferenceResult implements InvocationInferenceResult { final List? hoistedArguments; - WrapInProblemInferenceResult( - this.message, - this.problemReporting, - this.compilerContext, { + @override + final List positional; + + @override + final List named; + + WrapInProblemInferenceResult({ + required this.message, + required this.problemReporting, + required this.compilerContext, required this.isInapplicable, required this.hoistedArguments, + required this.positional, + required this.named, }); @override diff --git a/pkg/front_end/lib/src/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/type_inference/inference_visitor.dart index 32db6a368ec..dfc32cc7653 100644 --- a/pkg/front_end/lib/src/type_inference/inference_visitor.dart +++ b/pkg/front_end/lib/src/type_inference/inference_visitor.dart @@ -1460,7 +1460,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase ) { ensureMemberType(node.target); TypeArguments? typeArguments = node.typeArguments; - ArgumentsImpl arguments = node.arguments; + ActualArguments arguments = node.arguments; bool hasInferredTypeArguments = typeArguments == null; FunctionType functionType = node.target.function.computeThisFunctionType( Nullability.nonNullable, @@ -1488,7 +1488,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase } Expression replacement = createConstructorInvocation( node.target, - createArgumentsFromInternalNode(result.typeArguments, arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + arguments, + ), fileOffset: node.fileOffset, isConst: node.isConst, ); @@ -2115,11 +2120,13 @@ class InferenceVisitorImpl extends InferenceVisitorBase ); StaticInvocation replacement = createExtensionInvocation( - node.fileOffset, - target, - receiver, - result.typeArguments, - node.arguments, + invocationOffset: node.fileOffset, + argumentsOffset: node.arguments.fileOffset, + target: target, + receiver: receiver, + explicitOrInferredTypeArguments: result.typeArguments, + positionalArguments: result.positional, + namedArguments: result.named, ); return new ExpressionInferenceResult( @@ -2562,6 +2569,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase Expression resolvedExpression = _resolveRedirectingFactoryTarget( target: node.target, explicitOrInferredTypeArguments: result.typeArguments, + positional: result.positional, + named: result.named, arguments: node.arguments, fileOffset: node.fileOffset, isConst: node.isConst, @@ -2581,7 +2590,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase Expression? _resolveRedirectingFactoryTarget({ required Procedure target, required List explicitOrInferredTypeArguments, - required ArgumentsImpl arguments, + required List positional, + required List named, + required ActualArguments arguments, required int fileOffset, required bool isConst, required bool hasInferredTypeArguments, @@ -2622,6 +2633,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase : null, effectiveTarget: resolvedTarget, explicitOrInferredTypeArguments: typeArguments, + positional: positional, + named: named, arguments: arguments, isConst: isConst, fileOffset: fileOffset, @@ -2635,7 +2648,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase required Procedure? redirectingFactoryTarget, required Member effectiveTarget, required List explicitOrInferredTypeArguments, - required ArgumentsImpl arguments, + required List positional, + required List named, + required ActualArguments arguments, required bool isConst, required int fileOffset, required bool hasInferredTypeArguments, @@ -2675,6 +2690,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase effectiveTarget, createArgumentsFromInternalNode( explicitOrInferredTypeArguments, + positional, + named, arguments, ), isConst: isConst, @@ -2725,6 +2742,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase effectiveTarget, createArgumentsFromInternalNode( explicitOrInferredTypeArguments, + positional, + named, arguments, ), isConst: isConst, @@ -2893,6 +2912,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase _unaliasSingleTypeAliasedConstructorInvocation( node, result.typeArguments, + result.positional, + result.named, ); Expression resultingExpression = result.applyResult(resolvedExpression); @@ -2905,6 +2926,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase Expression _unaliasSingleTypeAliasedConstructorInvocation( TypeAliasedConstructorInvocation node, List explicitOrInferredTypeArguments, + List positional, + List named, ) { DartType aliasedType = new TypedefType( node.typeAliasBuilder.typedef, @@ -2926,9 +2949,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase invocationTypeArguments = unaliasedType.typeArguments.toList(); } Arguments invocationArguments = new Arguments( - node.arguments.positional, + positional, types: invocationTypeArguments, - named: node.arguments.named, + named: named, )..fileOffset = node.arguments.fileOffset; return new ConstructorInvocation( node.target, @@ -3026,6 +3049,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase Expression resolvedExpression = _unaliasSingleTypeAliasedFactoryInvocation( node, result.typeArguments, + result.positional, + result.named, )!; Expression resultExpression = result.applyResult(resolvedExpression); @@ -3036,6 +3061,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase Expression? _unaliasSingleTypeAliasedFactoryInvocation( TypeAliasedFactoryInvocation node, List explicitOrInferredTypeArguments, + List positional, + List named, ) { bool hasInferredTypeArguments = node.typeArguments == null; DartType aliasedType = new TypedefType( @@ -3062,6 +3089,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase explicitOrInferredTypeArguments: invocationTypeArguments ?? // Coverage-ignore(suite): Not run. [], + positional: positional, + named: named, arguments: node.arguments, fileOffset: node.fileOffset, isConst: node.isConst, @@ -8421,7 +8450,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase ); StaticInvocation invocation = new StaticInvocation( member, - createArgumentsFromInternalNode(result.typeArguments, node.arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + node.arguments, + ), ); String targetName = member.name.text; if (member.enclosingClass != null) { @@ -12335,7 +12369,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase ensureMemberType(node.target); List classTypeParameters = node.target.enclosingClass.typeParameters; - ArgumentsImpl arguments = node.arguments; + ActualArguments arguments = node.arguments; // The redirecting initializer syntax doesn't include type arguments passed // to the target constructor so we synthesize them for calling // [inferInvocation]. @@ -12386,7 +12420,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase result ?? (new RedirectingInitializer( node.target, - createArgumentsFromInternalNode([], arguments), + createArgumentsFromInternalNode( + [], + inferenceResult.positional, + inferenceResult.named, + arguments, + ), )..fileOffset = node.fileOffset), inferenceResult, ); @@ -12425,6 +12464,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase staticTarget: node.target, ); node.inferredTypeArguments = inferenceResult.typeArguments; + node.positional = inferenceResult.positional; + node.named = inferenceResult.named; LocatedMessage? message = problemReporting.checkArgumentsForFunction( function: node.target.function, @@ -12720,7 +12761,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase FunctionType calleeType = node.target.function.computeFunctionType( Nullability.nonNullable, ); - ArgumentsImpl arguments = node.arguments; + ActualArguments arguments = node.arguments; InvocationInferenceResult result = inferInvocation( this, typeContext, @@ -12747,7 +12788,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase ); Expression replacement = createStaticInvocation( node.target, - createArgumentsFromInternalNode(result.typeArguments, arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + arguments, + ), fileOffset: node.fileOffset, ); flowAnalysis.forwardExpression(replacement, node); @@ -12848,7 +12894,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase result ?? (new SuperInitializer( node.target, - createArgumentsFromInternalNode([], node.arguments), + createArgumentsFromInternalNode( + [], + inferenceResult.positional, + inferenceResult.named, + node.arguments, + ), ) ..fileOffset = node.fileOffset ..isSynthetic = node.isSynthetic), @@ -16335,7 +16386,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase ); expr = new StaticInvocation( member, - createArgumentsFromInternalNode(result.typeArguments, node.arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + node.arguments, + ), )..fileOffset = node.fileOffset; return new ExpressionInferenceResult( result.inferredType, @@ -16411,7 +16467,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase ); expr = new ConstructorInvocation( constructor, - createArgumentsFromInternalNode(result.typeArguments, node.arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + node.arguments, + ), isConst: node.isConst, )..fileOffset = node.fileOffset; return new ExpressionInferenceResult( @@ -16453,6 +16514,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase expr = _resolveRedirectingFactoryTarget( target: constructor, explicitOrInferredTypeArguments: result.typeArguments, + positional: result.positional, + named: result.named, arguments: node.arguments, fileOffset: node.fileOffset, isConst: node.isConst, @@ -16463,6 +16526,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase constructor, createArgumentsFromInternalNode( result.typeArguments, + result.positional, + result.named, node.arguments, ), isConst: node.isConst, diff --git a/pkg/front_end/lib/src/type_inference/inference_visitor_base.dart b/pkg/front_end/lib/src/type_inference/inference_visitor_base.dart index 2da8e66fca6..96e4537a53c 100644 --- a/pkg/front_end/lib/src/type_inference/inference_visitor_base.dart +++ b/pkg/front_end/lib/src/type_inference/inference_visitor_base.dart @@ -95,28 +95,6 @@ Map _computeParameterMap(FunctionType functionType) => { namedType.name: namedType.type, }; -/// Computes a list of [_ParamInfo] objects corresponding to the invocation -/// parameters that were *not* deferred. -List<_ParamInfo> _computeUndeferredParamInfo( - List formalTypes, - List<_DeferredParamInfo> deferredFunctionLiterals, -) { - Set evaluationOrderIndicesAlreadyCovered = { - for (_DeferredParamInfo functionLiteral in deferredFunctionLiterals) - functionLiteral.evaluationOrderIndex, - }; - assert( - evaluationOrderIndicesAlreadyCovered.every( - (i) => 0 <= i && i < formalTypes.length, - ), - ); - return [ - for (int i = 0; i < formalTypes.length; i++) - if (!evaluationOrderIndicesAlreadyCovered.contains(i)) - new _ParamInfo(formalTypes[i]), - ]; -} - /// Enum denoting the kinds of contravariance check that might need to be /// inserted for a method call. enum MethodContravarianceCheckKind { @@ -1675,7 +1653,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { int offset, InvocationTargetType invocationTargetType, TypeArguments? typeArguments, - ArgumentsImpl arguments, { + ActualArguments arguments, { List? hoistedExpressions, bool isSpecialCasedBinaryOperator = false, bool isSpecialCasedTernaryOperator = false, @@ -1713,7 +1691,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { int offset, FunctionType calleeType, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments actualArguments, List? hoistedExpressions, { bool isSpecialCasedBinaryOperator = false, bool isSpecialCasedTernaryOperator = false, @@ -1756,12 +1734,9 @@ abstract class InferenceVisitorBase implements InferenceVisitor { List? inferredTypes; FunctionTypeInstantiator? instantiator; - List formalTypes = []; - List actualTypes = []; List? localHoistedExpressions; - if (libraryFeatures.namedArgumentsAnywhere.isEnabled && - arguments.argumentsOriginalOrder != null && + if (actualArguments.hasNamedBeforePositional && hoistedExpressions == null && !isConst) { hoistedExpressions = localHoistedExpressions = []; @@ -1785,7 +1760,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { inferenceResultForTesting: dataForTesting // Coverage-ignore(suite): Not run. ?.typeInferenceResult, - treeNodeForTesting: arguments, + treeNodeForTesting: actualArguments, ); inferredTypes = typeSchemaEnvironment.choosePreliminaryTypes( gatherer.computeConstraints(), @@ -1794,7 +1769,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { inferenceUsingBoundsIsEnabled: libraryFeatures.inferenceUsingBounds.isEnabled, dataForTesting: dataForTesting, - treeNodeForTesting: arguments, + treeNodeForTesting: actualArguments, typeOperations: cfeOperations, ); instantiator = new FunctionTypeInstantiator.fromIterables( @@ -1816,21 +1791,12 @@ abstract class InferenceVisitorBase implements InferenceVisitor { ), ); } - bool isIdentical = - staticTarget == typeSchemaEnvironment.coreTypes.identicalProcedure; + bool isIdenticalCall = + staticTarget == typeSchemaEnvironment.coreTypes.identicalProcedure && + actualArguments.positionalCount == 2; // TODO(paulberry): if we are doing top level inference and type arguments // were omitted, report an error. - List argumentsEvaluationOrder; - if (libraryFeatures.namedArgumentsAnywhere.isEnabled && - arguments.argumentsOriginalOrder != null) { - argumentsEvaluationOrder = arguments.argumentsOriginalOrder!; - } else { - argumentsEvaluationOrder = [ - ...arguments.positional, - ...arguments.named, - ]; - } - arguments.argumentsOriginalOrder = null; + List arguments = actualArguments.argumentList; // The following loop determines how many argument expressions should be // hoisted to preserve the evaluation order. The computation is based on the @@ -1844,19 +1810,15 @@ abstract class InferenceVisitorBase implements InferenceVisitor { // vector, and none of the arguments is hoisted. That way the legacy // behavior is preserved. int hoistingEndIndex; - if (libraryFeatures.namedArgumentsAnywhere.isEnabled) { - hoistingEndIndex = argumentsEvaluationOrder.length - 1; + if (actualArguments.hasNamedBeforePositional) { + hoistingEndIndex = arguments.length - 1; for ( - int i = argumentsEvaluationOrder.length - 2; + int i = arguments.length - 2; i >= 0 && hoistingEndIndex == i + 1; i-- ) { - int previousWeight = argumentsEvaluationOrder[i + 1] is NamedExpression - ? 1 - : 0; - int currentWeight = argumentsEvaluationOrder[i] is NamedExpression - ? 1 - : 0; + int previousWeight = arguments[i + 1] is NamedArgument ? 1 : 0; + int currentWeight = arguments[i] is NamedArgument ? 1 : 0; if (currentWeight <= previousWeight) { --hoistingEndIndex; } @@ -1865,15 +1827,11 @@ abstract class InferenceVisitorBase implements InferenceVisitor { hoistingEndIndex = 0; } - ExpressionInferenceResult inferArgument( - DartType formalType, - Expression argumentExpression, { - required bool isNamed, - }) { - DartType inferredFormalType = instantiator != null - ? instantiator.substitute(formalType) - : formalType; - if (!isNamed) { + ExpressionInferenceResult inferArgument(_ArgumentInfo argumentInfo) { + DartType inferredFormalType = argumentInfo.computeInferredFormalType( + instantiator, + ); + if (!argumentInfo.isNamed) { if (isSpecialCasedBinaryOperator) { inferredFormalType = typeSchemaEnvironment .getContextTypeOfSpecialCasedBinaryOperator( @@ -1891,74 +1849,51 @@ abstract class InferenceVisitorBase implements InferenceVisitor { } } return visitor.inferExpression( - argumentExpression, + argumentInfo.argument.expression, inferredFormalType, isVoidAllowed: true, ); } - List? identicalInfo = - isIdentical && arguments.positional.length == 2 ? [] : null; int positionalIndex = 0; - int namedIndex = 0; - List<_DeferredParamInfo>? deferredFunctionLiterals; - for ( - int evaluationOrderIndex = 0; - evaluationOrderIndex < argumentsEvaluationOrder.length; - evaluationOrderIndex++ - ) { - Object? argument = argumentsEvaluationOrder[evaluationOrderIndex]; - assert( - argument is Expression || argument is NamedExpression, - "Expected the argument to be either an Expression " - "or a NamedExpression, got '${argument.runtimeType}'.", - ); - int index; + List<_ArgumentInfo> argumentsInfo = []; + List<_ArgumentInfo> undeferredArguments = []; + List<_DeferredArgumentInfo>? deferredFunctionLiterals; + for (int index = 0; index < arguments.length; index++) { + Argument argument = arguments[index]; DartType formalType; - Expression argumentExpression; - bool isExpression = argument is Expression; - if (isExpression) { - index = positionalIndex++; - formalType = getPositionalParameterType(calleeType, index); - argumentExpression = arguments.positional[index]; - } else { - index = namedIndex++; - NamedExpression namedArgument = arguments.named[index]; - formalType = getNamedParameterType(calleeType, namedArgument.name); - argumentExpression = namedArgument.value; + switch (argument) { + case PositionalArgument(): + formalType = getPositionalParameterType( + calleeType, + positionalIndex++, + ); + case NamedArgument(): + formalType = getNamedParameterType(calleeType, argument.name); } - Expression unparenthesizedExpression = argumentExpression; + Expression unparenthesizedExpression = argument.expression; while (unparenthesizedExpression is ParenthesizedExpression) { unparenthesizedExpression = unparenthesizedExpression.expression; } if (isInferenceUpdate1Enabled && unparenthesizedExpression is FunctionExpression) { - (deferredFunctionLiterals ??= []).add( - new _DeferredParamInfo( - formalType: formalType, - argumentExpression: argumentExpression, - unparenthesizedExpression: unparenthesizedExpression, - isNamed: !isExpression, - evaluationOrderIndex: evaluationOrderIndex, - index: index, - ), + _DeferredArgumentInfo argumentInfo = new _DeferredArgumentInfo( + argument: argument, + formalType: formalType, + unparenthesizedExpression: unparenthesizedExpression, ); - // We don't have `identical` info yet, so fill it in with `null` for - // now. Later, when we visit the function literal, we'll replace it. - identicalInfo?.add(null); - formalTypes.add(formalType); - // We don't have an inferred type yet, so fill it in with UnknownType - // for now. Later, when we infer a type, we'll replace it. - actualTypes.add(const UnknownType()); + argumentsInfo.add(argumentInfo); + (deferredFunctionLiterals ??= []).add(argumentInfo); } else { - ExpressionInferenceResult result = inferArgument( - formalType, - argumentExpression, - isNamed: !isExpression, + _ArgumentInfo argumentInfo = new _ArgumentInfo( + argument: argument, + formalType: formalType, ); - DartType inferredType = _computeInferredType(result); - if (localHoistedExpressions != null && - evaluationOrderIndex >= hoistingEndIndex) { + argumentsInfo.add(argumentInfo); + undeferredArguments.add(argumentInfo); + ExpressionInferenceResult result = inferArgument(argumentInfo); + DartType inferredType = result.inferredType; + if (localHoistedExpressions != null && index >= hoistingEndIndex) { hoistedExpressions = null; } Expression expression = _hoist( @@ -1966,33 +1901,31 @@ abstract class InferenceVisitorBase implements InferenceVisitor { inferredType, hoistedExpressions, ); - identicalInfo?.add(flowAnalysis.equalityOperand_end(expression)); - if (isExpression) { - arguments.positional[index] = expression..parent = arguments; - } else { - NamedExpression namedArgument = arguments.named[index]; - namedArgument.value = expression..parent = namedArgument; + if (isIdenticalCall) { + argumentInfo.identicalInfo = flowAnalysis.equalityOperand_end( + expression, + ); } + argument.expression = expression; gatherer?.tryConstrainLower( formalType, inferredType, - treeNodeForTesting: arguments, + treeNodeForTesting: actualArguments, ); - formalTypes.add(formalType); - actualTypes.add(inferredType); + argumentInfo.actualType = inferredType; + argumentInfo.argumentInferenceResult = result; } } if (deferredFunctionLiterals != null) { bool isFirstStage = true; - List> stages = new _FunctionLiteralDependencies( - deferredFunctionLiterals, - calleeType.typeParameters.toSet(), - inferenceNeeded - ? _computeUndeferredParamInfo(formalTypes, deferredFunctionLiterals) - : const [], - ).planReconciliationStages(); + List> stages = + new _FunctionLiteralDependencies( + deferredFunctionLiterals, + calleeType.typeParameters.toSet(), + inferenceNeeded ? undeferredArguments : const [], + ).planReconciliationStages(); for (int i = 0; i < stages.length; i++) { - List<_DeferredParamInfo> stage = stages[i]; + List<_DeferredArgumentInfo> stage = stages[i]; if (gatherer != null && !isFirstStage) { inferredTypes = typeSchemaEnvironment.choosePreliminaryTypes( gatherer.computeConstraints(), @@ -2001,7 +1934,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { inferenceUsingBoundsIsEnabled: libraryFeatures.inferenceUsingBounds.isEnabled, dataForTesting: dataForTesting, - treeNodeForTesting: arguments, + treeNodeForTesting: actualArguments, typeOperations: cfeOperations, ); instantiator = new FunctionTypeInstantiator.fromIterables( @@ -2010,69 +1943,57 @@ abstract class InferenceVisitorBase implements InferenceVisitor { ); } for (int j = 0; j < stage.length; j++) { - _DeferredParamInfo deferredArgument = stage[j]; - ExpressionInferenceResult result = inferArgument( - deferredArgument.formalType, - deferredArgument.argumentExpression, - isNamed: deferredArgument.isNamed, - ); - DartType inferredType = _computeInferredType(result); + _DeferredArgumentInfo deferredArgument = stage[j]; + ExpressionInferenceResult result = inferArgument(deferredArgument); + DartType inferredType = result.inferredType; Expression expression = result.expression; - identicalInfo?[deferredArgument.evaluationOrderIndex] = flowAnalysis - .equalityOperand_end(expression); - if (deferredArgument.isNamed) { - NamedExpression namedArgument = - arguments.named[deferredArgument.index]; - namedArgument.value = expression..parent = namedArgument; - } else { - arguments.positional[deferredArgument.index] = expression - ..parent = arguments; + if (isIdenticalCall) { + deferredArgument.identicalInfo = flowAnalysis.equalityOperand_end( + expression, + ); } + deferredArgument.argument.expression = expression; gatherer?.tryConstrainLower( deferredArgument.formalType, inferredType, - treeNodeForTesting: arguments, + treeNodeForTesting: actualArguments, ); - actualTypes[deferredArgument.evaluationOrderIndex] = inferredType; + deferredArgument.actualType = inferredType; + deferredArgument.argumentInferenceResult = result; } isFirstStage = false; } } - if (identicalInfo != null) { + + if (isIdenticalCall) { flowAnalysis.equalityOperation_end( - arguments.parent as Expression, - identicalInfo[0], - new SharedTypeView(actualTypes[0]), - identicalInfo[1], - new SharedTypeView(actualTypes[1]), + actualArguments.parent as Expression, + argumentsInfo[0].identicalInfo, + new SharedTypeView(argumentsInfo[0].actualType), + argumentsInfo[1].identicalInfo, + new SharedTypeView(argumentsInfo[1].actualType), ); } - assert( - positionalIndex == arguments.positional.length, - "Expected 'positionalIndex' to be ${arguments.positional.length}, " - "got ${positionalIndex}.", - ); - assert( - namedIndex == arguments.named.length, - "Expected 'namedIndex' to be ${arguments.named.length}, " - "got ${namedIndex}.", - ); if (isSpecialCasedBinaryOperator || isSpecialCasedTernaryOperator) { LocatedMessage? argMessage = problemReporting.checkArgumentsForType( function: calleeType, explicitTypeArguments: typeArguments, - arguments: arguments, + arguments: actualArguments, fileUri: fileUri, fileOffset: offset, ); if (argMessage != null) { + var (List positional, List named) = + argumentsInfo.computeArguments(); return new WrapInProblemInferenceResult( - argMessage, - problemReporting, - compilerContext, + message: argMessage, + problemReporting: problemReporting, + compilerContext: compilerContext, isInapplicable: true, hoistedArguments: localHoistedExpressions, + positional: positional, + named: named, ); } if (isSpecialCasedBinaryOperator) { @@ -2080,7 +2001,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { calleeType, typeSchemaEnvironment.getTypeOfSpecialCasedBinaryOperator( receiverType!, - actualTypes[0], + argumentsInfo[0].actualType, ), ); } else if (isSpecialCasedTernaryOperator) { @@ -2088,127 +2009,55 @@ abstract class InferenceVisitorBase implements InferenceVisitor { calleeType, typeSchemaEnvironment.getTypeOfSpecialCasedTernaryOperator( receiverType!, - actualTypes[0], - actualTypes[1], + argumentsInfo[0].actualType, + argumentsInfo[1].actualType, ), ); } } // Check for and remove duplicated named arguments. - List named = arguments.named; Map seenNames = {}; - bool hasProblem = false; - int namedTypeIndex = arguments.positional.length; - List uniqueNamed = []; - for (int i = 0; i < named.length; i++) { - NamedExpression expression = named[i]; - String name = expression.name; - if (seenNames.containsKey(name)) { - hasProblem = true; - NamedExpression prevNamedExpression = seenNames[name]!; - prevNamedExpression.value = problemReporting.wrapInProblem( - compilerContext: compilerContext, - expression: _createDuplicateExpression( - prevNamedExpression.fileOffset, - prevNamedExpression.value, - expression.value, - ), - message: codeDuplicatedNamedArgument.withArgumentsOld(name), - fileUri: fileUri, - fileOffset: expression.fileOffset, - length: name.length, - )..parent = prevNamedExpression; - formalTypes.removeAt(namedTypeIndex); - actualTypes.removeAt(namedTypeIndex); - } else { - seenNames[name] = expression; - uniqueNamed.add(expression); - namedTypeIndex++; + for (_ArgumentInfo argumentInfo in argumentsInfo) { + Argument argument = argumentInfo.argument; + switch (argument) { + case NamedArgument(): + NamedExpression namedExpression = argument.namedExpression; + String name = namedExpression.name; + if (seenNames.containsKey(name)) { + argumentInfo.isDuplicateNamed = true; + NamedExpression prevNamedExpression = seenNames[name]!; + prevNamedExpression.value = problemReporting.wrapInProblem( + compilerContext: compilerContext, + expression: _createDuplicateExpression( + prevNamedExpression.fileOffset, + prevNamedExpression.value, + namedExpression.value, + ), + message: codeDuplicatedNamedArgument.withArgumentsOld(name), + fileUri: fileUri, + fileOffset: namedExpression.fileOffset, + length: name.length, + )..parent = prevNamedExpression; + } else { + seenNames[name] = namedExpression; + } + case PositionalArgument(): + break; } } - if (hasProblem) { - arguments.named = uniqueNamed; - } - - void forEachArgument( - void Function({ - required DartType actualType, - required DartType expectedType, - required DartType formalType, - required Expression argumentExpression, - required bool coerceExpression, - required NamedExpression? namedArgumentExpression, - required int positionalArgumentIndex, - required int overallArgumentIndex, - }) - argumentHandlingCallback, - ) { - // Argument counts and names match. Compare types. - int positionalIndex = 0; - int namedIndex = 0; - int overallArgumentIndex = 0; - for (int i = 0; i < formalTypes.length; i++) { - DartType formalType = formalTypes[i]; - DartType expectedType = instantiator != null - ? instantiator.substitute(formalType) - : formalType; - DartType actualType = actualTypes[i]; - Expression expression; - NamedExpression? namedExpression; - bool coerceExpression; - Object? argumentInEvaluationOrder = argumentsEvaluationOrder[i]; - if (argumentInEvaluationOrder is Expression) { - expression = arguments.positional[positionalIndex]; - coerceExpression = !arguments.positionalAreSuperParameters; - } else { - namedExpression = arguments.named[namedIndex]; - expression = namedExpression.value; - coerceExpression = - !(arguments.namedSuperParameterNames?.contains( - namedExpression.name, - ) ?? - false); - } - argumentHandlingCallback( - actualType: actualType, - expectedType: expectedType, - formalType: formalType, - argumentExpression: expression, - namedArgumentExpression: namedExpression, - coerceExpression: coerceExpression, - positionalArgumentIndex: positionalIndex, - overallArgumentIndex: overallArgumentIndex, - ); - overallArgumentIndex++; - - if (namedExpression == null) { - positionalIndex++; - } else { - namedIndex++; - } - } - } - - List argumentInferenceResultsToCheck = []; // Before choosing the final types, we perform coercion and feed the // resulting types back into the type inference via constraint generation. - forEachArgument(({ - required DartType actualType, - required DartType expectedType, - required DartType formalType, - required Expression argumentExpression, - required bool coerceExpression, - required NamedExpression? namedArgumentExpression, - required int positionalArgumentIndex, - required int overallArgumentIndex, - }) { + for (_ArgumentInfo paramInfo in argumentsInfo) { ExpressionInferenceResult argumentResult = new ExpressionInferenceResult( - actualType, - argumentExpression, + paramInfo.actualType, + paramInfo.argument.expression, ); - if (coerceExpression) { + if (paramInfo.coerceExpression) { + DartType expectedType = paramInfo.computeInferredFormalType( + instantiator, + ); ExpressionInferenceResult? coercionResult = coerceExpressionForAssignment( expectedType, @@ -2219,25 +2068,18 @@ abstract class InferenceVisitorBase implements InferenceVisitor { if (coercionResult != null) { argumentResult = coercionResult; - argumentExpression = argumentResult.expression; - if (namedArgumentExpression == null) { - arguments.positional[positionalArgumentIndex] = argumentExpression - ..parent = arguments; - } else { - namedArgumentExpression.value = argumentExpression - ..parent = namedArgumentExpression; - } + paramInfo.argument.expression = argumentResult.expression; // Feed the coercion result back to the inference. gatherer?.tryConstrainLower( - formalType, + paramInfo.formalType, argumentResult.inferredType, - treeNodeForTesting: arguments, + treeNodeForTesting: actualArguments, ); } } - argumentInferenceResultsToCheck.add(argumentResult); - }); + paramInfo.argumentInferenceResult = argumentResult; + } if (inferenceNeeded) { inferredTypes = typeSchemaEnvironment.chooseFinalTypes( @@ -2247,7 +2089,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { inferenceUsingBoundsIsEnabled: libraryFeatures.inferenceUsingBounds.isEnabled, dataForTesting: dataForTesting, - treeNodeForTesting: arguments, + treeNodeForTesting: actualArguments, typeOperations: cfeOperations, ); assert( @@ -2264,8 +2106,10 @@ abstract class InferenceVisitorBase implements InferenceVisitor { ); if (dataForTesting != null) { // Coverage-ignore-block(suite): Not run. - assert(arguments.fileOffset != TreeNode.noOffset); - dataForTesting!.typeInferenceResult.inferredTypeArguments[arguments] = + assert(actualArguments.fileOffset != TreeNode.noOffset); + dataForTesting! + .typeInferenceResult + .inferredTypeArguments[actualArguments] = inferredTypes; } } @@ -2273,48 +2117,39 @@ abstract class InferenceVisitorBase implements InferenceVisitor { LocatedMessage? argMessage = problemReporting.checkArgumentsForType( function: calleeType, explicitTypeArguments: typeArguments, - arguments: arguments, + arguments: actualArguments, fileUri: fileUri, fileOffset: offset, ); if (argMessage != null) { + var (List positional, List named) = + argumentsInfo.computeArguments(); return new WrapInProblemInferenceResult( - argMessage, - problemReporting, - compilerContext, + message: argMessage, + problemReporting: problemReporting, + compilerContext: compilerContext, isInapplicable: true, hoistedArguments: localHoistedExpressions, + positional: positional, + named: named, ); } else { - forEachArgument(({ - required DartType actualType, - required DartType expectedType, - required DartType formalType, - required Expression argumentExpression, - required bool coerceExpression, - required NamedExpression? namedArgumentExpression, - required int positionalArgumentIndex, - required int overallArgumentIndex, - }) { - ExpressionInferenceResult? argumentResultToCheck = - argumentInferenceResultsToCheck[overallArgumentIndex]; + for (_ArgumentInfo argumentInfo in argumentsInfo) { + ExpressionInferenceResult argumentResultToCheck = + argumentInfo.argumentInferenceResult!; + DartType expectedType = argumentInfo.computeInferredFormalType( + instantiator, + ); argumentResultToCheck = reportAssignabilityErrors( expectedType, argumentResultToCheck, isVoidAllowed: expectedType is VoidType, - isCoercionAllowed: coerceExpression, + isCoercionAllowed: argumentInfo.coerceExpression, errorTemplate: codeArgumentTypeNotAssignable, ); - argumentExpression = argumentResultToCheck.expression; - if (namedArgumentExpression == null) { - arguments.positional[positionalArgumentIndex] = argumentExpression - ..parent = arguments; - } else { - namedArgumentExpression.value = argumentExpression - ..parent = namedArgumentExpression; - } - }); + argumentInfo.argument.expression = argumentResultToCheck.expression; + } } DartType inferredType; @@ -2330,10 +2165,14 @@ abstract class InferenceVisitorBase implements InferenceVisitor { "Inferred function type: $calleeType.", ); + var (List positional, List named) = + argumentsInfo.computeArguments(); return new SuccessfulInferenceResult( - inferredType, - calleeType, - inferredTypes ?? explicitTypeArguments ?? [], + inferredType: inferredType, + functionType: calleeType, + typeArguments: inferredTypes ?? explicitTypeArguments ?? [], + positional: positional, + named: named, hoistedArguments: localHoistedExpressions, inferredReceiverType: receiverType, ); @@ -2601,13 +2440,15 @@ abstract class InferenceVisitorBase implements InferenceVisitor { annotations[index] = result.expression..parent = annotatable; } - StaticInvocation createExtensionInvocation( - int fileOffset, - ObjectAccessTarget target, - Expression receiver, - List explicitOrInferredTypeArguments, - ArgumentsImpl arguments, - ) { + StaticInvocation createExtensionInvocation({ + required int invocationOffset, + required int argumentsOffset, + required ObjectAccessTarget target, + required Expression receiver, + required List explicitOrInferredTypeArguments, + required List positionalArguments, + required List namedArguments, + }) { assert( target.isExtensionMember || target.isNullableExtensionMember || @@ -2616,17 +2457,17 @@ abstract class InferenceVisitorBase implements InferenceVisitor { ); Procedure procedure = target.member as Procedure; Arguments extensionInvocationArguments = new Arguments( - [receiver, ...arguments.positional], - named: arguments.named, + [receiver, ...positionalArguments], + named: namedArguments, types: [ ...target.receiverTypeArguments, ...explicitOrInferredTypeArguments, ], - )..fileOffset = arguments.fileOffset; + )..fileOffset = argumentsOffset; return createStaticInvocation( procedure, extensionInvocationArguments, - fileOffset: fileOffset, + fileOffset: invocationOffset, ); } @@ -2636,7 +2477,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { Expression receiver, Name name, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, DartType typeContext, List? hoistedExpressions, { required bool isImplicitCall, @@ -2658,7 +2499,12 @@ abstract class InferenceVisitorBase implements InferenceVisitor { DynamicAccessKind.Dynamic, receiver, name, - createArgumentsFromInternalNode(result.typeArguments, arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + arguments, + ), ) ..isImplicitCall = isImplicitCall ..fileOffset = fileOffset; @@ -2675,7 +2521,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { DartType receiverType, Name name, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, DartType typeContext, List? hoistedExpressions, { required bool isImplicitCall, @@ -2696,7 +2542,12 @@ abstract class InferenceVisitorBase implements InferenceVisitor { DynamicAccessKind.Never, receiver, name, - createArgumentsFromInternalNode(result.typeArguments, arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + arguments, + ), )..fileOffset = fileOffset; return new ExpressionInferenceResult( const NeverType.nonNullable(), @@ -2712,7 +2563,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { ObjectAccessTarget target, Name name, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, DartType typeContext, List? hoistedExpressions, { required bool isExpressionInvocation, @@ -2720,19 +2571,6 @@ abstract class InferenceVisitorBase implements InferenceVisitor { Name? implicitInvocationPropertyName, }) { assert(target.isMissing || target.isAmbiguous); - Expression error = createMissingMethodInvocation( - fileOffset, - receiverType, - name, - receiver: receiver, - arguments: createArgumentsFromInternalNode( - typeArguments?.types ?? [], - arguments, - ), - isExpressionInvocation: isExpressionInvocation, - implicitInvocationPropertyName: implicitInvocationPropertyName, - extensionAccessCandidates: target.isAmbiguous ? target.candidates : null, - ); InvocationInferenceResult inferenceResult = inferInvocation( visitor, typeContext, @@ -2744,6 +2582,22 @@ abstract class InferenceVisitorBase implements InferenceVisitor { receiverType: receiverType, isImplicitCall: isExpressionInvocation || isImplicitCall, ); + Expression error = createMissingMethodInvocation( + fileOffset, + receiverType, + name, + receiver: receiver, + arguments: createArgumentsFromInternalNode( + // TODO(johnniwinther): Should these be the inferred type arguments? + typeArguments?.types ?? [], + inferenceResult.positional, + inferenceResult.named, + arguments, + ), + isExpressionInvocation: isExpressionInvocation, + implicitInvocationPropertyName: implicitInvocationPropertyName, + extensionAccessCandidates: target.isAmbiguous ? target.candidates : null, + ); Expression replacementError = inferenceResult.applyResult(error); assert(name != equalsName); // TODO(johnniwinther): Use InvalidType instead. @@ -2758,7 +2612,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { ObjectAccessTarget target, Name name, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, DartType typeContext, List? hoistedExpressions, { required bool isImplicitCall, @@ -2774,11 +2628,13 @@ abstract class InferenceVisitorBase implements InferenceVisitor { if (target.declarationMethodKind == ClassMemberKind.Getter) { StaticInvocation staticInvocation = createExtensionInvocation( - fileOffset, - target, - receiver, - [], - new ArgumentsImpl.empty(), + invocationOffset: fileOffset, + argumentsOffset: fileOffset, + target: target, + receiver: receiver, + explicitOrInferredTypeArguments: [], + positionalArguments: [], + namedArguments: [], ); ExpressionInferenceResult result = inferMethodInvocation( visitor, @@ -2844,11 +2700,13 @@ abstract class InferenceVisitorBase implements InferenceVisitor { ); StaticInvocation staticInvocation = createExtensionInvocation( - fileOffset, - target, - receiver, - result.typeArguments, - arguments, + invocationOffset: fileOffset, + argumentsOffset: arguments.fileOffset, + target: target, + receiver: receiver, + explicitOrInferredTypeArguments: result.typeArguments, + positionalArguments: result.positional, + namedArguments: result.named, ); Expression replacement = result.applyResult( @@ -2914,7 +2772,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { DartType receiverType, ObjectAccessTarget target, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, DartType typeContext, List? hoistedExpressions, { required bool isImplicitCall, @@ -2942,7 +2800,12 @@ abstract class InferenceVisitorBase implements InferenceVisitor { expression = new FunctionInvocation( FunctionAccessKind.Inapplicable, receiver, - createArgumentsFromInternalNode(result.typeArguments, arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + arguments, + ), functionType: null, )..fileOffset = fileOffset; } else if (receiver is VariableGet) { @@ -2956,7 +2819,12 @@ abstract class InferenceVisitorBase implements InferenceVisitor { localName = variable.cosmeticName!; expression = new LocalFunctionInvocation( variable as VariableDeclaration, - createArgumentsFromInternalNode(result.typeArguments, arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + arguments, + ), functionType: inferredFunctionType as FunctionType, )..fileOffset = receiver.fileOffset; } @@ -2966,7 +2834,12 @@ abstract class InferenceVisitorBase implements InferenceVisitor { ? FunctionAccessKind.Nullable : invocationTargetType.functionAccessKind, receiver, - createArgumentsFromInternalNode(result.typeArguments, arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + arguments, + ), functionType: switch (invocationTargetType) { InvocationTargetFunctionType() => inferredFunctionType as FunctionType, _ => null, @@ -3031,20 +2904,52 @@ abstract class InferenceVisitorBase implements InferenceVisitor { } FunctionType _computeFunctionTypeForArguments( - ArgumentsImpl arguments, + ActualArguments arguments, DartType type, ) { return new FunctionType( - new List.filled(arguments.positional.length, type), + new List.filled(arguments.positionalCount, type), type, Nullability.nonNullable, - namedParameters: new List.generate( - arguments.named.length, - (int index) => new NamedType(arguments.named[index].name, type), - ), + namedParameters: arguments.namedCount > 0 + ? arguments.argumentList + .whereType() + .map((a) => new NamedType(a.name, type)) + .toList() + : [], ); } + /// Returns `true` if [arguments] don't apply to [signature]. + /// + /// This is used to determine whether an invocation on `dynamic` matches the + /// resolved target on `Object`. + bool _isInvalidDynamicTarget( + FunctionNode signature, + ActualArguments arguments, + ) { + if (arguments.positionalCount < signature.requiredParameterCount || + arguments.positionalCount > signature.positionalParameters.length) { + return true; + } + if (arguments.namedCount > 0) { + for (Argument argument in arguments.argumentList) { + switch (argument) { + case NamedArgument(): + if (!signature.namedParameters.any( + // Coverage-ignore(suite): Not run. + (declaration) => declaration.name == argument.name, + )) { + return true; + } + case PositionalArgument(): + break; + } + } + } + return false; + } + ExpressionInferenceResult _inferInstanceMethodInvocation( InferenceVisitor visitor, int fileOffset, @@ -3052,7 +2957,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { DartType receiverType, ObjectAccessTarget target, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, DartType typeContext, List? hoistedExpressions, { required bool isImplicitCall, @@ -3072,23 +2977,10 @@ abstract class InferenceVisitorBase implements InferenceVisitor { "Unexpected instance method $method", ); Name methodName = method.name; - - if (receiverType == const DynamicType()) { - FunctionNode signature = method.function; - if (arguments.positional.length < signature.requiredParameterCount || - arguments.positional.length > signature.positionalParameters.length) { - target = const ObjectAccessTarget.dynamic(); - method = null; - } - for (NamedExpression argument in arguments.named) { - if (!signature.namedParameters.any( - // Coverage-ignore(suite): Not run. - (declaration) => declaration.name == argument.name, - )) { - target = const ObjectAccessTarget.dynamic(); - method = null; - } - } + if (receiverType == const DynamicType() && + _isInvalidDynamicTarget(method.function, arguments)) { + target = const ObjectAccessTarget.dynamic(); + method = null; } DartType calleeType = target.getGetterType(this); @@ -3127,7 +3019,12 @@ abstract class InferenceVisitorBase implements InferenceVisitor { DynamicAccessKind.Dynamic, receiver, methodName, - createArgumentsFromInternalNode(result.typeArguments, arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + arguments, + ), ) ..isImplicitCall = isImplicitCall ..fileOffset = fileOffset; @@ -3138,7 +3035,12 @@ abstract class InferenceVisitorBase implements InferenceVisitor { InstanceAccessKind.Inapplicable, receiver, methodName, - createArgumentsFromInternalNode(result.typeArguments, arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + arguments, + ), functionType: _computeFunctionTypeForArguments( arguments, const InvalidType(), @@ -3171,7 +3073,12 @@ abstract class InferenceVisitorBase implements InferenceVisitor { kind, receiver, methodName, - createArgumentsFromInternalNode(result.typeArguments, arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + arguments, + ), functionType: inferredFunctionType as FunctionType, interfaceTarget: method!, )..fileOffset = fileOffset; @@ -3254,7 +3161,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { DartType receiverType, ObjectAccessTarget target, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, DartType typeContext, List? hoistedExpressions, { required bool isExpressionInvocation, @@ -3269,22 +3176,10 @@ abstract class InferenceVisitorBase implements InferenceVisitor { // TODO(johnniwinther): This is inconsistent with the handling below. Remove // this or add handling similar to [_inferMethodInvocation]. - if (receiverType == const DynamicType()) { - FunctionNode signature = getter.function; - if (arguments.positional.length < signature.requiredParameterCount || - arguments.positional.length > signature.positionalParameters.length) { - target = const ObjectAccessTarget.dynamic(); - getter = null; - } - for (NamedExpression argument in arguments.named) { - // Coverage-ignore-block(suite): Not run. - if (!signature.namedParameters.any( - (declaration) => declaration.name == argument.name, - )) { - target = const ObjectAccessTarget.dynamic(); - getter = null; - } - } + if (receiverType == const DynamicType() && + _isInvalidDynamicTarget(getter.function, arguments)) { + target = const ObjectAccessTarget.dynamic(); + getter = null; } DartType calleeType = target.getGetterType(this); @@ -3293,7 +3188,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { if (hoistedExpressions == null) { hoistedExpressions = locallyHoistedExpressions = []; } - if (arguments.positional.isNotEmpty || arguments.named.isNotEmpty) { + if (arguments.positionalCount > 0 || arguments.namedCount > 0) { receiver = _hoist(receiver, receiverType, hoistedExpressions); } @@ -3482,7 +3377,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { DartType receiverType, ObjectAccessTarget target, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, DartType typeContext, List? hoistedExpressions, { required bool isExpressionInvocation, @@ -3501,7 +3396,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { if (hoistedExpressions == null) { hoistedExpressions = locallyHoistedExpressions = []; } - if (arguments.positional.isNotEmpty || arguments.named.isNotEmpty) { + if (arguments.positionalCount > 0 || arguments.namedCount > 0) { receiver = _hoist(receiver, receiverType, hoistedExpressions); } @@ -3693,7 +3588,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { DartType receiverType, Name name, TypeArguments? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, DartType typeContext, { required bool isExpressionInvocation, required bool isImplicitCall, @@ -4012,7 +3907,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { DartType calleeType, Name methodName, List typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, int fileOffset, { required bool hasInferredTypeArguments, }) { @@ -4080,7 +3975,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { FunctionType functionType, String? localName, List explicitOrInferredTypeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, int fileOffset, { required bool hasInferredTypeArguments, }) { @@ -4104,7 +3999,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { InferenceVisitor visitor, { required Name name, required TypeArguments? typeArguments, - required ArgumentsImpl arguments, + required ActualArguments arguments, required DartType typeContext, required Procedure procedure, required int fileOffset, @@ -4177,7 +4072,12 @@ abstract class InferenceVisitorBase implements InferenceVisitor { createSuperMethodInvocation( name, procedure, - createArgumentsFromInternalNode(result.typeArguments, arguments), + createArgumentsFromInternalNode( + result.typeArguments, + result.positional, + result.named, + arguments, + ), fileOffset: fileOffset, ), ), @@ -5553,9 +5453,6 @@ abstract class InferenceVisitorBase implements InferenceVisitor { } } - DartType _computeInferredType(ExpressionInferenceResult result) => - result.inferredType; - Expression? checkWebIntLiteralsErrorIfUnexact( int value, String? literal, @@ -5595,9 +5492,15 @@ abstract class InferenceVisitorBase implements InferenceVisitor { /// This records the relation which data for testing. Arguments createArgumentsFromInternalNode( List typeArguments, - ArgumentsImpl node, + List positionalArguments, + List namedArguments, + ActualArguments node, ) { - Arguments arguments = node.toArguments(typeArguments); + Arguments arguments = node.toArguments( + typeArguments, + positionalArguments, + namedArguments, + ); if (dataForTesting != null) { // Coverage-ignore-block(suite): Not run. dataForTesting!.externalToInternalNodeMap[arguments] = node; @@ -5882,33 +5785,20 @@ class ImplicitInstantiation { /// Information about an invocation argument that needs to be resolved later due /// to the fact that it's a function literal and the `inference-update-1` /// feature is enabled. -class _DeferredParamInfo extends _ParamInfo { - /// The argument expression (possibly wrapped in an arbitrary number of - /// ParenthesizedExpressions). - final Expression argumentExpression; - +class _DeferredArgumentInfo extends _ArgumentInfo { /// The unparenthesized argument expression. final FunctionExpression unparenthesizedExpression; - /// Indicates whether this is a named argument. - final bool isNamed; - - /// The index into the full argument list (considering both named and unnamed - /// arguments) of the function literal expression. - final int evaluationOrderIndex; - - /// The index into either [Arguments.named] or [Arguments.positional] of the - /// function literal expression (depending upon the value of [isNamed]). - final int index; - - _DeferredParamInfo({ - required DartType formalType, - required this.argumentExpression, + _DeferredArgumentInfo({ + required super.argument, + required super.formalType, required this.unparenthesizedExpression, - required this.isNamed, - required this.evaluationOrderIndex, - required this.index, - }) : super(formalType); + }); + + // Coverage-ignore(suite): Not run. + /// The argument expression (possibly wrapped in an arbitrary number of + /// ParenthesizedExpressions). + Expression get argumentExpression => argument.expression; } /// Extension of the shared [FunctionLiteralDependencies] logic used by the @@ -5917,26 +5807,24 @@ class _FunctionLiteralDependencies extends FunctionLiteralDependencies< StructuralParameter, - _ParamInfo, - _DeferredParamInfo + _ArgumentInfo, + _DeferredArgumentInfo > { _FunctionLiteralDependencies( - Iterable<_DeferredParamInfo> deferredParamInfo, + Iterable<_DeferredArgumentInfo> deferredParamInfo, Iterable typeParameters, - List<_ParamInfo> undeferredParamInfo, + List<_ArgumentInfo> undeferredParamInfo, ) : super(deferredParamInfo, typeParameters, undeferredParamInfo); @override Iterable typeVarsFreeInParamParams( - _DeferredParamInfo paramInfo, + _DeferredArgumentInfo param, ) { - DartType type = paramInfo.formalType; + DartType type = param.formalType; if (type is FunctionType) { Map parameterMap = _computeParameterMap(type); Set explicitlyTypedParameters = - _computeExplicitlyTypedParameterSet( - paramInfo.unparenthesizedExpression, - ); + _computeExplicitlyTypedParameterSet(param.unparenthesizedExpression); Set result = {}; for (MapEntry entry in parameterMap.entries) { if (explicitlyTypedParameters.contains(entry.key)) continue; @@ -5950,9 +5838,9 @@ class _FunctionLiteralDependencies @override Iterable typeVarsFreeInParamReturns( - _ParamInfo paramInfo, + _ArgumentInfo param, ) { - DartType type = paramInfo.formalType; + DartType type = param.formalType; if (type is FunctionType) { return allFreeTypeParameters(type.returnType); } else { @@ -5962,14 +5850,68 @@ class _FunctionLiteralDependencies } /// Information about an invocation argument that may or may not have already -/// been resolved, as part of the deferred resolution mechanism for the -/// `inference-update-1` feature. -class _ParamInfo { +/// been resolved. +class _ArgumentInfo { + /// The actual argument. + final Argument argument; + /// The (unsubstituted) type of the formal parameter corresponding to this /// argument. final DartType formalType; - _ParamInfo(this.formalType); + /// The actual type of the argument. + /// + /// Initially we don't have an inferred type, so we fill it in with + /// [UnknownType]. Later, when we infer a type, we'll replace it. + DartType actualType = const UnknownType(); + + /// The (substituted) type of the formal parameter corresponding to this + /// argument. + DartType computeInferredFormalType(FunctionTypeInstantiator? instantiator) => + instantiator != null ? instantiator.substitute(formalType) : formalType; + + /// If this is an argument to a call to `identical`, this will hold the + /// flow analysis information computed during inference. + ExpressionInfo? identicalInfo; + + /// The holds the possibly coerced result of the inference. + /// + /// This is used to check the argument for assignability. + ExpressionInferenceResult? argumentInferenceResult; + + /// Set to `true` if this argument is a duplicate named argument. + /// + /// If `true`, the argument is not included in the output AST. + bool isDuplicateNamed = false; + + _ArgumentInfo({required this.argument, required this.formalType}); + + /// Indicates whether this is a named argument. + bool get isNamed => argument is NamedArgument; + + /// Returns `true` if the argument expression should be coerced. + bool get coerceExpression => !argument.isSuperParameter; +} + +extension on List<_ArgumentInfo> { + (List positional, List named) + computeArguments() { + List positional = []; + List named = []; + for (_ArgumentInfo argumentInfo in this) { + if (argumentInfo.isDuplicateNamed) { + continue; + } + Argument argument = argumentInfo.argument; + switch (argument) { + case PositionalArgument(): + positional.add(argument.expression); + case NamedArgument(): + named.add(argument.namedExpression); + } + } + return (positional, named); + } } class _ObjectAccessDescriptor { diff --git a/pkg/front_end/lib/src/type_inference/object_access_target.dart b/pkg/front_end/lib/src/type_inference/object_access_target.dart index aec83812618..4d185a7fffd 100644 --- a/pkg/front_end/lib/src/type_inference/object_access_target.dart +++ b/pkg/front_end/lib/src/type_inference/object_access_target.dart @@ -142,7 +142,7 @@ sealed class InvocationTargetType { /// [typeArguments] and [arguments]. FunctionType computeFunctionTypeForInference( List? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, ); } @@ -191,7 +191,7 @@ class InvocationTargetFunctionType extends InvocationTargetType { @override FunctionType computeFunctionTypeForInference( List? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, ) { return functionType; } @@ -285,19 +285,18 @@ sealed class InvocationTargetNonFunctionType extends InvocationTargetType { @override FunctionType computeFunctionTypeForInference( List? typeArguments, - ArgumentsImpl arguments, + ActualArguments arguments, ) { return new FunctionType( - new List.filled( - arguments.positional.length, - const DynamicType(), - ), + new List.filled(arguments.positionalCount, const DynamicType()), this.returnType, Nullability.nonNullable, - namedParameters: [ - for (NamedExpression namedExpression in arguments.named) - new NamedType(namedExpression.name, const DynamicType()), - ], + namedParameters: arguments.namedCount > 0 + ? arguments.argumentList + .whereType() + .map((a) => new NamedType(a.name, const DynamicType())) + .toList() + : [], typeParameters: [ if (typeArguments != null) for (DartType _ in typeArguments) diff --git a/pkg/front_end/lib/src/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/type_inference/type_inferrer.dart index 89aa18b85f5..32f8ef70ed5 100644 --- a/pkg/front_end/lib/src/type_inference/type_inferrer.dart +++ b/pkg/front_end/lib/src/type_inference/type_inferrer.dart @@ -269,7 +269,8 @@ class TypeInferrerImpl implements TypeInferrer { required FunctionType targetType, }) { InferenceVisitorBase visitor = _createInferenceVisitor(fileUri: fileUri); - List positionalArguments = []; + List arguments = []; + int positionalCount = 0; for (VariableDeclaration parameter in redirectingFactoryFunction.positionalParameters) { flowAnalysis.declare( @@ -277,9 +278,10 @@ class TypeInferrerImpl implements TypeInferrer { new SharedTypeView(parameter.type), initialized: true, ); - positionalArguments.add(new VariableGet(parameter)); + Expression variableGet = new VariableGet(parameter); + arguments.add(new PositionalArgument(variableGet)); + positionalCount++; } - List namedArguments = []; for (VariableDeclaration parameter in redirectingFactoryFunction.namedParameters) { flowAnalysis.declare( @@ -287,15 +289,18 @@ class TypeInferrerImpl implements TypeInferrer { new SharedTypeView(parameter.type), initialized: true, ); - namedArguments.add( - new NamedExpression(parameter.name!, new VariableGet(parameter)), + NamedExpression namedExpression = new NamedExpression( + parameter.name!, + new VariableGet(parameter), ); + arguments.add(new NamedArgument(namedExpression)); } // If arguments are created using [ArgumentsImpl], and the // type arguments are omitted, they are to be inferred. - ArgumentsImpl targetInvocationArguments = new ArgumentsImpl( - positionalArguments, - named: namedArguments, + ActualArguments targetInvocationArguments = new ActualArguments( + argumentList: arguments, + hasNamedBeforePositional: false, + positionalCount: positionalCount, )..fileOffset = fileOffset; InvocationInferenceResult result = visitor.inferInvocation( diff --git a/pkg/front_end/test/compile_and_lint_impl.dart b/pkg/front_end/test/compile_and_lint_impl.dart index 86024c267c4..4b323c3d209 100644 --- a/pkg/front_end/test/compile_and_lint_impl.dart +++ b/pkg/front_end/test/compile_and_lint_impl.dart @@ -246,7 +246,7 @@ mixin BodyBuilderTestMixin on BodyBuilderImpl { TypeDeclarationBuilder? type, Token nameToken, Token nameLastToken, - ArgumentsImpl arguments, + ActualArguments arguments, String name, List? typeArgumentBuilders, TypeArguments? typeArguments, diff --git a/pkg/front_end/test/generator_to_string_test.dart b/pkg/front_end/test/generator_to_string_test.dart index 8e88567d04a..3dee0975f0b 100644 --- a/pkg/front_end/test/generator_to_string_test.dart +++ b/pkg/front_end/test/generator_to_string_test.dart @@ -76,7 +76,12 @@ Future main() async { CoreTypes coreTypes = new CoreTypes(component); ClassHierarchy hierarchy = new ClassHierarchy(component, coreTypes); - ArgumentsImpl arguments = new ArgumentsImpl([new StringLiteral("arg")]); + Expression argument = new StringLiteral("arg"); + ActualArguments arguments = new ActualArguments( + argumentList: [new PositionalArgument(argument)], + hasNamedBeforePositional: false, + positionalCount: 1, + ); Expression expression = new VariableGet( new VariableDeclaration("expression"), ); diff --git a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart index 51d97f0f4dd..bd1e9fc462f 100644 --- a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart +++ b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart @@ -648,7 +648,7 @@ void _testFactoryConstructorInvocation() { new FactoryConstructorInvocation( factoryConstructor, null, - new ArgumentsImpl([]), + new ActualArguments.empty(), isConst: false, ), ''' @@ -661,7 +661,7 @@ new library test:dummy::Class()''', new FactoryConstructorInvocation( factoryConstructor, null, - new ArgumentsImpl([]), + new ActualArguments.empty(), isConst: true, ), ''' @@ -670,13 +670,20 @@ const Class()''', const library test:dummy::Class()''', ); + Expression positionalArgument = new IntLiteral(0); + NamedExpression namedArgument = new NamedExpression('bar', new IntLiteral(1)); + testExpression( new FactoryConstructorInvocation( factoryConstructor, new TypeArguments([const VoidType()]), - new ArgumentsImpl( - [new IntLiteral(0)], - named: [new NamedExpression('bar', new IntLiteral(1))], + new ActualArguments( + argumentList: [ + new PositionalArgument(positionalArgument), + new NamedArgument(namedArgument), + ], + hasNamedBeforePositional: false, + positionalCount: 1, ), isConst: false, ), @@ -691,9 +698,13 @@ new library test:dummy::Class(0, bar: 1)''', new FactoryConstructorInvocation( factoryConstructor, new TypeArguments([const VoidType()]), - new ArgumentsImpl( - [new IntLiteral(0)], - named: [new NamedExpression('bar', new IntLiteral(1))], + new ActualArguments( + argumentList: [ + new PositionalArgument(positionalArgument), + new NamedArgument(namedArgument), + ], + hasNamedBeforePositional: false, + positionalCount: 1, ), isConst: false, ), @@ -746,7 +757,7 @@ void _testTypeAliasedConstructorInvocation(CompilerContext c) { typeAliasBuilder, constructor, null, - new ArgumentsImpl([]), + new ActualArguments.empty(), ), ''' new Typedef()''', @@ -754,14 +765,21 @@ new Typedef()''', new library test:dummy::Typedef()''', ); + Expression positionalArgument = new IntLiteral(0); + NamedExpression namedArgument = new NamedExpression('bar', new IntLiteral(1)); + testExpression( new TypeAliasedConstructorInvocation( typeAliasBuilder, constructor, new TypeArguments([const VoidType()]), - new ArgumentsImpl( - [new IntLiteral(0)], - named: [new NamedExpression('bar', new IntLiteral(1))], + new ActualArguments( + argumentList: [ + new PositionalArgument(positionalArgument), + new NamedArgument(namedArgument), + ], + hasNamedBeforePositional: false, + positionalCount: 1, ), ), ''' @@ -776,9 +794,13 @@ new library test:dummy::Typedef(0, bar: 1)''', typeAliasBuilder, constructor, new TypeArguments([const VoidType()]), - new ArgumentsImpl( - [new IntLiteral(0)], - named: [new NamedExpression('bar', new IntLiteral(1))], + new ActualArguments( + argumentList: [ + new PositionalArgument(positionalArgument), + new NamedArgument(namedArgument), + ], + hasNamedBeforePositional: false, + positionalCount: 1, ), ), ''' @@ -793,9 +815,13 @@ new library test:dummy::Typedef.foo(0, bar: 1)''', typeAliasBuilder, constructor, new TypeArguments([const VoidType()]), - new ArgumentsImpl( - [new IntLiteral(0)], - named: [new NamedExpression('bar', new IntLiteral(1))], + new ActualArguments( + argumentList: [ + new PositionalArgument(positionalArgument), + new NamedArgument(namedArgument), + ], + hasNamedBeforePositional: false, + positionalCount: 1, ), isConst: true, ), @@ -849,7 +875,7 @@ void _testTypeAliasedFactoryInvocation(CompilerContext c) { typeAliasBuilder, factoryConstructor, null, - new ArgumentsImpl([]), + new ActualArguments.empty(), isConst: false, ), ''' @@ -858,14 +884,21 @@ new Typedef()''', new library test:dummy::Typedef()''', ); + Expression positionalArgument = new IntLiteral(0); + NamedExpression namedArgument = new NamedExpression('bar', new IntLiteral(1)); + testExpression( new TypeAliasedFactoryInvocation( typeAliasBuilder, factoryConstructor, new TypeArguments([const VoidType()]), - new ArgumentsImpl( - [new IntLiteral(0)], - named: [new NamedExpression('bar', new IntLiteral(1))], + new ActualArguments( + argumentList: [ + new PositionalArgument(positionalArgument), + new NamedArgument(namedArgument), + ], + hasNamedBeforePositional: false, + positionalCount: 1, ), isConst: false, ), @@ -881,9 +914,13 @@ new library test:dummy::Typedef(0, bar: 1)''', typeAliasBuilder, factoryConstructor, new TypeArguments([const VoidType()]), - new ArgumentsImpl( - [new IntLiteral(0)], - named: [new NamedExpression('bar', new IntLiteral(1))], + new ActualArguments( + argumentList: [ + new PositionalArgument(positionalArgument), + new NamedArgument(namedArgument), + ], + hasNamedBeforePositional: false, + positionalCount: 1, ), isConst: false, ), @@ -899,9 +936,13 @@ new library test:dummy::Typedef.foo(0, bar: 1)''', typeAliasBuilder, factoryConstructor, new TypeArguments([const VoidType()]), - new ArgumentsImpl( - [new IntLiteral(0)], - named: [new NamedExpression('bar', new IntLiteral(1))], + new ActualArguments( + argumentList: [ + new PositionalArgument(positionalArgument), + new NamedArgument(namedArgument), + ], + hasNamedBeforePositional: false, + positionalCount: 1, ), isConst: true, ), @@ -943,23 +984,36 @@ void _testInternalMethodInvocation() { new IntLiteral(0), new Name('boz'), null, - new ArgumentsImpl([]), + new ActualArguments.empty(), isNullAware: false, ), ''' 0.boz()''', ); + + Expression positionalArgument = new IntLiteral(1); + NamedExpression namedArgument1 = new NamedExpression( + 'foo', + new IntLiteral(2), + ); + NamedExpression namedArgument2 = new NamedExpression( + 'bar', + new IntLiteral(3), + ); + testExpression( new MethodInvocation( new IntLiteral(0), new Name('boz'), new TypeArguments([const VoidType(), const DynamicType()]), - new ArgumentsImpl( - [new IntLiteral(1)], - named: [ - new NamedExpression('foo', new IntLiteral(2)), - new NamedExpression('bar', new IntLiteral(3)), + new ActualArguments( + argumentList: [ + new PositionalArgument(positionalArgument), + new NamedArgument(namedArgument1), + new NamedArgument(namedArgument2), ], + hasNamedBeforePositional: false, + positionalCount: 1, ), isNullAware: false, ), @@ -971,7 +1025,7 @@ void _testInternalMethodInvocation() { new IntLiteral(0), new Name('boz'), null, - new ArgumentsImpl([]), + new ActualArguments.empty(), isNullAware: true, ), ''' @@ -982,12 +1036,14 @@ void _testInternalMethodInvocation() { new IntLiteral(0), new Name('boz'), new TypeArguments([const VoidType(), const DynamicType()]), - new ArgumentsImpl( - [new IntLiteral(1)], - named: [ - new NamedExpression('foo', new IntLiteral(2)), - new NamedExpression('bar', new IntLiteral(3)), + new ActualArguments( + argumentList: [ + new PositionalArgument(positionalArgument), + new NamedArgument(namedArgument1), + new NamedArgument(namedArgument2), ], + hasNamedBeforePositional: false, + positionalCount: 1, ), isNullAware: true, ), @@ -1040,20 +1096,37 @@ void _testPropertySet() { void _testExpressionInvocation() { testExpression( - new ExpressionInvocation(new IntLiteral(0), null, new ArgumentsImpl([])), + new ExpressionInvocation( + new IntLiteral(0), + null, + new ActualArguments.empty(), + ), ''' 0()''', ); + + Expression positionalArgument = new IntLiteral(1); + NamedExpression namedArgument1 = new NamedExpression( + 'foo', + new IntLiteral(2), + ); + NamedExpression namedArgument2 = new NamedExpression( + 'bar', + new IntLiteral(3), + ); + testExpression( new ExpressionInvocation( new IntLiteral(0), new TypeArguments([const VoidType(), const DynamicType()]), - new ArgumentsImpl( - [new IntLiteral(1)], - named: [ - new NamedExpression('foo', new IntLiteral(2)), - new NamedExpression('bar', new IntLiteral(3)), + new ActualArguments( + argumentList: [ + new PositionalArgument(positionalArgument), + new NamedArgument(namedArgument1), + new NamedArgument(namedArgument2), ], + hasNamedBeforePositional: false, + positionalCount: 1, ), ), ''' @@ -1067,7 +1140,7 @@ void _testMethodInvocation() { new IntLiteral(0), new Name('foo'), null, - new ArgumentsImpl([]), + new ActualArguments.empty(), isNullAware: false, ), ''' @@ -1079,7 +1152,7 @@ void _testMethodInvocation() { new IntLiteral(0), new Name('foo'), null, - new ArgumentsImpl([]), + new ActualArguments.empty(), isNullAware: true, ), ''' @@ -1155,10 +1228,23 @@ void _testLoadLibraryImpl() { library, 'pre', ); - testExpression(new LoadLibraryImpl(dependency, new ArgumentsImpl([])), ''' -pre.loadLibrary()'''); testExpression( - new LoadLibraryImpl(dependency, new ArgumentsImpl([new IntLiteral(0)])), + new LoadLibraryImpl(dependency, new ActualArguments.empty()), + ''' +pre.loadLibrary()''', + ); + + Expression positionalArgument = new IntLiteral(0); + + testExpression( + new LoadLibraryImpl( + dependency, + new ActualArguments( + argumentList: [new PositionalArgument(positionalArgument)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), + ), ''' pre.loadLibrary(0)''', ); @@ -2645,6 +2731,8 @@ void _testExtensionGetterInvocation() { ); library.addProcedure(method); + Expression positionalArgument = new IntLiteral(1); + testExpression( new ExtensionGetterInvocation.explicit( extension: extension, @@ -2654,7 +2742,11 @@ void _testExtensionGetterInvocation() { name: name, target: method, typeArguments: null, - arguments: new ArgumentsImpl([new IntLiteral(1)]), + arguments: new ActualArguments( + argumentList: [new PositionalArgument(positionalArgument)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), isNullAware: false, ), ''' @@ -2670,7 +2762,11 @@ Extension(0).foo(1)''', name: name, target: method, typeArguments: null, - arguments: new ArgumentsImpl([new IntLiteral(1)]), + arguments: new ActualArguments( + argumentList: [new PositionalArgument(positionalArgument)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), isNullAware: true, ), ''' @@ -2686,7 +2782,11 @@ Extension(0)?.foo(1)''', name: name, target: method, typeArguments: null, - arguments: new ArgumentsImpl([new IntLiteral(1)]), + arguments: new ActualArguments( + argumentList: [new PositionalArgument(positionalArgument)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), isNullAware: false, ), ''' @@ -2702,7 +2802,11 @@ Extension(0).foo(1)''', name: name, target: method, typeArguments: null, - arguments: new ArgumentsImpl([new IntLiteral(1)]), + arguments: new ActualArguments( + argumentList: [new PositionalArgument(positionalArgument)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), isNullAware: true, ), ''' @@ -2722,7 +2826,11 @@ Extension(0)?.foo(1)''', name: name, target: method, typeArguments: null, - arguments: new ArgumentsImpl([new IntLiteral(1)]), + arguments: new ActualArguments( + argumentList: [new PositionalArgument(positionalArgument)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), ), ''' 0.foo(1)''', @@ -2746,6 +2854,8 @@ void _testExtensionMethodInvocation() { ); library.addProcedure(method); + Expression positionalArgument = new IntLiteral(1); + testExpression( new ExtensionMethodInvocation.explicit( extension: extension, @@ -2755,7 +2865,11 @@ void _testExtensionMethodInvocation() { name: name, target: method, typeArguments: null, - arguments: new ArgumentsImpl([new IntLiteral(1)]), + arguments: new ActualArguments( + argumentList: [new PositionalArgument(positionalArgument)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), isNullAware: false, ), ''' @@ -2771,7 +2885,11 @@ Extension(0).foo(1)''', name: name, target: method, typeArguments: null, - arguments: new ArgumentsImpl([new IntLiteral(1)]), + arguments: new ActualArguments( + argumentList: [new PositionalArgument(positionalArgument)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), isNullAware: true, ), ''' @@ -2787,7 +2905,11 @@ Extension(0)?.foo(1)''', name: name, target: method, typeArguments: null, - arguments: new ArgumentsImpl([new IntLiteral(1)]), + arguments: new ActualArguments( + argumentList: [new PositionalArgument(positionalArgument)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), isNullAware: false, ), ''' @@ -2803,7 +2925,11 @@ Extension(0).foo(1)''', name: name, target: method, typeArguments: null, - arguments: new ArgumentsImpl([new IntLiteral(1)]), + arguments: new ActualArguments( + argumentList: [new PositionalArgument(positionalArgument)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), isNullAware: true, ), ''' @@ -2823,7 +2949,11 @@ Extension(0)?.foo(1)''', name: name, target: method, typeArguments: null, - arguments: new ArgumentsImpl([new IntLiteral(1)]), + arguments: new ActualArguments( + argumentList: [new PositionalArgument(positionalArgument)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), ), ''' 0.foo(1)''', @@ -3533,16 +3663,22 @@ void _testExtensionTypeRedirectingInitializer() { testInitializer( new ExtensionTypeRedirectingInitializer( unnamedTarget, - new ArgumentsImpl([]), + new ActualArguments.empty(), ), ''' this()''', ); + Expression positionalArgument = new IntLiteral(0); + testInitializer( new ExtensionTypeRedirectingInitializer( namedTarget, - new ArgumentsImpl([new IntLiteral(0)]), + new ActualArguments( + argumentList: [new PositionalArgument(positionalArgument)], + hasNamedBeforePositional: false, + positionalCount: 1, + ), ), ''' this.named(0)''', diff --git a/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.strong.expect b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.strong.expect index bcccf7de97c..7c30018623a 100644 --- a/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.strong.expect +++ b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.strong.expect @@ -9,7 +9,7 @@ class Super extends core::Object { } class SubNamed extends self::Super { constructor namedAnywhere(core::double x, core::String z, {core::bool y = #C1}) → self::SubNamed - : final core::String #t1 = z, final core::bool #t2 = y, super self::Super::named(x, z: #t1, y: #t2) + : final core::bool #t1 = y, final core::String #t2 = z, super self::Super::named(x, y: #t1, z: #t2) ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.strong.modular.expect b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.strong.modular.expect index bcccf7de97c..7c30018623a 100644 --- a/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.strong.modular.expect +++ b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.strong.modular.expect @@ -9,7 +9,7 @@ class Super extends core::Object { } class SubNamed extends self::Super { constructor namedAnywhere(core::double x, core::String z, {core::bool y = #C1}) → self::SubNamed - : final core::String #t1 = z, final core::bool #t2 = y, super self::Super::named(x, z: #t1, y: #t2) + : final core::bool #t1 = y, final core::String #t2 = z, super self::Super::named(x, y: #t1, z: #t2) ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.strong.transformed.expect b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.strong.transformed.expect index bcccf7de97c..7c30018623a 100644 --- a/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.strong.transformed.expect @@ -9,7 +9,7 @@ class Super extends core::Object { } class SubNamed extends self::Super { constructor namedAnywhere(core::double x, core::String z, {core::bool y = #C1}) → self::SubNamed - : final core::String #t1 = z, final core::bool #t2 = y, super self::Super::named(x, z: #t1, y: #t2) + : final core::bool #t1 = y, final core::String #t2 = z, super self::Super::named(x, y: #t1, z: #t2) ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/trailing_comma1.dart.strong.expect b/pkg/front_end/testcases/general/trailing_comma1.dart.strong.expect index aa98364edfc..0177b9978e1 100644 --- a/pkg/front_end/testcases/general/trailing_comma1.dart.strong.expect +++ b/pkg/front_end/testcases/general/trailing_comma1.dart.strong.expect @@ -20,12 +20,9 @@ library; // c.instance2(z:z,,); // ^ // -// pkg/front_end/testcases/general/trailing_comma1.dart:19:16: Error: No named parameter with the name '#1'. +// pkg/front_end/testcases/general/trailing_comma1.dart:19:16: Error: Too many positional arguments: 0 allowed, but 1 found. +// Try removing the extra positional arguments. // c.instance1(z:z,,); -// ^^ -// -// pkg/front_end/testcases/general/trailing_comma1.dart:20:16: Error: Too few positional arguments: 1 required, 0 given. -// c.instance2(z:z,,); // ^ // import self as self; @@ -43,16 +40,15 @@ class Bad extends core::Object { : super core::Object::•() ; method method() → dynamic { - invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:19:16: Error: No named parameter with the name '#1'. + let final core::int #t1 = self::z in invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:19:16: Error: Too many positional arguments: 0 allowed, but 1 found. +Try removing the extra positional arguments. c.instance1(z:z,,); - ^^" in self::c.{self::C::instance1}{}.(z: self::z, #1: invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:19:21: Error: Expected named argument. + ^" in self::c.{self::C::instance1}{}.(invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:19:21: Error: This couldn't be parsed. c.instance1(z:z,,); - ^"){({z: invalid-type, #1: invalid-type}) → invalid-type}; - invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:20:16: Error: Too few positional arguments: 1 required, 0 given. + ^", z: #t1){(invalid-type, {z: invalid-type}) → invalid-type}; + let final self::C #t2 = self::c in let final core::int #t3 = self::z in #t2.{self::C::instance2}(invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:20:21: Error: This couldn't be parsed. c.instance2(z:z,,); - ^" in self::c.{self::C::instance2}{}.(z: self::z, #1: invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:20:21: Error: Expected named argument. - c.instance2(z:z,,); - ^"){({z: invalid-type, #1: invalid-type}) → invalid-type}; + ^", z: #t3){(dynamic, {z: dynamic}) → void}; } } static field self::C c = new self::C::•(); diff --git a/pkg/front_end/testcases/general/trailing_comma1.dart.strong.modular.expect b/pkg/front_end/testcases/general/trailing_comma1.dart.strong.modular.expect index aa98364edfc..0177b9978e1 100644 --- a/pkg/front_end/testcases/general/trailing_comma1.dart.strong.modular.expect +++ b/pkg/front_end/testcases/general/trailing_comma1.dart.strong.modular.expect @@ -20,12 +20,9 @@ library; // c.instance2(z:z,,); // ^ // -// pkg/front_end/testcases/general/trailing_comma1.dart:19:16: Error: No named parameter with the name '#1'. +// pkg/front_end/testcases/general/trailing_comma1.dart:19:16: Error: Too many positional arguments: 0 allowed, but 1 found. +// Try removing the extra positional arguments. // c.instance1(z:z,,); -// ^^ -// -// pkg/front_end/testcases/general/trailing_comma1.dart:20:16: Error: Too few positional arguments: 1 required, 0 given. -// c.instance2(z:z,,); // ^ // import self as self; @@ -43,16 +40,15 @@ class Bad extends core::Object { : super core::Object::•() ; method method() → dynamic { - invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:19:16: Error: No named parameter with the name '#1'. + let final core::int #t1 = self::z in invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:19:16: Error: Too many positional arguments: 0 allowed, but 1 found. +Try removing the extra positional arguments. c.instance1(z:z,,); - ^^" in self::c.{self::C::instance1}{}.(z: self::z, #1: invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:19:21: Error: Expected named argument. + ^" in self::c.{self::C::instance1}{}.(invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:19:21: Error: This couldn't be parsed. c.instance1(z:z,,); - ^"){({z: invalid-type, #1: invalid-type}) → invalid-type}; - invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:20:16: Error: Too few positional arguments: 1 required, 0 given. + ^", z: #t1){(invalid-type, {z: invalid-type}) → invalid-type}; + let final self::C #t2 = self::c in let final core::int #t3 = self::z in #t2.{self::C::instance2}(invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:20:21: Error: This couldn't be parsed. c.instance2(z:z,,); - ^" in self::c.{self::C::instance2}{}.(z: self::z, #1: invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:20:21: Error: Expected named argument. - c.instance2(z:z,,); - ^"){({z: invalid-type, #1: invalid-type}) → invalid-type}; + ^", z: #t3){(dynamic, {z: dynamic}) → void}; } } static field self::C c = new self::C::•(); diff --git a/pkg/front_end/testcases/general/trailing_comma1.dart.strong.transformed.expect b/pkg/front_end/testcases/general/trailing_comma1.dart.strong.transformed.expect index aa98364edfc..0177b9978e1 100644 --- a/pkg/front_end/testcases/general/trailing_comma1.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/general/trailing_comma1.dart.strong.transformed.expect @@ -20,12 +20,9 @@ library; // c.instance2(z:z,,); // ^ // -// pkg/front_end/testcases/general/trailing_comma1.dart:19:16: Error: No named parameter with the name '#1'. +// pkg/front_end/testcases/general/trailing_comma1.dart:19:16: Error: Too many positional arguments: 0 allowed, but 1 found. +// Try removing the extra positional arguments. // c.instance1(z:z,,); -// ^^ -// -// pkg/front_end/testcases/general/trailing_comma1.dart:20:16: Error: Too few positional arguments: 1 required, 0 given. -// c.instance2(z:z,,); // ^ // import self as self; @@ -43,16 +40,15 @@ class Bad extends core::Object { : super core::Object::•() ; method method() → dynamic { - invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:19:16: Error: No named parameter with the name '#1'. + let final core::int #t1 = self::z in invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:19:16: Error: Too many positional arguments: 0 allowed, but 1 found. +Try removing the extra positional arguments. c.instance1(z:z,,); - ^^" in self::c.{self::C::instance1}{}.(z: self::z, #1: invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:19:21: Error: Expected named argument. + ^" in self::c.{self::C::instance1}{}.(invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:19:21: Error: This couldn't be parsed. c.instance1(z:z,,); - ^"){({z: invalid-type, #1: invalid-type}) → invalid-type}; - invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:20:16: Error: Too few positional arguments: 1 required, 0 given. + ^", z: #t1){(invalid-type, {z: invalid-type}) → invalid-type}; + let final self::C #t2 = self::c in let final core::int #t3 = self::z in #t2.{self::C::instance2}(invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:20:21: Error: This couldn't be parsed. c.instance2(z:z,,); - ^" in self::c.{self::C::instance2}{}.(z: self::z, #1: invalid-expression "pkg/front_end/testcases/general/trailing_comma1.dart:20:21: Error: Expected named argument. - c.instance2(z:z,,); - ^"){({z: invalid-type, #1: invalid-type}) → invalid-type}; + ^", z: #t3){(dynamic, {z: dynamic}) → void}; } } static field self::C c = new self::C::•(); diff --git a/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.expect b/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.expect index f5966cc8062..f99a28585a3 100644 --- a/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.expect +++ b/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.expect @@ -42,10 +42,10 @@ class A1 extends core::Object { } class B1 extends self::A1 { constructor foo({dynamic x = #C1}) → self::B1 - : super self::A1::•(y: new self::Test::foo(), x: x) + : super self::A1::•(x: x, y: new self::Test::foo()) ; constructor bar({dynamic x = #C1}) → self::B1 - : super self::A1::•(y: self::Test::bar(), x: x) + : super self::A1::•(x: x, y: self::Test::bar()) ; } class A2 extends core::Object { @@ -68,10 +68,10 @@ class A3 extends core::Object { } class B3 extends self::A3 { constructor foo({dynamic y = #C1}) → self::B3 - : super self::A3::•(new self::Test::foo(), y: y) + : final dynamic #t1 = y, super self::A3::•(new self::Test::foo(), y: #t1) ; constructor bar({dynamic y = #C1}) → self::B3 - : super self::A3::•(self::Test::bar(), y: y) + : final dynamic #t2 = y, super self::A3::•(self::Test::bar(), y: #t2) ; } class A4 extends core::Object /*hasConstConstructor*/ { @@ -81,10 +81,10 @@ class A4 extends core::Object /*hasConstConstructor*/ { } class B4 extends self::A4 { constructor foo({dynamic x = #C1}) → self::B4 - : super self::A4::•(y: new self::Test::foo(), x: x) + : super self::A4::•(x: x, y: new self::Test::foo()) ; constructor bar({dynamic x = #C1}) → self::B4 - : super self::A4::•(y: self::Test::bar(), x: x) + : super self::A4::•(x: x, y: self::Test::bar()) ; } class A5 extends core::Object /*hasConstConstructor*/ { @@ -107,10 +107,10 @@ class A6 extends core::Object /*hasConstConstructor*/ { } class B6 extends self::A6 { constructor foo({dynamic y = #C1}) → self::B6 - : super self::A6::•(new self::Test::foo(), y: y) + : final dynamic #t3 = y, super self::A6::•(new self::Test::foo(), y: #t3) ; constructor bar({dynamic y = #C1}) → self::B6 - : super self::A6::•(self::Test::bar(), y: y) + : final dynamic #t4 = y, super self::A6::•(self::Test::bar(), y: #t4) ; } class A7 extends core::Object /*hasConstConstructor*/ { @@ -120,14 +120,14 @@ class A7 extends core::Object /*hasConstConstructor*/ { } class B7 extends self::A7 /*hasConstConstructor*/ { const constructor foo({dynamic x = #C1}) → self::B7 - : super self::A7::•(y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:69:38: Error: New expression is not a constant expression. + : super self::A7::•(x: x, y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:69:38: Error: New expression is not a constant expression. const B7.foo({super.x}) : super(y: new Test.foo()); // Error. - ^^^", x: x) + ^^^") ; const constructor bar({dynamic x = #C1}) → self::B7 - : super self::A7::•(y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:70:38: Error: New expression is not a constant expression. + : super self::A7::•(x: x, y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:70:38: Error: New expression is not a constant expression. const B7.bar({super.x}) : super(y: new Test.bar()); // Error. - ^^^", x: x) + ^^^") ; } class A8 extends core::Object /*hasConstConstructor*/ { @@ -154,14 +154,14 @@ class A9 extends core::Object /*hasConstConstructor*/ { } class B9 extends self::A9 /*hasConstConstructor*/ { const constructor foo({dynamic y = #C1}) → self::B9 - : super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:87:35: Error: New expression is not a constant expression. + : final dynamic #t5 = y, super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:87:35: Error: New expression is not a constant expression. const B9.foo({super.y}) : super(new Test.foo()); // Error. - ^^^", y: y) + ^^^", y: #t5) ; const constructor bar({dynamic y = #C1}) → self::B9 - : super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:88:35: Error: New expression is not a constant expression. + : final dynamic #t6 = y, super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:88:35: Error: New expression is not a constant expression. const B9.bar({super.y}) : super(new Test.bar()); // Error. - ^^^", y: y) + ^^^", y: #t6) ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.modular.expect b/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.modular.expect index f5966cc8062..f99a28585a3 100644 --- a/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.modular.expect +++ b/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.modular.expect @@ -42,10 +42,10 @@ class A1 extends core::Object { } class B1 extends self::A1 { constructor foo({dynamic x = #C1}) → self::B1 - : super self::A1::•(y: new self::Test::foo(), x: x) + : super self::A1::•(x: x, y: new self::Test::foo()) ; constructor bar({dynamic x = #C1}) → self::B1 - : super self::A1::•(y: self::Test::bar(), x: x) + : super self::A1::•(x: x, y: self::Test::bar()) ; } class A2 extends core::Object { @@ -68,10 +68,10 @@ class A3 extends core::Object { } class B3 extends self::A3 { constructor foo({dynamic y = #C1}) → self::B3 - : super self::A3::•(new self::Test::foo(), y: y) + : final dynamic #t1 = y, super self::A3::•(new self::Test::foo(), y: #t1) ; constructor bar({dynamic y = #C1}) → self::B3 - : super self::A3::•(self::Test::bar(), y: y) + : final dynamic #t2 = y, super self::A3::•(self::Test::bar(), y: #t2) ; } class A4 extends core::Object /*hasConstConstructor*/ { @@ -81,10 +81,10 @@ class A4 extends core::Object /*hasConstConstructor*/ { } class B4 extends self::A4 { constructor foo({dynamic x = #C1}) → self::B4 - : super self::A4::•(y: new self::Test::foo(), x: x) + : super self::A4::•(x: x, y: new self::Test::foo()) ; constructor bar({dynamic x = #C1}) → self::B4 - : super self::A4::•(y: self::Test::bar(), x: x) + : super self::A4::•(x: x, y: self::Test::bar()) ; } class A5 extends core::Object /*hasConstConstructor*/ { @@ -107,10 +107,10 @@ class A6 extends core::Object /*hasConstConstructor*/ { } class B6 extends self::A6 { constructor foo({dynamic y = #C1}) → self::B6 - : super self::A6::•(new self::Test::foo(), y: y) + : final dynamic #t3 = y, super self::A6::•(new self::Test::foo(), y: #t3) ; constructor bar({dynamic y = #C1}) → self::B6 - : super self::A6::•(self::Test::bar(), y: y) + : final dynamic #t4 = y, super self::A6::•(self::Test::bar(), y: #t4) ; } class A7 extends core::Object /*hasConstConstructor*/ { @@ -120,14 +120,14 @@ class A7 extends core::Object /*hasConstConstructor*/ { } class B7 extends self::A7 /*hasConstConstructor*/ { const constructor foo({dynamic x = #C1}) → self::B7 - : super self::A7::•(y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:69:38: Error: New expression is not a constant expression. + : super self::A7::•(x: x, y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:69:38: Error: New expression is not a constant expression. const B7.foo({super.x}) : super(y: new Test.foo()); // Error. - ^^^", x: x) + ^^^") ; const constructor bar({dynamic x = #C1}) → self::B7 - : super self::A7::•(y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:70:38: Error: New expression is not a constant expression. + : super self::A7::•(x: x, y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:70:38: Error: New expression is not a constant expression. const B7.bar({super.x}) : super(y: new Test.bar()); // Error. - ^^^", x: x) + ^^^") ; } class A8 extends core::Object /*hasConstConstructor*/ { @@ -154,14 +154,14 @@ class A9 extends core::Object /*hasConstConstructor*/ { } class B9 extends self::A9 /*hasConstConstructor*/ { const constructor foo({dynamic y = #C1}) → self::B9 - : super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:87:35: Error: New expression is not a constant expression. + : final dynamic #t5 = y, super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:87:35: Error: New expression is not a constant expression. const B9.foo({super.y}) : super(new Test.foo()); // Error. - ^^^", y: y) + ^^^", y: #t5) ; const constructor bar({dynamic y = #C1}) → self::B9 - : super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:88:35: Error: New expression is not a constant expression. + : final dynamic #t6 = y, super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:88:35: Error: New expression is not a constant expression. const B9.bar({super.y}) : super(new Test.bar()); // Error. - ^^^", y: y) + ^^^", y: #t6) ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.outline.expect b/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.outline.expect index 9dc47f02941..2ebc7ef6224 100644 --- a/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.outline.expect +++ b/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.outline.expect @@ -105,14 +105,14 @@ class A7 extends core::Object /*hasConstConstructor*/ { } class B7 extends self::A7 /*hasConstConstructor*/ { const constructor foo({dynamic x = null}) → self::B7 - : super self::A7::•(y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:69:38: Error: New expression is not a constant expression. + : super self::A7::•(x: x, y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:69:38: Error: New expression is not a constant expression. const B7.foo({super.x}) : super(y: new Test.foo()); // Error. - ^^^", x: x) + ^^^") ; const constructor bar({dynamic x = null}) → self::B7 - : super self::A7::•(y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:70:38: Error: New expression is not a constant expression. + : super self::A7::•(x: x, y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:70:38: Error: New expression is not a constant expression. const B7.bar({super.x}) : super(y: new Test.bar()); // Error. - ^^^", x: x) + ^^^") ; } class A8 extends core::Object /*hasConstConstructor*/ { @@ -139,14 +139,14 @@ class A9 extends core::Object /*hasConstConstructor*/ { } class B9 extends self::A9 /*hasConstConstructor*/ { const constructor foo({dynamic y = null}) → self::B9 - : super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:87:35: Error: New expression is not a constant expression. + : final dynamic #t1 = y, super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:87:35: Error: New expression is not a constant expression. const B9.foo({super.y}) : super(new Test.foo()); // Error. - ^^^", y: y) + ^^^", y: #t1) ; const constructor bar({dynamic y = null}) → self::B9 - : super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:88:35: Error: New expression is not a constant expression. + : final dynamic #t2 = y, super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:88:35: Error: New expression is not a constant expression. const B9.bar({super.y}) : super(new Test.bar()); // Error. - ^^^", y: y) + ^^^", y: #t2) ; } static method main() → dynamic diff --git a/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.transformed.expect b/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.transformed.expect index f5966cc8062..f99a28585a3 100644 --- a/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/super_parameters/issue48642.dart.strong.transformed.expect @@ -42,10 +42,10 @@ class A1 extends core::Object { } class B1 extends self::A1 { constructor foo({dynamic x = #C1}) → self::B1 - : super self::A1::•(y: new self::Test::foo(), x: x) + : super self::A1::•(x: x, y: new self::Test::foo()) ; constructor bar({dynamic x = #C1}) → self::B1 - : super self::A1::•(y: self::Test::bar(), x: x) + : super self::A1::•(x: x, y: self::Test::bar()) ; } class A2 extends core::Object { @@ -68,10 +68,10 @@ class A3 extends core::Object { } class B3 extends self::A3 { constructor foo({dynamic y = #C1}) → self::B3 - : super self::A3::•(new self::Test::foo(), y: y) + : final dynamic #t1 = y, super self::A3::•(new self::Test::foo(), y: #t1) ; constructor bar({dynamic y = #C1}) → self::B3 - : super self::A3::•(self::Test::bar(), y: y) + : final dynamic #t2 = y, super self::A3::•(self::Test::bar(), y: #t2) ; } class A4 extends core::Object /*hasConstConstructor*/ { @@ -81,10 +81,10 @@ class A4 extends core::Object /*hasConstConstructor*/ { } class B4 extends self::A4 { constructor foo({dynamic x = #C1}) → self::B4 - : super self::A4::•(y: new self::Test::foo(), x: x) + : super self::A4::•(x: x, y: new self::Test::foo()) ; constructor bar({dynamic x = #C1}) → self::B4 - : super self::A4::•(y: self::Test::bar(), x: x) + : super self::A4::•(x: x, y: self::Test::bar()) ; } class A5 extends core::Object /*hasConstConstructor*/ { @@ -107,10 +107,10 @@ class A6 extends core::Object /*hasConstConstructor*/ { } class B6 extends self::A6 { constructor foo({dynamic y = #C1}) → self::B6 - : super self::A6::•(new self::Test::foo(), y: y) + : final dynamic #t3 = y, super self::A6::•(new self::Test::foo(), y: #t3) ; constructor bar({dynamic y = #C1}) → self::B6 - : super self::A6::•(self::Test::bar(), y: y) + : final dynamic #t4 = y, super self::A6::•(self::Test::bar(), y: #t4) ; } class A7 extends core::Object /*hasConstConstructor*/ { @@ -120,14 +120,14 @@ class A7 extends core::Object /*hasConstConstructor*/ { } class B7 extends self::A7 /*hasConstConstructor*/ { const constructor foo({dynamic x = #C1}) → self::B7 - : super self::A7::•(y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:69:38: Error: New expression is not a constant expression. + : super self::A7::•(x: x, y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:69:38: Error: New expression is not a constant expression. const B7.foo({super.x}) : super(y: new Test.foo()); // Error. - ^^^", x: x) + ^^^") ; const constructor bar({dynamic x = #C1}) → self::B7 - : super self::A7::•(y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:70:38: Error: New expression is not a constant expression. + : super self::A7::•(x: x, y: invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:70:38: Error: New expression is not a constant expression. const B7.bar({super.x}) : super(y: new Test.bar()); // Error. - ^^^", x: x) + ^^^") ; } class A8 extends core::Object /*hasConstConstructor*/ { @@ -154,14 +154,14 @@ class A9 extends core::Object /*hasConstConstructor*/ { } class B9 extends self::A9 /*hasConstConstructor*/ { const constructor foo({dynamic y = #C1}) → self::B9 - : super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:87:35: Error: New expression is not a constant expression. + : final dynamic #t5 = y, super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:87:35: Error: New expression is not a constant expression. const B9.foo({super.y}) : super(new Test.foo()); // Error. - ^^^", y: y) + ^^^", y: #t5) ; const constructor bar({dynamic y = #C1}) → self::B9 - : super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:88:35: Error: New expression is not a constant expression. + : final dynamic #t6 = y, super self::A9::•(invalid-expression "pkg/front_end/testcases/super_parameters/issue48642.dart:88:35: Error: New expression is not a constant expression. const B9.bar({super.y}) : super(new Test.bar()); // Error. - ^^^", y: y) + ^^^", y: #t6) ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/super_parameters/no_coercions.dart.strong.expect b/pkg/front_end/testcases/super_parameters/no_coercions.dart.strong.expect index 634ebfd7863..dfcd260210d 100644 --- a/pkg/front_end/testcases/super_parameters/no_coercions.dart.strong.expect +++ b/pkg/front_end/testcases/super_parameters/no_coercions.dart.strong.expect @@ -189,14 +189,14 @@ class A7 extends core::Object { } class B7 extends self::A7 { constructor •({required dynamic x1, required dynamic x2, required (core::Object) → X% f1, required (core::Object) → X% f2, required (X%) → void g1, required (X%) → void g2}) → self::B7 - : super self::A7::•(x2: x2 as{TypeError,ForDynamic} core::int, f2: f2, g2: g2, x1: invalid-expression "pkg/front_end/testcases/super_parameters/no_coercions.dart:73:30: Error: The argument type 'dynamic' can't be assigned to the parameter type 'int'. + : super self::A7::•(x1: invalid-expression "pkg/front_end/testcases/super_parameters/no_coercions.dart:73:30: Error: The argument type 'dynamic' can't be assigned to the parameter type 'int'. B7({required dynamic super.x1, // Error. ^" in x1 as{TypeError} core::int, f1: invalid-expression "pkg/front_end/testcases/super_parameters/no_coercions.dart:75:44: Error: The argument type 'X Function(Object)' can't be assigned to the parameter type 'bool Function(Object)'. - 'Object' is from 'dart:core'. required X Function(Object) super.f1, // Error. ^" in f1 as{TypeError} (core::Object) → core::bool, g1: invalid-expression "pkg/front_end/testcases/super_parameters/no_coercions.dart:77:42: Error: The argument type 'void Function(X)' can't be assigned to the parameter type 'void Function(dynamic)'. required void Function(X) super.g1, // Error. - ^" in g1 as{TypeError} (dynamic) → void) + ^" in g1 as{TypeError} (dynamic) → void, x2: x2 as{TypeError,ForDynamic} core::int, f2: f2, g2: g2) ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/super_parameters/no_coercions.dart.strong.modular.expect b/pkg/front_end/testcases/super_parameters/no_coercions.dart.strong.modular.expect index 634ebfd7863..dfcd260210d 100644 --- a/pkg/front_end/testcases/super_parameters/no_coercions.dart.strong.modular.expect +++ b/pkg/front_end/testcases/super_parameters/no_coercions.dart.strong.modular.expect @@ -189,14 +189,14 @@ class A7 extends core::Object { } class B7 extends self::A7 { constructor •({required dynamic x1, required dynamic x2, required (core::Object) → X% f1, required (core::Object) → X% f2, required (X%) → void g1, required (X%) → void g2}) → self::B7 - : super self::A7::•(x2: x2 as{TypeError,ForDynamic} core::int, f2: f2, g2: g2, x1: invalid-expression "pkg/front_end/testcases/super_parameters/no_coercions.dart:73:30: Error: The argument type 'dynamic' can't be assigned to the parameter type 'int'. + : super self::A7::•(x1: invalid-expression "pkg/front_end/testcases/super_parameters/no_coercions.dart:73:30: Error: The argument type 'dynamic' can't be assigned to the parameter type 'int'. B7({required dynamic super.x1, // Error. ^" in x1 as{TypeError} core::int, f1: invalid-expression "pkg/front_end/testcases/super_parameters/no_coercions.dart:75:44: Error: The argument type 'X Function(Object)' can't be assigned to the parameter type 'bool Function(Object)'. - 'Object' is from 'dart:core'. required X Function(Object) super.f1, // Error. ^" in f1 as{TypeError} (core::Object) → core::bool, g1: invalid-expression "pkg/front_end/testcases/super_parameters/no_coercions.dart:77:42: Error: The argument type 'void Function(X)' can't be assigned to the parameter type 'void Function(dynamic)'. required void Function(X) super.g1, // Error. - ^" in g1 as{TypeError} (dynamic) → void) + ^" in g1 as{TypeError} (dynamic) → void, x2: x2 as{TypeError,ForDynamic} core::int, f2: f2, g2: g2) ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/super_parameters/no_coercions.dart.strong.transformed.expect b/pkg/front_end/testcases/super_parameters/no_coercions.dart.strong.transformed.expect index 634ebfd7863..dfcd260210d 100644 --- a/pkg/front_end/testcases/super_parameters/no_coercions.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/super_parameters/no_coercions.dart.strong.transformed.expect @@ -189,14 +189,14 @@ class A7 extends core::Object { } class B7 extends self::A7 { constructor •({required dynamic x1, required dynamic x2, required (core::Object) → X% f1, required (core::Object) → X% f2, required (X%) → void g1, required (X%) → void g2}) → self::B7 - : super self::A7::•(x2: x2 as{TypeError,ForDynamic} core::int, f2: f2, g2: g2, x1: invalid-expression "pkg/front_end/testcases/super_parameters/no_coercions.dart:73:30: Error: The argument type 'dynamic' can't be assigned to the parameter type 'int'. + : super self::A7::•(x1: invalid-expression "pkg/front_end/testcases/super_parameters/no_coercions.dart:73:30: Error: The argument type 'dynamic' can't be assigned to the parameter type 'int'. B7({required dynamic super.x1, // Error. ^" in x1 as{TypeError} core::int, f1: invalid-expression "pkg/front_end/testcases/super_parameters/no_coercions.dart:75:44: Error: The argument type 'X Function(Object)' can't be assigned to the parameter type 'bool Function(Object)'. - 'Object' is from 'dart:core'. required X Function(Object) super.f1, // Error. ^" in f1 as{TypeError} (core::Object) → core::bool, g1: invalid-expression "pkg/front_end/testcases/super_parameters/no_coercions.dart:77:42: Error: The argument type 'void Function(X)' can't be assigned to the parameter type 'void Function(dynamic)'. required void Function(X) super.g1, // Error. - ^" in g1 as{TypeError} (dynamic) → void) + ^" in g1 as{TypeError} (dynamic) → void, x2: x2 as{TypeError,ForDynamic} core::int, f2: f2, g2: g2) ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/super_parameters/opt_out.dart.strong.expect b/pkg/front_end/testcases/super_parameters/opt_out.dart.strong.expect index d81fae22020..a08b60359d9 100644 --- a/pkg/front_end/testcases/super_parameters/opt_out.dart.strong.expect +++ b/pkg/front_end/testcases/super_parameters/opt_out.dart.strong.expect @@ -10,11 +10,6 @@ library; // // @dart=2.15 // ^^^^^^^^^^^^^ // -// pkg/front_end/testcases/super_parameters/opt_out.dart:14:3: Error: The implicitly called unnamed constructor from 'A' has required parameters. -// Try adding an explicit super initializer with the required arguments. -// B(super.field); -// ^ -// import self as self; import "dart:core" as core; @@ -26,10 +21,7 @@ class A extends core::Object { } class B extends self::A { constructor •(core::int field) → self::B - : invalid-initializer "pkg/front_end/testcases/super_parameters/opt_out.dart:14:3: Error: The implicitly called unnamed constructor from 'A' has required parameters. -Try adding an explicit super initializer with the required arguments. - B(super.field); - ^" + : super self::A::•(field) ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/super_parameters/opt_out.dart.strong.modular.expect b/pkg/front_end/testcases/super_parameters/opt_out.dart.strong.modular.expect index d81fae22020..a08b60359d9 100644 --- a/pkg/front_end/testcases/super_parameters/opt_out.dart.strong.modular.expect +++ b/pkg/front_end/testcases/super_parameters/opt_out.dart.strong.modular.expect @@ -10,11 +10,6 @@ library; // // @dart=2.15 // ^^^^^^^^^^^^^ // -// pkg/front_end/testcases/super_parameters/opt_out.dart:14:3: Error: The implicitly called unnamed constructor from 'A' has required parameters. -// Try adding an explicit super initializer with the required arguments. -// B(super.field); -// ^ -// import self as self; import "dart:core" as core; @@ -26,10 +21,7 @@ class A extends core::Object { } class B extends self::A { constructor •(core::int field) → self::B - : invalid-initializer "pkg/front_end/testcases/super_parameters/opt_out.dart:14:3: Error: The implicitly called unnamed constructor from 'A' has required parameters. -Try adding an explicit super initializer with the required arguments. - B(super.field); - ^" + : super self::A::•(field) ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/super_parameters/opt_out.dart.strong.transformed.expect b/pkg/front_end/testcases/super_parameters/opt_out.dart.strong.transformed.expect index d81fae22020..a08b60359d9 100644 --- a/pkg/front_end/testcases/super_parameters/opt_out.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/super_parameters/opt_out.dart.strong.transformed.expect @@ -10,11 +10,6 @@ library; // // @dart=2.15 // ^^^^^^^^^^^^^ // -// pkg/front_end/testcases/super_parameters/opt_out.dart:14:3: Error: The implicitly called unnamed constructor from 'A' has required parameters. -// Try adding an explicit super initializer with the required arguments. -// B(super.field); -// ^ -// import self as self; import "dart:core" as core; @@ -26,10 +21,7 @@ class A extends core::Object { } class B extends self::A { constructor •(core::int field) → self::B - : invalid-initializer "pkg/front_end/testcases/super_parameters/opt_out.dart:14:3: Error: The implicitly called unnamed constructor from 'A' has required parameters. -Try adding an explicit super initializer with the required arguments. - B(super.field); - ^" + : super self::A::•(field) ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart.strong.expect b/pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart.strong.expect index 4c0275987ae..a34094d6784 100644 --- a/pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart.strong.expect +++ b/pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart.strong.expect @@ -2,9 +2,9 @@ library; // // Problems in library: // -// pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:15:22: Error: Duplicated named argument 'foo'. +// pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:15:36: Error: Duplicated named argument 'foo'. // C1({required super.foo}) : super(foo: foo); // Error. -// ^^^ +// ^^^ // // pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:25:37: Error: No named parameter with the name 'baz'. // B2() : super(foo: 42, bar: "bar", baz: false); // Error. @@ -30,9 +30,9 @@ class B1 extends self::A1 { } class C1 extends self::A1 { constructor •({required core::int foo}) → self::C1 - : super self::A1::•(foo: invalid-expression "pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:15:22: Error: Duplicated named argument 'foo'. + : super self::A1::•(foo: invalid-expression "pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:15:36: Error: Duplicated named argument 'foo'. C1({required super.foo}) : super(foo: foo); // Error. - ^^^" in block { + ^^^" in block { foo; } =>foo) ; @@ -58,7 +58,7 @@ class C2 extends self::A2 { ^" ; constructor other({required core::int foo}) → self::C2 - : super self::A2::•(bar: "bar", foo: foo) + : super self::A2::•(foo: foo, bar: "bar") ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart.strong.modular.expect b/pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart.strong.modular.expect index 4c0275987ae..a34094d6784 100644 --- a/pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart.strong.modular.expect +++ b/pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart.strong.modular.expect @@ -2,9 +2,9 @@ library; // // Problems in library: // -// pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:15:22: Error: Duplicated named argument 'foo'. +// pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:15:36: Error: Duplicated named argument 'foo'. // C1({required super.foo}) : super(foo: foo); // Error. -// ^^^ +// ^^^ // // pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:25:37: Error: No named parameter with the name 'baz'. // B2() : super(foo: 42, bar: "bar", baz: false); // Error. @@ -30,9 +30,9 @@ class B1 extends self::A1 { } class C1 extends self::A1 { constructor •({required core::int foo}) → self::C1 - : super self::A1::•(foo: invalid-expression "pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:15:22: Error: Duplicated named argument 'foo'. + : super self::A1::•(foo: invalid-expression "pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:15:36: Error: Duplicated named argument 'foo'. C1({required super.foo}) : super(foo: foo); // Error. - ^^^" in block { + ^^^" in block { foo; } =>foo) ; @@ -58,7 +58,7 @@ class C2 extends self::A2 { ^" ; constructor other({required core::int foo}) → self::C2 - : super self::A2::•(bar: "bar", foo: foo) + : super self::A2::•(foo: foo, bar: "bar") ; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart.strong.transformed.expect b/pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart.strong.transformed.expect index 4c0275987ae..a34094d6784 100644 --- a/pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart.strong.transformed.expect @@ -2,9 +2,9 @@ library; // // Problems in library: // -// pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:15:22: Error: Duplicated named argument 'foo'. +// pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:15:36: Error: Duplicated named argument 'foo'. // C1({required super.foo}) : super(foo: foo); // Error. -// ^^^ +// ^^^ // // pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:25:37: Error: No named parameter with the name 'baz'. // B2() : super(foo: 42, bar: "bar", baz: false); // Error. @@ -30,9 +30,9 @@ class B1 extends self::A1 { } class C1 extends self::A1 { constructor •({required core::int foo}) → self::C1 - : super self::A1::•(foo: invalid-expression "pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:15:22: Error: Duplicated named argument 'foo'. + : super self::A1::•(foo: invalid-expression "pkg/front_end/testcases/super_parameters/simple_named_super_parameters.dart:15:36: Error: Duplicated named argument 'foo'. C1({required super.foo}) : super(foo: foo); // Error. - ^^^" in block { + ^^^" in block { foo; } =>foo) ; @@ -58,7 +58,7 @@ class C2 extends self::A2 { ^" ; constructor other({required core::int foo}) → self::C2 - : super self::A2::•(bar: "bar", foo: foo) + : super self::A2::•(foo: foo, bar: "bar") ; } static method main() → dynamic {}