From 5a6c1e515849b453220939cff697c6397c5d3c70 Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Tue, 23 Jun 2020 14:14:11 +0000 Subject: [PATCH] Type aliased inference of generative constructor invocation. This CL adds some infrastructure that makes it possible to defer the inference of type arguments for a type alias which is used to specify an instance creation: class B {} class C implements B {} typedef T = C>; void main() { B> c = T(); // Infer `T()`. } The CL contains an implementation for type inference in the case where the target is a non-redirecting constructor. There is not yet an implementation of type inference for the case where the type alias ultimately resolves to a redirecting factory constructor, and the shadow nodes are eliminated as null. Change-Id: I9721b293dce37313e046a8339359e51c2d54b4c3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150301 Commit-Queue: Erik Ernst Reviewed-by: Dmitry Stefantsov --- .../lib/src/fasta/kernel/body_builder.dart | 182 +++++++++++++++--- .../src/fasta/kernel/inference_visitor.dart | 35 ++++ .../lib/src/fasta/kernel/internal_ast.dart | 61 ++++++ .../test/spell_checking_list_common.txt | 3 + pkg/kernel/lib/ast.dart | 43 +++++ ...fer_aliased_instance_creation_01_test.dart | 20 ++ ...fer_aliased_instance_creation_02_test.dart | 16 ++ ...fer_aliased_instance_creation_03_test.dart | 20 ++ ...fer_aliased_instance_creation_04_test.dart | 22 +++ ...fer_aliased_instance_creation_05_test.dart | 21 ++ ...fer_aliased_instance_creation_06_test.dart | 19 ++ ...fer_aliased_instance_creation_07_test.dart | 21 ++ ...fer_aliased_instance_creation_08_test.dart | 20 ++ ...fer_aliased_instance_creation_09_test.dart | 16 ++ ...fer_aliased_instance_creation_10_test.dart | 20 ++ ...fer_aliased_instance_creation_11_test.dart | 22 +++ ...fer_aliased_instance_creation_12_test.dart | 21 ++ 17 files changed, 535 insertions(+), 27 deletions(-) create mode 100644 tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_01_test.dart create mode 100644 tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_02_test.dart create mode 100644 tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_03_test.dart create mode 100644 tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_04_test.dart create mode 100644 tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_05_test.dart create mode 100644 tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_06_test.dart create mode 100644 tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_07_test.dart create mode 100644 tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_08_test.dart create mode 100644 tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_09_test.dart create mode 100644 tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_10_test.dart create mode 100644 tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_11_test.dart create mode 100644 tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_12_test.dart diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart index 2d1f0a28cd4ac..12b828df4b66d 100644 --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart @@ -317,6 +317,16 @@ class BodyBuilder extends ScopeListener /// invocations are to be resolved in a separate step. final List redirectingFactoryInvocations = []; + /// List of built type aliased generative constructor invocations that + /// require unaliasing. + final List typeAliasedConstructorInvocations = + []; + + /// List of built type aliased factory constructor invocations that require + /// unaliasing. + final List typeAliasedFactoryInvocations = + []; + /// Variables with metadata. Their types need to be inferred late, for /// example, in [finishFunction]. List variablesWithMetadata; @@ -1129,7 +1139,14 @@ class BodyBuilder extends ScopeListener return true; } + // TODO(eernst): Rename this method now that it handles more tasks. void resolveRedirectingFactoryTargets() { + _unaliasTypeAliasedConstructorInvocations(); + _unaliasTypeAliasedFactoryInvocations(); + _resolveRedirectingFactoryTargets(); + } + + void _resolveRedirectingFactoryTargets() { for (StaticInvocation invocation in redirectingFactoryInvocations) { // If the invocation was invalid, it or its parent has already been // desugared into an exception throwing expression. There is nothing to @@ -1221,6 +1238,25 @@ class BodyBuilder extends ScopeListener redirectingFactoryInvocations.clear(); } + void _unaliasTypeAliasedConstructorInvocations() { + for (ConstructorInvocation invocation + in typeAliasedConstructorInvocations) { + // TODO(eernst): Should replace aliased constructor invocations, + // such that back ends don't see instance creations on type aliases. + invocation.replaceWith(new NullLiteral()); + } + typeAliasedConstructorInvocations.clear(); + } + + void _unaliasTypeAliasedFactoryInvocations() { + for (StaticInvocation invocation in typeAliasedFactoryInvocations) { + // TODO(eernst): Should replace aliased factory invocations, + // such that back ends don't see instance creations on type aliases. + invocation.replaceWith(new NullLiteral()); + } + typeAliasedFactoryInvocations.clear(); + } + void finishVariableMetadata() { List variablesWithMetadata = this.variablesWithMetadata; @@ -3907,6 +3943,7 @@ class BodyBuilder extends ScopeListener @override Expression buildStaticInvocation(Member target, Arguments arguments, {Constness constness: Constness.implicit, + TypeAliasBuilder typeAliasBuilder, int charOffset: -1, int charLength: noLength}) { // The argument checks for the initial target of redirecting factories @@ -3935,11 +3972,21 @@ class BodyBuilder extends ScopeListener return buildProblem( fasta.messageNonConstConstructor, charOffset, charLength); } - ConstructorInvocation node = - new ConstructorInvocation(target, arguments, isConst: isConst) - ..fileOffset = charOffset; - libraryBuilder.checkBoundsInConstructorInvocation( - node, typeEnvironment, uri); + ConstructorInvocation node; + if (typeAliasBuilder == null) { + node = new ConstructorInvocation(target, arguments, isConst: isConst) + ..fileOffset = charOffset; + libraryBuilder.checkBoundsInConstructorInvocation( + node, typeEnvironment, uri); + } else { + node = new TypeAliasedConstructorInvocationJudgment( + typeAliasBuilder, target, arguments, + isConst: isConst) + ..fileOffset = charOffset; + // No type arguments were passed, so we need not check bounds. + assert(arguments.types.isEmpty); + typeAliasedConstructorInvocations.add(node); + } return node; } else { Procedure procedure = target; @@ -3952,12 +3999,22 @@ class BodyBuilder extends ScopeListener return buildProblem( fasta.messageNonConstFactory, charOffset, charLength); } - StaticInvocation node = new FactoryConstructorInvocationJudgment( - target, arguments, - isConst: isConst) - ..fileOffset = charOffset; - libraryBuilder.checkBoundsInFactoryInvocation( - node, typeEnvironment, uri); + StaticInvocation node; + if (typeAliasBuilder == null) { + node = new FactoryConstructorInvocationJudgment(target, arguments, + isConst: isConst) + ..fileOffset = charOffset; + libraryBuilder.checkBoundsInFactoryInvocation( + node, typeEnvironment, uri); + } else { + node = new TypeAliasedFactoryInvocationJudgment( + typeAliasBuilder, target, arguments, + isConst: isConst) + ..fileOffset = charOffset; + // No type arguments were passed, so we need not check bounds. + assert(arguments.types.isEmpty); + typeAliasedFactoryInvocations.add(node); + } return node; } else { assert(constness == Constness.implicit); @@ -4248,13 +4305,83 @@ class BodyBuilder extends ScopeListener } } else { if (aliasBuilder.typeVariables?.isNotEmpty ?? false) { - // No type arguments provided to alias, but it is generic. - typeArgumentBuilders = new List.filled( - aliasBuilder.typeVariables.length, null, - growable: true); - for (int i = 0; i < typeArgumentBuilders.length; ++i) { - // TODO(eernst): We must use inferred types, for now use defaults. - typeArgumentBuilders[i] = aliasBuilder.typeVariables[i].defaultType; + // Raw generic type alias used for instance creation, needs inference. + ClassBuilder classBuilder; + if (type is ClassBuilder) { + classBuilder = type; + } else { + if (type is InvalidTypeDeclarationBuilder) { + LocatedMessage message = type.message; + return evaluateArgumentsBefore( + arguments, + buildProblem(message.messageObject, nameToken.charOffset, + nameToken.lexeme.length)); + } else { + errorName ??= debugName(type.fullNameForErrors, name); + } + errorName ??= name; + + return throwNoSuchMethodError(forest.createNullLiteral(charOffset), + errorName, arguments, nameLastToken.charOffset, + message: message); + } + MemberBuilder b = classBuilder.findConstructorOrFactory( + name, charOffset, uri, libraryBuilder); + Member target = b?.member; + if (b == null) { + // Not found. Reported below. + } else if (b is AmbiguousMemberBuilder) { + message = b.message.withLocation(uri, charOffset, noLength); + } else if (b.isConstructor) { + if (classBuilder.isAbstract) { + return evaluateArgumentsBefore( + arguments, + buildAbstractClassInstantiationError( + fasta.templateAbstractClassInstantiation + .withArguments(type.name), + type.name, + nameToken.charOffset)); + } + } + if (target is Constructor || + (target is Procedure && target.kind == ProcedureKind.Factory)) { + Expression invocation; + invocation = buildStaticInvocation(target, arguments, + constness: constness, + typeAliasBuilder: aliasBuilder, + charOffset: nameToken.charOffset, + charLength: nameToken.length); + return invocation; + } else { + errorName ??= debugName(type.name, name); + return throwNoSuchMethodError(forest.createNullLiteral(charOffset), + errorName, arguments, nameLastToken.charOffset, + message: message); + } + } else { + // Empty `typeArguments` and `aliasBuilder``is non-generic, but it + // may still unalias to a class type with some type arguments. + if (type is ClassBuilder) { + List unaliasedTypeArgumentBuilders = + aliasBuilder.unaliasTypeArguments(const []); + if (unaliasedTypeArgumentBuilders == null) { + // TODO(eernst): This is a wrong number of type arguments, + // occurring indirectly (in an alias of an alias, etc.). + return evaluateArgumentsBefore( + arguments, + buildProblem( + fasta.templateTypeArgumentMismatch + .withArguments(numberOfTypeParameters), + nameToken.charOffset, + nameToken.length, + suppressMessage: true)); + } + List dartTypeArguments = []; + for (TypeBuilder typeBuilder in unaliasedTypeArgumentBuilders) { + dartTypeArguments.add(typeBuilder.build(libraryBuilder)); + } + assert(forest.argumentsTypeArguments(arguments).isEmpty); + forest.argumentsSetTypeArguments(arguments, dartTypeArguments); } } } @@ -4296,16 +4423,17 @@ class BodyBuilder extends ScopeListener assert(forest.argumentsTypeArguments(arguments).isEmpty); forest.argumentsSetTypeArguments(arguments, []); } else { - // No type arguments provided to unaliased class, use defaults. - List result = new List.filled( - type.typeVariables.length, null, - growable: true); - for (int i = 0; i < result.length; ++i) { - result[i] = - type.typeVariables[i].defaultType?.build(type.library); + if (forest.argumentsTypeArguments(arguments).isEmpty) { + // No type arguments provided to unaliased class, use defaults. + List result = new List.filled( + type.typeVariables.length, null, + growable: true); + for (int i = 0; i < result.length; ++i) { + result[i] = + type.typeVariables[i].defaultType?.build(type.library); + } + forest.argumentsSetTypeArguments(arguments, result); } - assert(forest.argumentsTypeArguments(arguments).isEmpty); - forest.argumentsSetTypeArguments(arguments, result); } } } diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart index 31903ea466927..9644894d6ea74 100644 --- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart +++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart @@ -743,6 +743,41 @@ class InferenceVisitor result.inferredType, result.applyResult(resultNode)); } + ExpressionInferenceResult visitTypeAliasedConstructorInvocationJudgment( + TypeAliasedConstructorInvocationJudgment node, DartType typeContext) { + assert(getExplicitTypeArguments(node.arguments) == null); + Typedef typedef = node.typeAliasBuilder.typedef; + FunctionType calleeType = node.target.function + .computeAliasedFunctionType(typedef, inferrer.library.library); + InvocationInferenceResult result = inferrer.inferInvocation( + typeContext, node.fileOffset, calleeType, node.arguments, + returnType: calleeType.returnType.unalias, isConst: node.isConst); + node.hasBeenInferred = true; + Expression resultNode = node; + if (!inferrer.isTopLevel) { + SourceLibraryBuilder library = inferrer.library; + library.checkBoundsInType(result.inferredType, + inferrer.typeSchemaEnvironment, inferrer.helper.uri, node.fileOffset, + inferred: true); + if (inferrer.isNonNullableByDefault) { + if (node.target == inferrer.coreTypes.listDefaultConstructor) { + resultNode = inferrer.helper.wrapInProblem(node, + messageDefaultListConstructorError, node.fileOffset, noLength); + } + } + } + return new ExpressionInferenceResult( + result.inferredType, result.applyResult(resultNode)); + } + + ExpressionInferenceResult visitTypeAliasedFactoryInvocationJudgment( + TypeAliasedFactoryInvocationJudgment node, DartType typeContext) { + // TODO(eernst): See visitTypeAliasedConstructorInvocationJudgment + // for an implementation handling a similar task. + throw "visitTypeAliasedFactoryInvocationJudgment: " + "${node.typeAliasBuilder}, ${node.target}, $typeContext"; + } + @override void visitFieldInitializer(FieldInitializer node) { ExpressionInferenceResult initializerResult = diff --git a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart index 991d0cdb1d1bd..377dace49000f 100644 --- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart +++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart @@ -25,6 +25,8 @@ import 'package:kernel/text/ast_to_text.dart' show Precedence, Printer; import 'package:kernel/src/printer.dart'; import 'package:kernel/core_types.dart'; +import '../builder/type_alias_builder.dart'; + import '../fasta_codes.dart' show noLength, templateWebLiteralCannotBeRepresentedExactly; @@ -704,6 +706,65 @@ class FactoryConstructorInvocationJudgment extends StaticInvocation } } +/// Shadow object for [ConstructorInvocation] when the procedure being invoked +/// is a type aliased constructor. +class TypeAliasedConstructorInvocationJudgment extends ConstructorInvocation + implements ExpressionJudgment { + bool hasBeenInferred = false; + final TypeAliasBuilder typeAliasBuilder; + + TypeAliasedConstructorInvocationJudgment( + this.typeAliasBuilder, Constructor target, ArgumentsImpl arguments, + {bool isConst: false}) + : super(target, arguments, isConst: isConst); + + @override + ExpressionInferenceResult acceptInference( + InferenceVisitor visitor, DartType typeContext) { + return visitor.visitTypeAliasedConstructorInvocationJudgment( + this, typeContext); + } + + @override + String toString() { + return "TypeAliasedConstructorInvocationJudgment(${toStringInternal()})"; + } + + @override + String toStringInternal() { + return ""; + } +} + +/// Shadow object for [StaticInvocation] when the procedure being invoked is a +/// type aliased factory constructor. +class TypeAliasedFactoryInvocationJudgment extends StaticInvocation + implements ExpressionJudgment { + bool hasBeenInferred = false; + final TypeAliasBuilder typeAliasBuilder; + + TypeAliasedFactoryInvocationJudgment( + this.typeAliasBuilder, Procedure target, ArgumentsImpl arguments, + {bool isConst: false}) + : super(target, arguments, isConst: isConst); + + @override + ExpressionInferenceResult acceptInference( + InferenceVisitor visitor, DartType typeContext) { + return visitor.visitTypeAliasedFactoryInvocationJudgment(this, typeContext); + } + + @override + String toString() { + return "TypeAliasedConstructorInvocationJudgment(${toStringInternal()})"; + } + + @override + String toStringInternal() { + return ""; + } +} + /// Front end specific implementation of [FunctionDeclaration]. class FunctionDeclarationImpl extends FunctionDeclaration { bool hasImplicitReturnType = false; diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt index 2e1286127bc7d..4e0e201963679 100644 --- a/pkg/front_end/test/spell_checking_list_common.txt +++ b/pkg/front_end/test/spell_checking_list_common.txt @@ -686,6 +686,7 @@ created creates creating creation +creations crossed curly current @@ -1077,6 +1078,7 @@ experimentally experiments expired explanation +explain explicit explicitly exponent @@ -2901,6 +2903,7 @@ targeted targeting targets task +tasks tear tearing technically diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart index c0d3f99bed6ff..7eff1a0a8d3b0 100644 --- a/pkg/kernel/lib/ast.dart +++ b/pkg/kernel/lib/ast.dart @@ -2818,6 +2818,49 @@ class FunctionNode extends TreeNode { .applyToFunctionType(computeThisFunctionType(nullability)); } + /// Return function type of node: return [typedefType], reuse type parameters. + /// + /// When this getter is invoked, the parent must be a [Constructor]. + /// This getter works similarly to [computeThisFunctionType], but uses + /// [typedef] to compute the return type of the returned function type. It + /// is useful in some contexts, especially during inference of aliased + /// constructor invocations. + FunctionType computeAliasedFunctionType(Typedef typedef, Library library) { + TreeNode parent = this.parent; + assert(parent is Constructor, "Only run this method on constructors"); + Constructor parentConstructor = parent; + // We need create a copy of the list of type parameters, otherwise + // transformations like erasure don't work. + List classTypeParametersCopy = + List.from(parentConstructor.enclosingClass.typeParameters); + List typedefTypeParametersCopy = + List.from(typedef.typeParameters); + List asTypeArguments = + getAsTypeArguments(typedefTypeParametersCopy, library); + TypedefType typedefType = + TypedefType(typedef, library.nonNullable, asTypeArguments); + DartType unaliasedTypedef = typedefType.unalias; + assert(unaliasedTypedef is InterfaceType, + "[typedef] is assumed to resolve to an interface type"); + InterfaceType targetType = unaliasedTypedef; + Substitution substitution = Substitution.fromPairs( + classTypeParametersCopy, targetType.typeArguments); + List positional = positionalParameters + .map((VariableDeclaration decl) => + substitution.substituteType(decl.type)) + .toList(growable: false); + List named = namedParameters + .map((VariableDeclaration decl) => NamedType( + decl.name, substitution.substituteType(decl.type), + isRequired: decl.isRequired)) + .toList(growable: false); + named.sort(); + return new FunctionType(positional, typedefType, library.nonNullable, + namedParameters: named, + typeParameters: typedefTypeParametersCopy, + requiredParameterCount: requiredParameterCount); + } + R accept(TreeVisitor v) => v.visitFunctionNode(this); visitChildren(Visitor v) { diff --git a/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_01_test.dart b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_01_test.dart new file mode 100644 index 0000000000000..99f6365c576f0 --- /dev/null +++ b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_01_test.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2020, 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. + +// SharedOptions=--enable-experiment=nonfunction-type-aliases + +import 'package:expect/expect.dart'; + +class C { + C(Type t) { + Expect.equals(t, X); + } +} + +typedef T = C; + +void main() { + T x1 = T(num); + C x2 = T(num); +} diff --git a/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_02_test.dart b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_02_test.dart new file mode 100644 index 0000000000000..081f4d80cf549 --- /dev/null +++ b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_02_test.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2020, 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. + +// SharedOptions=--enable-experiment=nonfunction-type-aliases + +import 'package:expect/expect.dart'; + +class C {} + +typedef T = C; + +void main() { + T x1 = T(); + C x2 = T(); +} diff --git a/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_03_test.dart b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_03_test.dart new file mode 100644 index 0000000000000..b11314a89b43a --- /dev/null +++ b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_03_test.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2020, 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. + +// SharedOptions=--enable-experiment=nonfunction-type-aliases + +import 'package:expect/expect.dart'; + +class C { + C(Type t) { + Expect.equals(t, X); + } +} + +typedef T = C; + +void main() { + T x1 = T(num); + C x2 = T(num); +} diff --git a/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_04_test.dart b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_04_test.dart new file mode 100644 index 0000000000000..97d6600ae04bd --- /dev/null +++ b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_04_test.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2020, 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. + +// SharedOptions=--enable-experiment=nonfunction-type-aliases + +import 'package:expect/expect.dart'; + +class C { + C(Type t) { + Expect.equals(t, X); + } +} + +typedef T = C>; + +Type typeOf() => X; + +void main() { + T x1 = T(typeOf>()); + C> x2 = T(typeOf>()); +} diff --git a/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_05_test.dart b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_05_test.dart new file mode 100644 index 0000000000000..7736a0dfbfcac --- /dev/null +++ b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_05_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2020, 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. + +// SharedOptions=--enable-experiment=nonfunction-type-aliases + +import 'package:expect/expect.dart'; + +class C { + C(Type tx, Type ty) { + Expect.equals(tx, X); + Expect.equals(ty, Y); + } +} + +typedef T = C; + +void main() { + T x1 = T(String, int); + C x2 = T(String, int); +} diff --git a/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_06_test.dart b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_06_test.dart new file mode 100644 index 0000000000000..543deb9211fa8 --- /dev/null +++ b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_06_test.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2020, 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. + +// SharedOptions=--enable-experiment=nonfunction-type-aliases + +import 'package:expect/expect.dart'; + +class C { + C(X x, Type t) { + Expect.equals(t, X); + } +} + +typedef T = C; + +void main() { + T(1, int); +} diff --git a/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_07_test.dart b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_07_test.dart new file mode 100644 index 0000000000000..0d619665578e0 --- /dev/null +++ b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_07_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2020, 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. + +// SharedOptions=--enable-experiment=nonfunction-type-aliases + +import 'package:expect/expect.dart'; + +class C { + C(X x, Type t) { + Expect.equals(t, X); + } +} + +typedef T = C>; + +Type typeOf() => X; + +void main() { + T([1], typeOf>()); +} diff --git a/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_08_test.dart b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_08_test.dart new file mode 100644 index 0000000000000..fe92b5708bf2d --- /dev/null +++ b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_08_test.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2020, 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. + +// SharedOptions=--enable-experiment=nonfunction-type-aliases + +import 'package:expect/expect.dart'; + +class C { + C(Type t) { + Expect.equals(t, X); + } +} + +typedef T = C; + +void main() { + T x1 = T(int); + C x2 = T(int); +} diff --git a/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_09_test.dart b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_09_test.dart new file mode 100644 index 0000000000000..7a076027015eb --- /dev/null +++ b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_09_test.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2020, 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. + +// SharedOptions=--enable-experiment=nonfunction-type-aliases + +import 'package:expect/expect.dart'; + +class C {} + +typedef T = C; + +void main() { + T x1 = T(); + C x2 = T(); +} diff --git a/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_10_test.dart b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_10_test.dart new file mode 100644 index 0000000000000..8ce475dedb009 --- /dev/null +++ b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_10_test.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2020, 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. + +// SharedOptions=--enable-experiment=nonfunction-type-aliases + +import 'package:expect/expect.dart'; + +class C { + C(Type t) { + Expect.equals(t, X); + } +} + +typedef T = C; + +void main() { + T x1 = T(num); + C x2 = T(num); +} diff --git a/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_11_test.dart b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_11_test.dart new file mode 100644 index 0000000000000..b669f0027a7fc --- /dev/null +++ b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_11_test.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2020, 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. + +// SharedOptions=--enable-experiment=nonfunction-type-aliases + +import 'package:expect/expect.dart'; + +class C> { + C(Type t) { + Expect.equals(t, X); + } +} + +typedef T = C>; + +Type typeOf() => X; + +void main() { + T x1 = T(typeOf>()); + C> x2 = T(typeOf>()); +} diff --git a/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_12_test.dart b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_12_test.dart new file mode 100644 index 0000000000000..4322e2d66e5ac --- /dev/null +++ b/tests/language_2/nonfunction_type_aliases/infer_aliased_instance_creation_12_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2020, 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. + +// SharedOptions=--enable-experiment=nonfunction-type-aliases + +import 'package:expect/expect.dart'; + +class C { + C(Type tx, Type ty) { + Expect.equals(tx, X); + Expect.equals(ty, Y); + } +} + +typedef T = C; + +void main() { + T x1 = T(String, int); + C x2 = T(String, int); +}