1/*
2 * Copyright (c) 2023-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// Global-scoped duplicate declarations
16import G0 from 'module';
17import { G1 } from 'module';
18import A from 'x';
19interface A {
20  f: number;
21}
22class A implements A {
23  m(); // Not duplicate, method overload
24  m(a?: number) {
25    if (a) a++;
26  } // Not duplicate, method overload
27}
28
29namespace A {
30  export interface B {
31    a: number;
32  }
33  export class B extends A {}
34  export interface C {
35    a: number;
36  } // Not duplicate, interface C has two merging declarations
37}
38
39namespace A {
40  export interface B {
41    b: string;
42  }
43  export interface C {
44    b: string;
45  } // Not duplicate, interface C has two merging declarations
46}
47
48import * as B from 'y';
49interface B {
50  f: number;
51}
52class B {}
53
54import { C, X as D, E, Y as F } from 'z'; // E and F are not duplicates
55interface C {
56  f: number;
57}
58class C extends A implements C {}
59
60function D(): number {
61  return 1;
62}
63interface D {
64  f: number;
65}
66
67function X(); // Not duplicate, function overload
68function X(x?: number) {
69  // Not duplicate, function overload
70  const ab = new A.B();
71}
72
73export function scopeDuplicateDeclarations() {
74  // Function-scoped duplicate declarations
75  const A = 1000;
76  interface A {
77    f: number;
78  }
79
80  const B = 'Text';
81  type B = number[];
82
83  class C {}
84  interface C {
85    f: number;
86  }
87
88  function D(): number {
89    return 1;
90  }
91  type D = number;
92
93  function E(): number {
94    return 1;
95  }
96  interface E {
97    f: number;
98  }
99
100  // Block-scoped duplicate declarations.
101  {
102    const A = 54;
103    interface A {
104      f: number;
105    }
106  }
107}
108
109export function destructuringDuplicates() {
110  interface F {
111    a: number;
112  }
113  interface H {
114    s: string;
115  }
116  const [F, G, ...H] = [1, 2, 3, 4, 5];
117
118  interface I {
119    b: boolean;
120  }
121  interface K {
122    i: I;
123  }
124  interface M {
125    k: K;
126  }
127  const {
128    I,
129    J: {
130      K,
131      L: [M, N],
132      O,
133    },
134  } = { I: 10, J: { K: 'foo', L: [30, 40], O: 'bar' } };
135}
136
137export function switchDuplicates(n: number) {
138  switch (n) {
139    case 1:
140      const XX = 10;
141      type XX = number;
142
143      function XY(): number {
144        return 1;
145      }
146      break;
147    case 25:
148      interface XY {
149        f: number;
150      }
151
152      function XZ(): number {
153        return 1;
154      }
155      break;
156    default:
157      type XZ = string[];
158      break;
159  }
160}
161
162class PrivateIdentifiers {
163  x: number;
164  #x: string;
165
166  y(x: number): number {
167    return 10;
168  }
169  #y(x: number): number {
170    return 20;
171  }
172
173  z: boolean;
174  #z(x: number): number {
175    return 30;
176  }
177}
178
179// namespace to every other type - no error
180enum T1 {}
181namespace T1 {}
182
183class T2 {}
184namespace T2 {}
185
186interface T3 {}
187namespace T3 {}
188
189type T4 = T2;
190namespace T4 {}
191
192namespace T5 {}
193namespace T5 {}
194
195// namespace to variable / function - error
196namespace G0 {}
197namespace G1 {}
198
199function G3() {}
200namespace G3 {}
201
202// declarations merging 
203namespace NP1 {} // namespace merging is allowed
204namespace NP1 {} // namespace merging is allowed
205
206enum EN1 {}
207enum EN1 {}
208
209interface IF1 {}
210interface IF1 {}
211
212// variable can't collide with interface, type alias and namespace
213const V1: number = 1;
214interface V1 {}
215
216const V2: number = 1;
217namespace V2 {}
218
219const V3: number = 1;
220type V3 = V1;
221
222// function can't collide with interface, type alias and namespace
223function F1() {}
224interface F1 {}
225
226function F2() {}
227namespace F2 {}
228
229function F3() {}
230type F3 = V1;
231
232// interface checks
233interface IF2 {}
234class IF2 {}
235