From 6fdaed9eba4277f2826553a28ea1dd703417170e Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Mon, 25 Apr 2022 15:50:47 +0000 Subject: [PATCH] [cfe] Handle tear-offs of patched constructors Previously the tear-offs created for the origin constructors were not replaced with the tear-offs created for the patch constructors - as is normally done for the constructors themselves. This lead the tear-offs to refer to unlowered code, breaking dart2js. Closes https://github.com/dart-lang/sdk/issues/48776 Change-Id: I1cb09c07bb2ac7fffb81acd31547ee96e7ecdc64 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/242284 Reviewed-by: Chloe Stefantsova Commit-Queue: Johnni Winther --- .../kernel/constructor_tearoff_lowering.dart | 131 ++++++++++++------ .../lib/src/fasta/kernel/kernel_helper.dart | 36 +++++ .../lib/src/fasta/kernel/kernel_target.dart | 16 ++- .../source/source_constructor_builder.dart | 33 +++-- .../fasta/source/source_factory_builder.dart | 32 ++--- .../source/source_procedure_builder.dart | 16 +-- .../source/source_type_alias_builder.dart | 34 +++-- .../testcases/dart2js/issue48776.dart | 7 + .../dart2js/issue48776.dart.strong.expect | 11 ++ .../issue48776.dart.strong.transformed.expect | 11 ++ .../issue48776.dart.textual_outline.expect | 1 + ...48776.dart.textual_outline_modelled.expect | 1 + .../dart2js/issue48776.dart.weak.expect | 11 ++ .../issue48776.dart.weak.modular.expect | 11 ++ .../issue48776.dart.weak.outline.expect | 5 + .../issue48776.dart.weak.transformed.expect | 11 ++ .../dart2js/tear_off_patch/libraries.json | 12 ++ .../dart2js/tear_off_patch/main.dart | 20 +++ .../tear_off_patch/main.dart.strong.expect | 104 ++++++++++++++ .../main.dart.strong.transformed.expect | 104 ++++++++++++++ .../main.dart.textual_outline.expect | 3 + .../main.dart.textual_outline_modelled.expect | 3 + .../tear_off_patch/main.dart.weak.expect | 104 ++++++++++++++ .../main.dart.weak.modular.expect | 104 ++++++++++++++ .../main.dart.weak.outline.expect | 77 ++++++++++ .../main.dart.weak.transformed.expect | 104 ++++++++++++++ .../dart2js/tear_off_patch/origin_lib.dart | 19 +++ .../dart2js/tear_off_patch/patch_lib.dart | 33 +++++ .../factory_patch/main.dart.strong.expect | 4 +- .../main.dart.strong.transformed.expect | 4 +- .../factory_patch/main.dart.weak.expect | 4 +- .../main.dart.weak.modular.expect | 4 +- .../main.dart.weak.transformed.expect | 4 +- .../general/tear_off_patch/libraries.json | 12 ++ .../general/tear_off_patch/main.dart | 20 +++ .../tear_off_patch/main.dart.strong.expect | 104 ++++++++++++++ .../main.dart.strong.transformed.expect | 104 ++++++++++++++ .../main.dart.textual_outline.expect | 3 + .../main.dart.textual_outline_modelled.expect | 3 + .../tear_off_patch/main.dart.weak.expect | 92 ++++++++++++ .../main.dart.weak.modular.expect | 92 ++++++++++++ .../main.dart.weak.outline.expect | 65 +++++++++ .../main.dart.weak.transformed.expect | 92 ++++++++++++ .../general/tear_off_patch/origin_lib.dart | 19 +++ .../general/tear_off_patch/patch_lib.dart | 33 +++++ .../constructor/patch_tear_off_test.dart | 10 ++ 46 files changed, 1606 insertions(+), 117 deletions(-) create mode 100644 pkg/front_end/testcases/dart2js/issue48776.dart create mode 100644 pkg/front_end/testcases/dart2js/issue48776.dart.strong.expect create mode 100644 pkg/front_end/testcases/dart2js/issue48776.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/dart2js/issue48776.dart.weak.expect create mode 100644 pkg/front_end/testcases/dart2js/issue48776.dart.weak.modular.expect create mode 100644 pkg/front_end/testcases/dart2js/issue48776.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/dart2js/issue48776.dart.weak.transformed.expect create mode 100644 pkg/front_end/testcases/dart2js/tear_off_patch/libraries.json create mode 100644 pkg/front_end/testcases/dart2js/tear_off_patch/main.dart create mode 100644 pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.expect create mode 100644 pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.expect create mode 100644 pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.modular.expect create mode 100644 pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.transformed.expect create mode 100644 pkg/front_end/testcases/dart2js/tear_off_patch/origin_lib.dart create mode 100644 pkg/front_end/testcases/dart2js/tear_off_patch/patch_lib.dart create mode 100644 pkg/front_end/testcases/general/tear_off_patch/libraries.json create mode 100644 pkg/front_end/testcases/general/tear_off_patch/main.dart create mode 100644 pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.expect create mode 100644 pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.expect create mode 100644 pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.modular.expect create mode 100644 pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.transformed.expect create mode 100644 pkg/front_end/testcases/general/tear_off_patch/origin_lib.dart create mode 100644 pkg/front_end/testcases/general/tear_off_patch/patch_lib.dart create mode 100644 tests/language/constructor/patch_tear_off_test.dart diff --git a/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart index 1edef5737add..77159ce80bf0 100644 --- a/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart +++ b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart @@ -159,22 +159,41 @@ Procedure createTypedefTearOffProcedure( reference); } -/// Creates the parameters and body for [tearOff] based on [constructor] in -/// [enclosingClass]. -void buildConstructorTearOffProcedure(Procedure tearOff, Member constructor, - Class enclosingClass, SourceLibraryBuilder libraryBuilder) { +/// Creates the parameters and body for [tearOff] based on +/// [declarationConstructor] in [enclosingClass]. +/// +/// The [declarationConstructor] is the origin constructor and +/// [implementationConstructor] is the patch constructor, if patched, otherwise +/// it is the [declarationConstructor]. +void buildConstructorTearOffProcedure( + {required Procedure tearOff, + required Member declarationConstructor, + required Member implementationConstructor, + required Class enclosingClass, + required SourceLibraryBuilder libraryBuilder}) { + assert( + declarationConstructor is Constructor || + (declarationConstructor is Procedure && + declarationConstructor.isFactory) || + (declarationConstructor is Procedure && + declarationConstructor.isStatic), + "Unexpected constructor tear off target $declarationConstructor " + "(${declarationConstructor.runtimeType})."); assert( - constructor is Constructor || - (constructor is Procedure && constructor.isFactory) || - (constructor is Procedure && constructor.isStatic), - "Unexpected constructor tear off target $constructor " - "(${constructor.runtimeType})."); + declarationConstructor is Constructor || + (declarationConstructor is Procedure && + declarationConstructor.isFactory) || + (declarationConstructor is Procedure && + declarationConstructor.isStatic), + "Unexpected constructor tear off target $declarationConstructor " + "(${declarationConstructor.runtimeType})."); + + FunctionNode function = implementationConstructor.function!; int fileOffset = tearOff.fileOffset; - FunctionNode function = constructor.function!; List classTypeParameters; - if (constructor is Constructor) { + if (declarationConstructor is Constructor) { // Generative constructors implicitly have the type parameters of the // enclosing class. classTypeParameters = enclosingClass.typeParameters; @@ -189,37 +208,54 @@ void buildConstructorTearOffProcedure(Procedure tearOff, Member constructor, List typeArguments = freshTypeParameters.freshTypeArguments; Substitution substitution = freshTypeParameters.substitution; - _createParameters(tearOff, constructor, substitution, libraryBuilder); + _createParameters(tearOff, implementationConstructor, function, substitution, + libraryBuilder); Arguments arguments = _createArguments(tearOff, typeArguments, fileOffset); - _createTearOffBody(tearOff, constructor, arguments); + _createTearOffBody(tearOff, declarationConstructor, arguments); tearOff.function.fileOffset = tearOff.fileOffset; tearOff.function.fileEndOffset = tearOff.fileOffset; updatePrivateMemberName(tearOff, libraryBuilder); } /// Creates the parameters and body for [tearOff] for a typedef tearoff of -/// [constructor] in [enclosingClass] with [typeParameters] as the typedef -/// parameters and [typeArguments] as the arguments passed to the +/// [declarationConstructor] in [enclosingClass] with [typeParameters] as the +/// typedef parameters and [typeArguments] as the arguments passed to the /// [enclosingClass]. +/// +/// The [declarationConstructor] is the origin constructor and +/// [implementationConstructor] is the patch constructor, if patched, otherwise +/// it is the [declarationConstructor]. void buildTypedefTearOffProcedure( - Procedure tearOff, - Member constructor, - Class enclosingClass, - List typeParameters, - List typeArguments, - SourceLibraryBuilder libraryBuilder) { + {required Procedure tearOff, + required Member declarationConstructor, + required Member implementationConstructor, + required Class enclosingClass, + required List typeParameters, + required List typeArguments, + required SourceLibraryBuilder libraryBuilder}) { assert( - constructor is Constructor || - (constructor is Procedure && constructor.isFactory) || - (constructor is Procedure && constructor.isStatic), - "Unexpected constructor tear off target $constructor " - "(${constructor.runtimeType})."); + declarationConstructor is Constructor || + (declarationConstructor is Procedure && + declarationConstructor.isFactory) || + (declarationConstructor is Procedure && + declarationConstructor.isStatic), + "Unexpected constructor tear off target $declarationConstructor " + "(${declarationConstructor.runtimeType})."); + assert( + implementationConstructor is Constructor || + (implementationConstructor is Procedure && + implementationConstructor.isFactory) || + (implementationConstructor is Procedure && + implementationConstructor.isStatic), + "Unexpected constructor tear off target $implementationConstructor " + "(${declarationConstructor.runtimeType})."); + + FunctionNode function = implementationConstructor.function!; int fileOffset = tearOff.fileOffset; - FunctionNode function = constructor.function!; List classTypeParameters; - if (constructor is Constructor) { + if (declarationConstructor is Constructor) { // Generative constructors implicitly have the type parameters of the // enclosing class. classTypeParameters = enclosingClass.typeParameters; @@ -242,37 +278,43 @@ void buildTypedefTearOffProcedure( } _createParameters( tearOff, - constructor, + implementationConstructor, + function, Substitution.fromPairs(classTypeParameters, typeArguments), libraryBuilder); Arguments arguments = _createArguments(tearOff, typeArguments, fileOffset); - _createTearOffBody(tearOff, constructor, arguments); + _createTearOffBody(tearOff, declarationConstructor, arguments); tearOff.function.fileOffset = tearOff.fileOffset; tearOff.function.fileEndOffset = tearOff.fileOffset; updatePrivateMemberName(tearOff, libraryBuilder); } /// Creates the parameters for the redirecting factory [tearOff] based on the -/// [redirectingConstructor] declaration. +/// [declarationConstructor] declaration. +/// +/// The [declarationConstructor] is the [Procedure] for the origin constructor +/// and [implementationConstructorFunctionNode] is the [FunctionNode] for the +/// implementation constructor. If the constructor is patched, these are not +/// connected until [Builder.finishPatch]. FreshTypeParameters buildRedirectingFactoryTearOffProcedureParameters( - Procedure tearOff, - Procedure redirectingConstructor, - SourceLibraryBuilder libraryBuilder) { - assert(redirectingConstructor.isRedirectingFactory); - FunctionNode function = redirectingConstructor.function; + {required Procedure tearOff, + required Procedure implementationConstructor, + required SourceLibraryBuilder libraryBuilder}) { + assert(implementationConstructor.isRedirectingFactory); + FunctionNode function = implementationConstructor.function; FreshTypeParameters freshTypeParameters = _createFreshTypeParameters(function.typeParameters, tearOff.function); Substitution substitution = freshTypeParameters.substitution; - _createParameters( - tearOff, redirectingConstructor, substitution, libraryBuilder); + _createParameters(tearOff, implementationConstructor, function, substitution, + libraryBuilder); tearOff.function.fileOffset = tearOff.fileOffset; tearOff.function.fileEndOffset = tearOff.fileOffset; updatePrivateMemberName(tearOff, libraryBuilder); return freshTypeParameters; } -/// Creates the body for the redirecting factory [tearOff] with the target -/// [constructor] and [typeArguments]. +/// Creates the body for the redirecting factory [tearOff] with the [target] +/// constructor and [typeArguments]. /// /// Returns the [DelayedDefaultValueCloner] object need to perform default value /// computation. @@ -355,9 +397,12 @@ FreshTypeParameters _createFreshTypeParameters( /// Creates the parameters for the [tearOff] lowering based of the parameters /// in [constructor] and using the [substitution] to compute the parameter and /// return types. -void _createParameters(Procedure tearOff, Member constructor, - Substitution substitution, SourceLibraryBuilder libraryBuilder) { - FunctionNode function = constructor.function!; +void _createParameters( + Procedure tearOff, + Member constructor, + FunctionNode function, + Substitution substitution, + SourceLibraryBuilder libraryBuilder) { for (VariableDeclaration constructorParameter in function.positionalParameters) { VariableDeclaration tearOffParameter = new VariableDeclaration( diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart index 75a94cf911c9..ffbbab7e74fa 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart @@ -300,3 +300,39 @@ class TypeDependency { _hasBeenInferred = true; } } + +/// Copies properties, function parameters and body from the [patch] constructor +/// to its [origin]. +void finishConstructorPatch(Constructor origin, Constructor patch) { + // TODO(ahe): restore file-offset once we track both origin and patch file + // URIs. See https://github.com/dart-lang/sdk/issues/31579 + origin.fileUri = patch.fileUri; + origin.startFileOffset = patch.startFileOffset; + origin.fileOffset = patch.fileOffset; + origin.fileEndOffset = patch.fileEndOffset; + origin.annotations.forEach((m) => m.fileOffset = patch.fileOffset); + + origin.isExternal = patch.isExternal; + origin.function = patch.function; + origin.function.parent = origin; + origin.initializers = patch.initializers; + setParents(origin.initializers, origin); +} + +/// Copies properties, function parameters and body from the [patch] procedure +/// to its [origin]. +void finishProcedurePatch(Procedure origin, Procedure patch) { + // TODO(ahe): restore file-offset once we track both origin and patch file + // URIs. See https://github.com/dart-lang/sdk/issues/31579 + origin.fileUri = patch.fileUri; + origin.startFileOffset = patch.startFileOffset; + origin.fileOffset = patch.fileOffset; + origin.fileEndOffset = patch.fileEndOffset; + origin.annotations.forEach((m) => m.fileOffset = patch.fileOffset); + + origin.isAbstract = patch.isAbstract; + origin.isExternal = patch.isExternal; + origin.function = patch.function; + origin.function.parent = origin; + origin.isRedirectingFactory = patch.isRedirectingFactory; +} diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart index 5794d255075f..c80faa19022a 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart @@ -1092,8 +1092,12 @@ class KernelTarget extends TargetImplementation { forAbstractClassOrEnum: classBuilder.isAbstract); if (constructorTearOff != null) { - buildConstructorTearOffProcedure(constructorTearOff, constructor, - classBuilder.cls, classBuilder.libraryBuilder); + buildConstructorTearOffProcedure( + tearOff: constructorTearOff, + declarationConstructor: constructor, + implementationConstructor: constructor, + enclosingClass: classBuilder.cls, + libraryBuilder: classBuilder.libraryBuilder); } SyntheticSourceConstructorBuilder constructorBuilder = new SyntheticSourceConstructorBuilder( @@ -1170,8 +1174,12 @@ class KernelTarget extends TargetImplementation { forAbstractClassOrEnum: enclosingClass.isAbstract || enclosingClass.isEnum); if (constructorTearOff != null) { - buildConstructorTearOffProcedure(constructorTearOff, constructor, - classBuilder.cls, classBuilder.libraryBuilder); + buildConstructorTearOffProcedure( + tearOff: constructorTearOff, + declarationConstructor: constructor, + implementationConstructor: constructor, + enclosingClass: classBuilder.cls, + libraryBuilder: classBuilder.libraryBuilder); } return new SyntheticSourceConstructorBuilder( classBuilder, constructor, constructorTearOff); diff --git a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart index 3aa7702550c9..c0dadf6423f6 100644 --- a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart @@ -27,7 +27,11 @@ import '../kernel/constructor_tearoff_lowering.dart'; import '../kernel/expression_generator_helper.dart'; import '../kernel/hierarchy/class_member.dart' show ClassMember; import '../kernel/kernel_helper.dart' - show DelayedDefaultValueCloner, TypeDependency; + show + DelayedDefaultValueCloner, + TypeDependency, + finishConstructorPatch, + finishProcedurePatch; import '../kernel/utils.dart' show isRedirectingGenerativeConstructorImplementation; import '../messages.dart' @@ -202,8 +206,12 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl updatePrivateMemberName(_constructor, libraryBuilder); if (_constructorTearOff != null) { - buildConstructorTearOffProcedure(_constructorTearOff!, _constructor, - classBuilder.cls, libraryBuilder); + buildConstructorTearOffProcedure( + tearOff: _constructorTearOff!, + declarationConstructor: constructor, + implementationConstructor: _constructor, + enclosingClass: classBuilder.cls, + libraryBuilder: libraryBuilder); } _hasBeenBuilt = true; @@ -660,20 +668,11 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl } void _finishPatch() { - // TODO(ahe): restore file-offset once we track both origin and patch file - // URIs. See https://github.com/dart-lang/sdk/issues/31579 - origin.constructor.fileUri = fileUri; - origin.constructor.startFileOffset = _constructor.startFileOffset; - origin.constructor.fileOffset = _constructor.fileOffset; - origin.constructor.fileEndOffset = _constructor.fileEndOffset; - origin.constructor.annotations - .forEach((m) => m.fileOffset = _constructor.fileOffset); - - origin.constructor.isExternal = _constructor.isExternal; - origin.constructor.function = _constructor.function; - origin.constructor.function.parent = origin.constructor; - origin.constructor.initializers = _constructor.initializers; - setParents(origin.constructor.initializers, origin.constructor); + finishConstructorPatch(origin.constructor, _constructor); + + if (_constructorTearOff != null) { + finishProcedurePatch(origin._constructorTearOff!, _constructorTearOff!); + } } @override diff --git a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart index cef67f3c936f..09523b6cc6c0 100644 --- a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart @@ -151,8 +151,12 @@ class SourceFactoryBuilder extends SourceFunctionBuilderImpl { _procedureInternal.isStatic = isStatic; if (_factoryTearOff != null) { - buildConstructorTearOffProcedure(_factoryTearOff!, _procedureInternal, - classBuilder!.cls, libraryBuilder); + buildConstructorTearOffProcedure( + tearOff: _factoryTearOff!, + declarationConstructor: _procedure, + implementationConstructor: _procedureInternal, + enclosingClass: classBuilder!.cls, + libraryBuilder: libraryBuilder); } return _procedureInternal; } @@ -224,21 +228,11 @@ class SourceFactoryBuilder extends SourceFunctionBuilderImpl { } void _finishPatch() { - // TODO(ahe): restore file-offset once we track both origin and patch file - // URIs. See https://github.com/dart-lang/sdk/issues/31579 - origin._procedure.fileUri = fileUri; - origin._procedure.startFileOffset = _procedureInternal.startFileOffset; - origin._procedure.fileOffset = _procedureInternal.fileOffset; - origin._procedure.fileEndOffset = _procedureInternal.fileEndOffset; - origin._procedure.annotations - .forEach((m) => m.fileOffset = _procedureInternal.fileOffset); - - origin._procedure.isAbstract = _procedureInternal.isAbstract; - origin._procedure.isExternal = _procedureInternal.isExternal; - origin._procedure.function = _procedureInternal.function; - origin._procedure.function.parent = origin._procedure; - origin._procedure.isRedirectingFactory = - _procedureInternal.isRedirectingFactory; + finishProcedurePatch(origin._procedure, _procedureInternal); + + if (_factoryTearOff != null) { + finishProcedurePatch(origin._factoryTearOff!, _factoryTearOff!); + } } @override @@ -373,7 +367,9 @@ class RedirectingFactoryBuilder extends SourceFactoryBuilder { if (_factoryTearOff != null) { _tearOffTypeParameters = buildRedirectingFactoryTearOffProcedureParameters( - _factoryTearOff!, _procedureInternal, libraryBuilder); + tearOff: _factoryTearOff!, + implementationConstructor: _procedureInternal, + libraryBuilder: libraryBuilder); } return _procedureInternal; } diff --git a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart index 89731b694aef..1a7fe1f58ef3 100644 --- a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart @@ -16,6 +16,7 @@ import '../builder/type_builder.dart'; import '../builder/type_variable_builder.dart'; import '../kernel/hierarchy/class_member.dart'; import '../kernel/hierarchy/members_builder.dart'; +import '../kernel/kernel_helper.dart'; import '../kernel/member_covariance.dart'; import '../source/name_scheme.dart'; import '../source/source_library_builder.dart' show SourceLibraryBuilder; @@ -470,20 +471,7 @@ class SourceProcedureBuilder extends SourceFunctionBuilderImpl int finishPatch() { if (!isPatch) return 0; - // TODO(ahe): restore file-offset once we track both origin and patch file - // URIs. See https://github.com/dart-lang/sdk/issues/31579 - origin.procedure.fileUri = fileUri; - origin.procedure.startFileOffset = _procedure.startFileOffset; - origin.procedure.fileOffset = _procedure.fileOffset; - origin.procedure.fileEndOffset = _procedure.fileEndOffset; - origin.procedure.annotations - .forEach((m) => m.fileOffset = _procedure.fileOffset); - - origin.procedure.isAbstract = _procedure.isAbstract; - origin.procedure.isExternal = _procedure.isExternal; - origin.procedure.function = _procedure.function; - origin.procedure.function.parent = origin.procedure; - origin.procedure.isRedirectingFactory = _procedure.isRedirectingFactory; + finishProcedurePatch(origin.procedure, _procedure); return 1; } diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart index 720a1b4691a4..c24455e73708 100644 --- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart @@ -4,7 +4,6 @@ library fasta.source_type_alias_builder; -import 'package:front_end/src/fasta/kernel/expression_generator_helper.dart'; import 'package:kernel/ast.dart'; import 'package:kernel/class_hierarchy.dart'; import 'package:kernel/type_environment.dart'; @@ -24,6 +23,7 @@ import '../builder/type_variable_builder.dart'; import '../fasta_codes.dart' show noLength, templateCyclicTypedef, templateTypeArgumentMismatch; import '../kernel/constructor_tearoff_lowering.dart'; +import '../kernel/expression_generator_helper.dart'; import '../kernel/kernel_helper.dart'; import '../problems.dart' show unhandled; import '../scope.dart'; @@ -275,14 +275,14 @@ class SourceTypeAliasBuilder extends TypeAliasBuilderImpl { Map? _tearOffDependencies; void buildTypedefTearOffs( - SourceLibraryBuilder library, void Function(Procedure) f) { + SourceLibraryBuilder libraryBuilder, void Function(Procedure) f) { TypeDeclarationBuilder? declaration = unaliasDeclaration(null); DartType? targetType = typedef.type; if (declaration is ClassBuilder && targetType is InterfaceType && typedef.typeParameters.isNotEmpty && - !isProperRenameForClass( - library.loader.typeEnvironment, typedef, library.library)) { + !isProperRenameForClass(libraryBuilder.loader.typeEnvironment, typedef, + libraryBuilder.library)) { tearOffs = {}; _tearOffDependencies = {}; declaration @@ -295,19 +295,31 @@ class SourceTypeAliasBuilder extends TypeAliasBuilderImpl { Name targetName = new Name(constructorName, declaration.libraryBuilder.library); Reference? tearOffReference; - if (library.referencesFromIndexed != null) { - tearOffReference = library.referencesFromIndexed! + if (libraryBuilder.referencesFromIndexed != null) { + tearOffReference = libraryBuilder.referencesFromIndexed! .lookupGetterReference(typedefTearOffName(name, constructorName, - library.referencesFromIndexed!.library)); + libraryBuilder.referencesFromIndexed!.library)); } Procedure tearOff = tearOffs![targetName] = - createTypedefTearOffProcedure(name, constructorName, library, - target.fileUri, target.fileOffset, tearOffReference); + createTypedefTearOffProcedure( + name, + constructorName, + libraryBuilder, + target.fileUri, + target.fileOffset, + tearOffReference); _tearOffDependencies![tearOff] = target; - buildTypedefTearOffProcedure(tearOff, target, declaration.cls, - typedef.typeParameters, targetType.typeArguments, library); + buildTypedefTearOffProcedure( + tearOff: tearOff, + declarationConstructor: target, + // TODO(johnniwinther): Handle patched constructors. + implementationConstructor: target, + enclosingClass: declaration.cls, + typeParameters: typedef.typeParameters, + typeArguments: targetType.typeArguments, + libraryBuilder: libraryBuilder); f(tearOff); } }); diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart b/pkg/front_end/testcases/dart2js/issue48776.dart new file mode 100644 index 000000000000..5bad3b17ddcc --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +main() { + BigInt.from; +} diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.strong.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.strong.expect new file mode 100644 index 000000000000..7fd424849601 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.strong.expect @@ -0,0 +1,11 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +static method main() → dynamic { + #C1; +} + +constants { + #C1 = static-tearoff core::BigInt::_#from#tearOff +} diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.strong.transformed.expect new file mode 100644 index 000000000000..7fd424849601 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.strong.transformed.expect @@ -0,0 +1,11 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +static method main() → dynamic { + #C1; +} + +constants { + #C1 = static-tearoff core::BigInt::_#from#tearOff +} diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline.expect new file mode 100644 index 000000000000..bae895adcb68 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline.expect @@ -0,0 +1 @@ +main() {} diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline_modelled.expect new file mode 100644 index 000000000000..bae895adcb68 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline_modelled.expect @@ -0,0 +1 @@ +main() {} diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.weak.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.expect new file mode 100644 index 000000000000..7fd424849601 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.expect @@ -0,0 +1,11 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +static method main() → dynamic { + #C1; +} + +constants { + #C1 = static-tearoff core::BigInt::_#from#tearOff +} diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.weak.modular.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.modular.expect new file mode 100644 index 000000000000..7fd424849601 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.modular.expect @@ -0,0 +1,11 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +static method main() → dynamic { + #C1; +} + +constants { + #C1 = static-tearoff core::BigInt::_#from#tearOff +} diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.outline.expect new file mode 100644 index 000000000000..e2cba6be4d13 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.outline.expect @@ -0,0 +1,5 @@ +library /*isNonNullableByDefault*/; +import self as self; + +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.transformed.expect new file mode 100644 index 000000000000..7fd424849601 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.transformed.expect @@ -0,0 +1,11 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +static method main() → dynamic { + #C1; +} + +constants { + #C1 = static-tearoff core::BigInt::_#from#tearOff +} diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/libraries.json b/pkg/front_end/testcases/dart2js/tear_off_patch/libraries.json new file mode 100644 index 000000000000..154c73c30b2b --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/libraries.json @@ -0,0 +1,12 @@ +{ + "none": { + "libraries": { + "test": { + "patches": [ + "patch_lib.dart" + ], + "uri": "origin_lib.dart" + } + } + } +} diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart new file mode 100644 index 000000000000..676f68ab0f39 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:test'; + +main() { + Class.new; + Class.fact; + Class.redirect; + Class.redirect2; + ClassImpl.new; + ClassImpl.patched; + Alias.new; + Alias.fact; + Alias.redirect; + Alias.redirect2; + AliasImpl.new; + AliasImpl.patched; +} diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.expect new file mode 100644 index 000000000000..3ba9f8689061 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.expect @@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias = test::Class; +typedef AliasImpl = test::ClassImpl; +@#C13 +class Class extends core::Object { + static final field dynamic _redirecting# = [#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl extends core::Object implements test::Class { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect#tearOff(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect2#tearOff(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +} diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.transformed.expect new file mode 100644 index 000000000000..3ba9f8689061 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.transformed.expect @@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias = test::Class; +typedef AliasImpl = test::ClassImpl; +@#C13 +class Class extends core::Object { + static final field dynamic _redirecting# = [#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl extends core::Object implements test::Class { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect#tearOff(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect2#tearOff(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +} diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline.expect new file mode 100644 index 000000000000..3c9c90e9437e --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline.expect @@ -0,0 +1,3 @@ +import 'dart:test'; + +main() {} diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline_modelled.expect new file mode 100644 index 000000000000..3c9c90e9437e --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline_modelled.expect @@ -0,0 +1,3 @@ +import 'dart:test'; + +main() {} diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.expect new file mode 100644 index 000000000000..3ba9f8689061 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.expect @@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias = test::Class; +typedef AliasImpl = test::ClassImpl; +@#C13 +class Class extends core::Object { + static final field dynamic _redirecting# = [#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl extends core::Object implements test::Class { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect#tearOff(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect2#tearOff(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +} diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.modular.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.modular.expect new file mode 100644 index 000000000000..3ba9f8689061 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.modular.expect @@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias = test::Class; +typedef AliasImpl = test::ClassImpl; +@#C13 +class Class extends core::Object { + static final field dynamic _redirecting# = [#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl extends core::Object implements test::Class { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect#tearOff(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect2#tearOff(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +} diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.outline.expect new file mode 100644 index 000000000000..49786e999040 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.outline.expect @@ -0,0 +1,77 @@ +library /*isNonNullableByDefault*/; +import self as self; + +import "dart:test"; + +static method main() → dynamic + ; + +library /*isNonNullableByDefault*/; +import self as self2; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias = self2::Class; +typedef AliasImpl = self2::ClassImpl; +@_js::patch +class Class extends core::Object { + static final field dynamic _redirecting# = [self2::Class::redirect, self2::Class::redirect2]/*isLegacy*/; + @_js::patch + external constructor •({core::bool defaultValue = true, required self2::Class::T% value = null}) → self2::Class + ; + static method _#new#tearOff({has-declared-initializer core::bool defaultValue, required self2::Class::_#new#tearOff::T% value}) → self2::Class + return new self2::Class::•(defaultValue: defaultValue, value: value); + @_js::patch + external static factory fact({has-declared-initializer core::bool defaultValue, required self2::Class::fact::T% value}) → self2::Class; + static method _#fact#tearOff({has-declared-initializer core::bool defaultValue, required self2::Class::_#fact#tearOff::T% value}) → self2::Class + return self2::Class::fact(defaultValue: defaultValue, value: value); + @_js::patch + external static factory redirect({core::bool defaultValue, required self2::Class::redirect::T% value}) → self2::Class + return new self2::ClassImpl::•(defaultValue: defaultValue, value: value); + static method _#redirect#tearOff({core::bool defaultValue, required self2::Class::_#redirect#tearOff::T% value}) → self2::Class + return self2::Class::redirect(defaultValue: defaultValue, value: value); + @_js::patch + external static factory redirect2({core::bool defaultValue, required self2::Class::redirect2::T% value}) → self2::Class + return new self2::ClassImpl::patched(defaultValue: defaultValue, value: value); + static method _#redirect2#tearOff({core::bool defaultValue, required self2::Class::_#redirect2#tearOff::T% value}) → self2::Class + return self2::Class::redirect2(defaultValue: defaultValue, value: value); +} +@_js::patch +class ClassImpl extends core::Object implements self2::Class { + constructor •({core::bool defaultValue = true, required self2::ClassImpl::T% value = null}) → self2::ClassImpl + ; + @_js::patch + external constructor patched({core::bool defaultValue = true, required self2::ClassImpl::T% value = null}) → self2::ClassImpl + ; + static method _#new#tearOff({has-declared-initializer core::bool defaultValue, required self2::ClassImpl::_#new#tearOff::T% value}) → self2::ClassImpl + return new self2::ClassImpl::•(defaultValue: defaultValue, value: value); + static method _#patched#tearOff({has-declared-initializer core::bool defaultValue, required self2::ClassImpl::_#patched#tearOff::T% value}) → self2::ClassImpl + return new self2::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff({has-declared-initializer core::bool defaultValue, required self2::_#Alias#new#tearOff::T value}) → self2::Class + return new self2::Class::•(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff({has-declared-initializer core::bool defaultValue, required self2::_#Alias#fact#tearOff::T value}) → self2::Class + return self2::Class::fact(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff({core::bool defaultValue, required self2::_#Alias#redirect#tearOff::T value}) → self2::Class + return self2::Class::_#redirect#tearOff(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff({core::bool defaultValue, required self2::_#Alias#redirect2#tearOff::T value}) → self2::Class + return self2::Class::_#redirect2#tearOff(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff({has-declared-initializer core::bool defaultValue, required self2::_#AliasImpl#new#tearOff::T value}) → self2::ClassImpl + return new self2::ClassImpl::•(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff({has-declared-initializer core::bool defaultValue, required self2::_#AliasImpl#patched#tearOff::T value}) → self2::ClassImpl + return new self2::ClassImpl::patched(defaultValue: defaultValue, value: value); + + +Extra constant evaluation status: +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:6:47 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:7:10 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:8:29 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:12:22 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:15:12 -> InstanceConstant(const _Patch{}) +Evaluated: ConstructorTearOff @ org-dartlang-testcase:///origin_lib.dart:5:7 -> ConstructorTearOffConstant(Class.redirect) +Evaluated: ConstructorTearOff @ org-dartlang-testcase:///origin_lib.dart:5:7 -> ConstructorTearOffConstant(Class.redirect2) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:18:39 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:19:48 -> InstanceConstant(const _Patch{}) +Extra constant evaluation: evaluated: 52, effectively constant: 9 diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.transformed.expect new file mode 100644 index 000000000000..3ba9f8689061 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.transformed.expect @@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias = test::Class; +typedef AliasImpl = test::ClassImpl; +@#C13 +class Class extends core::Object { + static final field dynamic _redirecting# = [#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl extends core::Object implements test::Class { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect#tearOff(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect2#tearOff(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +} diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/origin_lib.dart b/pkg/front_end/testcases/dart2js/tear_off_patch/origin_lib.dart new file mode 100644 index 000000000000..c29cf6f2e642 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/origin_lib.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +class Class { + external Class({bool defaultValue: true, required T value}); + external factory Class.fact({bool defaultValue: true, required T value}); + external factory Class.redirect({bool defaultValue, required T value}); + external factory Class.redirect2({bool defaultValue, required T value}); +} + +class ClassImpl implements Class { + ClassImpl({bool defaultValue: true, required T value}); + + external ClassImpl.patched({bool defaultValue: true, required T value}); +} + +typedef Alias = Class; +typedef AliasImpl = ClassImpl; diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/patch_lib.dart b/pkg/front_end/testcases/dart2js/tear_off_patch/patch_lib.dart new file mode 100644 index 000000000000..77fdfb02e68f --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/patch_lib.dart @@ -0,0 +1,33 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// ignore: import_internal_library +import 'dart:_js_helper'; + +@patch +class Class { + @patch + Class({bool defaultValue: true, required T value}) { + print('patch Class'); + } + + @patch + factory Class.fact({bool defaultValue: true, required T value}) => + new ClassImpl(defaultValue: defaultValue, value: value); + + @patch + factory Class.redirect({bool defaultValue, required T value}) = ClassImpl; + + @patch + factory Class.redirect2({bool defaultValue, required T value}) = + ClassImpl.patched; +} + +@patch +class ClassImpl implements Class { + @patch + ClassImpl.patched({bool defaultValue: true, required T value}) { + print('patch ClassImpl'); + } +} diff --git a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.expect b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.expect index 3eaf93271eb8..af740373d134 100644 --- a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.expect +++ b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.expect @@ -24,12 +24,12 @@ class Class extends core::Object { @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C3}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); - static method _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::fact(defaultValue: defaultValue); @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ constFact({core::bool defaultValue = #C3}) → test::Class return throw "unsupported"; - static method _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::constFact(defaultValue: defaultValue); static method /* from org-dartlang-testcase:///patch_lib.dart */ _#_internal#tearOff({core::bool defaultValue = #C2}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); diff --git a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.transformed.expect b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.transformed.expect index 3eaf93271eb8..af740373d134 100644 --- a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.transformed.expect @@ -24,12 +24,12 @@ class Class extends core::Object { @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C3}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); - static method _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::fact(defaultValue: defaultValue); @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ constFact({core::bool defaultValue = #C3}) → test::Class return throw "unsupported"; - static method _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::constFact(defaultValue: defaultValue); static method /* from org-dartlang-testcase:///patch_lib.dart */ _#_internal#tearOff({core::bool defaultValue = #C2}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); diff --git a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.expect b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.expect index 3eaf93271eb8..af740373d134 100644 --- a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.expect +++ b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.expect @@ -24,12 +24,12 @@ class Class extends core::Object { @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C3}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); - static method _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::fact(defaultValue: defaultValue); @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ constFact({core::bool defaultValue = #C3}) → test::Class return throw "unsupported"; - static method _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::constFact(defaultValue: defaultValue); static method /* from org-dartlang-testcase:///patch_lib.dart */ _#_internal#tearOff({core::bool defaultValue = #C2}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); diff --git a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.modular.expect b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.modular.expect index 3eaf93271eb8..af740373d134 100644 --- a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.modular.expect +++ b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.modular.expect @@ -24,12 +24,12 @@ class Class extends core::Object { @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C3}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); - static method _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::fact(defaultValue: defaultValue); @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ constFact({core::bool defaultValue = #C3}) → test::Class return throw "unsupported"; - static method _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::constFact(defaultValue: defaultValue); static method /* from org-dartlang-testcase:///patch_lib.dart */ _#_internal#tearOff({core::bool defaultValue = #C2}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); diff --git a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.transformed.expect b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.transformed.expect index 3eaf93271eb8..af740373d134 100644 --- a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.transformed.expect @@ -24,12 +24,12 @@ class Class extends core::Object { @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C3}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); - static method _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::fact(defaultValue: defaultValue); @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ constFact({core::bool defaultValue = #C3}) → test::Class return throw "unsupported"; - static method _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::constFact(defaultValue: defaultValue); static method /* from org-dartlang-testcase:///patch_lib.dart */ _#_internal#tearOff({core::bool defaultValue = #C2}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); diff --git a/pkg/front_end/testcases/general/tear_off_patch/libraries.json b/pkg/front_end/testcases/general/tear_off_patch/libraries.json new file mode 100644 index 000000000000..154c73c30b2b --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/libraries.json @@ -0,0 +1,12 @@ +{ + "none": { + "libraries": { + "test": { + "patches": [ + "patch_lib.dart" + ], + "uri": "origin_lib.dart" + } + } + } +} diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart b/pkg/front_end/testcases/general/tear_off_patch/main.dart new file mode 100644 index 000000000000..676f68ab0f39 --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:test'; + +main() { + Class.new; + Class.fact; + Class.redirect; + Class.redirect2; + ClassImpl.new; + ClassImpl.patched; + Alias.new; + Alias.fact; + Alias.redirect; + Alias.redirect2; + AliasImpl.new; + AliasImpl.patched; +} diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.expect new file mode 100644 index 000000000000..3ba9f8689061 --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.expect @@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias = test::Class; +typedef AliasImpl = test::ClassImpl; +@#C13 +class Class extends core::Object { + static final field dynamic _redirecting# = [#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl extends core::Object implements test::Class { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect#tearOff(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect2#tearOff(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +} diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.transformed.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.transformed.expect new file mode 100644 index 000000000000..3ba9f8689061 --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.transformed.expect @@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias = test::Class; +typedef AliasImpl = test::ClassImpl; +@#C13 +class Class extends core::Object { + static final field dynamic _redirecting# = [#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl extends core::Object implements test::Class { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect#tearOff(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class + return test::Class::_#redirect2#tearOff(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +} diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline.expect new file mode 100644 index 000000000000..3c9c90e9437e --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline.expect @@ -0,0 +1,3 @@ +import 'dart:test'; + +main() {} diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline_modelled.expect new file mode 100644 index 000000000000..3c9c90e9437e --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline_modelled.expect @@ -0,0 +1,3 @@ +import 'dart:test'; + +main() {} diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.expect new file mode 100644 index 000000000000..7663f6b06ab6 --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.expect @@ -0,0 +1,92 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_internal" as _in; + +import "dart:_internal"; + +typedef Alias = test::Class; +typedef AliasImpl = test::ClassImpl; +@#C13 +class Class extends core::Object { + static final field dynamic _redirecting# = [#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class + : super core::Object::•() { + core::print("patch Class"); + } + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl extends core::Object implements test::Class { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() { + core::print("patch ClassImpl"); + } +} +static method _#Alias#new#tearOff({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff({core::bool defaultValue = #C16, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class + return test::Class::redirect(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff({core::bool defaultValue = #C16, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class + return test::Class::redirect2(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + +constants { + #C1 = constructor-tearoff test::Class::• + #C2 = constructor-tearoff test::Class::fact + #C3 = redirecting-factory-tearoff test::Class::redirect + #C4 = redirecting-factory-tearoff test::Class::redirect2 + #C5 = constructor-tearoff test::ClassImpl::• + #C6 = constructor-tearoff test::ClassImpl::patched + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _in::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +} diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.modular.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.modular.expect new file mode 100644 index 000000000000..7663f6b06ab6 --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.modular.expect @@ -0,0 +1,92 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_internal" as _in; + +import "dart:_internal"; + +typedef Alias = test::Class; +typedef AliasImpl = test::ClassImpl; +@#C13 +class Class extends core::Object { + static final field dynamic _redirecting# = [#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class + : super core::Object::•() { + core::print("patch Class"); + } + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl extends core::Object implements test::Class { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() { + core::print("patch ClassImpl"); + } +} +static method _#Alias#new#tearOff({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff({core::bool defaultValue = #C16, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class + return test::Class::redirect(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff({core::bool defaultValue = #C16, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class + return test::Class::redirect2(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + +constants { + #C1 = constructor-tearoff test::Class::• + #C2 = constructor-tearoff test::Class::fact + #C3 = redirecting-factory-tearoff test::Class::redirect + #C4 = redirecting-factory-tearoff test::Class::redirect2 + #C5 = constructor-tearoff test::ClassImpl::• + #C6 = constructor-tearoff test::ClassImpl::patched + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _in::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +} diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.outline.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.outline.expect new file mode 100644 index 000000000000..40d29d32f89f --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.outline.expect @@ -0,0 +1,65 @@ +library /*isNonNullableByDefault*/; +import self as self; + +import "dart:test"; + +static method main() → dynamic + ; + +library /*isNonNullableByDefault*/; +import self as self2; +import "dart:core" as core; +import "dart:_internal" as _in; + +import "dart:_internal"; + +typedef Alias = self2::Class; +typedef AliasImpl = self2::ClassImpl; +@_in::patch +class Class extends core::Object { + static final field dynamic _redirecting# = [self2::Class::redirect, self2::Class::redirect2]/*isLegacy*/; + @_in::patch + external constructor •({core::bool defaultValue = true, required self2::Class::T% value = null}) → self2::Class + ; + @_in::patch + external static factory fact({has-declared-initializer core::bool defaultValue, required self2::Class::fact::T% value}) → self2::Class; + @_in::patch + external static factory redirect({core::bool defaultValue, required self2::Class::redirect::T% value}) → self2::Class + return new self2::ClassImpl::•(defaultValue: defaultValue, value: value); + @_in::patch + external static factory redirect2({core::bool defaultValue, required self2::Class::redirect2::T% value}) → self2::Class + return new self2::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +@_in::patch +class ClassImpl extends core::Object implements self2::Class { + constructor •({core::bool defaultValue = true, required self2::ClassImpl::T% value = null}) → self2::ClassImpl + ; + @_in::patch + external constructor patched({core::bool defaultValue = true, required self2::ClassImpl::T% value = null}) → self2::ClassImpl + ; +} +static method _#Alias#new#tearOff({has-declared-initializer core::bool defaultValue, required self2::_#Alias#new#tearOff::T value}) → self2::Class + return new self2::Class::•(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff({has-declared-initializer core::bool defaultValue, required self2::_#Alias#fact#tearOff::T value}) → self2::Class + return self2::Class::fact(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff({core::bool defaultValue, required self2::_#Alias#redirect#tearOff::T value}) → self2::Class + return self2::Class::redirect(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff({core::bool defaultValue, required self2::_#Alias#redirect2#tearOff::T value}) → self2::Class + return self2::Class::redirect2(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff({has-declared-initializer core::bool defaultValue, required self2::_#AliasImpl#new#tearOff::T value}) → self2::ClassImpl + return new self2::ClassImpl::•(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff({has-declared-initializer core::bool defaultValue, required self2::_#AliasImpl#patched#tearOff::T value}) → self2::ClassImpl + return new self2::ClassImpl::patched(defaultValue: defaultValue, value: value); + + +Extra constant evaluation status: +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:6:46 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:7:9 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:8:28 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:12:21 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:15:11 -> InstanceConstant(const _Patch{}) +Evaluated: ConstructorTearOff @ org-dartlang-testcase:///origin_lib.dart:5:7 -> ConstructorTearOffConstant(Class.redirect) +Evaluated: ConstructorTearOff @ org-dartlang-testcase:///origin_lib.dart:5:7 -> ConstructorTearOffConstant(Class.redirect2) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:18:38 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:19:47 -> InstanceConstant(const _Patch{}) +Extra constant evaluation: evaluated: 34, effectively constant: 9 diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.transformed.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.transformed.expect new file mode 100644 index 000000000000..7663f6b06ab6 --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.transformed.expect @@ -0,0 +1,92 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_internal" as _in; + +import "dart:_internal"; + +typedef Alias = test::Class; +typedef AliasImpl = test::ClassImpl; +@#C13 +class Class extends core::Object { + static final field dynamic _redirecting# = [#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class + : super core::Object::•() { + core::print("patch Class"); + } + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl extends core::Object implements test::Class { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl + : super core::Object::•() { + core::print("patch ClassImpl"); + } +} +static method _#Alias#new#tearOff({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class + return new test::Class::•(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class + return test::Class::fact(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff({core::bool defaultValue = #C16, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class + return test::Class::redirect(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff({core::bool defaultValue = #C16, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class + return test::Class::redirect2(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::•(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl + return new test::ClassImpl::patched(defaultValue: defaultValue, value: value); + +constants { + #C1 = constructor-tearoff test::Class::• + #C2 = constructor-tearoff test::Class::fact + #C3 = redirecting-factory-tearoff test::Class::redirect + #C4 = redirecting-factory-tearoff test::Class::redirect2 + #C5 = constructor-tearoff test::ClassImpl::• + #C6 = constructor-tearoff test::ClassImpl::patched + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _in::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +} diff --git a/pkg/front_end/testcases/general/tear_off_patch/origin_lib.dart b/pkg/front_end/testcases/general/tear_off_patch/origin_lib.dart new file mode 100644 index 000000000000..c29cf6f2e642 --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/origin_lib.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +class Class { + external Class({bool defaultValue: true, required T value}); + external factory Class.fact({bool defaultValue: true, required T value}); + external factory Class.redirect({bool defaultValue, required T value}); + external factory Class.redirect2({bool defaultValue, required T value}); +} + +class ClassImpl implements Class { + ClassImpl({bool defaultValue: true, required T value}); + + external ClassImpl.patched({bool defaultValue: true, required T value}); +} + +typedef Alias = Class; +typedef AliasImpl = ClassImpl; diff --git a/pkg/front_end/testcases/general/tear_off_patch/patch_lib.dart b/pkg/front_end/testcases/general/tear_off_patch/patch_lib.dart new file mode 100644 index 000000000000..7265272d4452 --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/patch_lib.dart @@ -0,0 +1,33 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// ignore: import_internal_library +import 'dart:_internal'; + +@patch +class Class { + @patch + Class({bool defaultValue: true, required T value}) { + print('patch Class'); + } + + @patch + factory Class.fact({bool defaultValue: true, required T value}) => + new ClassImpl(defaultValue: defaultValue, value: value); + + @patch + factory Class.redirect({bool defaultValue, required T value}) = ClassImpl; + + @patch + factory Class.redirect2({bool defaultValue, required T value}) = + ClassImpl.patched; +} + +@patch +class ClassImpl implements Class { + @patch + ClassImpl.patched({bool defaultValue: true, required T value}) { + print('patch ClassImpl'); + } +} diff --git a/tests/language/constructor/patch_tear_off_test.dart b/tests/language/constructor/patch_tear_off_test.dart new file mode 100644 index 000000000000..632a208bd4ba --- /dev/null +++ b/tests/language/constructor/patch_tear_off_test.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Regression test for https://github.com/dart-lang/sdk/issues/48776 + +main() { + /// BigInt.from is a patched constructor. + BigInt.from; +}