blob: 240859f14a5577bbe61510ca09f808086f941371 [file] [log] [blame] [edit]
// 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);
}