[cfe] Reimplement typedef tearoff lowering

Using top level procedures generated for each constructor in the
targeted class.

Closes #46676

Change-Id: I42e98254e5cdb8922fafd29e0170dd70ef3e693e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/207961
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
Johnni Winther 2021-07-23 14:29:37 +00:00
parent 80b05d07e8
commit ca8ea1d936
37 changed files with 2085 additions and 335 deletions

View file

@ -78,9 +78,8 @@ class SourceFactoryBuilder extends FunctionBuilderImpl {
..fileOffset = charOffset
..fileEndOffset = charEndOffset
..isNonNullableByDefault = libraryBuilder.isNonNullableByDefault,
_factoryTearOff = createConstructorTearOffProcedure(
name, libraryBuilder, libraryBuilder.fileUri, charOffset,
forAbstractClassOrEnum: false),
_factoryTearOff = createFactoryTearOffProcedure(
name, libraryBuilder, libraryBuilder.fileUri, charOffset),
super(metadata, modifiers, returnType, name, typeVariables, formals,
libraryBuilder, charOffset, nativeMethodName) {
this.asyncModifier = asyncModifier;

View file

@ -5,7 +5,6 @@
library fasta.function_type_alias_builder;
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/src/legacy_erasure.dart';
import 'package:kernel/type_algebra.dart' show substitute, uniteNullabilities;
@ -20,7 +19,6 @@ import '../fasta_codes.dart'
import '../problems.dart' show unhandled;
import '../source/source_library_builder.dart';
import '../util/helpers.dart';
import 'class_builder.dart';
import 'library_builder.dart';
@ -113,10 +111,28 @@ abstract class TypeAliasBuilder implements TypeDeclarationBuilder {
// as stated in the docs? It is not needed for the implementation.
List<TypeBuilder>? unaliasTypeArguments(List<TypeBuilder>? typeArguments);
void buildOutlineExpressions(
SourceLibraryBuilder library,
CoreTypes coreTypes,
List<DelayedActionPerformer> delayedActionPerformers);
/// Returns the lowering for the constructor or factory named [name] on the
/// effective target class of this typedef.
///
/// For instance, if we have
///
/// class A<T> {
/// A();
/// }
/// typedef F = A<int>;
/// typedef G = F;
/// typedef H<X, Y> = A<X>;
///
/// the lowering will create
///
/// A<int> _#F#new#tearOff() => new A<int>();
/// A<int> _#G#new#tearOff() => new A<int>();
/// A<int> _#H#new#tearOff<X, Y>() => new A<X>();
///
/// which will be return by [findConstructorOrFactory] on `F`, `G`, `H` with
/// name 'new' or ''.
Procedure? findConstructorOrFactory(
String name, int charOffset, Uri uri, LibraryBuilder accessingLibrary);
}
abstract class TypeAliasBuilderImpl extends TypeDeclarationBuilderImpl
@ -494,6 +510,17 @@ abstract class TypeAliasBuilderImpl extends TypeDeclarationBuilderImpl
}
return currentTypeArguments;
}
Map<Name, Procedure>? get tearOffs;
Procedure? findConstructorOrFactory(
String text, int charOffset, Uri uri, LibraryBuilder accessingLibrary) {
if (tearOffs != null) {
Name name = new Name(text == 'new' ? '' : text, accessingLibrary.library);
return tearOffs![name];
}
return null;
}
}
/// Used to detect cycles in the declaration of a typedef

View file

@ -6,29 +6,7 @@ library fasta.dill_library_builder;
import 'dart:convert' show jsonDecode;
import 'package:kernel/ast.dart'
show
Class,
ConstantExpression,
Constructor,
DartType,
DynamicType,
Expression,
Extension,
Field,
FunctionType,
Library,
ListLiteral,
Member,
NamedNode,
NeverType,
Procedure,
ProcedureKind,
Reference,
StaticGet,
StringConstant,
StringLiteral,
Typedef;
import 'package:kernel/ast.dart';
import '../builder/builder.dart';
import '../builder/class_builder.dart';
@ -122,8 +100,23 @@ class DillLibraryBuilder extends LibraryBuilderImpl {
isBuilt = true;
library.classes.forEach(addClass);
library.extensions.forEach(addExtension);
Map<String, Map<Name, Procedure>> tearOffs = {};
List<Procedure> nonTearOffs = [];
for (Procedure procedure in library.procedures) {
List<Object>? names = extractTypedefNameFromTearOff(procedure.name);
if (names != null) {
Map<Name, Procedure> map = tearOffs[names[0] as String] ??= {};
map[names[1] as Name] = procedure;
} else {
nonTearOffs.add(procedure);
}
}
nonTearOffs.forEach(addMember);
library.procedures.forEach(addMember);
library.typedefs.forEach(addTypedef);
for (Typedef typedef in library.typedefs) {
addTypedef(typedef, tearOffs[typedef.name]);
}
library.fields.forEach(addMember);
if (isReadyToFinalizeExports) {
@ -285,12 +278,12 @@ class DillLibraryBuilder extends LibraryBuilderImpl {
return declaration;
}
void addTypedef(Typedef typedef) {
void addTypedef(Typedef typedef, Map<Name, Procedure>? tearOffs) {
DartType? type = typedef.type;
if (type is FunctionType && type.typedefType == null) {
unhandled("null", "addTypedef", typedef.fileOffset, typedef.fileUri);
}
addBuilder(typedef.name, new DillTypeAliasBuilder(typedef, this),
addBuilder(typedef.name, new DillTypeAliasBuilder(typedef, tearOffs, this),
typedef.fileOffset);
}

View file

@ -4,8 +4,7 @@
library fasta.dill_typedef_builder;
import 'package:kernel/ast.dart' show DartType, InvalidType, NullType, Typedef;
import 'package:kernel/core_types.dart';
import 'package:kernel/ast.dart';
import '../builder/library_builder.dart';
import '../builder/metadata_builder.dart';
@ -15,20 +14,20 @@ import '../builder/type_variable_builder.dart';
import '../problems.dart' show unimplemented;
import '../util/helpers.dart';
import 'dill_class_builder.dart' show computeTypeVariableBuilders;
import 'dill_library_builder.dart' show DillLibraryBuilder;
class DillTypeAliasBuilder extends TypeAliasBuilderImpl {
final Typedef typedef;
final Map<Name, Procedure>? tearOffs;
List<TypeVariableBuilder>? _typeVariables;
TypeBuilder? _type;
DartType? thisType;
DillTypeAliasBuilder(this.typedef, DillLibraryBuilder parent)
DillTypeAliasBuilder(this.typedef, this.tearOffs, DillLibraryBuilder parent)
: super(null, typedef.name, parent, typedef.fileOffset);
List<MetadataBuilder> get metadata {
@ -91,10 +90,4 @@ class DillTypeAliasBuilder extends TypeAliasBuilderImpl {
@override
bool get isNullAlias => typedef.type is NullType;
@override
void buildOutlineExpressions(LibraryBuilder library, CoreTypes coreTypes,
List<DelayedActionPerformer> delayedActionPerformers) {
// TODO(johnniwinther): Remove the need for this.
}
}

View file

@ -23,6 +23,18 @@ Name constructorTearOffName(String name, Library library) {
library);
}
/// Creates the synthesized name to use for the lowering of the tear off of a
/// constructor or factory by the given [constructorName] in [library].
Name typedefTearOffName(
String typedefName, String constructorName, Library library) {
return new Name(
'$_tearOffNamePrefix'
'$typedefName#'
'${constructorName.isEmpty ? 'new' : constructorName}'
'$_tearOffNameSuffix',
library);
}
/// Returns the name of the corresponding constructor or factory if [name] is
/// the synthesized name of a lowering of the tear off of a constructor or
/// factory. Returns `null` otherwise.
@ -34,11 +46,37 @@ String? extractConstructorNameFromTearOff(Name name) {
String text =
name.text.substring(0, name.text.length - _tearOffNameSuffix.length);
text = text.substring(_tearOffNamePrefix.length);
if (text.contains('#')) {
return null;
}
return text == 'new' ? '' : text;
}
return null;
}
/// If [name] is the synthesized name of a lowering of a typedef tear off, a
/// list containing the [String] name of the typedef and the [Name] name of the
/// corresponding constructor or factory is returned. Returns `null` otherwise.
List<Object>? extractTypedefNameFromTearOff(Name name) {
if (name.text.startsWith(_tearOffNamePrefix) &&
name.text.endsWith(_tearOffNameSuffix) &&
name.text.length >
_tearOffNamePrefix.length + _tearOffNameSuffix.length) {
String text =
name.text.substring(0, name.text.length - _tearOffNameSuffix.length);
text = text.substring(_tearOffNamePrefix.length);
int hashIndex = text.indexOf('#');
if (hashIndex == -1) {
return null;
}
String typedefName = text.substring(0, hashIndex);
String constructorName = text.substring(hashIndex + 1);
constructorName = constructorName == 'new' ? '' : constructorName;
return [typedefName, new Name(constructorName, name.library)];
}
return null;
}
/// Creates the [Procedure] for the lowering of a generative constructor of
/// the given [name] in [compilationUnit].
///
@ -58,11 +96,45 @@ Procedure? createConstructorTearOffProcedure(String name,
return null;
}
/// Creates the parameters and body for [tearOff] based on [constructor].
/// Creates the [Procedure] for the lowering of a non-redirecting factory of
/// the given [name] in [compilationUnit].
///
/// If constructor tear off lowering is not enabled, `null` is returned.
Procedure? createFactoryTearOffProcedure(String name,
SourceLibraryBuilder compilationUnit, Uri fileUri, int fileOffset) {
if (compilationUnit
.loader.target.backendTarget.isFactoryTearOffLoweringEnabled) {
return _createTearOffProcedure(
compilationUnit,
constructorTearOffName(name, compilationUnit.library),
fileUri,
fileOffset);
}
return null;
}
/// Creates the [Procedure] for the lowering of a typedef tearoff of a
/// constructor of the given [name] in with the typedef defined in
/// [libraryBuilder].
Procedure createTypedefTearOffProcedure(String typedefName, String name,
SourceLibraryBuilder libraryBuilder, Uri fileUri, int fileOffset) {
return _createTearOffProcedure(
libraryBuilder,
typedefTearOffName(typedefName, name, libraryBuilder.library),
fileUri,
fileOffset);
}
/// Creates the parameters and body for [tearOff] based on [constructor] in
/// [enclosingClass].
void buildConstructorTearOffProcedure(Procedure tearOff, Member constructor,
Class enclosingClass, SourceLibraryBuilder libraryBuilder) {
assert(constructor is Constructor ||
(constructor is Procedure && constructor.isFactory));
assert(
constructor is Constructor ||
(constructor is Procedure && constructor.isFactory) ||
(constructor is Procedure && constructor.isStatic),
"Unexpected constructor tear off target $constructor "
"(${constructor.runtimeType}).");
int fileOffset = tearOff.fileOffset;
@ -91,6 +163,58 @@ void buildConstructorTearOffProcedure(Procedure tearOff, Member constructor,
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
/// [enclosingClass].
void buildTypedefTearOffProcedure(
Procedure tearOff,
Member constructor,
Class enclosingClass,
List<TypeParameter> typeParameters,
List<DartType> typeArguments,
SourceLibraryBuilder libraryBuilder) {
assert(
constructor is Constructor ||
(constructor is Procedure && constructor.isFactory) ||
(constructor is Procedure && constructor.isStatic),
"Unexpected constructor tear off target $constructor "
"(${constructor.runtimeType}).");
int fileOffset = tearOff.fileOffset;
FunctionNode function = constructor.function!;
List<TypeParameter> classTypeParameters;
if (constructor is Constructor) {
// Generative constructors implicitly have the type parameters of the
// enclosing class.
classTypeParameters = enclosingClass.typeParameters;
} else {
// Factory constructors explicitly copy over the type parameters of the
// enclosing class.
classTypeParameters = function.typeParameters;
}
FreshTypeParameters freshTypeParameters =
_createFreshTypeParameters(typeParameters, tearOff.function);
Substitution substitution = freshTypeParameters.substitution;
if (!substitution.isEmpty) {
if (typeArguments.isNotEmpty) {
// Translate [typeArgument] into the context of the synthesized procedure.
typeArguments = new List<DartType>.generate(typeArguments.length,
(int index) => substitution.substituteType(typeArguments[index]));
}
}
_createParameters(tearOff, function,
Substitution.fromPairs(classTypeParameters, typeArguments));
Arguments arguments = _createArguments(tearOff, typeArguments, fileOffset);
_createTearOffBody(tearOff, constructor, arguments);
tearOff.function.fileOffset = tearOff.fileOffset;
tearOff.function.fileEndOffset = tearOff.fileOffset;
updatePrivateMemberName(tearOff, libraryBuilder);
}
/// Copies the parameter types from [constructor] to [tearOff].
///
/// These might have been inferred and therefore not available when the
@ -125,25 +249,6 @@ void buildConstructorTearOffOutline(
}
}
void copyTearOffDefaultValues(Procedure tearOff, FunctionNode function) {
CloneVisitorNotMembers cloner = new CloneVisitorNotMembers();
for (int i = 0; i < function.positionalParameters.length; i++) {
VariableDeclaration tearOffParameter =
tearOff.function.positionalParameters[i];
VariableDeclaration constructorParameter = function.positionalParameters[i];
tearOffParameter.initializer =
cloner.cloneOptional(constructorParameter.initializer);
tearOffParameter.initializer?.parent = tearOffParameter;
}
for (int i = 0; i < function.namedParameters.length; i++) {
VariableDeclaration tearOffParameter = tearOff.function.namedParameters[i];
VariableDeclaration constructorParameter = function.namedParameters[i];
tearOffParameter.initializer =
cloner.cloneOptional(constructorParameter.initializer);
tearOffParameter.initializer?.parent = tearOffParameter;
}
}
/// Creates the parameters for the redirecting factory [tearOff] based on the
/// [redirectingConstructor] declaration.
FreshTypeParameters buildRedirectingFactoryTearOffProcedureParameters(
@ -194,79 +299,6 @@ SynthesizedFunctionNode buildRedirectingFactoryTearOffBody(
identicalSignatures: false);
}
/// Creates the synthesized name to use for the lowering of the tear off of a
/// typedef in [library] using [index] for a unique name within the library.
Name typedefTearOffName(int index, Library library) {
return new Name(
'$_tearOffNamePrefix'
'${index}'
'$_tearOffNameSuffix',
library);
}
/// Creates a top level procedure to be used as the lowering for the typedef
/// tear off [node] of a target of type [targetType]. [fileUri] together with
/// the `fileOffset` of [node] is used as the location for the procedure.
/// [index] is used to create a unique name for the procedure within
/// [libraryBuilder].
Procedure createTypedefTearOffLowering(SourceLibraryBuilder libraryBuilder,
TypedefTearOff node, FunctionType targetType, Uri fileUri, int index) {
int fileOffset = node.fileOffset;
Procedure tearOff = _createTearOffProcedure(
libraryBuilder,
typedefTearOffName(index, libraryBuilder.library),
fileUri,
node.fileOffset);
FreshTypeParameters freshTypeParameters =
_createFreshTypeParameters(node.typeParameters, tearOff.function);
Substitution substitution = freshTypeParameters.substitution;
List<DartType> typeArguments = node.typeArguments;
if (typeArguments.isNotEmpty) {
if (!substitution.isEmpty) {
// Translate [typeArgument] into the context of the synthesized procedure.
typeArguments = new List<DartType>.generate(typeArguments.length,
(int index) => substitution.substituteType(typeArguments[index]));
}
// Instantiate [targetType] with [typeArguments].
targetType =
Substitution.fromPairs(targetType.typeParameters, typeArguments)
.substituteType(targetType.withoutTypeParameters) as FunctionType;
}
for (DartType constructorParameter in targetType.positionalParameters) {
VariableDeclaration tearOffParameter = new VariableDeclaration(null,
type: substitution.substituteType(constructorParameter))
..fileOffset = fileOffset;
tearOff.function.positionalParameters.add(tearOffParameter);
tearOffParameter.parent = tearOff.function;
}
for (NamedType constructorParameter in targetType.namedParameters) {
VariableDeclaration tearOffParameter = new VariableDeclaration(
constructorParameter.name,
type: substitution.substituteType(constructorParameter.type),
isRequired: constructorParameter.isRequired)
..fileOffset = fileOffset;
tearOff.function.namedParameters.add(tearOffParameter);
tearOffParameter.parent = tearOff.function;
}
tearOff.function.returnType =
substitution.substituteType(targetType.returnType);
tearOff.function.requiredParameterCount = targetType.requiredParameterCount;
Arguments arguments = _createArguments(tearOff, typeArguments, fileOffset);
Expression constructorInvocation = new FunctionInvocation(
FunctionAccessKind.FunctionType, node.expression, arguments,
functionType: targetType)
..fileOffset = tearOff.fileOffset;
tearOff.function.body = new ReturnStatement(constructorInvocation)
..fileOffset = tearOff.fileOffset
..parent = tearOff.function;
tearOff.function.fileOffset = tearOff.fileOffset;
tearOff.function.fileEndOffset = tearOff.fileOffset;
return tearOff;
}
/// Creates the synthesized [Procedure] node for a tear off lowering by the
/// given [name].
Procedure _createTearOffProcedure(SourceLibraryBuilder libraryBuilder,
@ -351,7 +383,9 @@ Arguments _createArguments(
/// Creates the tear of body for [tearOff] which calls [target] with
/// [arguments].
void _createTearOffBody(Procedure tearOff, Member target, Arguments arguments) {
assert(target is Constructor || (target is Procedure && target.isFactory));
assert(target is Constructor ||
(target is Procedure && target.isFactory) ||
(target is Procedure && target.isStatic));
Expression constructorInvocation;
if (target is Constructor) {
constructorInvocation = new ConstructorInvocation(target, arguments)

View file

@ -3220,6 +3220,13 @@ class TypeUseGenerator extends AbstractReadOnlyAccessGenerator {
if (_helper.isProperRenameForClass(aliasBuilder!.typedef)) {
return tearOffExpression;
}
Procedure? tearOffLowering = aliasBuilder
.findConstructorOrFactory(
name.text, nameOffset, _uri, _helper.libraryBuilder);
if (tearOffLowering != null) {
return _helper.forest
.createStaticTearOff(token.charOffset, tearOffLowering);
}
FreshTypeParameters freshTypeParameters =
getFreshTypeParameters(aliasBuilder.typedef.typeParameters);
List<DartType>? substitutedTypeArguments;
@ -3230,6 +3237,7 @@ class TypeUseGenerator extends AbstractReadOnlyAccessGenerator {
.add(freshTypeParameters.substitute(builtTypeArgument));
}
}
tearOffExpression = _helper.forest.createTypedefTearOff(
token.charOffset,
freshTypeParameters.freshTypeParameters,

View file

@ -258,16 +258,8 @@ class InferenceVisitor
typeParameters: freshTypeParameters.freshTypeParameters,
requiredParameterCount: resultType.requiredParameterCount,
typedefType: null);
Expression replacement = node;
if (!inferrer.isTopLevel &&
inferrer.library.loader.target.backendTarget
.isTypedefTearOffLoweringEnabled) {
replacement = inferrer.library.getTypedefTearOffLowering(
node, expressionType, inferrer.helper!.uri);
}
ExpressionInferenceResult inferredResult =
inferrer.instantiateTearOff(resultType, typeContext, replacement);
inferrer.instantiateTearOff(resultType, typeContext, node);
Expression ensuredResultExpression =
inferrer.ensureAssignableResult(typeContext, inferredResult);
return new ExpressionInferenceResult(

View file

@ -326,6 +326,7 @@ class KernelTarget extends TargetImplementation {
installDefaultSupertypes();
installSyntheticConstructors(myClasses);
loader.resolveConstructors();
loader.installTypedefTearOffs();
component =
link(new List<Library>.from(loader.libraries), nameRoot: nameRoot);
computeCoreTypes();

View file

@ -81,8 +81,6 @@ import '../identifiers.dart' show QualifiedName, flattenName;
import '../import.dart' show Import;
import '../kernel/constructor_tearoff_lowering.dart';
import '../kernel/internal_ast.dart';
import '../kernel/kernel_builder.dart'
@ -4237,15 +4235,23 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
uncheckedTypedefTypes.clear();
}
int _typedefTearOffLoweringIndex = 0;
Expression getTypedefTearOffLowering(
TypedefTearOff node, FunctionType targetType, Uri fileUri) {
assert(loader.target.backendTarget.isTypedefTearOffLoweringEnabled);
Procedure tearOff = createTypedefTearOffLowering(
this, node, targetType, fileUri, _typedefTearOffLoweringIndex++);
library.addProcedure(tearOff);
return new StaticTearOff(tearOff)..fileOffset = node.fileOffset;
void installTypedefTearOffs() {
Iterator<Builder> iterator = this.iterator;
while (iterator.moveNext()) {
Builder? declaration = iterator.current;
while (declaration != null) {
if (declaration is SourceTypeAliasBuilder) {
declaration.buildTypedefTearOffs(this,
(Procedure procedure) {
procedure.isStatic = true;
if (!declaration!.isPatch && !declaration.isDuplicate) {
library.addProcedure(procedure);
}
});
}
declaration = declaration.next;
}
}
}
}

View file

@ -124,6 +124,7 @@ import 'outline_builder.dart' show OutlineBuilder;
import 'source_class_builder.dart' show SourceClassBuilder;
import 'source_library_builder.dart' show SourceLibraryBuilder;
import 'source_type_alias_builder.dart';
class SourceLoader extends Loader {
/// The [FileSystem] which should be used to access files.
@ -719,6 +720,16 @@ class SourceLoader extends Loader {
ticker.logMs("Resolved $count constructors");
}
void installTypedefTearOffs() {
if (target.backendTarget.isTypedefTearOffLoweringEnabled) {
for (LibraryBuilder library in builders.values) {
if (library.loader == this && library is SourceLibraryBuilder) {
library.installTypedefTearOffs();
}
}
}
}
void finishTypeVariables(ClassBuilder object, TypeBuilder dynamicType) {
int count = 0;
for (LibraryBuilder library in builders.values) {
@ -1202,9 +1213,9 @@ class SourceLoader extends Loader {
} else if (declaration is MemberBuilder) {
declaration.buildOutlineExpressions(library, coreTypes,
delayedActionPerformers, synthesizedFunctionNodes);
} else if (declaration is TypeAliasBuilder) {
declaration.buildOutlineExpressions(
library, coreTypes, delayedActionPerformers);
} else if (declaration is SourceTypeAliasBuilder) {
declaration.buildOutlineExpressions(library, coreTypes,
delayedActionPerformers, synthesizedFunctionNodes);
} else {
assert(
declaration is PrefixBuilder ||

View file

@ -4,17 +4,7 @@
library fasta.source_type_alias_builder;
import 'package:kernel/ast.dart'
show
DartType,
DynamicType,
InvalidType,
TypeParameter,
TypeParameterType,
Typedef,
TypedefType,
VariableDeclaration,
getAsTypeArguments;
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';
@ -33,6 +23,7 @@ import '../builder/fixed_type_builder.dart';
import '../builder/formal_parameter_builder.dart';
import '../builder/function_type_builder.dart';
import '../builder/library_builder.dart';
import '../builder/member_builder.dart';
import '../builder/metadata_builder.dart';
import '../builder/named_type_builder.dart';
import '../builder/type_builder.dart';
@ -40,6 +31,9 @@ import '../builder/type_alias_builder.dart';
import '../builder/type_declaration_builder.dart';
import '../builder/type_variable_builder.dart';
import '../kernel/constructor_tearoff_lowering.dart';
import '../kernel/kernel_target.dart';
import '../util/helpers.dart';
import 'source_library_builder.dart' show SourceLibraryBuilder;
@ -54,6 +48,8 @@ class SourceTypeAliasBuilder extends TypeAliasBuilderImpl {
DartType? thisType;
Map<Name, Procedure>? tearOffs;
SourceTypeAliasBuilder(
List<MetadataBuilder>? metadata,
String name,
@ -253,11 +249,11 @@ class SourceTypeAliasBuilder extends TypeAliasBuilderImpl {
allowSuperBounded: false);
}
@override
void buildOutlineExpressions(
SourceLibraryBuilder library,
CoreTypes coreTypes,
List<DelayedActionPerformer> delayedActionPerformers) {
List<DelayedActionPerformer> delayedActionPerformers,
List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
MetadataBuilder.buildAnnotations(
typedef, metadata, library, null, null, fileUri);
if (typeVariables != null) {
@ -266,5 +262,42 @@ class SourceTypeAliasBuilder extends TypeAliasBuilderImpl {
library, null, null, coreTypes, delayedActionPerformers);
}
}
_tearOffDependencies?.forEach((Procedure tearOff, Member target) {
InterfaceType targetType = typedef.type as InterfaceType;
buildTypedefTearOffProcedure(tearOff, target, target.enclosingClass!,
typedef.typeParameters, targetType.typeArguments, library);
synthesizedFunctionNodes.add(new SynthesizedFunctionNode(
new Map<TypeParameter, DartType>.fromIterables(
target.enclosingClass!.typeParameters, targetType.typeArguments),
target.function!,
tearOff.function));
});
}
Map<Procedure, Member>? _tearOffDependencies;
void buildTypedefTearOffs(
SourceLibraryBuilder library, void Function(Procedure) f) {
TypeDeclarationBuilder? declaration = unaliasDeclaration(null);
if (declaration is ClassBuilder) {
tearOffs = {};
_tearOffDependencies = {};
declaration
.forEachConstructor((String constructorName, MemberBuilder builder) {
Member? target = builder.invokeTarget;
if (target != null) {
if (target is Procedure && target.isRedirectingFactory) {
target = builder.readTarget!;
}
Name targetName =
new Name(constructorName, declaration.library.library);
Procedure tearOff = tearOffs![targetName] =
createTypedefTearOffProcedure(
name, constructorName, library, fileUri, charOffset);
_tearOffDependencies![tearOff] = target;
f(tearOff);
}
});
}
}
}

View file

@ -48,10 +48,10 @@ Evaluated: StaticTearOff @ org-dartlang-testcase:///const_tear_off.dart:22:11 ->
Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:23:11 -> InstantiationConstant(A.fact<int*>)
Evaluated: RedirectingFactoryTearOff @ org-dartlang-testcase:///const_tear_off.dart:24:11 -> RedirectingFactoryTearOffConstant(A.redirect)
Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:25:11 -> InstantiationConstant(A.redirect<int*>)
Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:26:11 -> TypedefTearOffConstant(A.<T><int>)
Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:26:11 -> TypedefTearOffConstant(<T>A.<int>)
Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:27:11 -> InstantiationConstant(A.<int*>)
Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:28:11 -> TypedefTearOffConstant(A.fact<T><int>)
Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:28:11 -> TypedefTearOffConstant(<T>A.fact<int>)
Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:29:11 -> InstantiationConstant(A.fact<int*>)
Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:30:11 -> TypedefTearOffConstant(A.redirect<T><int>)
Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:30:11 -> TypedefTearOffConstant(<T>A.redirect<int>)
Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:31:11 -> InstantiationConstant(A.redirect<int*>)
Extra constant evaluation: evaluated: 23, effectively constant: 18

View file

@ -0,0 +1,78 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'main_lib.dart';
typedef H<X, Y> = A<Y>;
// TODO(johnniwinther): Use 'var' here when dependency on inferred parameter
// types is handled.
dynamic H_new = H.new;
dynamic H_named = H.named;
dynamic H_fact = H.fact;
dynamic H_redirect = H.redirect;
dynamic F_new = F.new;
dynamic F_named = F.named;
dynamic F_fact = F.fact;
dynamic F_redirect = F.redirect;
main() {
expect(true, identical(F_new, F_new_lib));
expect(false, identical(F_new, F_named_lib));
expect(false, identical(F_new, F_fact_lib));
expect(false, identical(F_new, F_redirect_lib));
expect(false, identical(F_new, G_new_lib));
expect(false, identical(F_new, G_named_lib));
expect(false, identical(F_new, G_fact_lib));
expect(false, identical(F_new, G_redirect_lib));
expect(false, identical(F_new, H_new));
expect(false, identical(F_new, H_named));
expect(false, identical(F_new, H_fact));
expect(false, identical(F_new, H_redirect));
expect(false, identical(F_named, F_new_lib));
expect(true, identical(F_named, F_named_lib));
expect(false, identical(F_named, F_fact_lib));
expect(false, identical(F_named, F_redirect_lib));
expect(false, identical(F_named, G_new_lib));
expect(false, identical(F_named, G_named_lib));
expect(false, identical(F_named, G_fact_lib));
expect(false, identical(F_named, G_redirect_lib));
expect(false, identical(F_named, H_new));
expect(false, identical(F_named, H_named));
expect(false, identical(F_named, H_fact));
expect(false, identical(F_named, H_redirect));
expect(false, identical(F_fact, F_new_lib));
expect(false, identical(F_fact, F_named_lib));
expect(true, identical(F_fact, F_fact_lib));
expect(false, identical(F_fact, F_redirect_lib));
expect(false, identical(F_fact, G_new_lib));
expect(false, identical(F_fact, G_named_lib));
expect(false, identical(F_fact, G_fact_lib));
expect(false, identical(F_fact, G_redirect_lib));
expect(false, identical(F_fact, H_new));
expect(false, identical(F_fact, H_named));
expect(false, identical(F_fact, H_fact));
expect(false, identical(F_fact, H_redirect));
expect(false, identical(F_redirect, F_new_lib));
expect(false, identical(F_redirect, F_named_lib));
expect(false, identical(F_redirect, F_fact_lib));
expect(true, identical(F_redirect, F_redirect_lib));
expect(false, identical(F_redirect, G_new_lib));
expect(false, identical(F_redirect, G_named_lib));
expect(false, identical(F_redirect, G_fact_lib));
expect(false, identical(F_redirect, G_redirect_lib));
expect(false, identical(F_redirect, H_new));
expect(false, identical(F_redirect, H_named));
expect(false, identical(F_redirect, H_fact));
expect(false, identical(F_redirect, H_redirect));
}
expect(expected, actual) {
if (expected != actual) throw 'Expected $expected, actual $actual';
}

View file

@ -0,0 +1,147 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
static field dynamic H_new = #C1;
static field dynamic H_named = #C2;
static field dynamic H_fact = #C3;
static field dynamic H_redirect = #C4;
static field dynamic F_new = #C5;
static field dynamic F_named = #C6;
static field dynamic F_fact = #C7;
static field dynamic F_redirect = #C8;
static method main() → dynamic {
self::expect(true, core::identical(self::F_new, mai::F_new_lib));
self::expect(false, core::identical(self::F_new, mai::F_named_lib));
self::expect(false, core::identical(self::F_new, mai::F_fact_lib));
self::expect(false, core::identical(self::F_new, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_new, mai::G_new_lib));
self::expect(false, core::identical(self::F_new, mai::G_named_lib));
self::expect(false, core::identical(self::F_new, mai::G_fact_lib));
self::expect(false, core::identical(self::F_new, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_new, self::H_new));
self::expect(false, core::identical(self::F_new, self::H_named));
self::expect(false, core::identical(self::F_new, self::H_fact));
self::expect(false, core::identical(self::F_new, self::H_redirect));
self::expect(false, core::identical(self::F_named, mai::F_new_lib));
self::expect(true, core::identical(self::F_named, mai::F_named_lib));
self::expect(false, core::identical(self::F_named, mai::F_fact_lib));
self::expect(false, core::identical(self::F_named, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_named, mai::G_new_lib));
self::expect(false, core::identical(self::F_named, mai::G_named_lib));
self::expect(false, core::identical(self::F_named, mai::G_fact_lib));
self::expect(false, core::identical(self::F_named, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_named, self::H_new));
self::expect(false, core::identical(self::F_named, self::H_named));
self::expect(false, core::identical(self::F_named, self::H_fact));
self::expect(false, core::identical(self::F_named, self::H_redirect));
self::expect(false, core::identical(self::F_fact, mai::F_new_lib));
self::expect(false, core::identical(self::F_fact, mai::F_named_lib));
self::expect(true, core::identical(self::F_fact, mai::F_fact_lib));
self::expect(false, core::identical(self::F_fact, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_fact, mai::G_new_lib));
self::expect(false, core::identical(self::F_fact, mai::G_named_lib));
self::expect(false, core::identical(self::F_fact, mai::G_fact_lib));
self::expect(false, core::identical(self::F_fact, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_fact, self::H_new));
self::expect(false, core::identical(self::F_fact, self::H_named));
self::expect(false, core::identical(self::F_fact, self::H_fact));
self::expect(false, core::identical(self::F_fact, self::H_redirect));
self::expect(false, core::identical(self::F_redirect, mai::F_new_lib));
self::expect(false, core::identical(self::F_redirect, mai::F_named_lib));
self::expect(false, core::identical(self::F_redirect, mai::F_fact_lib));
self::expect(true, core::identical(self::F_redirect, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_new_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_named_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_fact_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_redirect, self::H_new));
self::expect(false, core::identical(self::F_redirect, self::H_named));
self::expect(false, core::identical(self::F_redirect, self::H_fact));
self::expect(false, core::identical(self::F_redirect, self::H_redirect));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
throw "Expected ${expected}, actual ${actual}";
}
static method _#H#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<self::_#H#fact#tearOff::Y%>
return mai::A::fact<self::_#H#fact#tearOff::Y%>(a, b: b, c: c);
static method _#H#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<self::_#H#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<self::_#H#redirect#tearOff::Y%>();
static method _#H#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<self::_#H#new#tearOff::Y%>
return new mai::A::•<self::_#H#new#tearOff::Y%>();
static method _#H#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#named#tearOff::Y% a, [core::int? b = #C9]) → mai::A<self::_#H#named#tearOff::Y%>
return new mai::A::named<self::_#H#named#tearOff::Y%>(a, b);
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
typedef F<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
typedef G<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
class A<T extends core::Object? = dynamic> extends core::Object {
static final field dynamic _redirecting# = <dynamic>[mai::A::redirect]/*isLegacy*/;
constructor •() → mai::A<mai::A::T%>
: super core::Object::•()
;
constructor named(mai::A::T% a, [core::int? b = #C9]) → mai::A<mai::A::T%>
: super core::Object::•()
;
static method _#new#tearOff<T extends core::Object? = dynamic>() → mai::A<mai::A::_#new#tearOff::T%>
return new mai::A::•<mai::A::_#new#tearOff::T%>();
static method _#named#tearOff<T extends core::Object? = dynamic>(mai::A::_#named#tearOff::T% a, [core::int? b = #C9]) → mai::A<mai::A::_#named#tearOff::T%>
return new mai::A::named<mai::A::_#named#tearOff::T%>(a, b);
static factory fact<T extends core::Object? = dynamic>(mai::A::fact::T% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::A::fact::T%>
return new mai::A::•<mai::A::fact::T%>();
static method _#fact#tearOff<T extends core::Object? = dynamic>(mai::A::_#fact#tearOff::T% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::A::_#fact#tearOff::T%>
return mai::A::fact<mai::A::_#fact#tearOff::T%>(a, b: b, c: c);
static factory redirect<T extends core::Object? = dynamic>() → mai::A<mai::A::redirect::T%>
let dynamic #redirecting_factory = mai::A::• in let mai::A::redirect::T% #typeArg0 = null in invalid-expression;
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → mai::A<mai::A::_#redirect#tearOff::T%>
return new mai::A::•<mai::A::_#redirect#tearOff::T%>();
}
static field dynamic F_new_lib = #C5;
static field dynamic F_named_lib = #C6;
static field dynamic F_fact_lib = #C7;
static field dynamic F_redirect_lib = #C8;
static field dynamic G_new_lib = #C11;
static field dynamic G_named_lib = #C12;
static field dynamic G_fact_lib = #C13;
static field dynamic G_redirect_lib = #C14;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#F#new#tearOff::Y%>
return new mai::A::•<mai::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#F#named#tearOff::Y% a, [core::int? b = #C9]) → mai::A<mai::_#F#named#tearOff::Y%>
return new mai::A::named<mai::_#F#named#tearOff::Y%>(a, b);
static method _#F#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#F#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::_#F#fact#tearOff::Y%>
return mai::A::fact<mai::_#F#fact#tearOff::Y%>(a, b: b, c: c);
static method _#F#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#F#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<mai::_#F#redirect#tearOff::Y%>();
static method _#G#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#G#new#tearOff::Y%>
return new mai::A::•<mai::_#G#new#tearOff::Y%>();
static method _#G#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#G#named#tearOff::Y% a, [core::int? b = #C9]) → mai::A<mai::_#G#named#tearOff::Y%>
return new mai::A::named<mai::_#G#named#tearOff::Y%>(a, b);
static method _#G#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#G#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::_#G#fact#tearOff::Y%>
return mai::A::fact<mai::_#G#fact#tearOff::Y%>(a, b: b, c: c);
static method _#G#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#G#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<mai::_#G#redirect#tearOff::Y%>();
constants {
#C1 = static-tearoff self::_#H#new#tearOff
#C2 = static-tearoff self::_#H#named#tearOff
#C3 = static-tearoff self::_#H#fact#tearOff
#C4 = static-tearoff self::_#H#redirect#tearOff
#C5 = static-tearoff mai::_#F#new#tearOff
#C6 = static-tearoff mai::_#F#named#tearOff
#C7 = static-tearoff mai::_#F#fact#tearOff
#C8 = static-tearoff mai::_#F#redirect#tearOff
#C9 = null
#C10 = 42
#C11 = static-tearoff mai::_#G#new#tearOff
#C12 = static-tearoff mai::_#G#named#tearOff
#C13 = static-tearoff mai::_#G#fact#tearOff
#C14 = static-tearoff mai::_#G#redirect#tearOff
}

View file

@ -0,0 +1,147 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
static field dynamic H_new = #C1;
static field dynamic H_named = #C2;
static field dynamic H_fact = #C3;
static field dynamic H_redirect = #C4;
static field dynamic F_new = #C5;
static field dynamic F_named = #C6;
static field dynamic F_fact = #C7;
static field dynamic F_redirect = #C8;
static method main() → dynamic {
self::expect(true, core::identical(self::F_new, mai::F_new_lib));
self::expect(false, core::identical(self::F_new, mai::F_named_lib));
self::expect(false, core::identical(self::F_new, mai::F_fact_lib));
self::expect(false, core::identical(self::F_new, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_new, mai::G_new_lib));
self::expect(false, core::identical(self::F_new, mai::G_named_lib));
self::expect(false, core::identical(self::F_new, mai::G_fact_lib));
self::expect(false, core::identical(self::F_new, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_new, self::H_new));
self::expect(false, core::identical(self::F_new, self::H_named));
self::expect(false, core::identical(self::F_new, self::H_fact));
self::expect(false, core::identical(self::F_new, self::H_redirect));
self::expect(false, core::identical(self::F_named, mai::F_new_lib));
self::expect(true, core::identical(self::F_named, mai::F_named_lib));
self::expect(false, core::identical(self::F_named, mai::F_fact_lib));
self::expect(false, core::identical(self::F_named, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_named, mai::G_new_lib));
self::expect(false, core::identical(self::F_named, mai::G_named_lib));
self::expect(false, core::identical(self::F_named, mai::G_fact_lib));
self::expect(false, core::identical(self::F_named, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_named, self::H_new));
self::expect(false, core::identical(self::F_named, self::H_named));
self::expect(false, core::identical(self::F_named, self::H_fact));
self::expect(false, core::identical(self::F_named, self::H_redirect));
self::expect(false, core::identical(self::F_fact, mai::F_new_lib));
self::expect(false, core::identical(self::F_fact, mai::F_named_lib));
self::expect(true, core::identical(self::F_fact, mai::F_fact_lib));
self::expect(false, core::identical(self::F_fact, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_fact, mai::G_new_lib));
self::expect(false, core::identical(self::F_fact, mai::G_named_lib));
self::expect(false, core::identical(self::F_fact, mai::G_fact_lib));
self::expect(false, core::identical(self::F_fact, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_fact, self::H_new));
self::expect(false, core::identical(self::F_fact, self::H_named));
self::expect(false, core::identical(self::F_fact, self::H_fact));
self::expect(false, core::identical(self::F_fact, self::H_redirect));
self::expect(false, core::identical(self::F_redirect, mai::F_new_lib));
self::expect(false, core::identical(self::F_redirect, mai::F_named_lib));
self::expect(false, core::identical(self::F_redirect, mai::F_fact_lib));
self::expect(true, core::identical(self::F_redirect, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_new_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_named_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_fact_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_redirect, self::H_new));
self::expect(false, core::identical(self::F_redirect, self::H_named));
self::expect(false, core::identical(self::F_redirect, self::H_fact));
self::expect(false, core::identical(self::F_redirect, self::H_redirect));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
throw "Expected ${expected}, actual ${actual}";
}
static method _#H#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<self::_#H#fact#tearOff::Y%>
return mai::A::fact<self::_#H#fact#tearOff::Y%>(a, b: b, c: c);
static method _#H#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<self::_#H#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<self::_#H#redirect#tearOff::Y%>();
static method _#H#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<self::_#H#new#tearOff::Y%>
return new mai::A::•<self::_#H#new#tearOff::Y%>();
static method _#H#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#named#tearOff::Y% a, [core::int? b = #C9]) → mai::A<self::_#H#named#tearOff::Y%>
return new mai::A::named<self::_#H#named#tearOff::Y%>(a, b);
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
typedef F<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
typedef G<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
class A<T extends core::Object? = dynamic> extends core::Object {
static final field dynamic _redirecting# = <dynamic>[mai::A::redirect]/*isLegacy*/;
constructor •() → mai::A<mai::A::T%>
: super core::Object::•()
;
constructor named(mai::A::T% a, [core::int? b = #C9]) → mai::A<mai::A::T%>
: super core::Object::•()
;
static method _#new#tearOff<T extends core::Object? = dynamic>() → mai::A<mai::A::_#new#tearOff::T%>
return new mai::A::•<mai::A::_#new#tearOff::T%>();
static method _#named#tearOff<T extends core::Object? = dynamic>(mai::A::_#named#tearOff::T% a, [core::int? b = #C9]) → mai::A<mai::A::_#named#tearOff::T%>
return new mai::A::named<mai::A::_#named#tearOff::T%>(a, b);
static factory fact<T extends core::Object? = dynamic>(mai::A::fact::T% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::A::fact::T%>
return new mai::A::•<mai::A::fact::T%>();
static method _#fact#tearOff<T extends core::Object? = dynamic>(mai::A::_#fact#tearOff::T% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::A::_#fact#tearOff::T%>
return mai::A::fact<mai::A::_#fact#tearOff::T%>(a, b: b, c: c);
static factory redirect<T extends core::Object? = dynamic>() → mai::A<mai::A::redirect::T%>
let Never #redirecting_factory = mai::A::• in let mai::A::redirect::T% #typeArg0 = null in invalid-expression;
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → mai::A<mai::A::_#redirect#tearOff::T%>
return new mai::A::•<mai::A::_#redirect#tearOff::T%>();
}
static field dynamic F_new_lib = #C5;
static field dynamic F_named_lib = #C6;
static field dynamic F_fact_lib = #C7;
static field dynamic F_redirect_lib = #C8;
static field dynamic G_new_lib = #C11;
static field dynamic G_named_lib = #C12;
static field dynamic G_fact_lib = #C13;
static field dynamic G_redirect_lib = #C14;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#F#new#tearOff::Y%>
return new mai::A::•<mai::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#F#named#tearOff::Y% a, [core::int? b = #C9]) → mai::A<mai::_#F#named#tearOff::Y%>
return new mai::A::named<mai::_#F#named#tearOff::Y%>(a, b);
static method _#F#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#F#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::_#F#fact#tearOff::Y%>
return mai::A::fact<mai::_#F#fact#tearOff::Y%>(a, b: b, c: c);
static method _#F#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#F#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<mai::_#F#redirect#tearOff::Y%>();
static method _#G#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#G#new#tearOff::Y%>
return new mai::A::•<mai::_#G#new#tearOff::Y%>();
static method _#G#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#G#named#tearOff::Y% a, [core::int? b = #C9]) → mai::A<mai::_#G#named#tearOff::Y%>
return new mai::A::named<mai::_#G#named#tearOff::Y%>(a, b);
static method _#G#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#G#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::_#G#fact#tearOff::Y%>
return mai::A::fact<mai::_#G#fact#tearOff::Y%>(a, b: b, c: c);
static method _#G#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#G#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<mai::_#G#redirect#tearOff::Y%>();
constants {
#C1 = static-tearoff self::_#H#new#tearOff
#C2 = static-tearoff self::_#H#named#tearOff
#C3 = static-tearoff self::_#H#fact#tearOff
#C4 = static-tearoff self::_#H#redirect#tearOff
#C5 = static-tearoff mai::_#F#new#tearOff
#C6 = static-tearoff mai::_#F#named#tearOff
#C7 = static-tearoff mai::_#F#fact#tearOff
#C8 = static-tearoff mai::_#F#redirect#tearOff
#C9 = null
#C10 = 42
#C11 = static-tearoff mai::_#G#new#tearOff
#C12 = static-tearoff mai::_#G#named#tearOff
#C13 = static-tearoff mai::_#G#fact#tearOff
#C14 = static-tearoff mai::_#G#redirect#tearOff
}

View file

@ -0,0 +1,12 @@
import 'main_lib.dart';
typedef H<X, Y> = A<Y>;
dynamic H_new = H.new;
dynamic H_named = H.named;
dynamic H_fact = H.fact;
dynamic H_redirect = H.redirect;
dynamic F_new = F.new;
dynamic F_named = F.named;
dynamic F_fact = F.fact;
dynamic F_redirect = F.redirect;
main() {}
expect(expected, actual) {}

View file

@ -0,0 +1,147 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
static field dynamic H_new = #C1;
static field dynamic H_named = #C2;
static field dynamic H_fact = #C3;
static field dynamic H_redirect = #C4;
static field dynamic F_new = #C5;
static field dynamic F_named = #C6;
static field dynamic F_fact = #C7;
static field dynamic F_redirect = #C8;
static method main() → dynamic {
self::expect(true, core::identical(self::F_new, mai::F_new_lib));
self::expect(false, core::identical(self::F_new, mai::F_named_lib));
self::expect(false, core::identical(self::F_new, mai::F_fact_lib));
self::expect(false, core::identical(self::F_new, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_new, mai::G_new_lib));
self::expect(false, core::identical(self::F_new, mai::G_named_lib));
self::expect(false, core::identical(self::F_new, mai::G_fact_lib));
self::expect(false, core::identical(self::F_new, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_new, self::H_new));
self::expect(false, core::identical(self::F_new, self::H_named));
self::expect(false, core::identical(self::F_new, self::H_fact));
self::expect(false, core::identical(self::F_new, self::H_redirect));
self::expect(false, core::identical(self::F_named, mai::F_new_lib));
self::expect(true, core::identical(self::F_named, mai::F_named_lib));
self::expect(false, core::identical(self::F_named, mai::F_fact_lib));
self::expect(false, core::identical(self::F_named, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_named, mai::G_new_lib));
self::expect(false, core::identical(self::F_named, mai::G_named_lib));
self::expect(false, core::identical(self::F_named, mai::G_fact_lib));
self::expect(false, core::identical(self::F_named, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_named, self::H_new));
self::expect(false, core::identical(self::F_named, self::H_named));
self::expect(false, core::identical(self::F_named, self::H_fact));
self::expect(false, core::identical(self::F_named, self::H_redirect));
self::expect(false, core::identical(self::F_fact, mai::F_new_lib));
self::expect(false, core::identical(self::F_fact, mai::F_named_lib));
self::expect(true, core::identical(self::F_fact, mai::F_fact_lib));
self::expect(false, core::identical(self::F_fact, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_fact, mai::G_new_lib));
self::expect(false, core::identical(self::F_fact, mai::G_named_lib));
self::expect(false, core::identical(self::F_fact, mai::G_fact_lib));
self::expect(false, core::identical(self::F_fact, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_fact, self::H_new));
self::expect(false, core::identical(self::F_fact, self::H_named));
self::expect(false, core::identical(self::F_fact, self::H_fact));
self::expect(false, core::identical(self::F_fact, self::H_redirect));
self::expect(false, core::identical(self::F_redirect, mai::F_new_lib));
self::expect(false, core::identical(self::F_redirect, mai::F_named_lib));
self::expect(false, core::identical(self::F_redirect, mai::F_fact_lib));
self::expect(true, core::identical(self::F_redirect, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_new_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_named_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_fact_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_redirect, self::H_new));
self::expect(false, core::identical(self::F_redirect, self::H_named));
self::expect(false, core::identical(self::F_redirect, self::H_fact));
self::expect(false, core::identical(self::F_redirect, self::H_redirect));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
throw "Expected ${expected}, actual ${actual}";
}
static method _#H#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<self::_#H#fact#tearOff::Y%>
return mai::A::fact<self::_#H#fact#tearOff::Y%>(a, b: b, c: c);
static method _#H#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<self::_#H#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<self::_#H#redirect#tearOff::Y%>();
static method _#H#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<self::_#H#new#tearOff::Y%>
return new mai::A::•<self::_#H#new#tearOff::Y%>();
static method _#H#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#named#tearOff::Y% a, [core::int? b = #C9]) → mai::A<self::_#H#named#tearOff::Y%>
return new mai::A::named<self::_#H#named#tearOff::Y%>(a, b);
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
typedef F<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
typedef G<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
class A<T extends core::Object? = dynamic> extends core::Object {
static final field dynamic _redirecting# = <dynamic>[mai::A::redirect]/*isLegacy*/;
constructor •() → mai::A<mai::A::T%>
: super core::Object::•()
;
constructor named(mai::A::T% a, [core::int? b = #C9]) → mai::A<mai::A::T%>
: super core::Object::•()
;
static method _#new#tearOff<T extends core::Object? = dynamic>() → mai::A<mai::A::_#new#tearOff::T%>
return new mai::A::•<mai::A::_#new#tearOff::T%>();
static method _#named#tearOff<T extends core::Object? = dynamic>(mai::A::_#named#tearOff::T% a, [core::int? b = #C9]) → mai::A<mai::A::_#named#tearOff::T%>
return new mai::A::named<mai::A::_#named#tearOff::T%>(a, b);
static factory fact<T extends core::Object? = dynamic>(mai::A::fact::T% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::A::fact::T%>
return new mai::A::•<mai::A::fact::T%>();
static method _#fact#tearOff<T extends core::Object? = dynamic>(mai::A::_#fact#tearOff::T% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::A::_#fact#tearOff::T%>
return mai::A::fact<mai::A::_#fact#tearOff::T%>(a, b: b, c: c);
static factory redirect<T extends core::Object? = dynamic>() → mai::A<mai::A::redirect::T%>
let dynamic #redirecting_factory = mai::A::• in let mai::A::redirect::T% #typeArg0 = null in invalid-expression;
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → mai::A<mai::A::_#redirect#tearOff::T%>
return new mai::A::•<mai::A::_#redirect#tearOff::T%>();
}
static field dynamic F_new_lib = #C5;
static field dynamic F_named_lib = #C6;
static field dynamic F_fact_lib = #C7;
static field dynamic F_redirect_lib = #C8;
static field dynamic G_new_lib = #C11;
static field dynamic G_named_lib = #C12;
static field dynamic G_fact_lib = #C13;
static field dynamic G_redirect_lib = #C14;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#F#new#tearOff::Y%>
return new mai::A::•<mai::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#F#named#tearOff::Y% a, [core::int? b = #C9]) → mai::A<mai::_#F#named#tearOff::Y%>
return new mai::A::named<mai::_#F#named#tearOff::Y%>(a, b);
static method _#F#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#F#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::_#F#fact#tearOff::Y%>
return mai::A::fact<mai::_#F#fact#tearOff::Y%>(a, b: b, c: c);
static method _#F#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#F#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<mai::_#F#redirect#tearOff::Y%>();
static method _#G#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#G#new#tearOff::Y%>
return new mai::A::•<mai::_#G#new#tearOff::Y%>();
static method _#G#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#G#named#tearOff::Y% a, [core::int? b = #C9]) → mai::A<mai::_#G#named#tearOff::Y%>
return new mai::A::named<mai::_#G#named#tearOff::Y%>(a, b);
static method _#G#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#G#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::_#G#fact#tearOff::Y%>
return mai::A::fact<mai::_#G#fact#tearOff::Y%>(a, b: b, c: c);
static method _#G#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#G#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<mai::_#G#redirect#tearOff::Y%>();
constants {
#C1 = static-tearoff self::_#H#new#tearOff
#C2 = static-tearoff self::_#H#named#tearOff
#C3 = static-tearoff self::_#H#fact#tearOff
#C4 = static-tearoff self::_#H#redirect#tearOff
#C5 = static-tearoff mai::_#F#new#tearOff
#C6 = static-tearoff mai::_#F#named#tearOff
#C7 = static-tearoff mai::_#F#fact#tearOff
#C8 = static-tearoff mai::_#F#redirect#tearOff
#C9 = null
#C10 = 42
#C11 = static-tearoff mai::_#G#new#tearOff
#C12 = static-tearoff mai::_#G#named#tearOff
#C13 = static-tearoff mai::_#G#fact#tearOff
#C14 = static-tearoff mai::_#G#redirect#tearOff
}

View file

@ -0,0 +1,78 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
static field dynamic H_new;
static field dynamic H_named;
static field dynamic H_fact;
static field dynamic H_redirect;
static field dynamic F_new;
static field dynamic F_named;
static field dynamic F_fact;
static field dynamic F_redirect;
static method main() → dynamic
;
static method expect(dynamic expected, dynamic actual) → dynamic
;
static method _#H#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#fact#tearOff::Y% a, {core::int? b, core::int c}) → mai::A<self::_#H#fact#tearOff::Y%>
return mai::A::fact<self::_#H#fact#tearOff::Y%>(a, b: b, c: c);
static method _#H#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<self::_#H#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<self::_#H#redirect#tearOff::Y%>();
static method _#H#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<self::_#H#new#tearOff::Y%>
return new mai::A::•<self::_#H#new#tearOff::Y%>();
static method _#H#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#named#tearOff::Y% a, [core::int? b]) → mai::A<self::_#H#named#tearOff::Y%>
return new mai::A::named<self::_#H#named#tearOff::Y%>(a, b);
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
typedef F<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
typedef G<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
class A<T extends core::Object? = dynamic> extends core::Object {
static final field dynamic _redirecting# = <dynamic>[mai::A::redirect]/*isLegacy*/;
constructor •() → mai::A<mai::A::T%>
;
constructor named(mai::A::T% a, [core::int? b]) → mai::A<mai::A::T%>
;
static method _#new#tearOff<T extends core::Object? = dynamic>() → mai::A<mai::A::_#new#tearOff::T%>
return new mai::A::•<mai::A::_#new#tearOff::T%>();
static method _#named#tearOff<T extends core::Object? = dynamic>(mai::A::_#named#tearOff::T% a, [core::int? b]) → mai::A<mai::A::_#named#tearOff::T%>
return new mai::A::named<mai::A::_#named#tearOff::T%>(a, b);
static factory fact<T extends core::Object? = dynamic>(mai::A::fact::T% a, {core::int? b, core::int c}) → mai::A<mai::A::fact::T%>
;
static method _#fact#tearOff<T extends core::Object? = dynamic>(mai::A::_#fact#tearOff::T% a, {core::int? b, core::int c}) → mai::A<mai::A::_#fact#tearOff::T%>
return mai::A::fact<mai::A::_#fact#tearOff::T%>(a, b: b, c: c);
static factory redirect<T extends core::Object? = dynamic>() → mai::A<mai::A::redirect::T%>
let dynamic #redirecting_factory = mai::A::• in let mai::A::redirect::T% #typeArg0 = null in invalid-expression;
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → mai::A<mai::A::_#redirect#tearOff::T%>
return new mai::A::•<mai::A::_#redirect#tearOff::T%>();
}
static field dynamic F_new_lib;
static field dynamic F_named_lib;
static field dynamic F_fact_lib;
static field dynamic F_redirect_lib;
static field dynamic G_new_lib;
static field dynamic G_named_lib;
static field dynamic G_fact_lib;
static field dynamic G_redirect_lib;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#F#new#tearOff::Y%>
return new mai::A::•<mai::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#F#named#tearOff::Y% a, [core::int? b]) → mai::A<mai::_#F#named#tearOff::Y%>
return new mai::A::named<mai::_#F#named#tearOff::Y%>(a, b);
static method _#F#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#F#fact#tearOff::Y% a, {core::int? b, core::int c}) → mai::A<mai::_#F#fact#tearOff::Y%>
return mai::A::fact<mai::_#F#fact#tearOff::Y%>(a, b: b, c: c);
static method _#F#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#F#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<mai::_#F#redirect#tearOff::Y%>();
static method _#G#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#G#new#tearOff::Y%>
return new mai::A::•<mai::_#G#new#tearOff::Y%>();
static method _#G#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#G#named#tearOff::Y% a, [core::int? b]) → mai::A<mai::_#G#named#tearOff::Y%>
return new mai::A::named<mai::_#G#named#tearOff::Y%>(a, b);
static method _#G#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#G#fact#tearOff::Y% a, {core::int? b, core::int c}) → mai::A<mai::_#G#fact#tearOff::Y%>
return mai::A::fact<mai::_#G#fact#tearOff::Y%>(a, b: b, c: c);
static method _#G#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#G#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<mai::_#G#redirect#tearOff::Y%>();

View file

@ -0,0 +1,147 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
static field dynamic H_new = #C1;
static field dynamic H_named = #C2;
static field dynamic H_fact = #C3;
static field dynamic H_redirect = #C4;
static field dynamic F_new = #C5;
static field dynamic F_named = #C6;
static field dynamic F_fact = #C7;
static field dynamic F_redirect = #C8;
static method main() → dynamic {
self::expect(true, core::identical(self::F_new, mai::F_new_lib));
self::expect(false, core::identical(self::F_new, mai::F_named_lib));
self::expect(false, core::identical(self::F_new, mai::F_fact_lib));
self::expect(false, core::identical(self::F_new, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_new, mai::G_new_lib));
self::expect(false, core::identical(self::F_new, mai::G_named_lib));
self::expect(false, core::identical(self::F_new, mai::G_fact_lib));
self::expect(false, core::identical(self::F_new, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_new, self::H_new));
self::expect(false, core::identical(self::F_new, self::H_named));
self::expect(false, core::identical(self::F_new, self::H_fact));
self::expect(false, core::identical(self::F_new, self::H_redirect));
self::expect(false, core::identical(self::F_named, mai::F_new_lib));
self::expect(true, core::identical(self::F_named, mai::F_named_lib));
self::expect(false, core::identical(self::F_named, mai::F_fact_lib));
self::expect(false, core::identical(self::F_named, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_named, mai::G_new_lib));
self::expect(false, core::identical(self::F_named, mai::G_named_lib));
self::expect(false, core::identical(self::F_named, mai::G_fact_lib));
self::expect(false, core::identical(self::F_named, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_named, self::H_new));
self::expect(false, core::identical(self::F_named, self::H_named));
self::expect(false, core::identical(self::F_named, self::H_fact));
self::expect(false, core::identical(self::F_named, self::H_redirect));
self::expect(false, core::identical(self::F_fact, mai::F_new_lib));
self::expect(false, core::identical(self::F_fact, mai::F_named_lib));
self::expect(true, core::identical(self::F_fact, mai::F_fact_lib));
self::expect(false, core::identical(self::F_fact, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_fact, mai::G_new_lib));
self::expect(false, core::identical(self::F_fact, mai::G_named_lib));
self::expect(false, core::identical(self::F_fact, mai::G_fact_lib));
self::expect(false, core::identical(self::F_fact, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_fact, self::H_new));
self::expect(false, core::identical(self::F_fact, self::H_named));
self::expect(false, core::identical(self::F_fact, self::H_fact));
self::expect(false, core::identical(self::F_fact, self::H_redirect));
self::expect(false, core::identical(self::F_redirect, mai::F_new_lib));
self::expect(false, core::identical(self::F_redirect, mai::F_named_lib));
self::expect(false, core::identical(self::F_redirect, mai::F_fact_lib));
self::expect(true, core::identical(self::F_redirect, mai::F_redirect_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_new_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_named_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_fact_lib));
self::expect(false, core::identical(self::F_redirect, mai::G_redirect_lib));
self::expect(false, core::identical(self::F_redirect, self::H_new));
self::expect(false, core::identical(self::F_redirect, self::H_named));
self::expect(false, core::identical(self::F_redirect, self::H_fact));
self::expect(false, core::identical(self::F_redirect, self::H_redirect));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
throw "Expected ${expected}, actual ${actual}";
}
static method _#H#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<self::_#H#fact#tearOff::Y%>
return mai::A::fact<self::_#H#fact#tearOff::Y%>(a, b: b, c: c);
static method _#H#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<self::_#H#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<self::_#H#redirect#tearOff::Y%>();
static method _#H#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<self::_#H#new#tearOff::Y%>
return new mai::A::•<self::_#H#new#tearOff::Y%>();
static method _#H#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#named#tearOff::Y% a, [core::int? b = #C9]) → mai::A<self::_#H#named#tearOff::Y%>
return new mai::A::named<self::_#H#named#tearOff::Y%>(a, b);
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
typedef F<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
typedef G<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = mai::A<Y%>;
class A<T extends core::Object? = dynamic> extends core::Object {
static final field dynamic _redirecting# = <dynamic>[mai::A::redirect]/*isLegacy*/;
constructor •() → mai::A<mai::A::T%>
: super core::Object::•()
;
constructor named(mai::A::T% a, [core::int? b = #C9]) → mai::A<mai::A::T%>
: super core::Object::•()
;
static method _#new#tearOff<T extends core::Object? = dynamic>() → mai::A<mai::A::_#new#tearOff::T%>
return new mai::A::•<mai::A::_#new#tearOff::T%>();
static method _#named#tearOff<T extends core::Object? = dynamic>(mai::A::_#named#tearOff::T% a, [core::int? b = #C9]) → mai::A<mai::A::_#named#tearOff::T%>
return new mai::A::named<mai::A::_#named#tearOff::T%>(a, b);
static factory fact<T extends core::Object? = dynamic>(mai::A::fact::T% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::A::fact::T%>
return new mai::A::•<mai::A::fact::T%>();
static method _#fact#tearOff<T extends core::Object? = dynamic>(mai::A::_#fact#tearOff::T% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::A::_#fact#tearOff::T%>
return mai::A::fact<mai::A::_#fact#tearOff::T%>(a, b: b, c: c);
static factory redirect<T extends core::Object? = dynamic>() → mai::A<mai::A::redirect::T%>
let Never #redirecting_factory = mai::A::• in let mai::A::redirect::T% #typeArg0 = null in invalid-expression;
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → mai::A<mai::A::_#redirect#tearOff::T%>
return new mai::A::•<mai::A::_#redirect#tearOff::T%>();
}
static field dynamic F_new_lib = #C5;
static field dynamic F_named_lib = #C6;
static field dynamic F_fact_lib = #C7;
static field dynamic F_redirect_lib = #C8;
static field dynamic G_new_lib = #C11;
static field dynamic G_named_lib = #C12;
static field dynamic G_fact_lib = #C13;
static field dynamic G_redirect_lib = #C14;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#F#new#tearOff::Y%>
return new mai::A::•<mai::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#F#named#tearOff::Y% a, [core::int? b = #C9]) → mai::A<mai::_#F#named#tearOff::Y%>
return new mai::A::named<mai::_#F#named#tearOff::Y%>(a, b);
static method _#F#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#F#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::_#F#fact#tearOff::Y%>
return mai::A::fact<mai::_#F#fact#tearOff::Y%>(a, b: b, c: c);
static method _#F#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#F#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<mai::_#F#redirect#tearOff::Y%>();
static method _#G#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#G#new#tearOff::Y%>
return new mai::A::•<mai::_#G#new#tearOff::Y%>();
static method _#G#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#G#named#tearOff::Y% a, [core::int? b = #C9]) → mai::A<mai::_#G#named#tearOff::Y%>
return new mai::A::named<mai::_#G#named#tearOff::Y%>(a, b);
static method _#G#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(mai::_#G#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → mai::A<mai::_#G#fact#tearOff::Y%>
return mai::A::fact<mai::_#G#fact#tearOff::Y%>(a, b: b, c: c);
static method _#G#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → mai::A<mai::_#G#redirect#tearOff::Y%>
return mai::A::_#redirect#tearOff<mai::_#G#redirect#tearOff::Y%>();
constants {
#C1 = static-tearoff self::_#H#new#tearOff
#C2 = static-tearoff self::_#H#named#tearOff
#C3 = static-tearoff self::_#H#fact#tearOff
#C4 = static-tearoff self::_#H#redirect#tearOff
#C5 = static-tearoff mai::_#F#new#tearOff
#C6 = static-tearoff mai::_#F#named#tearOff
#C7 = static-tearoff mai::_#F#fact#tearOff
#C8 = static-tearoff mai::_#F#redirect#tearOff
#C9 = null
#C10 = 42
#C11 = static-tearoff mai::_#G#new#tearOff
#C12 = static-tearoff mai::_#G#named#tearOff
#C13 = static-tearoff mai::_#G#fact#tearOff
#C14 = static-tearoff mai::_#G#redirect#tearOff
}

View file

@ -0,0 +1,23 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
class A<T> {
A();
A.named(T a, [int? b]);
factory A.fact(T a, {int? b, int c = 42}) => new A();
factory A.redirect() = A;
}
typedef F<X, Y> = A<Y>;
typedef G<X, Y> = A<Y>;
dynamic F_new_lib = F.new;
dynamic F_named_lib = F.named;
dynamic F_fact_lib = F.fact;
dynamic F_redirect_lib = F.redirect;
dynamic G_new_lib = G.new;
dynamic G_named_lib = G.named;
dynamic G_fact_lib = G.fact;
dynamic G_redirect_lib = G.redirect;

View file

@ -0,0 +1,78 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'typedef_identical_lib.dart';
typedef H<X, Y> = A<Y>;
// TODO(johnniwinther): Use 'var' here when dependency on inferred parameter
// types is handled.
dynamic H_new = H.new;
dynamic H_named = H.named;
dynamic H_fact = H.fact;
dynamic H_redirect = H.redirect;
dynamic F_new = F.new;
dynamic F_named = F.named;
dynamic F_fact = F.fact;
dynamic F_redirect = F.redirect;
main() {
expect(true, identical(F_new, F_new_lib));
expect(false, identical(F_new, F_named_lib));
expect(false, identical(F_new, F_fact_lib));
expect(false, identical(F_new, F_redirect_lib));
expect(false, identical(F_new, G_new_lib));
expect(false, identical(F_new, G_named_lib));
expect(false, identical(F_new, G_fact_lib));
expect(false, identical(F_new, G_redirect_lib));
expect(false, identical(F_new, H_new));
expect(false, identical(F_new, H_named));
expect(false, identical(F_new, H_fact));
expect(false, identical(F_new, H_redirect));
expect(false, identical(F_named, F_new_lib));
expect(true, identical(F_named, F_named_lib));
expect(false, identical(F_named, F_fact_lib));
expect(false, identical(F_named, F_redirect_lib));
expect(false, identical(F_named, G_new_lib));
expect(false, identical(F_named, G_named_lib));
expect(false, identical(F_named, G_fact_lib));
expect(false, identical(F_named, G_redirect_lib));
expect(false, identical(F_named, H_new));
expect(false, identical(F_named, H_named));
expect(false, identical(F_named, H_fact));
expect(false, identical(F_named, H_redirect));
expect(false, identical(F_fact, F_new_lib));
expect(false, identical(F_fact, F_named_lib));
expect(true, identical(F_fact, F_fact_lib));
expect(false, identical(F_fact, F_redirect_lib));
expect(false, identical(F_fact, G_new_lib));
expect(false, identical(F_fact, G_named_lib));
expect(false, identical(F_fact, G_fact_lib));
expect(false, identical(F_fact, G_redirect_lib));
expect(false, identical(F_fact, H_new));
expect(false, identical(F_fact, H_named));
expect(false, identical(F_fact, H_fact));
expect(false, identical(F_fact, H_redirect));
expect(false, identical(F_redirect, F_new_lib));
expect(false, identical(F_redirect, F_named_lib));
expect(false, identical(F_redirect, F_fact_lib));
expect(true, identical(F_redirect, F_redirect_lib));
expect(false, identical(F_redirect, G_new_lib));
expect(false, identical(F_redirect, G_named_lib));
expect(false, identical(F_redirect, G_fact_lib));
expect(false, identical(F_redirect, G_redirect_lib));
expect(false, identical(F_redirect, H_new));
expect(false, identical(F_redirect, H_named));
expect(false, identical(F_redirect, H_fact));
expect(false, identical(F_redirect, H_redirect));
}
expect(expected, actual) {
if (expected != actual) throw 'Expected $expected, actual $actual';
}

View file

@ -0,0 +1,147 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "typedef_identical_lib.dart" as typ;
import "org-dartlang-testcase:///typedef_identical_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
static field dynamic H_new = #C1;
static field dynamic H_named = #C2;
static field dynamic H_fact = #C3;
static field dynamic H_redirect = #C4;
static field dynamic F_new = #C5;
static field dynamic F_named = #C6;
static field dynamic F_fact = #C7;
static field dynamic F_redirect = #C8;
static method main() → dynamic {
self::expect(true, core::identical(self::F_new, typ::F_new_lib));
self::expect(false, core::identical(self::F_new, typ::F_named_lib));
self::expect(false, core::identical(self::F_new, typ::F_fact_lib));
self::expect(false, core::identical(self::F_new, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_new, typ::G_new_lib));
self::expect(false, core::identical(self::F_new, typ::G_named_lib));
self::expect(false, core::identical(self::F_new, typ::G_fact_lib));
self::expect(false, core::identical(self::F_new, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_new, self::H_new));
self::expect(false, core::identical(self::F_new, self::H_named));
self::expect(false, core::identical(self::F_new, self::H_fact));
self::expect(false, core::identical(self::F_new, self::H_redirect));
self::expect(false, core::identical(self::F_named, typ::F_new_lib));
self::expect(true, core::identical(self::F_named, typ::F_named_lib));
self::expect(false, core::identical(self::F_named, typ::F_fact_lib));
self::expect(false, core::identical(self::F_named, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_named, typ::G_new_lib));
self::expect(false, core::identical(self::F_named, typ::G_named_lib));
self::expect(false, core::identical(self::F_named, typ::G_fact_lib));
self::expect(false, core::identical(self::F_named, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_named, self::H_new));
self::expect(false, core::identical(self::F_named, self::H_named));
self::expect(false, core::identical(self::F_named, self::H_fact));
self::expect(false, core::identical(self::F_named, self::H_redirect));
self::expect(false, core::identical(self::F_fact, typ::F_new_lib));
self::expect(false, core::identical(self::F_fact, typ::F_named_lib));
self::expect(true, core::identical(self::F_fact, typ::F_fact_lib));
self::expect(false, core::identical(self::F_fact, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_fact, typ::G_new_lib));
self::expect(false, core::identical(self::F_fact, typ::G_named_lib));
self::expect(false, core::identical(self::F_fact, typ::G_fact_lib));
self::expect(false, core::identical(self::F_fact, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_fact, self::H_new));
self::expect(false, core::identical(self::F_fact, self::H_named));
self::expect(false, core::identical(self::F_fact, self::H_fact));
self::expect(false, core::identical(self::F_fact, self::H_redirect));
self::expect(false, core::identical(self::F_redirect, typ::F_new_lib));
self::expect(false, core::identical(self::F_redirect, typ::F_named_lib));
self::expect(false, core::identical(self::F_redirect, typ::F_fact_lib));
self::expect(true, core::identical(self::F_redirect, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_new_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_named_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_fact_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_redirect, self::H_new));
self::expect(false, core::identical(self::F_redirect, self::H_named));
self::expect(false, core::identical(self::F_redirect, self::H_fact));
self::expect(false, core::identical(self::F_redirect, self::H_redirect));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
throw "Expected ${expected}, actual ${actual}";
}
static method _#H#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<self::_#H#new#tearOff::Y%>
return new typ::A::•<self::_#H#new#tearOff::Y%>();
static method _#H#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<self::_#H#named#tearOff::Y%>
return new typ::A::named<self::_#H#named#tearOff::Y%>(a, b);
static method _#H#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<self::_#H#fact#tearOff::Y%>
return typ::A::fact<self::_#H#fact#tearOff::Y%>(a, b: b, c: c);
static method _#H#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<self::_#H#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<self::_#H#redirect#tearOff::Y%>();
library /*isNonNullableByDefault*/;
import self as typ;
import "dart:core" as core;
typedef F<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
typedef G<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
class A<T extends core::Object? = dynamic> extends core::Object {
static final field dynamic _redirecting# = <dynamic>[typ::A::redirect]/*isLegacy*/;
constructor •() → typ::A<typ::A::T%>
: super core::Object::•()
;
constructor named(typ::A::T% a, [core::int? b = #C9]) → typ::A<typ::A::T%>
: super core::Object::•()
;
static method _#new#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#new#tearOff::T%>
return new typ::A::•<typ::A::_#new#tearOff::T%>();
static method _#named#tearOff<T extends core::Object? = dynamic>(typ::A::_#named#tearOff::T% a, [core::int? b = #C9]) → typ::A<typ::A::_#named#tearOff::T%>
return new typ::A::named<typ::A::_#named#tearOff::T%>(a, b);
static factory fact<T extends core::Object? = dynamic>(typ::A::fact::T% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::A::fact::T%>
return new typ::A::•<typ::A::fact::T%>();
static method _#fact#tearOff<T extends core::Object? = dynamic>(typ::A::_#fact#tearOff::T% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::A::_#fact#tearOff::T%>
return typ::A::fact<typ::A::_#fact#tearOff::T%>(a, b: b, c: c);
static factory redirect<T extends core::Object? = dynamic>() → typ::A<typ::A::redirect::T%>
let dynamic #redirecting_factory = typ::A::• in let typ::A::redirect::T% #typeArg0 = null in invalid-expression;
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#redirect#tearOff::T%>
return new typ::A::•<typ::A::_#redirect#tearOff::T%>();
}
static field dynamic F_new_lib = #C5;
static field dynamic F_named_lib = #C6;
static field dynamic F_fact_lib = #C7;
static field dynamic F_redirect_lib = #C8;
static field dynamic G_new_lib = #C11;
static field dynamic G_named_lib = #C12;
static field dynamic G_fact_lib = #C13;
static field dynamic G_redirect_lib = #C14;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#new#tearOff::Y%>
return new typ::A::•<typ::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<typ::_#F#named#tearOff::Y%>
return new typ::A::named<typ::_#F#named#tearOff::Y%>(a, b);
static method _#F#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::_#F#fact#tearOff::Y%>
return typ::A::fact<typ::_#F#fact#tearOff::Y%>(a, b: b, c: c);
static method _#F#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<typ::_#F#redirect#tearOff::Y%>();
static method _#G#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#G#new#tearOff::Y%>
return new typ::A::•<typ::_#G#new#tearOff::Y%>();
static method _#G#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#G#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<typ::_#G#named#tearOff::Y%>
return new typ::A::named<typ::_#G#named#tearOff::Y%>(a, b);
static method _#G#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#G#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::_#G#fact#tearOff::Y%>
return typ::A::fact<typ::_#G#fact#tearOff::Y%>(a, b: b, c: c);
static method _#G#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#G#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<typ::_#G#redirect#tearOff::Y%>();
constants {
#C1 = static-tearoff self::_#H#new#tearOff
#C2 = static-tearoff self::_#H#named#tearOff
#C3 = static-tearoff self::_#H#fact#tearOff
#C4 = static-tearoff self::_#H#redirect#tearOff
#C5 = static-tearoff typ::_#F#new#tearOff
#C6 = static-tearoff typ::_#F#named#tearOff
#C7 = static-tearoff typ::_#F#fact#tearOff
#C8 = static-tearoff typ::_#F#redirect#tearOff
#C9 = null
#C10 = 42
#C11 = static-tearoff typ::_#G#new#tearOff
#C12 = static-tearoff typ::_#G#named#tearOff
#C13 = static-tearoff typ::_#G#fact#tearOff
#C14 = static-tearoff typ::_#G#redirect#tearOff
}

View file

@ -0,0 +1,147 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "typedef_identical_lib.dart" as typ;
import "org-dartlang-testcase:///typedef_identical_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
static field dynamic H_new = #C1;
static field dynamic H_named = #C2;
static field dynamic H_fact = #C3;
static field dynamic H_redirect = #C4;
static field dynamic F_new = #C5;
static field dynamic F_named = #C6;
static field dynamic F_fact = #C7;
static field dynamic F_redirect = #C8;
static method main() → dynamic {
self::expect(true, core::identical(self::F_new, typ::F_new_lib));
self::expect(false, core::identical(self::F_new, typ::F_named_lib));
self::expect(false, core::identical(self::F_new, typ::F_fact_lib));
self::expect(false, core::identical(self::F_new, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_new, typ::G_new_lib));
self::expect(false, core::identical(self::F_new, typ::G_named_lib));
self::expect(false, core::identical(self::F_new, typ::G_fact_lib));
self::expect(false, core::identical(self::F_new, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_new, self::H_new));
self::expect(false, core::identical(self::F_new, self::H_named));
self::expect(false, core::identical(self::F_new, self::H_fact));
self::expect(false, core::identical(self::F_new, self::H_redirect));
self::expect(false, core::identical(self::F_named, typ::F_new_lib));
self::expect(true, core::identical(self::F_named, typ::F_named_lib));
self::expect(false, core::identical(self::F_named, typ::F_fact_lib));
self::expect(false, core::identical(self::F_named, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_named, typ::G_new_lib));
self::expect(false, core::identical(self::F_named, typ::G_named_lib));
self::expect(false, core::identical(self::F_named, typ::G_fact_lib));
self::expect(false, core::identical(self::F_named, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_named, self::H_new));
self::expect(false, core::identical(self::F_named, self::H_named));
self::expect(false, core::identical(self::F_named, self::H_fact));
self::expect(false, core::identical(self::F_named, self::H_redirect));
self::expect(false, core::identical(self::F_fact, typ::F_new_lib));
self::expect(false, core::identical(self::F_fact, typ::F_named_lib));
self::expect(true, core::identical(self::F_fact, typ::F_fact_lib));
self::expect(false, core::identical(self::F_fact, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_fact, typ::G_new_lib));
self::expect(false, core::identical(self::F_fact, typ::G_named_lib));
self::expect(false, core::identical(self::F_fact, typ::G_fact_lib));
self::expect(false, core::identical(self::F_fact, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_fact, self::H_new));
self::expect(false, core::identical(self::F_fact, self::H_named));
self::expect(false, core::identical(self::F_fact, self::H_fact));
self::expect(false, core::identical(self::F_fact, self::H_redirect));
self::expect(false, core::identical(self::F_redirect, typ::F_new_lib));
self::expect(false, core::identical(self::F_redirect, typ::F_named_lib));
self::expect(false, core::identical(self::F_redirect, typ::F_fact_lib));
self::expect(true, core::identical(self::F_redirect, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_new_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_named_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_fact_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_redirect, self::H_new));
self::expect(false, core::identical(self::F_redirect, self::H_named));
self::expect(false, core::identical(self::F_redirect, self::H_fact));
self::expect(false, core::identical(self::F_redirect, self::H_redirect));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
throw "Expected ${expected}, actual ${actual}";
}
static method _#H#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<self::_#H#new#tearOff::Y%>
return new typ::A::•<self::_#H#new#tearOff::Y%>();
static method _#H#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<self::_#H#named#tearOff::Y%>
return new typ::A::named<self::_#H#named#tearOff::Y%>(a, b);
static method _#H#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<self::_#H#fact#tearOff::Y%>
return typ::A::fact<self::_#H#fact#tearOff::Y%>(a, b: b, c: c);
static method _#H#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<self::_#H#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<self::_#H#redirect#tearOff::Y%>();
library /*isNonNullableByDefault*/;
import self as typ;
import "dart:core" as core;
typedef F<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
typedef G<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
class A<T extends core::Object? = dynamic> extends core::Object {
static final field dynamic _redirecting# = <dynamic>[typ::A::redirect]/*isLegacy*/;
constructor •() → typ::A<typ::A::T%>
: super core::Object::•()
;
constructor named(typ::A::T% a, [core::int? b = #C9]) → typ::A<typ::A::T%>
: super core::Object::•()
;
static method _#new#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#new#tearOff::T%>
return new typ::A::•<typ::A::_#new#tearOff::T%>();
static method _#named#tearOff<T extends core::Object? = dynamic>(typ::A::_#named#tearOff::T% a, [core::int? b = #C9]) → typ::A<typ::A::_#named#tearOff::T%>
return new typ::A::named<typ::A::_#named#tearOff::T%>(a, b);
static factory fact<T extends core::Object? = dynamic>(typ::A::fact::T% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::A::fact::T%>
return new typ::A::•<typ::A::fact::T%>();
static method _#fact#tearOff<T extends core::Object? = dynamic>(typ::A::_#fact#tearOff::T% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::A::_#fact#tearOff::T%>
return typ::A::fact<typ::A::_#fact#tearOff::T%>(a, b: b, c: c);
static factory redirect<T extends core::Object? = dynamic>() → typ::A<typ::A::redirect::T%>
let Never #redirecting_factory = typ::A::• in let typ::A::redirect::T% #typeArg0 = null in invalid-expression;
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#redirect#tearOff::T%>
return new typ::A::•<typ::A::_#redirect#tearOff::T%>();
}
static field dynamic F_new_lib = #C5;
static field dynamic F_named_lib = #C6;
static field dynamic F_fact_lib = #C7;
static field dynamic F_redirect_lib = #C8;
static field dynamic G_new_lib = #C11;
static field dynamic G_named_lib = #C12;
static field dynamic G_fact_lib = #C13;
static field dynamic G_redirect_lib = #C14;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#new#tearOff::Y%>
return new typ::A::•<typ::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<typ::_#F#named#tearOff::Y%>
return new typ::A::named<typ::_#F#named#tearOff::Y%>(a, b);
static method _#F#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::_#F#fact#tearOff::Y%>
return typ::A::fact<typ::_#F#fact#tearOff::Y%>(a, b: b, c: c);
static method _#F#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<typ::_#F#redirect#tearOff::Y%>();
static method _#G#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#G#new#tearOff::Y%>
return new typ::A::•<typ::_#G#new#tearOff::Y%>();
static method _#G#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#G#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<typ::_#G#named#tearOff::Y%>
return new typ::A::named<typ::_#G#named#tearOff::Y%>(a, b);
static method _#G#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#G#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::_#G#fact#tearOff::Y%>
return typ::A::fact<typ::_#G#fact#tearOff::Y%>(a, b: b, c: c);
static method _#G#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#G#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<typ::_#G#redirect#tearOff::Y%>();
constants {
#C1 = static-tearoff self::_#H#new#tearOff
#C2 = static-tearoff self::_#H#named#tearOff
#C3 = static-tearoff self::_#H#fact#tearOff
#C4 = static-tearoff self::_#H#redirect#tearOff
#C5 = static-tearoff typ::_#F#new#tearOff
#C6 = static-tearoff typ::_#F#named#tearOff
#C7 = static-tearoff typ::_#F#fact#tearOff
#C8 = static-tearoff typ::_#F#redirect#tearOff
#C9 = null
#C10 = 42
#C11 = static-tearoff typ::_#G#new#tearOff
#C12 = static-tearoff typ::_#G#named#tearOff
#C13 = static-tearoff typ::_#G#fact#tearOff
#C14 = static-tearoff typ::_#G#redirect#tearOff
}

View file

@ -0,0 +1,12 @@
import 'typedef_identical_lib.dart';
typedef H<X, Y> = A<Y>;
dynamic H_new = H.new;
dynamic H_named = H.named;
dynamic H_fact = H.fact;
dynamic H_redirect = H.redirect;
dynamic F_new = F.new;
dynamic F_named = F.named;
dynamic F_fact = F.fact;
dynamic F_redirect = F.redirect;
main() {}
expect(expected, actual) {}

View file

@ -0,0 +1,147 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "typedef_identical_lib.dart" as typ;
import "org-dartlang-testcase:///typedef_identical_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
static field dynamic H_new = #C1;
static field dynamic H_named = #C2;
static field dynamic H_fact = #C3;
static field dynamic H_redirect = #C4;
static field dynamic F_new = #C5;
static field dynamic F_named = #C6;
static field dynamic F_fact = #C7;
static field dynamic F_redirect = #C8;
static method main() → dynamic {
self::expect(true, core::identical(self::F_new, typ::F_new_lib));
self::expect(false, core::identical(self::F_new, typ::F_named_lib));
self::expect(false, core::identical(self::F_new, typ::F_fact_lib));
self::expect(false, core::identical(self::F_new, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_new, typ::G_new_lib));
self::expect(false, core::identical(self::F_new, typ::G_named_lib));
self::expect(false, core::identical(self::F_new, typ::G_fact_lib));
self::expect(false, core::identical(self::F_new, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_new, self::H_new));
self::expect(false, core::identical(self::F_new, self::H_named));
self::expect(false, core::identical(self::F_new, self::H_fact));
self::expect(false, core::identical(self::F_new, self::H_redirect));
self::expect(false, core::identical(self::F_named, typ::F_new_lib));
self::expect(true, core::identical(self::F_named, typ::F_named_lib));
self::expect(false, core::identical(self::F_named, typ::F_fact_lib));
self::expect(false, core::identical(self::F_named, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_named, typ::G_new_lib));
self::expect(false, core::identical(self::F_named, typ::G_named_lib));
self::expect(false, core::identical(self::F_named, typ::G_fact_lib));
self::expect(false, core::identical(self::F_named, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_named, self::H_new));
self::expect(false, core::identical(self::F_named, self::H_named));
self::expect(false, core::identical(self::F_named, self::H_fact));
self::expect(false, core::identical(self::F_named, self::H_redirect));
self::expect(false, core::identical(self::F_fact, typ::F_new_lib));
self::expect(false, core::identical(self::F_fact, typ::F_named_lib));
self::expect(true, core::identical(self::F_fact, typ::F_fact_lib));
self::expect(false, core::identical(self::F_fact, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_fact, typ::G_new_lib));
self::expect(false, core::identical(self::F_fact, typ::G_named_lib));
self::expect(false, core::identical(self::F_fact, typ::G_fact_lib));
self::expect(false, core::identical(self::F_fact, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_fact, self::H_new));
self::expect(false, core::identical(self::F_fact, self::H_named));
self::expect(false, core::identical(self::F_fact, self::H_fact));
self::expect(false, core::identical(self::F_fact, self::H_redirect));
self::expect(false, core::identical(self::F_redirect, typ::F_new_lib));
self::expect(false, core::identical(self::F_redirect, typ::F_named_lib));
self::expect(false, core::identical(self::F_redirect, typ::F_fact_lib));
self::expect(true, core::identical(self::F_redirect, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_new_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_named_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_fact_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_redirect, self::H_new));
self::expect(false, core::identical(self::F_redirect, self::H_named));
self::expect(false, core::identical(self::F_redirect, self::H_fact));
self::expect(false, core::identical(self::F_redirect, self::H_redirect));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
throw "Expected ${expected}, actual ${actual}";
}
static method _#H#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<self::_#H#new#tearOff::Y%>
return new typ::A::•<self::_#H#new#tearOff::Y%>();
static method _#H#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<self::_#H#named#tearOff::Y%>
return new typ::A::named<self::_#H#named#tearOff::Y%>(a, b);
static method _#H#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<self::_#H#fact#tearOff::Y%>
return typ::A::fact<self::_#H#fact#tearOff::Y%>(a, b: b, c: c);
static method _#H#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<self::_#H#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<self::_#H#redirect#tearOff::Y%>();
library /*isNonNullableByDefault*/;
import self as typ;
import "dart:core" as core;
typedef F<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
typedef G<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
class A<T extends core::Object? = dynamic> extends core::Object {
static final field dynamic _redirecting# = <dynamic>[typ::A::redirect]/*isLegacy*/;
constructor •() → typ::A<typ::A::T%>
: super core::Object::•()
;
constructor named(typ::A::T% a, [core::int? b = #C9]) → typ::A<typ::A::T%>
: super core::Object::•()
;
static method _#new#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#new#tearOff::T%>
return new typ::A::•<typ::A::_#new#tearOff::T%>();
static method _#named#tearOff<T extends core::Object? = dynamic>(typ::A::_#named#tearOff::T% a, [core::int? b = #C9]) → typ::A<typ::A::_#named#tearOff::T%>
return new typ::A::named<typ::A::_#named#tearOff::T%>(a, b);
static factory fact<T extends core::Object? = dynamic>(typ::A::fact::T% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::A::fact::T%>
return new typ::A::•<typ::A::fact::T%>();
static method _#fact#tearOff<T extends core::Object? = dynamic>(typ::A::_#fact#tearOff::T% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::A::_#fact#tearOff::T%>
return typ::A::fact<typ::A::_#fact#tearOff::T%>(a, b: b, c: c);
static factory redirect<T extends core::Object? = dynamic>() → typ::A<typ::A::redirect::T%>
let dynamic #redirecting_factory = typ::A::• in let typ::A::redirect::T% #typeArg0 = null in invalid-expression;
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#redirect#tearOff::T%>
return new typ::A::•<typ::A::_#redirect#tearOff::T%>();
}
static field dynamic F_new_lib = #C5;
static field dynamic F_named_lib = #C6;
static field dynamic F_fact_lib = #C7;
static field dynamic F_redirect_lib = #C8;
static field dynamic G_new_lib = #C11;
static field dynamic G_named_lib = #C12;
static field dynamic G_fact_lib = #C13;
static field dynamic G_redirect_lib = #C14;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#new#tearOff::Y%>
return new typ::A::•<typ::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<typ::_#F#named#tearOff::Y%>
return new typ::A::named<typ::_#F#named#tearOff::Y%>(a, b);
static method _#F#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::_#F#fact#tearOff::Y%>
return typ::A::fact<typ::_#F#fact#tearOff::Y%>(a, b: b, c: c);
static method _#F#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<typ::_#F#redirect#tearOff::Y%>();
static method _#G#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#G#new#tearOff::Y%>
return new typ::A::•<typ::_#G#new#tearOff::Y%>();
static method _#G#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#G#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<typ::_#G#named#tearOff::Y%>
return new typ::A::named<typ::_#G#named#tearOff::Y%>(a, b);
static method _#G#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#G#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::_#G#fact#tearOff::Y%>
return typ::A::fact<typ::_#G#fact#tearOff::Y%>(a, b: b, c: c);
static method _#G#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#G#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<typ::_#G#redirect#tearOff::Y%>();
constants {
#C1 = static-tearoff self::_#H#new#tearOff
#C2 = static-tearoff self::_#H#named#tearOff
#C3 = static-tearoff self::_#H#fact#tearOff
#C4 = static-tearoff self::_#H#redirect#tearOff
#C5 = static-tearoff typ::_#F#new#tearOff
#C6 = static-tearoff typ::_#F#named#tearOff
#C7 = static-tearoff typ::_#F#fact#tearOff
#C8 = static-tearoff typ::_#F#redirect#tearOff
#C9 = null
#C10 = 42
#C11 = static-tearoff typ::_#G#new#tearOff
#C12 = static-tearoff typ::_#G#named#tearOff
#C13 = static-tearoff typ::_#G#fact#tearOff
#C14 = static-tearoff typ::_#G#redirect#tearOff
}

View file

@ -0,0 +1,78 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "typedef_identical_lib.dart" as typ;
import "org-dartlang-testcase:///typedef_identical_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
static field dynamic H_new;
static field dynamic H_named;
static field dynamic H_fact;
static field dynamic H_redirect;
static field dynamic F_new;
static field dynamic F_named;
static field dynamic F_fact;
static field dynamic F_redirect;
static method main() → dynamic
;
static method expect(dynamic expected, dynamic actual) → dynamic
;
static method _#H#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<self::_#H#new#tearOff::Y%>
return new typ::A::•<self::_#H#new#tearOff::Y%>();
static method _#H#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#named#tearOff::Y% a, [core::int? b]) → typ::A<self::_#H#named#tearOff::Y%>
return new typ::A::named<self::_#H#named#tearOff::Y%>(a, b);
static method _#H#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#fact#tearOff::Y% a, {core::int? b, core::int c}) → typ::A<self::_#H#fact#tearOff::Y%>
return typ::A::fact<self::_#H#fact#tearOff::Y%>(a, b: b, c: c);
static method _#H#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<self::_#H#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<self::_#H#redirect#tearOff::Y%>();
library /*isNonNullableByDefault*/;
import self as typ;
import "dart:core" as core;
typedef F<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
typedef G<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
class A<T extends core::Object? = dynamic> extends core::Object {
static final field dynamic _redirecting# = <dynamic>[typ::A::redirect]/*isLegacy*/;
constructor •() → typ::A<typ::A::T%>
;
constructor named(typ::A::T% a, [core::int? b]) → typ::A<typ::A::T%>
;
static method _#new#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#new#tearOff::T%>
return new typ::A::•<typ::A::_#new#tearOff::T%>();
static method _#named#tearOff<T extends core::Object? = dynamic>(typ::A::_#named#tearOff::T% a, [core::int? b]) → typ::A<typ::A::_#named#tearOff::T%>
return new typ::A::named<typ::A::_#named#tearOff::T%>(a, b);
static factory fact<T extends core::Object? = dynamic>(typ::A::fact::T% a, {core::int? b, core::int c}) → typ::A<typ::A::fact::T%>
;
static method _#fact#tearOff<T extends core::Object? = dynamic>(typ::A::_#fact#tearOff::T% a, {core::int? b, core::int c}) → typ::A<typ::A::_#fact#tearOff::T%>
return typ::A::fact<typ::A::_#fact#tearOff::T%>(a, b: b, c: c);
static factory redirect<T extends core::Object? = dynamic>() → typ::A<typ::A::redirect::T%>
let dynamic #redirecting_factory = typ::A::• in let typ::A::redirect::T% #typeArg0 = null in invalid-expression;
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#redirect#tearOff::T%>
return new typ::A::•<typ::A::_#redirect#tearOff::T%>();
}
static field dynamic F_new_lib;
static field dynamic F_named_lib;
static field dynamic F_fact_lib;
static field dynamic F_redirect_lib;
static field dynamic G_new_lib;
static field dynamic G_named_lib;
static field dynamic G_fact_lib;
static field dynamic G_redirect_lib;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#new#tearOff::Y%>
return new typ::A::•<typ::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#named#tearOff::Y% a, [core::int? b]) → typ::A<typ::_#F#named#tearOff::Y%>
return new typ::A::named<typ::_#F#named#tearOff::Y%>(a, b);
static method _#F#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#fact#tearOff::Y% a, {core::int? b, core::int c}) → typ::A<typ::_#F#fact#tearOff::Y%>
return typ::A::fact<typ::_#F#fact#tearOff::Y%>(a, b: b, c: c);
static method _#F#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<typ::_#F#redirect#tearOff::Y%>();
static method _#G#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#G#new#tearOff::Y%>
return new typ::A::•<typ::_#G#new#tearOff::Y%>();
static method _#G#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#G#named#tearOff::Y% a, [core::int? b]) → typ::A<typ::_#G#named#tearOff::Y%>
return new typ::A::named<typ::_#G#named#tearOff::Y%>(a, b);
static method _#G#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#G#fact#tearOff::Y% a, {core::int? b, core::int c}) → typ::A<typ::_#G#fact#tearOff::Y%>
return typ::A::fact<typ::_#G#fact#tearOff::Y%>(a, b: b, c: c);
static method _#G#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#G#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<typ::_#G#redirect#tearOff::Y%>();

View file

@ -0,0 +1,147 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "typedef_identical_lib.dart" as typ;
import "org-dartlang-testcase:///typedef_identical_lib.dart";
typedef H<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
static field dynamic H_new = #C1;
static field dynamic H_named = #C2;
static field dynamic H_fact = #C3;
static field dynamic H_redirect = #C4;
static field dynamic F_new = #C5;
static field dynamic F_named = #C6;
static field dynamic F_fact = #C7;
static field dynamic F_redirect = #C8;
static method main() → dynamic {
self::expect(true, core::identical(self::F_new, typ::F_new_lib));
self::expect(false, core::identical(self::F_new, typ::F_named_lib));
self::expect(false, core::identical(self::F_new, typ::F_fact_lib));
self::expect(false, core::identical(self::F_new, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_new, typ::G_new_lib));
self::expect(false, core::identical(self::F_new, typ::G_named_lib));
self::expect(false, core::identical(self::F_new, typ::G_fact_lib));
self::expect(false, core::identical(self::F_new, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_new, self::H_new));
self::expect(false, core::identical(self::F_new, self::H_named));
self::expect(false, core::identical(self::F_new, self::H_fact));
self::expect(false, core::identical(self::F_new, self::H_redirect));
self::expect(false, core::identical(self::F_named, typ::F_new_lib));
self::expect(true, core::identical(self::F_named, typ::F_named_lib));
self::expect(false, core::identical(self::F_named, typ::F_fact_lib));
self::expect(false, core::identical(self::F_named, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_named, typ::G_new_lib));
self::expect(false, core::identical(self::F_named, typ::G_named_lib));
self::expect(false, core::identical(self::F_named, typ::G_fact_lib));
self::expect(false, core::identical(self::F_named, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_named, self::H_new));
self::expect(false, core::identical(self::F_named, self::H_named));
self::expect(false, core::identical(self::F_named, self::H_fact));
self::expect(false, core::identical(self::F_named, self::H_redirect));
self::expect(false, core::identical(self::F_fact, typ::F_new_lib));
self::expect(false, core::identical(self::F_fact, typ::F_named_lib));
self::expect(true, core::identical(self::F_fact, typ::F_fact_lib));
self::expect(false, core::identical(self::F_fact, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_fact, typ::G_new_lib));
self::expect(false, core::identical(self::F_fact, typ::G_named_lib));
self::expect(false, core::identical(self::F_fact, typ::G_fact_lib));
self::expect(false, core::identical(self::F_fact, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_fact, self::H_new));
self::expect(false, core::identical(self::F_fact, self::H_named));
self::expect(false, core::identical(self::F_fact, self::H_fact));
self::expect(false, core::identical(self::F_fact, self::H_redirect));
self::expect(false, core::identical(self::F_redirect, typ::F_new_lib));
self::expect(false, core::identical(self::F_redirect, typ::F_named_lib));
self::expect(false, core::identical(self::F_redirect, typ::F_fact_lib));
self::expect(true, core::identical(self::F_redirect, typ::F_redirect_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_new_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_named_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_fact_lib));
self::expect(false, core::identical(self::F_redirect, typ::G_redirect_lib));
self::expect(false, core::identical(self::F_redirect, self::H_new));
self::expect(false, core::identical(self::F_redirect, self::H_named));
self::expect(false, core::identical(self::F_redirect, self::H_fact));
self::expect(false, core::identical(self::F_redirect, self::H_redirect));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
throw "Expected ${expected}, actual ${actual}";
}
static method _#H#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<self::_#H#new#tearOff::Y%>
return new typ::A::•<self::_#H#new#tearOff::Y%>();
static method _#H#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<self::_#H#named#tearOff::Y%>
return new typ::A::named<self::_#H#named#tearOff::Y%>(a, b);
static method _#H#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(self::_#H#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<self::_#H#fact#tearOff::Y%>
return typ::A::fact<self::_#H#fact#tearOff::Y%>(a, b: b, c: c);
static method _#H#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<self::_#H#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<self::_#H#redirect#tearOff::Y%>();
library /*isNonNullableByDefault*/;
import self as typ;
import "dart:core" as core;
typedef F<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
typedef G<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = typ::A<Y%>;
class A<T extends core::Object? = dynamic> extends core::Object {
static final field dynamic _redirecting# = <dynamic>[typ::A::redirect]/*isLegacy*/;
constructor •() → typ::A<typ::A::T%>
: super core::Object::•()
;
constructor named(typ::A::T% a, [core::int? b = #C9]) → typ::A<typ::A::T%>
: super core::Object::•()
;
static method _#new#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#new#tearOff::T%>
return new typ::A::•<typ::A::_#new#tearOff::T%>();
static method _#named#tearOff<T extends core::Object? = dynamic>(typ::A::_#named#tearOff::T% a, [core::int? b = #C9]) → typ::A<typ::A::_#named#tearOff::T%>
return new typ::A::named<typ::A::_#named#tearOff::T%>(a, b);
static factory fact<T extends core::Object? = dynamic>(typ::A::fact::T% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::A::fact::T%>
return new typ::A::•<typ::A::fact::T%>();
static method _#fact#tearOff<T extends core::Object? = dynamic>(typ::A::_#fact#tearOff::T% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::A::_#fact#tearOff::T%>
return typ::A::fact<typ::A::_#fact#tearOff::T%>(a, b: b, c: c);
static factory redirect<T extends core::Object? = dynamic>() → typ::A<typ::A::redirect::T%>
let Never #redirecting_factory = typ::A::• in let typ::A::redirect::T% #typeArg0 = null in invalid-expression;
static method _#redirect#tearOff<T extends core::Object? = dynamic>() → typ::A<typ::A::_#redirect#tearOff::T%>
return new typ::A::•<typ::A::_#redirect#tearOff::T%>();
}
static field dynamic F_new_lib = #C5;
static field dynamic F_named_lib = #C6;
static field dynamic F_fact_lib = #C7;
static field dynamic F_redirect_lib = #C8;
static field dynamic G_new_lib = #C11;
static field dynamic G_named_lib = #C12;
static field dynamic G_fact_lib = #C13;
static field dynamic G_redirect_lib = #C14;
static method _#F#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#new#tearOff::Y%>
return new typ::A::•<typ::_#F#new#tearOff::Y%>();
static method _#F#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<typ::_#F#named#tearOff::Y%>
return new typ::A::named<typ::_#F#named#tearOff::Y%>(a, b);
static method _#F#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#F#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::_#F#fact#tearOff::Y%>
return typ::A::fact<typ::_#F#fact#tearOff::Y%>(a, b: b, c: c);
static method _#F#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#F#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<typ::_#F#redirect#tearOff::Y%>();
static method _#G#new#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#G#new#tearOff::Y%>
return new typ::A::•<typ::_#G#new#tearOff::Y%>();
static method _#G#named#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#G#named#tearOff::Y% a, [core::int? b = #C9]) → typ::A<typ::_#G#named#tearOff::Y%>
return new typ::A::named<typ::_#G#named#tearOff::Y%>(a, b);
static method _#G#fact#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(typ::_#G#fact#tearOff::Y% a, {core::int? b = #C9, core::int c = #C10}) → typ::A<typ::_#G#fact#tearOff::Y%>
return typ::A::fact<typ::_#G#fact#tearOff::Y%>(a, b: b, c: c);
static method _#G#redirect#tearOff<unrelated X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → typ::A<typ::_#G#redirect#tearOff::Y%>
return typ::A::_#redirect#tearOff<typ::_#G#redirect#tearOff::Y%>();
constants {
#C1 = static-tearoff self::_#H#new#tearOff
#C2 = static-tearoff self::_#H#named#tearOff
#C3 = static-tearoff self::_#H#fact#tearOff
#C4 = static-tearoff self::_#H#redirect#tearOff
#C5 = static-tearoff typ::_#F#new#tearOff
#C6 = static-tearoff typ::_#F#named#tearOff
#C7 = static-tearoff typ::_#F#fact#tearOff
#C8 = static-tearoff typ::_#F#redirect#tearOff
#C9 = null
#C10 = 42
#C11 = static-tearoff typ::_#G#new#tearOff
#C12 = static-tearoff typ::_#G#named#tearOff
#C13 = static-tearoff typ::_#G#fact#tearOff
#C14 = static-tearoff typ::_#G#redirect#tearOff
}

View file

@ -0,0 +1,23 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
class A<T> {
A();
A.named(T a, [int? b]);
factory A.fact(T a, {int? b, int c = 42}) => new A();
factory A.redirect() = A;
}
typedef F<X, Y> = A<Y>;
typedef G<X, Y> = A<Y>;
dynamic F_new_lib = F.new;
dynamic F_named_lib = F.named;
dynamic F_fact_lib = F.fact;
dynamic F_redirect_lib = F.redirect;
dynamic G_new_lib = G.new;
dynamic G_named_lib = G.named;
dynamic G_fact_lib = G.fact;
dynamic G_redirect_lib = G.redirect;

View file

@ -143,14 +143,14 @@ Try removing the extra positional arguments.
^" in f2a{<inapplicable>}.<core::num>(0);
f2a<core::String>(){() → self::A};
};
dynamic f2b = #C3;
dynamic f2b = #C2;
dynamic c2b = f2b{dynamic}.call();
self::expect(true, c2b is{ForNonNullableByDefault} self::A);
dynamic c2c = f2b{dynamic}.call<core::int>();
self::expect(true, c2c is{ForNonNullableByDefault} self::A);
self::throws(() → dynamic => f2b{dynamic}.call(0));
self::throws(() → dynamic => f2b{dynamic}.call<core::String>());
() → self::B<core::String> f3a = #C5;
() → self::B<core::String> f3a = #C4;
self::B<core::String> c3a = f3a(){() → self::B<core::String>};
self::expect(true, c3a is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3a is{ForNonNullableByDefault} self::B<core::int>);
@ -165,7 +165,7 @@ Try removing the extra positional arguments.
f3a<String>(); // error
^" in f3a{<inapplicable>}.<core::String>();
};
dynamic f3b = #C5;
dynamic f3b = #C4;
dynamic c3b = f3b{dynamic}.call();
self::expect(true, c3b is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3b is{ForNonNullableByDefault} self::B<core::int>);
@ -173,7 +173,7 @@ Try removing the extra positional arguments.
self::expect("", c3a.{self::B::field2}{core::String});
self::throws(() → dynamic => f3b{dynamic}.call(0));
self::throws(() → dynamic => f3b{dynamic}.call<core::String>());
(core::int) → self::B<core::String> f3c = #C7;
(core::int) → self::B<core::String> f3c = #C6;
self::B<core::String> c3c = f3c(42){(core::int) → self::B<core::String>};
self::expect(true, c3c is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3c is{ForNonNullableByDefault} self::B<core::int>);
@ -191,7 +191,7 @@ Try removing the extra positional arguments.
f3c<String>(0); // error
^" in f3c{<inapplicable>}.<core::String>(0);
};
dynamic f3d = #C7;
dynamic f3d = #C6;
dynamic c3d = f3d{dynamic}.call(42);
self::expect(true, c3d is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3d is{ForNonNullableByDefault} self::B<core::int>);
@ -200,7 +200,7 @@ Try removing the extra positional arguments.
self::throws(() → dynamic => f3d{dynamic}.call());
self::throws(() → dynamic => f3d{dynamic}.call(0, 0));
self::throws(() → dynamic => f3d{dynamic}.call<core::String>(0));
(core::int, core::String) → self::B<core::String> f3e = #C9;
(core::int, core::String) → self::B<core::String> f3e = #C8;
self::B<core::String> c3e = f3e(42, "foo"){(core::int, core::String) → self::B<core::String>};
self::expect(true, c3e is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3e is{ForNonNullableByDefault} self::B<core::int>);
@ -217,7 +217,7 @@ Try removing the extra positional arguments.
f3e<String>(0, ''); // error
^" in f3e{<inapplicable>}.<core::String>(0, "");
};
dynamic f3f = #C9;
dynamic f3f = #C8;
dynamic c3f = f3f{dynamic}.call(42, "foo");
self::expect(true, c3f is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3f is{ForNonNullableByDefault} self::B<core::int>);
@ -226,7 +226,7 @@ Try removing the extra positional arguments.
self::throws(() → dynamic => c3f{dynamic}.call());
self::throws(() → dynamic => c3f{dynamic}.call(0));
self::throws(() → dynamic => c3f{dynamic}.call<core::String>(0));
<X extends core::num>() → self::B<X> f4a = #C10;
<X extends core::num>() → self::B<X> f4a = #C9;
self::B<core::num> c4a = f4a<core::num>(){() → self::B<core::num>};
self::expect(true, c4a is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c4a is{ForNonNullableByDefault} self::B<core::int>);
@ -240,7 +240,7 @@ Try removing the extra positional arguments.
^" in f4a{<inapplicable>}.<core::num>(0);
f4a<core::String>(){() → self::B<core::String>};
};
dynamic f4b = #C11;
dynamic f4b = #C9;
dynamic c4c = f4b{dynamic}.call();
self::expect(true, c4c is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c4c is{ForNonNullableByDefault} self::B<core::int>);
@ -249,7 +249,7 @@ Try removing the extra positional arguments.
self::expect(false, c4d is{ForNonNullableByDefault} self::B<core::double>);
self::throws(() → dynamic => f4b{dynamic}.call(0));
self::throws(() → dynamic => f4b{dynamic}.call<core::String>());
<X extends core::num, unrelated Y extends core::String>() → self::B<X> f5a = #C12;
<X extends core::num, unrelated Y extends core::String>() → self::B<X> f5a = #C10;
self::B<core::num> c5a = f5a<core::num, core::String>(){() → self::B<core::num>};
self::expect(true, c5a is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c5a is{ForNonNullableByDefault} self::B<core::int>);
@ -267,7 +267,7 @@ Try removing the extra positional arguments.
f5a<core::String, core::String>(){() → self::B<core::String>};
f5a<core::num, core::num>(){() → self::B<core::num>};
};
dynamic f5b = #C13;
dynamic f5b = #C10;
dynamic c5c = f5b{dynamic}.call();
self::expect(true, c5c is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c5c is{ForNonNullableByDefault} self::B<core::int>);
@ -283,7 +283,7 @@ static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
throw "Expected ${expected}, actual ${actual}";
}
static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C14}) → dynamic {
static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C11}) → dynamic {
try {
f(){() → dynamic};
}
@ -296,32 +296,45 @@ static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C14}) →
}
throw "Expected exception";
}
static method _#0#tearOff<unrelated X extends core::num>() → self::A
return (#C1)(){() → self::A};
static method _#1#tearOff<unrelated X extends core::num>() → self::A
return (#C1)(){() → self::A};
static method _#2#tearOff<X extends core::num>() → self::B<self::_#2#tearOff::X>
return (#C4)<self::_#2#tearOff::X>(){() → self::B<self::_#2#tearOff::X>};
static method _#3#tearOff<X extends core::num>() → self::B<self::_#3#tearOff::X>
return (#C4)<self::_#3#tearOff::X>(){() → self::B<self::_#3#tearOff::X>};
static method _#4#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#4#tearOff::X>
return (#C4)<self::_#4#tearOff::X>(){() → self::B<self::_#4#tearOff::X>};
static method _#5#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#5#tearOff::X>
return (#C4)<self::_#5#tearOff::X>(){() → self::B<self::_#5#tearOff::X>};
static method _#DA1#new#tearOff() → self::A
return new self::A::•();
static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
return new self::A::•();
static method _#DB1#_#tearOff(core::int field1, core::String field2) → self::B<core::String>
return new self::B::_<core::String>(field1, field2);
static method _#DB1#new#tearOff() → self::B<core::String>
return new self::B::•<core::String>();
static method _#DB1#foo#tearOff(core::int field1) → self::B<core::String>
return new self::B::foo<core::String>(field1);
static method _#DB1#bar#tearOff(core::int i, core::String j) → self::B<core::String>
return self::B::bar<core::String>(i, j);
static method _#DB2#_#tearOff<X extends core::num>(core::int field1, core::String field2) → self::B<self::_#DB2#_#tearOff::X>
return new self::B::_<self::_#DB2#_#tearOff::X>(field1, field2);
static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
return new self::B::•<self::_#DB2#new#tearOff::X>();
static method _#DB2#foo#tearOff<X extends core::num>(core::int field1) → self::B<self::_#DB2#foo#tearOff::X>
return new self::B::foo<self::_#DB2#foo#tearOff::X>(field1);
static method _#DB2#bar#tearOff<X extends core::num>(core::int i, core::String j) → self::B<self::_#DB2#bar#tearOff::X>
return self::B::bar<self::_#DB2#bar#tearOff::X>(i, j);
static method _#DB3#_#tearOff<X extends core::num, unrelated Y extends core::String>(core::int field1, core::String field2) → self::B<self::_#DB3#_#tearOff::X>
return new self::B::_<self::_#DB3#_#tearOff::X>(field1, field2);
static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
return new self::B::•<self::_#DB3#new#tearOff::X>();
static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>(core::int field1) → self::B<self::_#DB3#foo#tearOff::X>
return new self::B::foo<self::_#DB3#foo#tearOff::X>(field1);
static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>(core::int i, core::String j) → self::B<self::_#DB3#bar#tearOff::X>
return self::B::bar<self::_#DB3#bar#tearOff::X>(i, j);
constants {
#C1 = static-tearoff self::A::_#new#tearOff
#C2 = static-tearoff self::_#0#tearOff
#C3 = static-tearoff self::_#1#tearOff
#C4 = static-tearoff self::B::_#new#tearOff
#C5 = instantiation self::B::_#new#tearOff <core::String>
#C6 = static-tearoff self::B::_#foo#tearOff
#C7 = instantiation self::B::_#foo#tearOff <core::String>
#C8 = static-tearoff self::B::_#bar#tearOff
#C9 = instantiation self::B::_#bar#tearOff <core::String>
#C10 = static-tearoff self::_#2#tearOff
#C11 = static-tearoff self::_#3#tearOff
#C12 = static-tearoff self::_#4#tearOff
#C13 = static-tearoff self::_#5#tearOff
#C14 = false
#C2 = static-tearoff self::_#DA2#new#tearOff
#C3 = static-tearoff self::B::_#new#tearOff
#C4 = instantiation self::B::_#new#tearOff <core::String>
#C5 = static-tearoff self::B::_#foo#tearOff
#C6 = instantiation self::B::_#foo#tearOff <core::String>
#C7 = static-tearoff self::B::_#bar#tearOff
#C8 = instantiation self::B::_#bar#tearOff <core::String>
#C9 = static-tearoff self::_#DB2#new#tearOff
#C10 = static-tearoff self::_#DB3#new#tearOff
#C11 = false
}

View file

@ -143,14 +143,14 @@ Try removing the extra positional arguments.
^" in f2a{<inapplicable>}.<core::num>(0);
f2a<core::String>(){() → self::A};
};
dynamic f2b = #C3;
dynamic f2b = #C2;
dynamic c2b = f2b{dynamic}.call();
self::expect(true, c2b is{ForNonNullableByDefault} self::A);
dynamic c2c = f2b{dynamic}.call<core::int>();
self::expect(true, c2c is{ForNonNullableByDefault} self::A);
self::throws(() → dynamic => f2b{dynamic}.call(0));
self::throws(() → dynamic => f2b{dynamic}.call<core::String>());
() → self::B<core::String> f3a = #C5;
() → self::B<core::String> f3a = #C4;
self::B<core::String> c3a = f3a(){() → self::B<core::String>};
self::expect(true, c3a is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3a is{ForNonNullableByDefault} self::B<core::int>);
@ -165,7 +165,7 @@ Try removing the extra positional arguments.
f3a<String>(); // error
^" in f3a{<inapplicable>}.<core::String>();
};
dynamic f3b = #C5;
dynamic f3b = #C4;
dynamic c3b = f3b{dynamic}.call();
self::expect(true, c3b is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3b is{ForNonNullableByDefault} self::B<core::int>);
@ -173,7 +173,7 @@ Try removing the extra positional arguments.
self::expect("", c3a.{self::B::field2}{core::String});
self::throws(() → dynamic => f3b{dynamic}.call(0));
self::throws(() → dynamic => f3b{dynamic}.call<core::String>());
(core::int) → self::B<core::String> f3c = #C7;
(core::int) → self::B<core::String> f3c = #C6;
self::B<core::String> c3c = f3c(42){(core::int) → self::B<core::String>};
self::expect(true, c3c is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3c is{ForNonNullableByDefault} self::B<core::int>);
@ -191,7 +191,7 @@ Try removing the extra positional arguments.
f3c<String>(0); // error
^" in f3c{<inapplicable>}.<core::String>(0);
};
dynamic f3d = #C7;
dynamic f3d = #C6;
dynamic c3d = f3d{dynamic}.call(42);
self::expect(true, c3d is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3d is{ForNonNullableByDefault} self::B<core::int>);
@ -200,7 +200,7 @@ Try removing the extra positional arguments.
self::throws(() → dynamic => f3d{dynamic}.call());
self::throws(() → dynamic => f3d{dynamic}.call(0, 0));
self::throws(() → dynamic => f3d{dynamic}.call<core::String>(0));
(core::int, core::String) → self::B<core::String> f3e = #C9;
(core::int, core::String) → self::B<core::String> f3e = #C8;
self::B<core::String> c3e = f3e(42, "foo"){(core::int, core::String) → self::B<core::String>};
self::expect(true, c3e is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3e is{ForNonNullableByDefault} self::B<core::int>);
@ -217,7 +217,7 @@ Try removing the extra positional arguments.
f3e<String>(0, ''); // error
^" in f3e{<inapplicable>}.<core::String>(0, "");
};
dynamic f3f = #C9;
dynamic f3f = #C8;
dynamic c3f = f3f{dynamic}.call(42, "foo");
self::expect(true, c3f is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3f is{ForNonNullableByDefault} self::B<core::int>);
@ -226,7 +226,7 @@ Try removing the extra positional arguments.
self::throws(() → dynamic => c3f{dynamic}.call());
self::throws(() → dynamic => c3f{dynamic}.call(0));
self::throws(() → dynamic => c3f{dynamic}.call<core::String>(0));
<X extends core::num>() → self::B<X> f4a = #C10;
<X extends core::num>() → self::B<X> f4a = #C9;
self::B<core::num> c4a = f4a<core::num>(){() → self::B<core::num>};
self::expect(true, c4a is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c4a is{ForNonNullableByDefault} self::B<core::int>);
@ -240,7 +240,7 @@ Try removing the extra positional arguments.
^" in f4a{<inapplicable>}.<core::num>(0);
f4a<core::String>(){() → self::B<core::String>};
};
dynamic f4b = #C11;
dynamic f4b = #C9;
dynamic c4c = f4b{dynamic}.call();
self::expect(true, c4c is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c4c is{ForNonNullableByDefault} self::B<core::int>);
@ -249,7 +249,7 @@ Try removing the extra positional arguments.
self::expect(false, c4d is{ForNonNullableByDefault} self::B<core::double>);
self::throws(() → dynamic => f4b{dynamic}.call(0));
self::throws(() → dynamic => f4b{dynamic}.call<core::String>());
<X extends core::num, unrelated Y extends core::String>() → self::B<X> f5a = #C12;
<X extends core::num, unrelated Y extends core::String>() → self::B<X> f5a = #C10;
self::B<core::num> c5a = f5a<core::num, core::String>(){() → self::B<core::num>};
self::expect(true, c5a is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c5a is{ForNonNullableByDefault} self::B<core::int>);
@ -267,7 +267,7 @@ Try removing the extra positional arguments.
f5a<core::String, core::String>(){() → self::B<core::String>};
f5a<core::num, core::num>(){() → self::B<core::num>};
};
dynamic f5b = #C13;
dynamic f5b = #C10;
dynamic c5c = f5b{dynamic}.call();
self::expect(true, c5c is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c5c is{ForNonNullableByDefault} self::B<core::int>);
@ -283,7 +283,7 @@ static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
throw "Expected ${expected}, actual ${actual}";
}
static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C14}) → dynamic {
static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C11}) → dynamic {
try {
f(){() → dynamic};
}
@ -296,32 +296,45 @@ static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C14}) →
}
throw "Expected exception";
}
static method _#0#tearOff<unrelated X extends core::num>() → self::A
return (#C1)(){() → self::A};
static method _#1#tearOff<unrelated X extends core::num>() → self::A
return (#C1)(){() → self::A};
static method _#2#tearOff<X extends core::num>() → self::B<self::_#2#tearOff::X>
return (#C4)<self::_#2#tearOff::X>(){() → self::B<self::_#2#tearOff::X>};
static method _#3#tearOff<X extends core::num>() → self::B<self::_#3#tearOff::X>
return (#C4)<self::_#3#tearOff::X>(){() → self::B<self::_#3#tearOff::X>};
static method _#4#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#4#tearOff::X>
return (#C4)<self::_#4#tearOff::X>(){() → self::B<self::_#4#tearOff::X>};
static method _#5#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#5#tearOff::X>
return (#C4)<self::_#5#tearOff::X>(){() → self::B<self::_#5#tearOff::X>};
static method _#DA1#new#tearOff() → self::A
return new self::A::•();
static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
return new self::A::•();
static method _#DB1#_#tearOff(core::int field1, core::String field2) → self::B<core::String>
return new self::B::_<core::String>(field1, field2);
static method _#DB1#new#tearOff() → self::B<core::String>
return new self::B::•<core::String>();
static method _#DB1#foo#tearOff(core::int field1) → self::B<core::String>
return new self::B::foo<core::String>(field1);
static method _#DB1#bar#tearOff(core::int i, core::String j) → self::B<core::String>
return self::B::bar<core::String>(i, j);
static method _#DB2#_#tearOff<X extends core::num>(core::int field1, core::String field2) → self::B<self::_#DB2#_#tearOff::X>
return new self::B::_<self::_#DB2#_#tearOff::X>(field1, field2);
static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
return new self::B::•<self::_#DB2#new#tearOff::X>();
static method _#DB2#foo#tearOff<X extends core::num>(core::int field1) → self::B<self::_#DB2#foo#tearOff::X>
return new self::B::foo<self::_#DB2#foo#tearOff::X>(field1);
static method _#DB2#bar#tearOff<X extends core::num>(core::int i, core::String j) → self::B<self::_#DB2#bar#tearOff::X>
return self::B::bar<self::_#DB2#bar#tearOff::X>(i, j);
static method _#DB3#_#tearOff<X extends core::num, unrelated Y extends core::String>(core::int field1, core::String field2) → self::B<self::_#DB3#_#tearOff::X>
return new self::B::_<self::_#DB3#_#tearOff::X>(field1, field2);
static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
return new self::B::•<self::_#DB3#new#tearOff::X>();
static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>(core::int field1) → self::B<self::_#DB3#foo#tearOff::X>
return new self::B::foo<self::_#DB3#foo#tearOff::X>(field1);
static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>(core::int i, core::String j) → self::B<self::_#DB3#bar#tearOff::X>
return self::B::bar<self::_#DB3#bar#tearOff::X>(i, j);
constants {
#C1 = static-tearoff self::A::_#new#tearOff
#C2 = static-tearoff self::_#0#tearOff
#C3 = static-tearoff self::_#1#tearOff
#C4 = static-tearoff self::B::_#new#tearOff
#C5 = instantiation self::B::_#new#tearOff <core::String>
#C6 = static-tearoff self::B::_#foo#tearOff
#C7 = instantiation self::B::_#foo#tearOff <core::String>
#C8 = static-tearoff self::B::_#bar#tearOff
#C9 = instantiation self::B::_#bar#tearOff <core::String>
#C10 = static-tearoff self::_#2#tearOff
#C11 = static-tearoff self::_#3#tearOff
#C12 = static-tearoff self::_#4#tearOff
#C13 = static-tearoff self::_#5#tearOff
#C14 = false
#C2 = static-tearoff self::_#DA2#new#tearOff
#C3 = static-tearoff self::B::_#new#tearOff
#C4 = instantiation self::B::_#new#tearOff <core::String>
#C5 = static-tearoff self::B::_#foo#tearOff
#C6 = instantiation self::B::_#foo#tearOff <core::String>
#C7 = static-tearoff self::B::_#bar#tearOff
#C8 = instantiation self::B::_#bar#tearOff <core::String>
#C9 = static-tearoff self::_#DB2#new#tearOff
#C10 = static-tearoff self::_#DB3#new#tearOff
#C11 = false
}

View file

@ -143,14 +143,14 @@ Try removing the extra positional arguments.
^" in f2a{<inapplicable>}.<core::num>(0);
f2a<core::String>(){() → self::A};
};
dynamic f2b = #C3;
dynamic f2b = #C2;
dynamic c2b = f2b{dynamic}.call();
self::expect(true, c2b is{ForNonNullableByDefault} self::A);
dynamic c2c = f2b{dynamic}.call<core::int>();
self::expect(true, c2c is{ForNonNullableByDefault} self::A);
self::throws(() → dynamic => f2b{dynamic}.call(0));
self::throws(() → dynamic => f2b{dynamic}.call<core::String>());
() → self::B<core::String> f3a = #C5;
() → self::B<core::String> f3a = #C4;
self::B<core::String> c3a = f3a(){() → self::B<core::String>};
self::expect(true, c3a is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3a is{ForNonNullableByDefault} self::B<core::int>);
@ -165,7 +165,7 @@ Try removing the extra positional arguments.
f3a<String>(); // error
^" in f3a{<inapplicable>}.<core::String>();
};
dynamic f3b = #C5;
dynamic f3b = #C4;
dynamic c3b = f3b{dynamic}.call();
self::expect(true, c3b is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3b is{ForNonNullableByDefault} self::B<core::int>);
@ -173,7 +173,7 @@ Try removing the extra positional arguments.
self::expect("", c3a.{self::B::field2}{core::String});
self::throws(() → dynamic => f3b{dynamic}.call(0));
self::throws(() → dynamic => f3b{dynamic}.call<core::String>());
(core::int) → self::B<core::String> f3c = #C7;
(core::int) → self::B<core::String> f3c = #C6;
self::B<core::String> c3c = f3c(42){(core::int) → self::B<core::String>};
self::expect(true, c3c is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3c is{ForNonNullableByDefault} self::B<core::int>);
@ -191,7 +191,7 @@ Try removing the extra positional arguments.
f3c<String>(0); // error
^" in f3c{<inapplicable>}.<core::String>(0);
};
dynamic f3d = #C7;
dynamic f3d = #C6;
dynamic c3d = f3d{dynamic}.call(42);
self::expect(true, c3d is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3d is{ForNonNullableByDefault} self::B<core::int>);
@ -200,7 +200,7 @@ Try removing the extra positional arguments.
self::throws(() → dynamic => f3d{dynamic}.call());
self::throws(() → dynamic => f3d{dynamic}.call(0, 0));
self::throws(() → dynamic => f3d{dynamic}.call<core::String>(0));
(core::int, core::String) → self::B<core::String> f3e = #C9;
(core::int, core::String) → self::B<core::String> f3e = #C8;
self::B<core::String> c3e = f3e(42, "foo"){(core::int, core::String) → self::B<core::String>};
self::expect(true, c3e is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3e is{ForNonNullableByDefault} self::B<core::int>);
@ -217,7 +217,7 @@ Try removing the extra positional arguments.
f3e<String>(0, ''); // error
^" in f3e{<inapplicable>}.<core::String>(0, "");
};
dynamic f3f = #C9;
dynamic f3f = #C8;
dynamic c3f = f3f{dynamic}.call(42, "foo");
self::expect(true, c3f is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3f is{ForNonNullableByDefault} self::B<core::int>);
@ -226,7 +226,7 @@ Try removing the extra positional arguments.
self::throws(() → dynamic => c3f{dynamic}.call());
self::throws(() → dynamic => c3f{dynamic}.call(0));
self::throws(() → dynamic => c3f{dynamic}.call<core::String>(0));
<X extends core::num>() → self::B<X> f4a = #C10;
<X extends core::num>() → self::B<X> f4a = #C9;
self::B<core::num> c4a = f4a<core::num>(){() → self::B<core::num>};
self::expect(true, c4a is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c4a is{ForNonNullableByDefault} self::B<core::int>);
@ -240,7 +240,7 @@ Try removing the extra positional arguments.
^" in f4a{<inapplicable>}.<core::num>(0);
f4a<core::String>(){() → self::B<core::String>};
};
dynamic f4b = #C11;
dynamic f4b = #C9;
dynamic c4c = f4b{dynamic}.call();
self::expect(true, c4c is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c4c is{ForNonNullableByDefault} self::B<core::int>);
@ -249,7 +249,7 @@ Try removing the extra positional arguments.
self::expect(false, c4d is{ForNonNullableByDefault} self::B<core::double>);
self::throws(() → dynamic => f4b{dynamic}.call(0));
self::throws(() → dynamic => f4b{dynamic}.call<core::String>());
<X extends core::num, unrelated Y extends core::String>() → self::B<X> f5a = #C12;
<X extends core::num, unrelated Y extends core::String>() → self::B<X> f5a = #C10;
self::B<core::num> c5a = f5a<core::num, core::String>(){() → self::B<core::num>};
self::expect(true, c5a is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c5a is{ForNonNullableByDefault} self::B<core::int>);
@ -267,7 +267,7 @@ Try removing the extra positional arguments.
f5a<core::String, core::String>(){() → self::B<core::String>};
f5a<core::num, core::num>(){() → self::B<core::num>};
};
dynamic f5b = #C13;
dynamic f5b = #C10;
dynamic c5c = f5b{dynamic}.call();
self::expect(true, c5c is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c5c is{ForNonNullableByDefault} self::B<core::int>);
@ -283,7 +283,7 @@ static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
throw "Expected ${expected}, actual ${actual}";
}
static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C14}) → dynamic {
static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C11}) → dynamic {
try {
f(){() → dynamic};
}
@ -296,32 +296,45 @@ static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C14}) →
}
throw "Expected exception";
}
static method _#0#tearOff<unrelated X extends core::num>() → self::A
return (#C1)(){() → self::A};
static method _#1#tearOff<unrelated X extends core::num>() → self::A
return (#C1)(){() → self::A};
static method _#2#tearOff<X extends core::num>() → self::B<self::_#2#tearOff::X>
return (#C4)<self::_#2#tearOff::X>(){() → self::B<self::_#2#tearOff::X>};
static method _#3#tearOff<X extends core::num>() → self::B<self::_#3#tearOff::X>
return (#C4)<self::_#3#tearOff::X>(){() → self::B<self::_#3#tearOff::X>};
static method _#4#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#4#tearOff::X>
return (#C4)<self::_#4#tearOff::X>(){() → self::B<self::_#4#tearOff::X>};
static method _#5#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#5#tearOff::X>
return (#C4)<self::_#5#tearOff::X>(){() → self::B<self::_#5#tearOff::X>};
static method _#DA1#new#tearOff() → self::A
return new self::A::•();
static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
return new self::A::•();
static method _#DB1#_#tearOff(core::int field1, core::String field2) → self::B<core::String>
return new self::B::_<core::String>(field1, field2);
static method _#DB1#new#tearOff() → self::B<core::String>
return new self::B::•<core::String>();
static method _#DB1#foo#tearOff(core::int field1) → self::B<core::String>
return new self::B::foo<core::String>(field1);
static method _#DB1#bar#tearOff(core::int i, core::String j) → self::B<core::String>
return self::B::bar<core::String>(i, j);
static method _#DB2#_#tearOff<X extends core::num>(core::int field1, core::String field2) → self::B<self::_#DB2#_#tearOff::X>
return new self::B::_<self::_#DB2#_#tearOff::X>(field1, field2);
static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
return new self::B::•<self::_#DB2#new#tearOff::X>();
static method _#DB2#foo#tearOff<X extends core::num>(core::int field1) → self::B<self::_#DB2#foo#tearOff::X>
return new self::B::foo<self::_#DB2#foo#tearOff::X>(field1);
static method _#DB2#bar#tearOff<X extends core::num>(core::int i, core::String j) → self::B<self::_#DB2#bar#tearOff::X>
return self::B::bar<self::_#DB2#bar#tearOff::X>(i, j);
static method _#DB3#_#tearOff<X extends core::num, unrelated Y extends core::String>(core::int field1, core::String field2) → self::B<self::_#DB3#_#tearOff::X>
return new self::B::_<self::_#DB3#_#tearOff::X>(field1, field2);
static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
return new self::B::•<self::_#DB3#new#tearOff::X>();
static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>(core::int field1) → self::B<self::_#DB3#foo#tearOff::X>
return new self::B::foo<self::_#DB3#foo#tearOff::X>(field1);
static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>(core::int i, core::String j) → self::B<self::_#DB3#bar#tearOff::X>
return self::B::bar<self::_#DB3#bar#tearOff::X>(i, j);
constants {
#C1 = static-tearoff self::A::_#new#tearOff
#C2 = static-tearoff self::_#0#tearOff
#C3 = static-tearoff self::_#1#tearOff
#C4 = static-tearoff self::B::_#new#tearOff
#C5 = instantiation self::B::_#new#tearOff <core::String*>
#C6 = static-tearoff self::B::_#foo#tearOff
#C7 = instantiation self::B::_#foo#tearOff <core::String*>
#C8 = static-tearoff self::B::_#bar#tearOff
#C9 = instantiation self::B::_#bar#tearOff <core::String*>
#C10 = static-tearoff self::_#2#tearOff
#C11 = static-tearoff self::_#3#tearOff
#C12 = static-tearoff self::_#4#tearOff
#C13 = static-tearoff self::_#5#tearOff
#C14 = false
#C2 = static-tearoff self::_#DA2#new#tearOff
#C3 = static-tearoff self::B::_#new#tearOff
#C4 = instantiation self::B::_#new#tearOff <core::String*>
#C5 = static-tearoff self::B::_#foo#tearOff
#C6 = instantiation self::B::_#foo#tearOff <core::String*>
#C7 = static-tearoff self::B::_#bar#tearOff
#C8 = instantiation self::B::_#bar#tearOff <core::String*>
#C9 = static-tearoff self::_#DB2#new#tearOff
#C10 = static-tearoff self::_#DB3#new#tearOff
#C11 = false
}

View file

@ -40,3 +40,31 @@ static method expect(dynamic expected, dynamic actual) → dynamic
;
static method throws(() → dynamic f, {core::bool inSoundModeOnly}) → dynamic
;
static method _#DA1#new#tearOff() → self::A
return new self::A::•();
static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
return new self::A::•();
static method _#DB1#_#tearOff(core::int field1, core::String field2) → self::B<core::String>
return new self::B::_<core::String>(field1, field2);
static method _#DB1#new#tearOff() → self::B<core::String>
return new self::B::•<core::String>();
static method _#DB1#foo#tearOff(core::int field1) → self::B<core::String>
return new self::B::foo<core::String>(field1);
static method _#DB1#bar#tearOff(core::int i, core::String j) → self::B<core::String>
return self::B::bar<core::String>(i, j);
static method _#DB2#_#tearOff<X extends core::num>(core::int field1, core::String field2) → self::B<self::_#DB2#_#tearOff::X>
return new self::B::_<self::_#DB2#_#tearOff::X>(field1, field2);
static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
return new self::B::•<self::_#DB2#new#tearOff::X>();
static method _#DB2#foo#tearOff<X extends core::num>(core::int field1) → self::B<self::_#DB2#foo#tearOff::X>
return new self::B::foo<self::_#DB2#foo#tearOff::X>(field1);
static method _#DB2#bar#tearOff<X extends core::num>(core::int i, core::String j) → self::B<self::_#DB2#bar#tearOff::X>
return self::B::bar<self::_#DB2#bar#tearOff::X>(i, j);
static method _#DB3#_#tearOff<X extends core::num, unrelated Y extends core::String>(core::int field1, core::String field2) → self::B<self::_#DB3#_#tearOff::X>
return new self::B::_<self::_#DB3#_#tearOff::X>(field1, field2);
static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
return new self::B::•<self::_#DB3#new#tearOff::X>();
static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>(core::int field1) → self::B<self::_#DB3#foo#tearOff::X>
return new self::B::foo<self::_#DB3#foo#tearOff::X>(field1);
static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>(core::int i, core::String j) → self::B<self::_#DB3#bar#tearOff::X>
return self::B::bar<self::_#DB3#bar#tearOff::X>(i, j);

View file

@ -143,14 +143,14 @@ Try removing the extra positional arguments.
^" in f2a{<inapplicable>}.<core::num>(0);
f2a<core::String>(){() → self::A};
};
dynamic f2b = #C3;
dynamic f2b = #C2;
dynamic c2b = f2b{dynamic}.call();
self::expect(true, c2b is{ForNonNullableByDefault} self::A);
dynamic c2c = f2b{dynamic}.call<core::int>();
self::expect(true, c2c is{ForNonNullableByDefault} self::A);
self::throws(() → dynamic => f2b{dynamic}.call(0));
self::throws(() → dynamic => f2b{dynamic}.call<core::String>());
() → self::B<core::String> f3a = #C5;
() → self::B<core::String> f3a = #C4;
self::B<core::String> c3a = f3a(){() → self::B<core::String>};
self::expect(true, c3a is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3a is{ForNonNullableByDefault} self::B<core::int>);
@ -165,7 +165,7 @@ Try removing the extra positional arguments.
f3a<String>(); // error
^" in f3a{<inapplicable>}.<core::String>();
};
dynamic f3b = #C5;
dynamic f3b = #C4;
dynamic c3b = f3b{dynamic}.call();
self::expect(true, c3b is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3b is{ForNonNullableByDefault} self::B<core::int>);
@ -173,7 +173,7 @@ Try removing the extra positional arguments.
self::expect("", c3a.{self::B::field2}{core::String});
self::throws(() → dynamic => f3b{dynamic}.call(0));
self::throws(() → dynamic => f3b{dynamic}.call<core::String>());
(core::int) → self::B<core::String> f3c = #C7;
(core::int) → self::B<core::String> f3c = #C6;
self::B<core::String> c3c = f3c(42){(core::int) → self::B<core::String>};
self::expect(true, c3c is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3c is{ForNonNullableByDefault} self::B<core::int>);
@ -191,7 +191,7 @@ Try removing the extra positional arguments.
f3c<String>(0); // error
^" in f3c{<inapplicable>}.<core::String>(0);
};
dynamic f3d = #C7;
dynamic f3d = #C6;
dynamic c3d = f3d{dynamic}.call(42);
self::expect(true, c3d is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3d is{ForNonNullableByDefault} self::B<core::int>);
@ -200,7 +200,7 @@ Try removing the extra positional arguments.
self::throws(() → dynamic => f3d{dynamic}.call());
self::throws(() → dynamic => f3d{dynamic}.call(0, 0));
self::throws(() → dynamic => f3d{dynamic}.call<core::String>(0));
(core::int, core::String) → self::B<core::String> f3e = #C9;
(core::int, core::String) → self::B<core::String> f3e = #C8;
self::B<core::String> c3e = f3e(42, "foo"){(core::int, core::String) → self::B<core::String>};
self::expect(true, c3e is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3e is{ForNonNullableByDefault} self::B<core::int>);
@ -217,7 +217,7 @@ Try removing the extra positional arguments.
f3e<String>(0, ''); // error
^" in f3e{<inapplicable>}.<core::String>(0, "");
};
dynamic f3f = #C9;
dynamic f3f = #C8;
dynamic c3f = f3f{dynamic}.call(42, "foo");
self::expect(true, c3f is{ForNonNullableByDefault} self::B<core::String>);
self::expect(false, c3f is{ForNonNullableByDefault} self::B<core::int>);
@ -226,7 +226,7 @@ Try removing the extra positional arguments.
self::throws(() → dynamic => c3f{dynamic}.call());
self::throws(() → dynamic => c3f{dynamic}.call(0));
self::throws(() → dynamic => c3f{dynamic}.call<core::String>(0));
<X extends core::num>() → self::B<X> f4a = #C10;
<X extends core::num>() → self::B<X> f4a = #C9;
self::B<core::num> c4a = f4a<core::num>(){() → self::B<core::num>};
self::expect(true, c4a is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c4a is{ForNonNullableByDefault} self::B<core::int>);
@ -240,7 +240,7 @@ Try removing the extra positional arguments.
^" in f4a{<inapplicable>}.<core::num>(0);
f4a<core::String>(){() → self::B<core::String>};
};
dynamic f4b = #C11;
dynamic f4b = #C9;
dynamic c4c = f4b{dynamic}.call();
self::expect(true, c4c is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c4c is{ForNonNullableByDefault} self::B<core::int>);
@ -249,7 +249,7 @@ Try removing the extra positional arguments.
self::expect(false, c4d is{ForNonNullableByDefault} self::B<core::double>);
self::throws(() → dynamic => f4b{dynamic}.call(0));
self::throws(() → dynamic => f4b{dynamic}.call<core::String>());
<X extends core::num, unrelated Y extends core::String>() → self::B<X> f5a = #C12;
<X extends core::num, unrelated Y extends core::String>() → self::B<X> f5a = #C10;
self::B<core::num> c5a = f5a<core::num, core::String>(){() → self::B<core::num>};
self::expect(true, c5a is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c5a is{ForNonNullableByDefault} self::B<core::int>);
@ -267,7 +267,7 @@ Try removing the extra positional arguments.
f5a<core::String, core::String>(){() → self::B<core::String>};
f5a<core::num, core::num>(){() → self::B<core::num>};
};
dynamic f5b = #C13;
dynamic f5b = #C10;
dynamic c5c = f5b{dynamic}.call();
self::expect(true, c5c is{ForNonNullableByDefault} self::B<core::num>);
self::expect(false, c5c is{ForNonNullableByDefault} self::B<core::int>);
@ -283,7 +283,7 @@ static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
throw "Expected ${expected}, actual ${actual}";
}
static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C14}) → dynamic {
static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C11}) → dynamic {
try {
f(){() → dynamic};
}
@ -296,32 +296,45 @@ static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C14}) →
}
throw "Expected exception";
}
static method _#0#tearOff<unrelated X extends core::num>() → self::A
return (#C1)(){() → self::A};
static method _#1#tearOff<unrelated X extends core::num>() → self::A
return (#C1)(){() → self::A};
static method _#2#tearOff<X extends core::num>() → self::B<self::_#2#tearOff::X>
return (#C4)<self::_#2#tearOff::X>(){() → self::B<self::_#2#tearOff::X>};
static method _#3#tearOff<X extends core::num>() → self::B<self::_#3#tearOff::X>
return (#C4)<self::_#3#tearOff::X>(){() → self::B<self::_#3#tearOff::X>};
static method _#4#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#4#tearOff::X>
return (#C4)<self::_#4#tearOff::X>(){() → self::B<self::_#4#tearOff::X>};
static method _#5#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#5#tearOff::X>
return (#C4)<self::_#5#tearOff::X>(){() → self::B<self::_#5#tearOff::X>};
static method _#DA1#new#tearOff() → self::A
return new self::A::•();
static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
return new self::A::•();
static method _#DB1#_#tearOff(core::int field1, core::String field2) → self::B<core::String>
return new self::B::_<core::String>(field1, field2);
static method _#DB1#new#tearOff() → self::B<core::String>
return new self::B::•<core::String>();
static method _#DB1#foo#tearOff(core::int field1) → self::B<core::String>
return new self::B::foo<core::String>(field1);
static method _#DB1#bar#tearOff(core::int i, core::String j) → self::B<core::String>
return self::B::bar<core::String>(i, j);
static method _#DB2#_#tearOff<X extends core::num>(core::int field1, core::String field2) → self::B<self::_#DB2#_#tearOff::X>
return new self::B::_<self::_#DB2#_#tearOff::X>(field1, field2);
static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
return new self::B::•<self::_#DB2#new#tearOff::X>();
static method _#DB2#foo#tearOff<X extends core::num>(core::int field1) → self::B<self::_#DB2#foo#tearOff::X>
return new self::B::foo<self::_#DB2#foo#tearOff::X>(field1);
static method _#DB2#bar#tearOff<X extends core::num>(core::int i, core::String j) → self::B<self::_#DB2#bar#tearOff::X>
return self::B::bar<self::_#DB2#bar#tearOff::X>(i, j);
static method _#DB3#_#tearOff<X extends core::num, unrelated Y extends core::String>(core::int field1, core::String field2) → self::B<self::_#DB3#_#tearOff::X>
return new self::B::_<self::_#DB3#_#tearOff::X>(field1, field2);
static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
return new self::B::•<self::_#DB3#new#tearOff::X>();
static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>(core::int field1) → self::B<self::_#DB3#foo#tearOff::X>
return new self::B::foo<self::_#DB3#foo#tearOff::X>(field1);
static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>(core::int i, core::String j) → self::B<self::_#DB3#bar#tearOff::X>
return self::B::bar<self::_#DB3#bar#tearOff::X>(i, j);
constants {
#C1 = static-tearoff self::A::_#new#tearOff
#C2 = static-tearoff self::_#0#tearOff
#C3 = static-tearoff self::_#1#tearOff
#C4 = static-tearoff self::B::_#new#tearOff
#C5 = instantiation self::B::_#new#tearOff <core::String*>
#C6 = static-tearoff self::B::_#foo#tearOff
#C7 = instantiation self::B::_#foo#tearOff <core::String*>
#C8 = static-tearoff self::B::_#bar#tearOff
#C9 = instantiation self::B::_#bar#tearOff <core::String*>
#C10 = static-tearoff self::_#2#tearOff
#C11 = static-tearoff self::_#3#tearOff
#C12 = static-tearoff self::_#4#tearOff
#C13 = static-tearoff self::_#5#tearOff
#C14 = false
#C2 = static-tearoff self::_#DA2#new#tearOff
#C3 = static-tearoff self::B::_#new#tearOff
#C4 = instantiation self::B::_#new#tearOff <core::String*>
#C5 = static-tearoff self::B::_#foo#tearOff
#C6 = instantiation self::B::_#foo#tearOff <core::String*>
#C7 = static-tearoff self::B::_#bar#tearOff
#C8 = instantiation self::B::_#bar#tearOff <core::String*>
#C9 = static-tearoff self::_#DB2#new#tearOff
#C10 = static-tearoff self::_#DB3#new#tearOff
#C11 = false
}

View file

@ -32,6 +32,8 @@ constructor_tearoffs/identical_instantiated_function_tearoffs: FormatterCrash
constructor_tearoffs/inferred_constructor_tear_off: FormatterCrash
constructor_tearoffs/instantiation: FormatterCrash
constructor_tearoffs/lowering/inferred_constructor_tear_off: FormatterCrash
constructor_tearoffs/lowering/typedef_from_dill/main: FormatterCrash
constructor_tearoffs/lowering/typedef_identical: FormatterCrash
constructor_tearoffs/nongeneric_tearoff_with_context: FormatterCrash
constructor_tearoffs/nongeneric_tearoff_without_context: FormatterCrash
constructor_tearoffs/redirecting_constructors: FormatterCrash

View file

@ -13116,8 +13116,8 @@ class TypedefTearOffConstant extends Constant {
@override
void toTextInternal(AstPrinter printer) {
printer.writeConstant(tearOffConstant);
printer.writeTypeParameters(parameters);
printer.writeConstant(tearOffConstant);
printer.writeTypeArguments(types);
}

View file

@ -354,7 +354,7 @@ abstract class Target {
/// synthesized top level functions.
int get enabledConstructorTearOffLowerings;
/// Returns `true` if lowering of constructor tear offs is enabled.
/// Returns `true` if lowering of generative constructor tear offs is enabled.
///
/// This is determined by the [enabledConstructorTearOffLowerings] mask.
bool get isConstructorTearOffLoweringEnabled =>
@ -362,6 +362,15 @@ abstract class Target {
ConstructorTearOffLowering.constructors) !=
0;
/// Returns `true` if lowering of non-redirecting factory tear offs is
/// enabled.
///
/// This is determined by the [enabledConstructorTearOffLowerings] mask.
bool get isFactoryTearOffLoweringEnabled =>
(enabledConstructorTearOffLowerings &
ConstructorTearOffLowering.factories) !=
0;
/// Returns `true` if lowering of redirecting factory tear offs is enabled.
///
/// This is determined by the [enabledConstructorTearOffLowerings] mask.
@ -643,16 +652,19 @@ class LateLowering {
}
class ConstructorTearOffLowering {
/// Create static functions to use as tear offs of constructors and.
/// Create static functions to use as tear offs of generative constructors.
static const int constructors = 1 << 0;
/// Create static functions to use as tear offs of non-redirecting factories.
static const int factories = 1 << 1;
/// Create static functions to use as tear offs of redirecting factories.
static const int redirectingFactories = 1 << 1;
static const int redirectingFactories = 1 << 2;
/// Create top level functions to use as tear offs of typedefs that are not
/// proper renames.
static const int typedefs = 1 << 2;
static const int typedefs = 1 << 3;
static const int none = 0;
static const int all = (1 << 3) - 1;
static const int all = (1 << 4) - 1;
}