• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #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::ASTVerifier;
25 using ark::es2panda::compiler::ast_verifier::InvariantNameSet;
26 using ark::es2panda::ir::AstNode;
27 
28 namespace {
TEST_F(ASTVerifierTest,TSQualifiedName)29 TEST_F(ASTVerifierTest, TSQualifiedName)
30 {
31     ASTVerifier verifier {Allocator()};
32 
33     char const *text = R"(
34         import * as Time from "std/time";
35 
36         function main() {
37         let value = new Time.Chrono();
38         }
39     )";
40 
41     es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.sts");
42     impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED);
43     ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED);
44 
45     auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
46 
47     InvariantNameSet checks;
48     checks.insert("IdentifierHasVariableForAll");
49     const auto &messages = verifier.Verify(ast, checks);
50     ASSERT_EQ(messages.size(), 0);
51 
52     impl_->DestroyContext(ctx);
53 }
54 
TEST_F(ASTVerifierTest,ParametersInArrowFunctionExpression)55 TEST_F(ASTVerifierTest, ParametersInArrowFunctionExpression)
56 {
57     ASTVerifier verifier {Allocator()};
58 
59     char const *text = R"(
60         let b = 1;
61         let f = (p: double) => b + p;
62         function main () {
63             assert f(42) == 43
64         }
65     )";
66 
67     es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.sts");
68     impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED);
69     ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED);
70 
71     auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
72 
73     InvariantNameSet checks;
74     checks.insert("IdentifierHasVariableForAll");
75     const auto &messages = verifier.Verify(ast, checks);
76     ASSERT_EQ(messages.size(), 0);
77 
78     impl_->DestroyContext(ctx);
79 }
80 
TEST_F(ASTVerifierTest,Lambdas)81 TEST_F(ASTVerifierTest, Lambdas)
82 {
83     ASTVerifier verifier {Allocator()};
84 
85     char const *text = R"(
86         type asyncLambda = () => Promise<void>;
87 
88         async function asyncFunc(): Promise<boolean> {
89             return true;
90         }
91 
92         function callAsyncLambda(): void {
93             let is_call_async_lambda: boolean = false;
94 
95             let async_lambda: asyncLambda = async (): Promise<void> => {
96                 await asyncFunc();
97                 is_call_async_lambda = true;
98             };
99         }
100 
101         type I2v = (i: int) => void;
102         type T1 = (lambda: (arg: int) => int, arg: int) => int;
103         type T2 = (c: int) => int;
104 
105         const F1: I2v = (counter: int) => {
106             let funcWithLambda: T1 = (lambda: (arg: int) => int, arg: int) => {
107                 return lambda(arg);
108             };
109 
110             let it: T2 = (c: int): int => {
111                 return c;
112             };
113 
114             while (counter > 0) counter = funcWithLambda(it, counter);
115         };
116 
117         function main() {
118             F1(44);
119             return 0;
120         }
121     )";
122 
123     es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.sts");
124     impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED);
125     ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED);
126 
127     auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
128 
129     InvariantNameSet checks;
130     checks.insert("IdentifierHasVariableForAll");
131     const auto &messages = verifier.Verify(ast, checks);
132     ASSERT_EQ(messages.size(), 0);
133 
134     impl_->DestroyContext(ctx);
135 }
136 
TEST_F(ASTVerifierTest,PromiseUndefined)137 TEST_F(ASTVerifierTest, PromiseUndefined)
138 {
139     ASTVerifier verifier {Allocator()};
140 
141     char const *text = R"(
142         async function testAsyncVoidNothing() {}
143     )";
144 
145     es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.sts");
146     impl_->ProceedToState(ctx, ES2PANDA_STATE_LOWERED);
147     ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_LOWERED);
148 
149     auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
150 
151     InvariantNameSet checks;
152     checks.insert("IdentifierHasVariableForAll");
153     const auto &messages = verifier.Verify(ast, checks);
154     ASSERT_EQ(messages.size(), 0);
155 
156     impl_->DestroyContext(ctx);
157 }
158 
TEST_F(ASTVerifierTest,AnonymousClassId)159 TEST_F(ASTVerifierTest, AnonymousClassId)
160 {
161     ASTVerifier verifier {Allocator()};
162 
163     char const *text = R"(
164         interface H {
165         }
166 
167         class B {
168             func: H = new H() {
169             }
170         }
171 
172         function main() {}
173     )";
174 
175     es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.sts");
176     impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED);
177     ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED);
178 
179     auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
180 
181     InvariantNameSet checks;
182     checks.insert("IdentifierHasVariableForAll");
183     const auto &messages = verifier.Verify(ast, checks);
184     ASSERT_EQ(messages.size(), 0);
185 
186     impl_->DestroyContext(ctx);
187 }
188 
TEST_F(ASTVerifierTest,EnumInts)189 TEST_F(ASTVerifierTest, EnumInts)
190 {
191     ASTVerifier verifier {Allocator()};
192 
193     char const *text = R"(
194         enum Color {
195             Red = 1,
196             Blue = 2
197         }
198 
199         function main() {
200             let color: Color = Color.Red;
201             let name = color.getName();
202         }
203     )";
204 
205     es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.sts");
206     impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED);
207     ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED);
208 
209     auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
210 
211     InvariantNameSet checks;
212     checks.insert("IdentifierHasVariableForAll");
213     const auto &messages = verifier.Verify(ast, checks);
214     ASSERT_EQ(messages.size(), 0);
215 
216     impl_->DestroyContext(ctx);
217 }
218 
TEST_F(ASTVerifierTest,EnumStrings)219 TEST_F(ASTVerifierTest, EnumStrings)
220 {
221     ASTVerifier verifier {Allocator()};
222 
223     char const *text = R"(
224         enum Shape {
225             Circle = "CIRCLE",
226             Square = "SQUARE",
227             Triangle = "TRIANGLE"
228         }
229 
230         function main() {
231             let shape = Shape.Circle.valueOf();
232         }
233     )";
234 
235     es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.sts");
236     impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED);
237     ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED);
238 
239     auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
240 
241     InvariantNameSet checks;
242     checks.insert("IdentifierHasVariableForAll");
243     const auto &messages = verifier.Verify(ast, checks);
244     ASSERT_EQ(messages.size(), 0);
245 
246     impl_->DestroyContext(ctx);
247 }
248 
249 }  // namespace
250