// 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. // @dart = 2.9 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'; 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(dmitryas): 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(dmitryas): 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(dmitryas): 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(dmitryas): 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(dmitryas): 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(String input, String output, [String typeParameters = '']) { Env env = new Env('', isNonNullableByDefault: true) ..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}"); } checkNormToSame(String type, [String typeParameters = '']) { return check(type, type, typeParameters); } main() => run();