// 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('Never*'); checkNormToSame('void'); checkNormToSame('dynamic'); checkNormToSame('Object?'); check('FutureOr', 'dynamic'); check('FutureOr', 'void'); check('FutureOr', 'Object'); check('FutureOr', 'Object?'); check('FutureOr', 'Object*'); check('FutureOr', 'Future'); check('FutureOr', 'Future?'); // TODO(cstefantsova): Use the following test case instead when FutureOr can // distinguish between the declared nullability and the nullability as a // property. // //check('FutureOr', 'Future'); check('FutureOr', 'Future*'); check('FutureOr', 'Future?'); check('FutureOr>', 'dynamic'); check('FutureOr>', 'void'); check('FutureOr>', 'Object'); 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*>*'); // 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('bool*'); checkNormToSame('List'); checkNormToSame('List'); checkNormToSame('List'); checkNormToSame('List?'); checkNormToSame('List?'); 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?'); checkNormToSame('() ->? bool?'); 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?]) -> void'); checkNormToSame('([int]) -> void'); checkNormToSame('({int* a}) -> void'); checkNormToSame('({int? a}) -> void'); checkNormToSame('({int a}) -> void'); checkNormToSame('({required 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();