// Copyright (c) 2021, 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. // Test the new context type rules for number operators, // as modified by Null Safety import "../static_type_helper.dart"; // The context rules for `e` of the form: // For e1 + e2, e1 - e2, e1 * e2, e1 % e2 or e1.remainder(e2),, // if the static type of e1 is a non-`Never` subtype of `int`, // and the context type of the entire expression is `int`, // then the context type of e2 is `int`. // If the static type of e1 is a non-`Never` subtype of `num` // that is not a subtype of `double`, // and the context type of the entire expression is `double`, // then the context type of e2 is `double`. // If the context type of `e1.clamp(e2, e3)`, *C*, // and the the static type of `e1`, *T*, // are both is a non-`Never` subtypes of `num`, // then the context types of `e2` and `e3` are both *C*. // Otherwise the context types of `e2` and `e3` are `num`. void main() { testIntContext(1, 1); testDoubleContext(1, 1.1, 1.1, 1.1); testNumContext(1, 1); } void testIntContext(I i, O o) { context(1 + (contextType(1)..expectStaticType>())); context(1 - (contextType(1)..expectStaticType>())); context(1 * (contextType(1)..expectStaticType>())); context(1 % (contextType(1)..expectStaticType>())); context(1.remainder(contextType(1)..expectStaticType>())); context(i + (contextType(1)..expectStaticType>())); context(i - (contextType(1)..expectStaticType>())); context(i * (contextType(1)..expectStaticType>())); context(i % (contextType(1)..expectStaticType>())); context(i.remainder(contextType(1)..expectStaticType>())); context(1 + (contextType(1)..expectStaticType>())); context(1 - (contextType(1)..expectStaticType>())); context(1 * (contextType(1)..expectStaticType>())); context(1 % (contextType(1)..expectStaticType>())); context(1.remainder(contextType(1)..expectStaticType>())); O oi = 1 as O; if (oi is! int) throw "promote oi to O&int"; context(oi + (contextType(1)..expectStaticType>())); context(oi - (contextType(1)..expectStaticType>())); context(oi * (contextType(1)..expectStaticType>())); context(oi % (contextType(1)..expectStaticType>())); context(oi.remainder(contextType(1)..expectStaticType>())); int ii = 0; ii += contextType(1)..expectStaticType>(); ii -= contextType(1)..expectStaticType>(); ii *= contextType(1)..expectStaticType>(); ii %= contextType(1)..expectStaticType>(); if (ii != 0) throw "use ii"; context(1.clamp(contextType(1)..expectStaticType>(), contextType(1)..expectStaticType>())); context(i.clamp(contextType(1)..expectStaticType>(), contextType(1)..expectStaticType>())); context(oi.clamp(contextType(1)..expectStaticType>(), contextType(1)..expectStaticType>())); } void testDoubleContext(I i, D d, N n, O o) { context(1 + (contextType(1.0)..expectStaticType>())); context(1 - (contextType(1.0)..expectStaticType>())); context(1 * (contextType(1.0)..expectStaticType>())); context(1 % (contextType(1.0)..expectStaticType>())); context( 1.remainder(contextType(1.0)..expectStaticType>())); context(n + (contextType(1.0)..expectStaticType>())); context(n - (contextType(1.0)..expectStaticType>())); context(n * (contextType(1.0)..expectStaticType>())); context(n % (contextType(1.0)..expectStaticType>())); context( n.remainder(contextType(1.0)..expectStaticType>())); context(i + (contextType(1.0)..expectStaticType>())); context(i - (contextType(1.0)..expectStaticType>())); context(i * (contextType(1.0)..expectStaticType>())); context(i % (contextType(1.0)..expectStaticType>())); context( i.remainder(contextType(1.0)..expectStaticType>())); context(d + (contextType(1.0)..expectStaticType>())); context(d - (contextType(1.0)..expectStaticType>())); context(d * (contextType(1.0)..expectStaticType>())); context(d % (contextType(1.0)..expectStaticType>())); context( d.remainder(contextType(1.0)..expectStaticType>())); var od = (1.0 as O); if (od is! double) throw "promote od to O&double"; context(od + (contextType(1.0)..expectStaticType>())); context(od - (contextType(1.0)..expectStaticType>())); context(od * (contextType(1.0)..expectStaticType>())); context(od % (contextType(1.0)..expectStaticType>())); context( od.remainder(contextType(1.0)..expectStaticType>())); // The context type also causes double literals. context(1 + (1..expectStaticType>())); context(1 - (1..expectStaticType>())); context(1 * (1..expectStaticType>())); context(1 % (1..expectStaticType>())); context(1.remainder(1..expectStaticType>())); double dd = 0.0; dd += contextType(1)..expectStaticType>(); dd -= contextType(1)..expectStaticType>(); dd *= contextType(1)..expectStaticType>(); dd %= contextType(2)..expectStaticType>(); context(1.1.clamp( contextType(1.0)..expectStaticType>(), contextType(1.0)..expectStaticType>())); context(d.clamp(contextType(1.0)..expectStaticType>(), contextType(1.0)..expectStaticType>())); context(od.clamp( contextType(1.0)..expectStaticType>(), contextType(1.0)..expectStaticType>())); } void testNumContext(N n, O o) { var i1 = 1; var d1 = 1.0; num n1 = 1; if (o is! num) throw "promote o to O&num"; context(i1 + (contextType(1)..expectStaticType>())); context(i1 - (contextType(1)..expectStaticType>())); context(i1 * (contextType(1)..expectStaticType>())); context(i1 % (contextType(1)..expectStaticType>())); context(i1.remainder(contextType(1)..expectStaticType>())); context(d1 + (contextType(1)..expectStaticType>())); context(d1 - (contextType(1)..expectStaticType>())); context(d1 * (contextType(1)..expectStaticType>())); context(d1 % (contextType(1)..expectStaticType>())); context(d1.remainder(contextType(1)..expectStaticType>())); context(n1 + (contextType(1)..expectStaticType>())); context(n1 - (contextType(1)..expectStaticType>())); context(n1 * (contextType(1)..expectStaticType>())); context(n1 % (contextType(1)..expectStaticType>())); context(n1.remainder(contextType(1)..expectStaticType>())); context(n + (contextType(1)..expectStaticType>())); context(n - (contextType(1)..expectStaticType>())); context(n * (contextType(1)..expectStaticType>())); context(n % (contextType(1)..expectStaticType>())); context(n.remainder(contextType(1)..expectStaticType>())); context(o + (contextType(1)..expectStaticType>())); context(o - (contextType(1)..expectStaticType>())); context(o * (contextType(1)..expectStaticType>())); context(o % (contextType(1)..expectStaticType>())); context(o.remainder(contextType(1)..expectStaticType>())); context(o.clamp(contextType(1)..expectStaticType>(), contextType(1)..expectStaticType>())); }