1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16// Following declarations are added to check that we don't generate new interfaces with names that already exist
17import GeneratedObjectLiteralInterface_4 from 'x';
18import * as GeneratedObjectLiteralInterface_7 from 'x';
19import {
20    GeneratedObjectLiteralInterface_8,
21    foo as GeneratedObjectLiteralInterface_9
22} from 'x';
23interface GeneratedObjectLiteralInterface_11 {} 
24class GeneratedObjectLiteralInterface_12 {}
25function GeneratedObjectLiteralInterface_15() {}
26
27class C<T> {}
28
29function foo(x): number {
30    return 1;
31}
32
33const o1 = {};
34const o2 = { hello: "world" };
35const o3! = {a: 1, b: 2};
36const o4 = { 
37    field: "hello",
38    field1: 2,
39    field2: "world",
40    field3: 4,
41    field4: true,
42    field5: false
43};
44
45// Properties with various types. Nested object literals
46const o5 = {
47    a: 1,
48    b: '2',
49    c: true,
50    d: new C<number>(),
51    e: {},
52    f: { a: 1, b: '2' },
53    g: {
54        q: 10,
55        w: 20
56    },
57};
58const o6 = {
59    a: 1,
60    b: '2',
61    c: { q: 10, w: 20 },
62    d: true,
63    e: { q: 30, w: 40 }
64};
65
66// Object literals inside another expression
67const o7 = { a:1, b:2 }.a + { a:3, b:4 }.b;
68const o8 = {
69    a: 1, 
70    b: 2,
71    c: ({x:1, y:2}),
72    d: foo({q:1, w:2}.q + {q:3, w:4}.w)
73};
74
75// Object literals inside class declaration
76class D {
77    f1 = {a: 1, b: 2};
78    f2? = {a: 1, b: 2};
79    f3! = {a: 1, b: 2};
80    f4 = ({c: 3, d: 4});
81    f5 = {e: 5}.e + {f: 6, g: 7}.f;
82
83    m() {
84        let x = {a:1, b:2};
85        let y = {c:1, d:2, e:3};
86    }
87}
88
89// Object literals as function parameter initializer
90function funInit(p = { a: 1, b: 2 }) {}
91function funInit2({a, b} = { a: 3, b: 4 }) {} // Not fixable, as in case of destructuring parameters, the contextual type of expression is implied by the binding pattern
92
93// Object literals inside function declaration
94function bar(): void {
95    let a = {a: 1, b: 2};
96    let b = {c: 3, d: 4};
97
98    if (a.b > b.c) {
99        let c = {e: 5, f: 6};
100    }
101
102    let d = {g: 7, d: foo({q:1,w:2}.q + {q:3,w:4}.w)};
103}
104
105const o9 = { 1: '1', '2': 2 };
106const o10 = { [3]: 3 }; // Not fixable, computed property value
107const o11 = { [o2.hello]: 'world' }; // Not fixable, computed property value
108
109const anyVal: any = 1;
110const o12 = { a: anyVal }; // Not fixable, type of property 'a' is not supported
111
112let val = 1;
113const o13 = { val }; // Not fixable, property is not 'key:value' pair
114const o14 = { ...o1 }; // Not fixable, property is not 'key:value' pair
115const o15 = { m() {} }; // Not fixable, property is not 'key:value' pair
116
117const o16 = { // Not fixable, property 'c' is initialized with non-fixable nested object literal, and thus will always have unsupported type (object type literal)
118    a: 1,
119    b: '2',
120    c: {
121        q: 1,
122        w: 2,
123        e: anyVal // Not fixable, unsupported type
124    }
125}
126
127class X<K> {}
128class Y<Q extends X<Q>> {}
129function captureFromLocalScope<T>(t: T): void {
130    let v1 = {a: 1, b: '2', c: t}; // Not fixable, `c` references local type parameter `T`
131    let v2 = {a: 1, b: '2', c: new X<T>()}; // Not fixable, `c` references local type parameter `T`
132    let v3 = {a: 1, b: '2', c: new Y<X<T>>()}; // Not fixable, `c` references local type parameter `T`
133  
134    type LocalType = {a: number, b: string};
135    let localTypeVar: LocalType = {a:1, b:'2'};
136    let v4 = { x: localTypeVar }; // Non-fixable, `x` references type `LocalType` declared in local scope
137  
138    class LocalClass {x: number = 1};
139    let v5 = { y: new LocalClass() }; // Non-fixable, `y` references type `LocalClass` declared in local scope
140  
141    let v6 = { z: LocalClass }; // Non-fixable, `z` references type `LocalClass` declared in local scope
142}
143
144// Record object literals
145let rec1: Record<string, any> = {
146    a: 1,
147    b: 2,
148    c: 3
149}
150
151let rec2: Record<string | number, any> = {
152    foo: 1,
153    bar: 2,
154    10: 'foo',
155    20: 'bar',
156    baz: 3,
157    'daz': 4
158}
159
160let rec3: Record<string | number, any> = { // Not fixable
161    f1: 1,
162    f2: 2,
163    f3: 3,
164    [val]: 4    // Not fixable, key is a computed value
165}
166
167interface NullableRecord {
168    params?: Record<string, string>;
169}
170let rec4: NullableRecord = {
171    params: {
172        key: '1',
173        message: '2'
174    }
175};