1 /**
2 * Copyright (c) 2024-2025 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 #include "ast_verifier_test.h"
17 #include "checker/ETSchecker.h"
18 #include "ir/expressions/identifier.h"
19 #include "ir/astNode.h"
20 #include "parser/ETSparser.h"
21
22 #include <gtest/gtest.h>
23
24 using ark::es2panda::compiler::ast_verifier::IdentifierHasVariable;
25
26 namespace {
TEST_F(ASTVerifierTest,LabelsHaveReferences)27 TEST_F(ASTVerifierTest, LabelsHaveReferences)
28 {
29 char const *text = R"(
30 function main(): void {
31 loop: for (let i = 0; i < 10; i++) {
32 break loop;
33 }
34 }
35 )";
36
37 CONTEXT(ES2PANDA_STATE_CHECKED, text)
38 {
39 EXPECT_TRUE(Verify<IdentifierHasVariable>());
40 }
41 }
42
TEST_F(ASTVerifierTest,ExtensionFunction)43 TEST_F(ASTVerifierTest, ExtensionFunction)
44 {
45 char const *text = R"(
46 class Fruit {
47 name(): void {
48 }
49 }
50
51 function name(this:Fruit, id: int): void {
52 }
53
54 function test() {
55 let fruit = new Fruit();
56 fruit.name()
57 }
58 )";
59
60 CONTEXT(ES2PANDA_STATE_CHECKED, text)
61 {
62 EXPECT_TRUE(Verify<IdentifierHasVariable>());
63 }
64 }
65
TEST_F(ASTVerifierTest,Imports)66 TEST_F(ASTVerifierTest, Imports)
67 {
68 char const *text = R"(
69 import { PI } from "std/math";
70 import { A } from "dynamic_import_tests"
71 import default_imported from "import_tests/modules/default_export";
72 import * as Time from "std/time";
73 )";
74
75 CONTEXT(ES2PANDA_STATE_CHECKED, text)
76 {
77 EXPECT_TRUE(Verify<IdentifierHasVariable>());
78 }
79 }
80
TEST_F(ASTVerifierTest,OptionalLambdas)81 TEST_F(ASTVerifierTest, OptionalLambdas)
82 {
83 char const *text = R"(
84 function main(): void {
85 let d = (c?: int) => {
86 }
87 }
88 )";
89
90 CONTEXT(ES2PANDA_STATE_LOWERED, text)
91 {
92 EXPECT_TRUE(Verify<IdentifierHasVariable>());
93 }
94 }
95
TEST_F(ASTVerifierTest,TSQualifiedName)96 TEST_F(ASTVerifierTest, TSQualifiedName)
97 {
98 char const *text = R"(
99 import * as Time from "std/time";
100
101 function main() {
102 let value = new Time.Chrono();
103 }
104 )";
105
106 CONTEXT(ES2PANDA_STATE_CHECKED, text)
107 {
108 EXPECT_TRUE(Verify<IdentifierHasVariable>());
109 }
110 }
111
TEST_F(ASTVerifierTest,ParametersInArrowFunctionExpression)112 TEST_F(ASTVerifierTest, ParametersInArrowFunctionExpression)
113 {
114 char const *text = R"(
115 let b = 1;
116 let f = (p: double) => b + p;
117 function main () {
118 assertEQ(f(42), 43)
119 }
120 )";
121
122 CONTEXT(ES2PANDA_STATE_CHECKED, text)
123 {
124 EXPECT_TRUE(Verify<IdentifierHasVariable>());
125 }
126 }
127
TEST_F(ASTVerifierTest,Lambdas)128 TEST_F(ASTVerifierTest, Lambdas)
129 {
130 char const *text = R"(
131 type asyncLambda = () => Promise<void>;
132
133 async function asyncFunc(): Promise<boolean> {
134 return true;
135 }
136
137 function callAsyncLambda(): void {
138 let is_call_async_lambda: boolean = false;
139
140 let async_lambda: asyncLambda = async (): Promise<void> => {
141 await asyncFunc();
142 is_call_async_lambda = true;
143 };
144 }
145
146 type I2v = (i: int) => void;
147 type T1 = (lambda: (arg: int) => int, arg: int) => int;
148 type T2 = (c: int) => int;
149
150 const F1: I2v = (counter: int) => {
151 let funcWithLambda: T1 = (lambda: (arg: int) => int, arg: int) => {
152 return lambda(arg);
153 };
154
155 let it: T2 = (c: int): int => {
156 return c;
157 };
158
159 while (counter > 0) counter = funcWithLambda(it, counter);
160 };
161
162 function main() {
163 F1(44);
164 return 0;
165 }
166 )";
167
168 CONTEXT(ES2PANDA_STATE_CHECKED, text)
169 {
170 EXPECT_TRUE(Verify<IdentifierHasVariable>());
171 }
172 }
173
TEST_F(ASTVerifierTest,PromiseUndefined)174 TEST_F(ASTVerifierTest, PromiseUndefined)
175 {
176 char const *text = R"(
177 async function testAsyncVoidNothing() {}
178 )";
179
180 CONTEXT(ES2PANDA_STATE_LOWERED, text)
181 {
182 EXPECT_TRUE(Verify<IdentifierHasVariable>());
183 }
184 }
185
TEST_F(ASTVerifierTest,EnumInts)186 TEST_F(ASTVerifierTest, EnumInts)
187 {
188 char const *text = R"(
189 enum Color {
190 Red = 1,
191 Blue = 2
192 }
193
194 function main() {
195 let color: Color = Color.Red;
196 let name = color.getName();
197 }
198 )";
199
200 CONTEXT(ES2PANDA_STATE_CHECKED, text)
201 {
202 EXPECT_TRUE(Verify<IdentifierHasVariable>());
203 }
204 }
205
TEST_F(ASTVerifierTest,EnumStrings)206 TEST_F(ASTVerifierTest, EnumStrings)
207 {
208 char const *text = R"(
209 enum Shape {
210 Circle = "CIRCLE",
211 Square = "SQUARE",
212 Triangle = "TRIANGLE"
213 }
214
215 function main() {
216 let shape = Shape.Circle.valueOf();
217 }
218 )";
219
220 CONTEXT(ES2PANDA_STATE_CHECKED, text)
221 {
222 EXPECT_TRUE(Verify<IdentifierHasVariable>());
223 }
224 }
225 } // namespace
226