| // 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'; |
| import 'package:front_end/src/kernel/member_covariance.dart'; |
| import 'package:kernel/ast.dart'; |
| |
| void main() { |
| void checkEquals(Covariance a, Covariance b) { |
| Expect.equals(a, b); |
| Expect.equals(a.hashCode, b.hashCode); |
| } |
| |
| checkEquals(const Covariance.empty(), new Covariance.empty()); |
| |
| Expect.isTrue(const Covariance.empty().isEmpty); |
| Expect.isTrue(new Covariance.empty().isEmpty); |
| Expect.isTrue(new Covariance.internal(null, null, null).isEmpty); |
| |
| checkEquals( |
| const Covariance.empty(), new Covariance.internal(null, null, null)); |
| |
| Expect.throws(() => new Covariance.internal([], null, null)); |
| Expect.throws(() => new Covariance.internal([0], null, null)); |
| |
| checkEquals( |
| new Covariance.internal([Covariance.GenericCovariantImpl], null, null), |
| new Covariance.internal( |
| [Covariance.GenericCovariantImpl, 0], null, null)); |
| |
| checkEquals(new Covariance.internal([Covariance.Covariant], null, null), |
| new Covariance.internal([Covariance.Covariant, 0], null, null)); |
| |
| checkEquals(new Covariance.internal([0, Covariance.Covariant], null, null), |
| new Covariance.internal([0, Covariance.Covariant, 0], null, null)); |
| |
| Expect.throws(() => new Covariance.internal(null, {}, null)); |
| Expect.throws(() => new Covariance.internal(null, {'a': 0}, null)); |
| |
| checkEquals(new Covariance.internal(null, {'a': Covariance.Covariant}, null), |
| new Covariance.internal(null, {'a': Covariance.Covariant}, null)); |
| |
| Expect.throws(() => new Covariance.internal(null, null, [])); |
| |
| Expect.throws(() => new Covariance.internal(null, null, [false])); |
| |
| checkEquals(new Covariance.internal(null, null, [true]), |
| new Covariance.internal(null, null, [true, false])); |
| |
| Covariance covariance = new Covariance.internal([ |
| Covariance.Covariant, |
| Covariance.GenericCovariantImpl, |
| 0, |
| Covariance.Covariant | Covariance.GenericCovariantImpl |
| ], { |
| 'a': Covariance.Covariant, |
| 'b': Covariance.GenericCovariantImpl, |
| 'd': Covariance.Covariant | Covariance.GenericCovariantImpl |
| }, [ |
| false, |
| true |
| ]); |
| |
| Expect.equals(Covariance.Covariant, covariance.getPositionalVariance(0)); |
| Expect.equals( |
| Covariance.GenericCovariantImpl, covariance.getPositionalVariance(1)); |
| Expect.equals(0, covariance.getPositionalVariance(2)); |
| Expect.equals(Covariance.Covariant | Covariance.GenericCovariantImpl, |
| covariance.getPositionalVariance(3)); |
| Expect.equals(0, covariance.getPositionalVariance(4)); |
| |
| Expect.equals(Covariance.Covariant, covariance.getNamedVariance('a')); |
| Expect.equals( |
| Covariance.GenericCovariantImpl, covariance.getNamedVariance('b')); |
| Expect.equals(0, covariance.getNamedVariance('c')); |
| Expect.equals(Covariance.Covariant | Covariance.GenericCovariantImpl, |
| covariance.getNamedVariance('d')); |
| Expect.equals(0, covariance.getNamedVariance('e')); |
| |
| Expect.isFalse(covariance.isTypeParameterGenericCovariantImpl(0)); |
| Expect.isTrue(covariance.isTypeParameterGenericCovariantImpl(1)); |
| Expect.isFalse(covariance.isTypeParameterGenericCovariantImpl(0)); |
| |
| Expect.stringEquals( |
| 'Covariance(' |
| '0:Covariant,1:GenericCovariantImpl,3:GenericCovariantImpl+Covariant,' |
| 'a:Covariant,b:GenericCovariantImpl,d:GenericCovariantImpl+Covariant,' |
| 'types:1)', |
| covariance.toString()); |
| |
| Procedure noParameterProcedure = new Procedure( |
| new Name('foo'), ProcedureKind.Method, new FunctionNode(null), |
| fileUri: dummyUri); |
| Covariance noParameterProcedureCovariance = |
| new Covariance.fromMember(noParameterProcedure, forSetter: false); |
| Expect.isTrue(noParameterProcedureCovariance.isEmpty); |
| |
| covariance.applyCovariance(noParameterProcedure); |
| noParameterProcedureCovariance = |
| new Covariance.fromMember(noParameterProcedure, forSetter: false); |
| Expect.isTrue(noParameterProcedureCovariance.isEmpty); |
| |
| Procedure oneParameterProcedure = new Procedure( |
| new Name('foo'), |
| ProcedureKind.Method, |
| new FunctionNode(null, positionalParameters: [ |
| new VariableDeclaration(null, isSynthesized: true) |
| ]), |
| fileUri: dummyUri); |
| Covariance oneParameterProcedureCovariance = |
| new Covariance.fromMember(oneParameterProcedure, forSetter: false); |
| Expect.isTrue(oneParameterProcedureCovariance.isEmpty); |
| |
| covariance.applyCovariance(oneParameterProcedure); |
| oneParameterProcedureCovariance = |
| new Covariance.fromMember(oneParameterProcedure, forSetter: false); |
| Expect.isFalse(oneParameterProcedureCovariance.isEmpty); |
| Expect.equals(new Covariance.internal([Covariance.Covariant], null, null), |
| oneParameterProcedureCovariance); |
| |
| Procedure positionalParametersProcedure = new Procedure( |
| new Name('foo'), |
| ProcedureKind.Method, |
| new FunctionNode(null, positionalParameters: [ |
| new VariableDeclaration(null, isSynthesized: true), |
| new VariableDeclaration(null, isSynthesized: true), |
| new VariableDeclaration(null, isSynthesized: true), |
| new VariableDeclaration(null, isSynthesized: true), |
| new VariableDeclaration(null, isSynthesized: true) |
| ]), |
| fileUri: dummyUri); |
| Covariance positionalParametersProcedureCovariance = |
| new Covariance.fromMember(positionalParametersProcedure, |
| forSetter: false); |
| Expect.isTrue(positionalParametersProcedureCovariance.isEmpty); |
| |
| covariance.applyCovariance(positionalParametersProcedure); |
| positionalParametersProcedureCovariance = new Covariance.fromMember( |
| positionalParametersProcedure, |
| forSetter: false); |
| Expect.isFalse(positionalParametersProcedureCovariance.isEmpty); |
| checkEquals( |
| new Covariance.internal([ |
| Covariance.Covariant, |
| Covariance.GenericCovariantImpl, |
| 0, |
| Covariance.Covariant | Covariance.GenericCovariantImpl |
| ], null, null), |
| positionalParametersProcedureCovariance); |
| |
| Procedure namedParametersProcedure = new Procedure( |
| new Name('foo'), |
| ProcedureKind.Method, |
| new FunctionNode(null, namedParameters: [ |
| new VariableDeclaration('a'), |
| new VariableDeclaration('b'), |
| new VariableDeclaration('c'), |
| new VariableDeclaration('d'), |
| new VariableDeclaration('e') |
| ]), |
| fileUri: dummyUri); |
| Covariance namedParametersProcedureCovariance = |
| new Covariance.fromMember(namedParametersProcedure, forSetter: false); |
| Expect.isTrue(namedParametersProcedureCovariance.isEmpty); |
| |
| covariance.applyCovariance(namedParametersProcedure); |
| namedParametersProcedureCovariance = |
| new Covariance.fromMember(namedParametersProcedure, forSetter: false); |
| Expect.isFalse(namedParametersProcedureCovariance.isEmpty); |
| checkEquals( |
| new Covariance.internal( |
| null, |
| { |
| 'a': Covariance.Covariant, |
| 'b': Covariance.GenericCovariantImpl, |
| 'd': Covariance.Covariant | Covariance.GenericCovariantImpl |
| }, |
| null), |
| namedParametersProcedureCovariance); |
| |
| Procedure typeParametersProcedure = new Procedure( |
| new Name('foo'), |
| ProcedureKind.Method, |
| new FunctionNode(null, typeParameters: [ |
| new TypeParameter(null), |
| new TypeParameter(null), |
| new TypeParameter(null), |
| ]), |
| fileUri: dummyUri); |
| Covariance typeParametersProcedureCovariance = |
| new Covariance.fromMember(typeParametersProcedure, forSetter: false); |
| Expect.isTrue(typeParametersProcedureCovariance.isEmpty); |
| |
| covariance.applyCovariance(typeParametersProcedure); |
| typeParametersProcedureCovariance = |
| new Covariance.fromMember(typeParametersProcedure, forSetter: false); |
| Expect.isFalse(typeParametersProcedureCovariance.isEmpty); |
| checkEquals(new Covariance.internal(null, null, [false, true]), |
| typeParametersProcedureCovariance); |
| |
| Covariance merged = |
| const Covariance.empty().merge(positionalParametersProcedureCovariance); |
| checkEquals(positionalParametersProcedureCovariance, merged); |
| merged = merged.merge(namedParametersProcedureCovariance); |
| checkEquals( |
| new Covariance.internal([ |
| Covariance.Covariant, |
| Covariance.GenericCovariantImpl, |
| 0, |
| Covariance.GenericCovariantImpl | Covariance.Covariant |
| ], { |
| 'a': Covariance.Covariant, |
| 'b': Covariance.GenericCovariantImpl, |
| 'd': Covariance.Covariant | Covariance.GenericCovariantImpl |
| }, null), |
| merged); |
| merged = merged.merge(typeParametersProcedureCovariance); |
| checkEquals(covariance, merged); |
| } |