blob: 54092f7754ea94b07e9ba7063e1c81b8ca81b03e [file] [log] [blame]
// Copyright (c) 2018, 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";
// Tests that const/new-insertion does the right thing for
// composite object creations.
//
// The right thing is that map and list literals are only constant
// if in a constant context.
// Object creation is const if constructor is const and all arguments are const.
//
// Not testing inference, so all type arguments are explicit.
main() {
var x = 42;
const cc42 = const C(42);
var c42 = cc42;
const clist = const <int>[37];
var list = clist;
const cmap = const <int, int>{19: 87};
var map = cmap;
{
// Constructor inside constructor.
var d42 = const D<int>(42);
const cd1 = const C(const D<int>(42));
const cd2 = C(D<int>(42)); // Const context.
var cd3 = C(D<int>(42)); // All constant, even in non-const context.
var cd4 = C(D<int>(x)); // x is a non-constant expression, so `new`.
var cd5 = C(d42); // d42 is a non-constant expression, so `new`.
Expect.identical(cd1, cd2);
Expect.identical(cd1, cd3);
Expect.allDistinct([cd1, cd4, cd5]);
}
{
// List inside other constructor
const cl1 = const C(const <int>[37]);
const cl2 = C(clist); // Constant context.
const cl3 = C(const <int>[37]); // Constant context.
const cl4 = C(<int>[37]);
var cl5 = C(clist); // Constant argument, so const.
var cl6 = C(const <int>[37]); // Constant arg, so const.
var cl7 = C(list); // Non-constant arg.
var cl8 = C(<int>[37]); // Same if literal.
Expect.identical(cl1, cl2);
Expect.identical(cl1, cl3);
Expect.identical(cl1, cl4);
Expect.identical(cl1, cl5);
Expect.identical(cl1, cl6);
Expect.allDistinct([cl1, cl7, cl8]);
}
{
// Map inside other constructor.
const cm1 = C(cmap); // Constant context.
const cm2 = C(const <int, int>{19: 87}); // Constant context.
const cm3 = C(<int, int>{19: 87}); // Constant context.
var cm4 = C(cmap); // Constant argument, so const.
var cm5 = C(const <int, int>{19: 87}); // Constant arg, so const.
var cm6 = C(map); // Non-constant arg, non-const context.
var cm7 = C(<int, int>{19: 87}); // Same if literal.
Expect.identical(cm1, cm2);
Expect.identical(cm1, cm3);
Expect.identical(cm1, cm4);
Expect.identical(cm1, cm5);
Expect.allDistinct([cm1, cm6, cm7]);
}
{
// Composite with more than one sub-expression.
const n1 = N(clist, cmap);
const n2 = N(const <int>[37], const <int, int>{19: 87});
const n3 = N(<int>[37], <int, int>{19: 87});
var n4 = N(const <int>[37], const <int, int>{19: 87});
var n5 = N(<int>[37], const <int, int>{19: 87});
var n6 = N(const <int>[37], <int, int>{19: 87});
var n7 = N(<int>[37], <int, int>{19: 87});
var n8 = N(clist, cmap);
var n9 = N(<int>[37], cmap);
var n10 = N(clist, <int, int>{19: 87});
var n11 = N(<int>[37], <int, int>{19: 87});
var n12 = N(list, cmap);
var n13 = N(clist, map);
var n14 = N(list, map);
Expect.identical(n1, n2);
Expect.identical(n1, n3);
Expect.identical(n1, n4);
Expect.identical(n1, n8);
Expect.allDistinct([n1, n5, n6, n7, n9, n10, n11, n12, n13, n14]);
Expect.identical(clist, n6.left);
Expect.identical(clist, n10.left);
Expect.identical(clist, n12.left);
Expect.identical(clist, n13.left);
Expect.identical(clist, n14.left);
Expect.allDistinct([n5.left, n7.left, n9.left, n11.left]);
Expect.identical(cmap, n5.right);
Expect.identical(cmap, n9.right);
Expect.identical(cmap, n12.right);
Expect.identical(cmap, n13.right);
Expect.identical(cmap, n14.right);
Expect.allDistinct([n6.right, n7.right, n10.right, n11.right]);
const n20 = const N(const C(42), const <int>[37]);
const n21 = N(const C(42), const <int>[37]);
const n22 = N(C(42), const <int>[37]);
const n23 = N(C(42), clist);
const n24 = N(C(42), <int>[37]);
var n25 = N(const C(42), const <int>[37]);
var n26 = N(C(42), const <int>[37]);
var n27 = N(C(42), clist);
var n28 = N(C(42), <int>[37]);
var n29 = N(C(42), list);
var n30 = N(c42, clist);
var n31 = N(cc42, list);
Expect.identical(n20, n21);
Expect.identical(n20, n22);
Expect.identical(n20, n23);
Expect.identical(n20, n24);
Expect.identical(n20, n25);
Expect.identical(n20, n26);
Expect.identical(n20, n27);
Expect.allDistinct([n28, n29, n30, n31]);
Expect.identical(cc42, n28.left);
Expect.identical(cc42, n29.left);
Expect.identical(cc42, n30.left);
Expect.identical(cc42, n31.left);
Expect.identical(clist, n29.right);
Expect.identical(clist, n30.right);
Expect.identical(clist, n31.right);
Expect.notIdentical(clist, n28.right);
}
{
// List literals.
const l20 = const [
const C(42),
const <int>[37]
];
const l21 = [
const C(42),
const <int>[37]
];
const l22 = [
C(42),
const <int>[37]
];
var l23 = const [C(42), clist];
const l24 = [
C(42),
<int>[37]
];
var l25 = [
const C(42),
const <int>[37]
];
var l26 = [
C(42),
const <int>[37]
];
var l27 = [C(42), clist];
var l28 = [
C(42),
<int>[37]
];
var l29 = [C(42), list];
var l30 = [c42, clist];
var l31 = [cc42, list];
Expect.identical(l20, l21);
Expect.identical(l20, l22);
Expect.identical(l20, l23);
Expect.identical(l20, l24);
// List literals are never const unless in const context.
Expect.allDistinct([l20, l25, l26, l27, l28, l29, l30, l31]);
Expect.identical(cc42, l25[0]);
Expect.identical(cc42, l26[0]);
Expect.identical(cc42, l27[0]);
Expect.identical(cc42, l28[0]);
Expect.identical(cc42, l29[0]);
Expect.identical(cc42, l30[0]);
Expect.identical(cc42, l31[0]);
Expect.identical(clist, l25[1]);
Expect.identical(clist, l26[1]);
Expect.identical(clist, l27[1]);
Expect.identical(clist, l29[1]);
Expect.identical(clist, l30[1]);
Expect.identical(clist, l31[1]);
Expect.notIdentical(clist, l28[1]);
}
{
// Map literals.
const m20 = const <C, List<int>>{
const C(42): const <int>[37]
};
const m21 = {
const C(42): const <int>[37]
};
const m22 = {
C(42): const <int>[37]
};
var m23 = const {C(42): clist};
const m24 = {
C(42): <int>[37]
};
var m25 = {
const C(42): const <int>[37]
};
var m26 = {
C(42): const <int>[37]
};
var m27 = {C(42): clist};
var m28 = {
C(42): <int>[37]
};
var m29 = {C(42): list};
var m30 = {c42: clist};
var m31 = {cc42: list};
Expect.identical(m20, m21);
Expect.identical(m20, m22);
Expect.identical(m20, m23);
Expect.identical(m20, m24);
// Map literals are never const unless in const context.
Expect.allDistinct([m20, m25, m26, m27, m28, m29, m30, m31]);
Expect.identical(cc42, m25.keys.first);
Expect.identical(cc42, m26.keys.first);
Expect.identical(cc42, m27.keys.first);
Expect.identical(cc42, m28.keys.first);
Expect.identical(cc42, m29.keys.first);
Expect.identical(cc42, m30.keys.first);
Expect.identical(cc42, m31.keys.first);
Expect.identical(clist, m25.values.first);
Expect.identical(clist, m26.values.first);
Expect.identical(clist, m27.values.first);
Expect.identical(clist, m29.values.first);
Expect.identical(clist, m30.values.first);
Expect.identical(clist, m31.values.first);
Expect.notIdentical(clist, m28.values.first);
}
}
class C {
final Object x;
const C(this.x);
}
class D<T> {
final T x;
const D(this.x);
}
class N {
final Object left, right;
const N(this.left, this.right);
}