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 "macros.h"
18#include "util/ast-builders/classDefinitionBuilder.h"
19#include "util/ast-builders/binaryExpressionBuilder.h"
20#include "util/ast-builders/classPropertyBuilder.h"
21#include "util/ast-builders/identifierBuilder.h"
22#include "util/ast-builders/numberLiteralBuilder.h"
23#include "util/ast-builders/awaitExpressionBuilder.h"
24#include "util/ast-builders/bigintLiteralBuilder.h"
25#include "util/ast-builders/blockExpressionBuilder.h"
26#include "util/ast-builders/blockStatementBuilder.h"
27#include "util/ast-builders/booleanLiteralBuilder.h"
28#include "util/ast-builders/breakStatementBuilder.h"
29#include "util/ast-builders/callExpressionBuilder.h"
30#include "util/ast-builders/superExpressionBuilder.h"
31#include "util/ast-builders/charLiteralBuilder.h"
32#include "util/ast-builders/classDeclarationBuilder.h"
33#include "util/ast-builders/etsTypeReferenceBuilder.h"
34#include "util/ast-builders/etsTypeReferencePartBuilder.h"
35#include "util/ast-builders/exportDefaultDeclarationBuilder.h"
36#include "util/ast-builders/expressionStatementBuilder.h"
37#include "util/ast-builders/ifStatementBuilder.h"
38#include "util/ast-builders/importDeclarationBuilder.h"
39#include "util/ast-builders/importSpecifierBuilder.h"
40#include "util/ast-builders/memberExpressionBuilder.h"
41#include "util/ast-builders/thisExpressionBuilder.h"
42#include "util/ast-builders/methodDefinitionBuilder.h"
43#include "util/ast-builders/functionExpressionBuilder.h"
44#include "util/ast-builders/scriptFunctionBuilder.h"
45#include "util/ast-builders/stringLiteralBuilder.h"
46#include "util/ast-builders/switchStatementBuilder.h"
47#include "util/ast-builders/tsClassImplementsBuilder.h"
48#include "util/ast-builders/tsEnumDeclarationBuilder.h"
49#include "util/ast-builders/tsEnumMemberBuilder.h"
50#include "util/ast-builders/tsTypeParameterInstantiationBuilder.h"
51#include "util/ast-builders/unaryExpressionBuilder.h"
52#include "util/ast-builders/undefinedLiteralBuilder.h"
53#include "util/ast-builders/updateExpressionBuilder.h"
54#include "util/ast-builders/variableDeclarationBuilder.h"
55#include "util/ast-builders/variableDeclaratorBuilder.h"
56#include "util/ast-builders/whileStatementBuilder.h"
57#include "util/ast-builders/switchCaseStatementBuilder.h"
58
59#include <gtest/gtest.h>
60
61using ark::es2panda::compiler::ast_verifier::InvariantNameSet;
62using ark::es2panda::ir::AwaitExpressionBuilder;
63using ark::es2panda::ir::BigIntLiteralBuilder;
64using ark::es2panda::ir::BinaryExpressionBuilder;
65using ark::es2panda::ir::BlockExpressionBuilder;
66using ark::es2panda::ir::BlockStatementBuilder;
67using ark::es2panda::ir::BooleanLiteralBuilder;
68using ark::es2panda::ir::BreakStatementBuilder;
69using ark::es2panda::ir::CallExpressionBuilder;
70using ark::es2panda::ir::CharLiteralBuilder;
71using ark::es2panda::ir::ClassDeclarationBuilder;
72using ark::es2panda::ir::ClassDefinitionBuilder;
73using ark::es2panda::ir::ClassPropertyBuilder;
74using ark::es2panda::ir::ETSTypeReferenceBuilder;
75using ark::es2panda::ir::ETSTypeReferencePartBuilder;
76using ark::es2panda::ir::ExportDefaultDeclarationBuilder;
77using ark::es2panda::ir::ExpressionStatementBuilder;
78using ark::es2panda::ir::FunctionExpressionBuilder;
79using ark::es2panda::ir::IdentifierBuilder;
80using ark::es2panda::ir::IfStatementBuilder;
81using ark::es2panda::ir::ImportDeclarationBuilder;
82using ark::es2panda::ir::ImportSpecifierBuilder;
83using ark::es2panda::ir::MemberExpressionBuilder;
84using ark::es2panda::ir::MethodDefinitionBuilder;
85using ark::es2panda::ir::NumberLiteralBuilder;
86using ark::es2panda::ir::ScriptFunctionBuilder;
87using ark::es2panda::ir::StringLiteralBuilder;
88using ark::es2panda::ir::SuperExpressionBuilder;
89using ark::es2panda::ir::SwitchCaseStatementBuilder;
90using ark::es2panda::ir::SwitchStatementBuilder;
91using ark::es2panda::ir::ThisExpressionBuilder;
92using ark::es2panda::ir::TSClassImplementsBuilder;
93using ark::es2panda::ir::TSEnumDeclarationBuilder;
94using ark::es2panda::ir::TSEnumMemberBuilder;
95using ark::es2panda::ir::TSTypeParameterInstantiationBuilder;
96using ark::es2panda::ir::UnaryExpressionBuilder;
97using ark::es2panda::ir::UndefinedLiteralBuilder;
98using ark::es2panda::ir::UpdateExpressionBuilder;
99using ark::es2panda::ir::VariableDeclarationBuilder;
100using ark::es2panda::ir::VariableDeclaratorBuilder;
101using ark::es2panda::ir::WhileStatementBuilder;
102
103namespace {
104TEST_F(ASTVerifierTest, arrowFunctionExpressionBuild)
105{
106    auto left = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
107    auto right = NumberLiteralBuilder(Allocator()).SetValue("5").Build();
108    auto binaryExpr = BinaryExpressionBuilder(Allocator())
109                          .SetLeft(left)
110                          .SetRight(right)
111                          .SetOperator(ark::es2panda::lexer::TokenType::PUNCTUATOR_PLUS)
112                          .Build();
113    auto awaitExpr = AwaitExpressionBuilder(Allocator()).SetArgument(binaryExpr).Build();
114    ASSERT_TRUE(awaitExpr->IsAwaitExpression());
115}
116
117TEST_F(ASTVerifierTest, awaitExpressionBuild)
118{
119    auto left = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
120    auto right = NumberLiteralBuilder(Allocator()).SetValue("5").Build();
121    auto binaryExpr = BinaryExpressionBuilder(Allocator())
122                          .SetLeft(left)
123                          .SetRight(right)
124                          .SetOperator(ark::es2panda::lexer::TokenType::PUNCTUATOR_PLUS)
125                          .Build();
126    auto awaitExpr = AwaitExpressionBuilder(Allocator()).SetArgument(binaryExpr).Build();
127    ASSERT_TRUE(awaitExpr->IsAwaitExpression());
128}
129
130TEST_F(ASTVerifierTest, bigintLiteralBuild)
131{
132    auto bigint = BigIntLiteralBuilder(Allocator()).SetValue("123").Build();
133    ASSERT_TRUE(bigint->IsBigIntLiteral());
134}
135
136TEST_F(ASTVerifierTest, binaryExpressionBuild)
137{
138    auto left = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
139    auto right = NumberLiteralBuilder(Allocator()).SetValue("5").Build();
140    auto binaryExpr = BinaryExpressionBuilder(Allocator())
141                          .SetLeft(left)
142                          .SetRight(right)
143                          .SetOperator(ark::es2panda::lexer::TokenType::PUNCTUATOR_PLUS)
144                          .Build();
145    ASSERT_TRUE(binaryExpr->IsBinaryExpression());
146}
147
148TEST_F(ASTVerifierTest, blockExpressionBuild)
149{
150    auto left = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
151    auto right = NumberLiteralBuilder(Allocator()).SetValue("5").Build();
152    auto binaryExpr = BinaryExpressionBuilder(Allocator())
153                          .SetLeft(left)
154                          .SetRight(right)
155                          .SetOperator(ark::es2panda::lexer::TokenType::PUNCTUATOR_PLUS)
156                          .Build();
157    auto exprStmnt = ExpressionStatementBuilder(Allocator()).SetExpression(binaryExpr).Build();
158    auto blockExpr = BlockExpressionBuilder(Allocator()).AddStatement(exprStmnt).Build();
159    ASSERT_TRUE(blockExpr->IsBlockExpression());
160}
161
162TEST_F(ASTVerifierTest, blockStatementBuild)
163{
164    auto left = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
165    auto right = NumberLiteralBuilder(Allocator()).SetValue("5").Build();
166    auto binaryExpr = BinaryExpressionBuilder(Allocator())
167                          .SetLeft(left)
168                          .SetRight(right)
169                          .SetOperator(ark::es2panda::lexer::TokenType::PUNCTUATOR_PLUS)
170                          .Build();
171    auto exprStmnt = ExpressionStatementBuilder(Allocator()).SetExpression(binaryExpr).Build();
172    auto blockStmnt = BlockStatementBuilder(Allocator()).AddStatement(exprStmnt).Build();
173    ASSERT_TRUE(blockStmnt->IsBlockStatement());
174}
175
176TEST_F(ASTVerifierTest, booleanLiteralBuild)
177{
178    auto boolLiteral = BooleanLiteralBuilder(Allocator()).SetValue(true).Build();
179    ASSERT_TRUE(boolLiteral->IsBooleanLiteral());
180}
181
182TEST_F(ASTVerifierTest, breakStatementBuild)
183{
184    auto breakStmnt = BreakStatementBuilder(Allocator()).Build();
185    ASSERT_TRUE(breakStmnt->IsBreakStatement());
186}
187
188TEST_F(ASTVerifierTest, callExpressionBuild)
189{
190    auto superExpr = SuperExpressionBuilder(Allocator()).Build();
191    auto callExpr = CallExpressionBuilder(Allocator()).SetCallee(superExpr).Build();
192    ASSERT_TRUE(callExpr->IsCallExpression());
193}
194
195TEST_F(ASTVerifierTest, charLiteralBuild)
196{
197    // Create char literal with default value u0000
198    auto charLiteral = CharLiteralBuilder(Allocator()).Build();
199    ASSERT_TRUE(charLiteral->IsCharLiteral());
200}
201
202TEST_F(ASTVerifierTest, classDeclarationBuild)
203{
204    auto id = IdentifierBuilder(Allocator()).SetName("a").Build();
205    auto number = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
206    auto classProperty = ClassPropertyBuilder(Allocator())
207                             .SetKey(id)
208                             .SetValue(number)
209                             .AddModifier(ark::es2panda::ir::ModifierFlags::PRIVATE)
210                             .Build();
211
212    auto classId = IdentifierBuilder(Allocator()).SetName("A").Build();
213    auto classDef = ClassDefinitionBuilder(Allocator()).SetIdentifier(classId).AddProperty(classProperty).Build();
214    auto classDecl = ClassDeclarationBuilder(Allocator()).SetDefinition(classDef).Build();
215    ASSERT_TRUE(classDecl->IsClassDeclaration());
216}
217
218TEST_F(ASTVerifierTest, etsTypeReferenceBuild)
219{
220    auto id = IdentifierBuilder(Allocator()).SetName("a").Build();
221    auto etsTypeReferencePart =
222        ETSTypeReferencePartBuilder(Allocator()).SetName(id).SetTypeParams(nullptr).SetPrev(nullptr).Build();
223    auto etsTypeReference = ETSTypeReferenceBuilder(Allocator()).SetETSTypeReferencePart(etsTypeReferencePart).Build();
224    ASSERT_TRUE(etsTypeReference->IsETSTypeReference());
225}
226
227TEST_F(ASTVerifierTest, exportDefaultDeclarationBuild)
228{
229    auto idParent = IdentifierBuilder(Allocator()).SetName("parent").Build();
230    auto id = IdentifierBuilder(Allocator()).SetName("a").SetParent<IdentifierBuilder>(idParent).Build();
231    auto number = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
232    auto classProperty = ClassPropertyBuilder(Allocator())
233                             .SetKey(id)
234                             .SetValue(number)
235                             .AddModifier(ark::es2panda::ir::ModifierFlags::PRIVATE)
236                             .Build();
237
238    auto classId = IdentifierBuilder(Allocator()).SetName("A").Build();
239    auto classDef = ClassDefinitionBuilder(Allocator()).SetIdentifier(classId).AddProperty(classProperty).Build();
240    auto classDecl = ClassDeclarationBuilder(Allocator()).SetDefinition(classDef).Build();
241    auto exportDefaultDecl =
242        ExportDefaultDeclarationBuilder(Allocator()).SetDeclaration(classDecl).SetExportEquals(true).Build();
243    ASSERT_TRUE(exportDefaultDecl->IsExportDefaultDeclaration());
244}
245
246TEST_F(ASTVerifierTest, expressionStatementBuild)
247{
248    auto left = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
249    auto right = NumberLiteralBuilder(Allocator()).SetValue("5").Build();
250    auto binaryExpr = BinaryExpressionBuilder(Allocator())
251                          .SetLeft(left)
252                          .SetRight(right)
253                          .SetOperator(ark::es2panda::lexer::TokenType::PUNCTUATOR_PLUS)
254                          .Build();
255    auto exprStmnt = ExpressionStatementBuilder(Allocator()).SetExpression(binaryExpr).Build();
256    ASSERT_TRUE(exprStmnt->IsExpressionStatement());
257}
258
259TEST_F(ASTVerifierTest, ifStatementBuild)
260{
261    auto left = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
262    auto right = NumberLiteralBuilder(Allocator()).SetValue("5").Build();
263    auto binaryExpr = BinaryExpressionBuilder(Allocator())
264                          .SetLeft(left)
265                          .SetRight(right)
266                          .SetOperator(ark::es2panda::lexer::TokenType::PUNCTUATOR_PLUS)
267                          .Build();
268    auto consStmnt = ExpressionStatementBuilder(Allocator()).SetExpression(binaryExpr).Build();
269    auto alterStmnt = ExpressionStatementBuilder(Allocator()).SetExpression(binaryExpr).Build();
270    auto ifStmnt =
271        IfStatementBuilder(Allocator()).SetTest(binaryExpr).SetConsequent(consStmnt).SetAlternate(alterStmnt).Build();
272    ASSERT_TRUE(ifStmnt->IsIfStatement());
273}
274
275TEST_F(ASTVerifierTest, memberExpressionBuild)
276{
277    auto member = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
278    auto thisExpr = ThisExpressionBuilder(Allocator()).Build();
279    auto memberExpression = MemberExpressionBuilder(Allocator())
280                                .SetObject(thisExpr)
281                                .SetProperty(member)
282                                .SetKind(ark::es2panda::ir::MemberExpressionKind::PROPERTY_ACCESS)
283                                .Build();
284    ASSERT_TRUE(memberExpression->IsMemberExpression());
285}
286
287TEST_F(ASTVerifierTest, methodDefinitionBuild)
288{
289    auto id = IdentifierBuilder(Allocator()).SetName("a").Build();
290    ark::ArenaVector<ark::es2panda::ir::Expression *> params(Allocator()->Adapter());
291    auto signature = ark::es2panda::ir::FunctionSignature(nullptr, std::move(params), nullptr);
292    auto func = ScriptFunctionBuilder(Allocator()).SetSignature(&signature).Build();
293    auto funcExpr = FunctionExpressionBuilder(Allocator()).SetFunction(func).Build();
294    auto methodDef = MethodDefinitionBuilder(Allocator())
295                         .SetKey(id)
296                         .SetMethodDefinitionKind(ark::es2panda::ir::MethodDefinitionKind::METHOD)
297                         .SetModifierFlags(ark::es2panda::ir::ModifierFlags::PUBLIC)
298                         .SetValue(funcExpr)
299                         .Build();
300    ASSERT_TRUE(methodDef->IsMethodDefinition());
301}
302
303TEST_F(ASTVerifierTest, stringLiteralBuild)
304{
305    auto stringLiteral = StringLiteralBuilder(Allocator()).SetValue("qwe").Build();
306    ASSERT_TRUE(stringLiteral->IsStringLiteral());
307}
308
309TEST_F(ASTVerifierTest, tsClassImplementsBuild)
310{
311    auto left = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
312    auto right = NumberLiteralBuilder(Allocator()).SetValue("5").Build();
313    auto binaryExpr = BinaryExpressionBuilder(Allocator())
314                          .SetLeft(left)
315                          .SetRight(right)
316                          .SetOperator(ark::es2panda::lexer::TokenType::PUNCTUATOR_PLUS)
317                          .Build();
318    ark::ArenaVector<ark::es2panda::ir::TypeNode *> types(Allocator()->Adapter());
319    auto typeParams = TSTypeParameterInstantiationBuilder(Allocator()).SetParams(std::move(types)).Build();
320    auto tsClassImpl =
321        TSClassImplementsBuilder(Allocator()).SetExpression(binaryExpr).SetTypeParameters(typeParams).Build();
322    ASSERT_TRUE(tsClassImpl->IsTSClassImplements());
323}
324
325TEST_F(ASTVerifierTest, switchStatementBuild)
326{
327    auto left = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
328    auto right = NumberLiteralBuilder(Allocator()).SetValue("5").Build();
329    auto binaryExpr = BinaryExpressionBuilder(Allocator())
330                          .SetLeft(left)
331                          .SetRight(right)
332                          .SetOperator(ark::es2panda::lexer::TokenType::PUNCTUATOR_PLUS)
333                          .Build();
334    auto consStmnt = ExpressionStatementBuilder(Allocator()).SetExpression(binaryExpr).Build();
335
336    auto thisExpr = ThisExpressionBuilder(Allocator()).Build();
337    ark::ArenaVector<ark::es2panda::ir::SwitchCaseStatement *> cases(Allocator()->Adapter());
338    ark::ArenaVector<ark::es2panda::ir::Statement *> conseq(Allocator()->Adapter());
339    conseq.push_back(consStmnt);
340    auto switchCase = SwitchCaseStatementBuilder(Allocator()).SetTest(binaryExpr).SetConsequent(conseq).Build();
341    cases.push_back(switchCase);
342    auto switchStmnt = SwitchStatementBuilder(Allocator()).SetCases(cases).SetDiscriminant(thisExpr).Build();
343    ASSERT_TRUE(switchStmnt->IsSwitchStatement());
344}
345
346TEST_F(ASTVerifierTest, enumBuild)
347{
348    auto id = IdentifierBuilder(Allocator()).SetName("a").Build();
349    auto idMember = IdentifierBuilder(Allocator()).SetName("s").Build();
350    auto init = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
351    auto enumMember = TSEnumMemberBuilder(Allocator()).SetKey(idMember).SetInit(init).Build();
352    auto enumDecl = TSEnumDeclarationBuilder(Allocator())
353                        .SetKey(id)
354                        .SetIsConst(false)
355                        .SetIsDeclare(true)
356                        .SetIsConst(false)
357                        .AddMember(enumMember)
358                        .Build();
359    ASSERT_TRUE(enumDecl->IsTSEnumDeclaration());
360}
361
362TEST_F(ASTVerifierTest, unaryExpressionBuild)
363{
364    auto id = IdentifierBuilder(Allocator()).SetName("a").Build();
365    auto unaryExpr = UnaryExpressionBuilder(Allocator())
366                         .SetArgument(id)
367                         .SetOperator(ark::es2panda::lexer::TokenType::PUNCTUATOR_MINUS)
368                         .Build();
369    ASSERT_TRUE(unaryExpr->IsUnaryExpression());
370}
371
372TEST_F(ASTVerifierTest, undefinedLiteralBuild)
373{
374    auto undefLiteral = UndefinedLiteralBuilder(Allocator()).Build();
375    ASSERT_TRUE(undefLiteral->IsUndefinedLiteral());
376}
377
378TEST_F(ASTVerifierTest, updateExpressionBuild)
379{
380    auto id = IdentifierBuilder(Allocator()).SetName("a").Build();
381    auto updateExpr = UpdateExpressionBuilder(Allocator())
382                          .SetArgument(id)
383                          .SetOperator(ark::es2panda::lexer::TokenType::PUNCTUATOR_MINUS_MINUS)
384                          .SetIsPrefix(true)
385                          .Build();
386    ASSERT_TRUE(updateExpr->IsUpdateExpression());
387}
388
389TEST_F(ASTVerifierTest, VariableDeclarationBuild)
390{
391    auto idDeclarator = IdentifierBuilder(Allocator()).SetName("a").Build();
392    auto init = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
393    auto varDeclarator = VariableDeclaratorBuilder(Allocator()).SetId(idDeclarator).SetInit(init).Build();
394    ark::ArenaVector<ark::es2panda::ir::VariableDeclarator *> declarators(Allocator()->Adapter());
395    declarators.push_back(varDeclarator);
396    auto varDecl = VariableDeclarationBuilder(Allocator())
397                       .SetDeclarators(std::move(declarators))
398                       .SetKind(ark::es2panda::ir::VariableDeclaration::VariableDeclarationKind::LET)
399                       .Build();
400    ASSERT_TRUE(varDecl->IsVariableDeclaration());
401}
402
403TEST_F(ASTVerifierTest, whileStatementBuild)
404{
405    auto left = NumberLiteralBuilder(Allocator()).SetValue("10").Build();
406    auto right = NumberLiteralBuilder(Allocator()).SetValue("5").Build();
407    auto binaryExpr = BinaryExpressionBuilder(Allocator())
408                          .SetLeft(left)
409                          .SetRight(right)
410                          .SetOperator(ark::es2panda::lexer::TokenType::PUNCTUATOR_PLUS)
411                          .Build();
412    auto exprStmnt = ExpressionStatementBuilder(Allocator()).SetExpression(binaryExpr).Build();
413    auto whileStmnt = WhileStatementBuilder(Allocator()).SetTest(binaryExpr).SetBody(exprStmnt).Build();
414    ASSERT_TRUE(whileStmnt->IsWhileStatement());
415}
416
417TEST_F(ASTVerifierTest, multipleImportTest)
418{
419    auto importedIdent = IdentifierBuilder(Allocator()).SetName("A").Build();
420    auto localIdent = IdentifierBuilder(Allocator()).SetName("A").Build();
421    auto stringLiteral = StringLiteralBuilder(Allocator()).SetValue("test").Build();
422    auto importSpecifier = ImportSpecifierBuilder(Allocator()).SetImported(importedIdent).SetLocal(localIdent).Build();
423    auto importDecl =
424        ImportDeclarationBuilder(Allocator()).SetSource(stringLiteral).AddSpecifier(importSpecifier).Build();
425    ASSERT_TRUE(importDecl->IsImportDeclaration());
426
427    auto classId = IdentifierBuilder(Allocator()).SetName("B").Build();
428    auto classDef = ClassDefinitionBuilder(Allocator()).SetIdentifier(classId).SetSuperClass(localIdent).Build();
429    auto classDecl = ClassDeclarationBuilder(Allocator()).SetDefinition(classDef).Build();
430    ASSERT_TRUE(classDecl->IsClassDeclaration());
431}
432}  // anonymous namespace
433