• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/compiler/staticAnonymousTypeNotReferencingTypeParameter.ts ===
20declare function AssertType(value:any, type:string):void;
21// This test case is a condensed version of Angular 2's ListWrapper. Prior to #7448
22// this would cause the compiler to run out of memory.
23
24function outer<T>(x: T) {
25  class Inner {
26    static y: T = x;
27  }
28AssertType(Inner, "typeof Inner");
29  return Inner;
30}
31let y: number = outer(5).y;
32AssertType(y, "number");
33AssertType(outer(5).y, "number");
34
35class ListWrapper2 {
36  static clone<T>(dit: typeof ListWrapper2, array: T[]): T[] {
37AssertType(array.slice(0), "T[]");
38return array.slice(0);
39
40AssertType(array.slice, "(?number, ?number) => T[]");
41
42AssertType(0, "int");
43}
44
45  static reversed<T>(dit: typeof ListWrapper2, array: T[]): T[] {
46    let a = ListWrapper2.clone(dit, array);
47AssertType(a, "T[]");
48AssertType(ListWrapper2.clone(dit, array), "T[]");
49AssertType(ListWrapper2.clone, "<T>(typeof ListWrapper2, T[]) => T[]");
50AssertType(dit, "typeof ListWrapper2");
51AssertType(array, "T[]");
52
53AssertType(a, "T[]");
54    return a;
55  }
56}
57namespace tessst {
58    /**
59     * Iterates through 'array' by index and performs the callback on each element of array until the callback
60     *
61returns a truthy value, then returns that value.
62     * If no such value is found, the callback is applied to each element of array and undefined is
63returned.
64     */
65    export function funkyFor<T, U>(array: T[], callback: (element: T, index: number) => U): U {
66        if (array) {
67AssertType(array, "T[]");
68
69            for (let i = 0, len = array.length; i < len; i++) {
70AssertType(i, "number");
71AssertType(0, "int");
72AssertType(len, "number");
73AssertType(array.length, "number");
74AssertType(i < len, "boolean");
75AssertType(i, "number");
76AssertType(len, "number");
77AssertType(i++, "number");
78AssertType(i, "number");
79
80                const result = callback(array[i], i);
81AssertType(result, "U");
82AssertType(callback(array[i], i), "U");
83AssertType(callback, "(T, number) => U");
84AssertType(array[i], "T");
85AssertType(array, "T[]");
86AssertType(i, "number");
87AssertType(i, "number");
88
89                if (result) {
90AssertType(result, "U");
91
92AssertType(result, "U");
93                    return result;
94                }
95            }
96        }
97AssertType(undefined, "undefined");
98        return undefined;
99    }
100}
101interface Scanner {
102  scanRange<T>(start: number, length: number, callback: () => T): T;
103}
104class ListWrapper {
105  // JS has no way to express a statically fixed size list, but dart does so we
106  // keep both methods.
107  static createFixedSize(dit: typeof ListWrapper, size: number): any[] {
108AssertType(new Array(size), "any[]");
109return new Array(size);
110
111AssertType(Array, "ArrayConstructor");
112
113AssertType(size, "number");
114}
115
116  static createGrowableSize(dit: typeof ListWrapper, size: number): any[] {
117AssertType(new Array(size), "any[]");
118return new Array(size);
119
120AssertType(Array, "ArrayConstructor");
121
122AssertType(size, "number");
123}
124
125  static clone<T>(dit: typeof ListWrapper, array: T[]): T[] {
126AssertType(array.slice(0), "T[]");
127return array.slice(0);
128
129AssertType(array.slice, "(?number, ?number) => T[]");
130
131AssertType(0, "int");
132}
133
134  static forEachWithIndex<T>(dit: typeof ListWrapper, array: T[], fn: (t: T, n: number) => void) {
135    for (let i = 0; i < array.length; i++) {
136AssertType(i, "number");
137AssertType(0, "int");
138AssertType(i < array.length, "boolean");
139AssertType(i, "number");
140AssertType(array.length, "number");
141AssertType(i++, "number");
142AssertType(i, "number");
143
144      fn(array[i], i);
145AssertType(fn(array[i], i), "void");
146AssertType(fn, "(T, number) => void");
147AssertType(array[i], "T");
148AssertType(array, "T[]");
149AssertType(i, "number");
150AssertType(i, "number");
151    }
152  }
153  static first<T>(dit: typeof ListWrapper, array: T[]): T {
154    if (!array)
155AssertType(!array, "boolean");
156AssertType(array, "T[]");
157AssertType(null, "null");
158return null;
159
160AssertType(array[0], "T");
161AssertType(array, "T[]");
162AssertType(0, "int");
163    return array[0];
164  }
165  static last<T>(dit: typeof ListWrapper, array: T[]): T {
166    if (!array || array.length == 0)
167AssertType(!array || array.length == 0, "boolean");
168AssertType(!array, "boolean");
169AssertType(array, "T[]");
170AssertType(array.length == 0, "boolean");
171AssertType(array.length, "number");
172AssertType(0, "int");
173AssertType(null, "null");
174return null;
175
176AssertType(array[array.length - 1], "T");
177AssertType(array, "T[]");
178AssertType(array.length - 1, "number");
179AssertType(array.length, "number");
180AssertType(1, "int");
181    return array[array.length - 1];
182  }
183  static indexOf<T>(dit: typeof ListWrapper, array: T[], value: T, startIndex: number = 0): number {
184AssertType(array.indexOf(value, startIndex), "number");
185AssertType(array.indexOf, "(T, ?number) => number");
186AssertType(value, "T");
187AssertType(startIndex, "number");
188    return array.indexOf(value, startIndex);
189  }
190  static contains<T>(dit: typeof ListWrapper, list: T[], el: T): boolean {
191AssertType(list.indexOf(el) !== -1, "boolean");
192return list.indexOf(el) !== -1;
193
194AssertType(list.indexOf(el), "number");
195
196AssertType(list.indexOf, "(T, ?number) => number");
197
198AssertType(el, "T");
199
200AssertType(-1, "int");
201
202AssertType(1, "int");
203}
204
205  static reversed<T>(dit: typeof ListWrapper, array: T[]): T[] {
206    let a = ListWrapper.clone(dit, array);
207AssertType(a, "T[]");
208AssertType(ListWrapper.clone(dit, array), "T[]");
209AssertType(ListWrapper.clone, "<T>(typeof ListWrapper, T[]) => T[]");
210AssertType(dit, "typeof ListWrapper");
211AssertType(array, "T[]");
212
213    let scanner: Scanner;
214AssertType(scanner, "Scanner");
215
216    scanner.scanRange(3, 5, () => {  });
217AssertType(scanner.scanRange(3, 5, () => {  }), "void");
218AssertType(scanner.scanRange, "<T>(number, number, () => T) => T");
219AssertType(3, "int");
220AssertType(5, "int");
221AssertType(() => {  }, "() => void");
222
223AssertType(tessst.funkyFor(array, t => t.toString()) ? a.reverse() : a, "T[]");
224AssertType(tessst.funkyFor(array, t => t.toString()), "string");
225AssertType(tessst.funkyFor, "<T, U>(T[], (T, number) => U) => U");
226AssertType(array, "T[]");
227AssertType(t => t.toString(), "(T) => string");
228AssertType(t, "T");
229AssertType(t.toString(), "string");
230AssertType(t.toString, "() => string");
231AssertType(a.reverse(), "T[]");
232AssertType(a.reverse, "() => T[]");
233AssertType(a, "T[]");
234    return tessst.funkyFor(array, t => t.toString()) ? a.reverse() : a;
235  }
236  static concat(dit: typeof ListWrapper, a: any[], b: any[]): any[] {
237AssertType(a.concat(b), "any[]");
238return a.concat(b);
239
240AssertType(a.concat, "{ (...ConcatArray<any>[]): any[]; (...any[]): any[]; }");
241
242AssertType(b, "any[]");
243}
244
245  static insert<T>(dit: typeof ListWrapper, list: T[], index: number, value: T) { list.splice(index, 0, value);
246AssertType(list.splice(index, 0, value), "T[]");
247
248AssertType(list.splice, "{ (number, ?number): T[]; (number, number, ...T[]): T[]; }");
249
250AssertType(index, "number");
251
252AssertType(0, "int");
253
254AssertType(value, "T");
255}
256
257  static removeAt<T>(dit: typeof ListWrapper, list: T[], index: number): T {
258    let res = list[index];
259AssertType(res, "T");
260AssertType(list[index], "T");
261AssertType(list, "T[]");
262AssertType(index, "number");
263
264    list.splice(index, 1);
265AssertType(list.splice(index, 1), "T[]");
266AssertType(list.splice, "{ (number, ?number): T[]; (number, number, ...T[]): T[]; }");
267AssertType(index, "number");
268AssertType(1, "int");
269
270AssertType(res, "T");
271    return res;
272  }
273  static removeAll<T>(dit: typeof ListWrapper, list: T[], items: T[]) {
274    for (let i = 0; i < items.length; ++i) {
275AssertType(i, "number");
276AssertType(0, "int");
277AssertType(i < items.length, "boolean");
278AssertType(i, "number");
279AssertType(items.length, "number");
280AssertType(++i, "number");
281AssertType(i, "number");
282
283      let index = list.indexOf(items[i]);
284AssertType(index, "number");
285AssertType(list.indexOf(items[i]), "number");
286AssertType(list.indexOf, "(T, ?number) => number");
287AssertType(items[i], "T");
288AssertType(items, "T[]");
289AssertType(i, "number");
290
291      list.splice(index, 1);
292AssertType(list.splice(index, 1), "T[]");
293AssertType(list.splice, "{ (number, ?number): T[]; (number, number, ...T[]): T[]; }");
294AssertType(index, "number");
295AssertType(1, "int");
296    }
297  }
298  static remove<T>(dit: typeof ListWrapper, list: T[], el: T): boolean {
299    let index = list.indexOf(el);
300AssertType(index, "number");
301AssertType(list.indexOf(el), "number");
302AssertType(list.indexOf, "(T, ?number) => number");
303AssertType(el, "T");
304
305    if (index > -1) {
306AssertType(index > -1, "boolean");
307AssertType(index, "number");
308AssertType(-1, "int");
309AssertType(1, "int");
310
311      list.splice(index, 1);
312AssertType(list.splice(index, 1), "T[]");
313AssertType(list.splice, "{ (number, ?number): T[]; (number, number, ...T[]): T[]; }");
314AssertType(index, "number");
315AssertType(1, "int");
316
317AssertType(true, "boolean");
318      return true;
319    }
320AssertType(false, "boolean");
321    return false;
322  }
323  static clear(dit: typeof ListWrapper, list: any[]) { list.length = 0;
324AssertType(list.length = 0, "int");
325
326AssertType(list.length, "number");
327
328AssertType(0, "int");
329}
330
331  static isEmpty(dit: typeof ListWrapper, list: any[]): boolean {
332AssertType(list.length == 0, "boolean");
333return list.length == 0;
334
335AssertType(list.length, "number");
336
337AssertType(0, "int");
338}
339
340  static fill(dit: typeof ListWrapper, list: any[], value: any, start: number = 0, end: number = null) {
341    list.fill(value, start, end === null ? list.length : end);
342AssertType(list.fill(value, start, end === null ? list.length : end), "void");
343AssertType(list.fill, "(any, number, number) => void");
344AssertType(value, "any");
345AssertType(start, "number");
346AssertType(end === null ? list.length : end, "number");
347AssertType(end === null, "boolean");
348AssertType(end, "number");
349AssertType(null, "null");
350AssertType(list.length, "number");
351AssertType(end, "number");
352  }
353  static equals(dit: typeof ListWrapper, a: any[], b: any[]): boolean {
354    if (a.length != b.length)
355AssertType(a.length != b.length, "boolean");
356AssertType(a.length, "number");
357AssertType(b.length, "number");
358AssertType(false, "boolean");
359return false;
360
361    for (let i = 0; i < a.length; ++i) {
362AssertType(i, "number");
363AssertType(0, "int");
364AssertType(i < a.length, "boolean");
365AssertType(i, "number");
366AssertType(a.length, "number");
367AssertType(++i, "number");
368AssertType(i, "number");
369
370      if (a[i] !== b[i])
371AssertType(a[i] !== b[i], "boolean");
372AssertType(a[i], "any");
373AssertType(a, "any[]");
374AssertType(i, "number");
375AssertType(b[i], "any");
376AssertType(b, "any[]");
377AssertType(i, "number");
378AssertType(false, "boolean");
379return false;
380    }
381AssertType(true, "boolean");
382    return true;
383  }
384  static slice<T>(dit: typeof ListWrapper, l: T[], from: number = 0, to: number = null): T[] {
385AssertType(l.slice(from, to === null ? undefined : to), "T[]");
386AssertType(l.slice, "(?number, ?number) => T[]");
387AssertType(from, "number");
388AssertType(to === null ? undefined : to, "number");
389AssertType(to === null, "boolean");
390AssertType(to, "number");
391AssertType(null, "null");
392AssertType(undefined, "undefined");
393AssertType(to, "number");
394    return l.slice(from, to === null ? undefined : to);
395  }
396  static splice<T>(dit: typeof ListWrapper, l: T[], from: number, length: number): T[] {
397AssertType(l.splice(from, length), "T[]");
398return l.splice(from, length);
399
400AssertType(l.splice, "{ (number, ?number): T[]; (number, number, ...T[]): T[]; }");
401
402AssertType(from, "number");
403
404AssertType(length, "number");
405}
406
407  static sort<T>(dit: typeof ListWrapper, l: T[], compareFn?: (a: T, b: T) => number) {
408    if (isPresent(compareFn)) {
409AssertType(isPresent(compareFn), "boolean");
410AssertType(isPresent, "<T>(?(T, T) => number) => boolean");
411AssertType(compareFn, "(T, T) => number");
412
413      l.sort(compareFn);
414AssertType(l.sort(compareFn), "T[]");
415AssertType(l.sort, "(?(T, T) => number) => T[]");
416AssertType(compareFn, "(T, T) => number");
417
418    } else {
419      l.sort();
420AssertType(l.sort(), "T[]");
421AssertType(l.sort, "(?(T, T) => number) => T[]");
422    }
423  }
424  static toString<T>(dit: typeof ListWrapper, l: T[]): string {
425AssertType(l.toString(), "string");
426return l.toString();
427
428AssertType(l.toString, "() => string");
429}
430
431  static toJSON<T>(dit: typeof ListWrapper, l: T[]): string {
432AssertType(JSON.stringify(l), "string");
433return JSON.stringify(l);
434
435AssertType(JSON.stringify, "{ (any, ?(any, string, any) => any, ?union): string; (any, ?(union)[], ?union): string; }");
436
437AssertType(l, "T[]");
438}
439
440  static maximum<T>(dit: typeof ListWrapper, list: T[], predicate: (t: T) => number): T {
441    if (list.length == 0) {
442AssertType(list.length == 0, "boolean");
443AssertType(list.length, "number");
444AssertType(0, "int");
445
446AssertType(null, "null");
447      return null;
448    }
449    let solution: T = null;
450AssertType(solution, "T");
451AssertType(null, "null");
452
453    let maxValue = -Infinity;
454AssertType(maxValue, "number");
455AssertType(-Infinity, "number");
456AssertType(Infinity, "number");
457
458    for (let index = 0; index < list.length; index++) {
459AssertType(index, "number");
460AssertType(0, "int");
461AssertType(index < list.length, "boolean");
462AssertType(index, "number");
463AssertType(list.length, "number");
464AssertType(index++, "number");
465AssertType(index, "number");
466
467      let candidate = list[index];
468AssertType(candidate, "T");
469AssertType(list[index], "T");
470AssertType(list, "T[]");
471AssertType(index, "number");
472
473      if (isBlank(candidate)) {
474AssertType(isBlank(candidate), "boolean");
475AssertType(isBlank, "(any) => boolean");
476AssertType(candidate, "T");
477
478        continue;
479      }
480      let candidateValue = predicate(candidate);
481AssertType(candidateValue, "number");
482AssertType(predicate(candidate), "number");
483AssertType(predicate, "(T) => number");
484AssertType(candidate, "T");
485
486      if (candidateValue > maxValue) {
487AssertType(candidateValue > maxValue, "boolean");
488AssertType(candidateValue, "number");
489AssertType(maxValue, "number");
490
491        solution = candidate;
492AssertType(solution = candidate, "T");
493AssertType(solution, "T");
494AssertType(candidate, "T");
495
496        maxValue = candidateValue;
497AssertType(maxValue = candidateValue, "number");
498AssertType(maxValue, "number");
499AssertType(candidateValue, "number");
500      }
501    }
502AssertType(solution, "T");
503    return solution;
504  }
505}
506let cloned = ListWrapper.clone(ListWrapper, [1,2,3,4]);
507AssertType(cloned, "number[]");
508AssertType(ListWrapper.clone(ListWrapper, [1,2,3,4]), "number[]");
509AssertType(ListWrapper.clone, "<T>(typeof ListWrapper, T[]) => T[]");
510AssertType(ListWrapper, "typeof ListWrapper");
511AssertType([1,2,3,4], "number[]");
512AssertType(1, "int");
513AssertType(2, "int");
514AssertType(3, "int");
515AssertType(4, "int");
516
517declare function isBlank(x: any): boolean;
518declare function isPresent<T>(compareFn?: (a: T, b: T) => number): boolean;
519interface Array<T> {
520	fill(value: any, start: number, end: number): void;
521}
522
523