// 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. import "package:expect/expect.dart" show Expect; import 'package:kernel/ast.dart'; import 'package:kernel/src/norm.dart'; import 'package:kernel/testing/type_parser_environment.dart'; void run() { checkNormToSame('Null'); checkNormToSame('Never'); check('Never?', 'Null'); checkNormToSame('void'); checkNormToSame('dynamic'); checkNormToSame('Object?'); check('FutureOr', 'dynamic'); check('FutureOr', 'void'); check('FutureOr', 'Object'); check('FutureOr', 'Object?'); check('FutureOr', 'Future'); check('FutureOr', 'Future?'); check('FutureOr', 'Future?'); check('FutureOr>', 'dynamic'); check('FutureOr>', 'void'); check('FutureOr>', 'Object'); check('FutureOr>', 'Object?'); check('FutureOr>', 'FutureOr>'); // TODO(cstefantsova): Use the following test case instead when FutureOr can // distinguish between the declared nullability and the nullability as a // property. // //check('FutureOr>', 'FutureOr?>'); check('FutureOr>', 'FutureOr?>?'); // TODO(cstefantsova): Use the following test case instead when FutureOr can // distinguish between the declared nullability and the nullability as a // property. // //check('FutureOr>', 'FutureOr?>'); check('FutureOr>', 'FutureOr?>?'); checkNormToSame('bool'); checkNormToSame('bool?'); checkNormToSame('List'); checkNormToSame('List'); checkNormToSame('List?'); checkNormToSame('List?'); check('List>', 'List'); check('List', 'List', 'T extends Never'); check('List', 'List', 'T extends Never'); checkNormToSame('() ->? bool?'); checkNormToSame('() -> bool?'); checkNormToSame('() ->? bool'); checkNormToSame('() -> bool'); check('() ->? List>', '() ->? List'); check('() ->? List', '() ->? List', 'T extends Never'); check( '() ->? List', '() ->? List', 'T extends S, S extends U, U extends Never', ); checkNormToSame('(int?) -> void'); checkNormToSame('(int) -> void'); checkNormToSame('([int?]) -> void'); checkNormToSame('([int]) -> void'); checkNormToSame('({int? a}) -> void'); checkNormToSame('({int a}) -> void'); checkNormToSame('({required int? a}) -> void'); checkNormToSame('({required int a}) -> void'); check('(List>) -> void', '(List) -> void'); check('([List>]) -> void', '([List]) -> void'); check('({List> x}) -> void', '({List x}) -> void'); check( '({required List> x}) -> void', '({required List x}) -> void', ); checkNormToSame('(T) -> void'); checkNormToSame('(T?) -> void'); checkNormToSame('(T) -> void'); checkNormToSame('>(T) -> void'); check( '>>(T) -> void', '>(T) -> void', ); checkNormToSame('T', 'T extends Object?'); checkNormToSame('T?', 'T extends Object?'); checkNormToSame('T', 'T extends FutureOr'); check('T', 'Never', 'T extends Never'); check('T & Never', 'Never', 'T extends Object?'); check('T', 'Never', 'T extends S, S extends Never'); check('List', 'List', 'T extends S, S extends Never'); check('FutureOr', 'Future?', 'T extends S, S extends Never'); check('FutureOr>', 'dynamic'); check('FutureOr>', 'void'); check('FutureOr>', 'Object?'); check('FutureOr?>?', 'dynamic'); check('FutureOr?>?', 'void'); check('FutureOr?>?', 'Object?'); // TODO(cstefantsova): The following test cases should be removed when // FutureOr can distinguish between the declared nullability and the // nullability as a property. check('FutureOr', 'FutureOr?'); check('FutureOr>', 'FutureOr?>?'); check('FutureOr?>', 'FutureOr?>?'); check( 'FutureOr>?>', 'FutureOr>?>?', ); check( '(T, S & Never, {R foo})', '(Never, Never, {Never foo})', 'T extends Never, S extends Object?, R extends T', ); check( '(T, bool?, {FutureOr foo, FutureOr bar})', '(Never, bool?, {Future? foo, dynamic bar})', 'T extends Never', ); check('() -> List<({FutureOr foo})>', '() -> List<({dynamic foo})>'); check( '((T, T)) -> void', '((Never, Never)) -> void', ); checkNormToSame('(int, {String? foo})'); checkNormToSame('(int, String?, {List foo, T bar})', 'T extends num'); checkNormToSame('()'); checkNormToSame('(int?)'); checkNormToSame('List<(int, {String foo})>'); } void check(String input, String output, [String typeParameters = '']) { Env env = new Env('')..extendWithTypeParameters(typeParameters); DartType inputType = env.parseType(input); DartType expectedOutputType = env.parseType(output); DartType actualOutputType = norm(env.coreTypes, inputType); print('norm($inputType) = $actualOutputType, expected $expectedOutputType'); Expect.equals( expectedOutputType, actualOutputType, "Unexpected norm of $inputType ('$input'):\n" "Expected: ${expectedOutputType} ('$output')\n" "Actual: ${actualOutputType}", ); } void checkNormToSame(String type, [String typeParameters = '']) { return check(type, type, typeParameters); } void main() => run();