1/* 2* Copyright (c) Microsoft Corporation. All rights reserved. 3* Copyright (c) 2023 Huawei Device Co., Ltd. 4* Licensed under the Apache License, Version 2.0 (the "License"); 5* you may not use this file except in compliance with the License. 6* You may obtain a copy of the License at 7* 8* http://www.apache.org/licenses/LICENSE-2.0 9* 10* Unless required by applicable law or agreed to in writing, software 11* distributed under the License is distributed on an "AS IS" BASIS, 12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13* See the License for the specific language governing permissions and 14* limitations under the License. 15* 16* This file has been modified by Huawei to verify type inference by adding verification statements. 17*/ 18 19// === tests/cases/conformance/controlFlow/controlFlowWhileStatement.ts === 20declare function AssertType(value:any, type:string):void; 21let cond: boolean; 22AssertType(cond, "boolean"); 23 24function a() { 25 let x: string | number; 26AssertType(x, "union"); 27 28 x = ""; 29AssertType(x = "", "string"); 30AssertType(x, "union"); 31AssertType("", "string"); 32 33 while (cond) { 34AssertType(cond, "boolean"); 35 36 x; // string 37AssertType(x, "string"); 38 } 39} 40function b() { 41 let x: string | number; 42AssertType(x, "union"); 43 44 x = ""; 45AssertType(x = "", "string"); 46AssertType(x, "union"); 47AssertType("", "string"); 48 49 while (cond) { 50AssertType(cond, "boolean"); 51 52 x; // string 53AssertType(x, "string"); 54 55 x = 42; 56AssertType(x = 42, "int"); 57AssertType(x, "union"); 58AssertType(42, "int"); 59 60 break; 61 } 62} 63function c() { 64 let x: string | number; 65AssertType(x, "union"); 66 67 x = ""; 68AssertType(x = "", "string"); 69AssertType(x, "union"); 70AssertType("", "string"); 71 72 while (cond) { 73AssertType(cond, "boolean"); 74 75 x; // string 76AssertType(x, "string"); 77 78 x = undefined; 79AssertType(x = undefined, "undefined"); 80AssertType(x, "union"); 81AssertType(undefined, "undefined"); 82 83 if (typeof x === "string") continue; 84AssertType(typeof x === "string", "boolean"); 85AssertType(typeof x, "union"); 86AssertType(x, "union"); 87AssertType("string", "string"); 88 89 break; 90 } 91} 92function d() { 93 let x: string | number; 94AssertType(x, "union"); 95 96 x = ""; 97AssertType(x = "", "string"); 98AssertType(x, "union"); 99AssertType("", "string"); 100 101 while (x = x.length) { 102AssertType(x = x.length, "number"); 103AssertType(x, "union"); 104AssertType(x.length, "number"); 105 106 x; // number 107AssertType(x, "number"); 108 109 x = ""; 110AssertType(x = "", "string"); 111AssertType(x, "union"); 112AssertType("", "string"); 113 } 114} 115function e() { 116 let x: string | number; 117AssertType(x, "union"); 118 119 x = ""; 120AssertType(x = "", "string"); 121AssertType(x, "union"); 122AssertType("", "string"); 123 124 while (cond) { 125AssertType(cond, "boolean"); 126 127 x; // string | number 128AssertType(x, "union"); 129 130 x = 42; 131AssertType(x = 42, "int"); 132AssertType(x, "union"); 133AssertType(42, "int"); 134 135 x; // number 136AssertType(x, "number"); 137 } 138 x; // string | number 139AssertType(x, "union"); 140} 141function f() { 142 let x: string | number | boolean | RegExp | Function; 143AssertType(x, "union"); 144 145 x = ""; 146AssertType(x = "", "string"); 147AssertType(x, "union"); 148AssertType("", "string"); 149 150 while (cond) { 151AssertType(cond, "boolean"); 152 153 if (cond) { 154AssertType(cond, "boolean"); 155 156 x = 42; 157AssertType(x = 42, "int"); 158AssertType(x, "union"); 159AssertType(42, "int"); 160 161 break; 162 } 163 if (cond) { 164AssertType(cond, "boolean"); 165 166 x = true; 167AssertType(x = true, "boolean"); 168AssertType(x, "union"); 169AssertType(true, "boolean"); 170 171 continue; 172 } 173 x = /a/; 174AssertType(x = /a/, "RegExp"); 175AssertType(x, "union"); 176AssertType(/a/, "RegExp"); 177 } 178 x; // string | number | boolean | RegExp 179AssertType(x, "union"); 180} 181function g() { 182 let x: string | number | boolean | RegExp | Function; 183AssertType(x, "union"); 184 185 x = ""; 186AssertType(x = "", "string"); 187AssertType(x, "union"); 188AssertType("", "string"); 189 190 while (true) { 191AssertType(true, "boolean"); 192 193 if (cond) { 194AssertType(cond, "boolean"); 195 196 x = 42; 197AssertType(x = 42, "int"); 198AssertType(x, "union"); 199AssertType(42, "int"); 200 201 break; 202 } 203 if (cond) { 204AssertType(cond, "boolean"); 205 206 x = true; 207AssertType(x = true, "boolean"); 208AssertType(x, "union"); 209AssertType(true, "boolean"); 210 211 continue; 212 } 213 x = /a/; 214AssertType(x = /a/, "RegExp"); 215AssertType(x, "union"); 216AssertType(/a/, "RegExp"); 217 } 218 x; // number 219AssertType(x, "number"); 220} 221function h1() { 222 let x: string | number | boolean; 223AssertType(x, "union"); 224 225 x = ""; 226AssertType(x = "", "string"); 227AssertType(x, "union"); 228AssertType("", "string"); 229 230 while (x > 1) { 231AssertType(x > 1, "boolean"); 232AssertType(x, "union"); 233AssertType(1, "int"); 234 235 x; // string | number 236AssertType(x, "union"); 237 238 x = 1; 239AssertType(x = 1, "int"); 240AssertType(x, "union"); 241AssertType(1, "int"); 242 243 x; // number 244AssertType(x, "number"); 245 } 246 x; // string | number 247AssertType(x, "union"); 248} 249declare function len(s: string | number): number; 250function h2() { 251 let x: string | number | boolean; 252AssertType(x, "union"); 253 254 x = ""; 255AssertType(x = "", "string"); 256AssertType(x, "union"); 257AssertType("", "string"); 258 259 while (cond) { 260AssertType(cond, "boolean"); 261 262 x = len(x); 263AssertType(x = len(x), "number"); 264AssertType(x, "union"); 265AssertType(len(x), "number"); 266AssertType(len, "(union) => number"); 267AssertType(x, "union"); 268 269 x; // number 270AssertType(x, "number"); 271 } 272 x; // string | number 273AssertType(x, "union"); 274} 275function h3() { 276 let x: string | number | boolean; 277AssertType(x, "union"); 278 279 x = ""; 280AssertType(x = "", "string"); 281AssertType(x, "union"); 282AssertType("", "string"); 283 284 while (cond) { 285AssertType(cond, "boolean"); 286 287 x; // string | number 288AssertType(x, "union"); 289 290 x = len(x); 291AssertType(x = len(x), "number"); 292AssertType(x, "union"); 293AssertType(len(x), "number"); 294AssertType(len, "(union) => number"); 295AssertType(x, "union"); 296 } 297 x; // string | number 298AssertType(x, "union"); 299} 300 301 302