• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 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 #include <iostream>
16 #include <ostream>
17 #include <string>
18 
19 #include "public/es2panda_lib.h"
20 #include "util.h"
21 
22 // NOLINTBEGIN
23 
24 /*
25  * Covered C API List:
26  *   size_t(*SourcePositionIndex)(es2panda_Context *context, es2panda_SourcePosition *position);
27  *   size_t(*SourcePositionLine)(es2panda_Context *context, es2panda_SourcePosition *position);
28  *   es2panda_Config *(*CreateConfig)(int argc, char const * const *argv);
29  *   es2panda_Context *(*CreateContextFromString)(es2panda_Config *config, const char *source, char const *file_name);
30  *   es2panda_SourcePosition *(*CreateSourcePosition)(es2panda_Context *context, size_t index, size_t line);
31  *   es2panda_SourceRange *(*CreateSourceRange)(es2panda_Context *context, es2panda_SourcePosition *start,
32  *                                              es2panda_SourcePosition *end);
33  *   es2panda_SourcePosition *(*SourceRangeStart)(es2panda_Context *context, es2panda_SourceRange *range);
34  *   es2panda_SourcePosition *(*SourceRangeEnd)(es2panda_Context *context, es2panda_SourceRange *range);
35  *   es2panda_AstNode *(*CreateNumberLiteral)(es2panda_Context *ctx, int32_t value);
36  *   es2panda_AstNode *(*CreateNumberLiteral1)(es2panda_Context *ctx, int64_t value);
37  *   es2panda_AstNode *(*CreateNumberLiteral2)(es2panda_Context *ctx, double value);
38  *   es2panda_AstNode *(*CreateNumberLiteral3)(es2panda_Context *ctx, float value);
39  *   es2panda_AstNode *(*UpdateNumberLiteral)(es2panda_Context *ctx, es2panda_AstNode *original, int32_t value);
40  *   es2panda_AstNode *(*UpdateNumberLiteral1)(es2panda_Context *ctx, es2panda_AstNode *original, int64_t value);
41  *   es2panda_AstNode *(*UpdateNumberLiteral2)(es2panda_Context *ctx, es2panda_AstNode *original, double value);
42  *   es2panda_AstNode *(*UpdateNumberLiteral3)(es2panda_Context *ctx, es2panda_AstNode *original, float value);
43  *   bool(*NumberLiteralSetInt)(es2panda_AstNode *node, int32_t new_value);
44  *   bool(*NumberLiteralSetLong)(es2panda_AstNode *node, int64_t new_value);
45  *   bool(*NumberLiteralSetDouble)(es2panda_AstNode *node, double new_value);
46  *   bool(*NumberLiteralSetFloat)(es2panda_AstNode *node, float new_value);
47  *   char *(*)(es2panda_Context *, Es2pandaEnum);
48  *   Es2pandaEnum (*)(es2panda_Context *, const char *);
49  *   void(*DestroyContext)(es2panda_Context *context);
50  *   void(*DestroyConfig)(es2panda_Config *config);
51  *   es2panda_Program *(*ContextProgram)(es2panda_Context *context);
52  *   es2panda_Context *(*ProceedToState)(es2panda_Context *context, es2panda_ContextState state);
53  *   es2panda_ExternalSource **(*ProgramExternalSources)(es2panda_Program *program, size_t *len_p)
54  *   char const *(*ExternalSourceName)(es2panda_ExternalSource *e_source)
55  *   es2panda_Program **(*ExternalSourcePrograms)(es2panda_ExternalSource *e_source, size_t *len_p)
56  */
57 
58 namespace {
59 // these FAIL_CODE does not share with other files.
60 constexpr int SOURCE_POSITION_FAIL_CODE = 0x10;
61 constexpr int NUMBER_LITERAL_FAIL_CODE = 0x11;
62 constexpr int ENUM_STRING_CONVERSION_FAIL_CODE = 0x12;
63 constexpr int EXTERNAL_SOURCE_FAIL_CODE = 0x13;
64 
65 es2panda_Impl *g_impl = nullptr;
66 }  // namespace
67 
IsSourcePositionEqual(es2panda_Context * ctx,es2panda_SourcePosition * firstPos,es2panda_SourcePosition * secondPos)68 bool IsSourcePositionEqual(es2panda_Context *ctx, es2panda_SourcePosition *firstPos, es2panda_SourcePosition *secondPos)
69 {
70     if (firstPos == nullptr || secondPos == nullptr) {
71         return false;
72     }
73     if (g_impl->SourcePositionIndex(ctx, firstPos) != g_impl->SourcePositionIndex(ctx, secondPos)) {
74         return false;
75     }
76     if (g_impl->SourcePositionLine(ctx, firstPos) != g_impl->SourcePositionLine(ctx, secondPos)) {
77         return false;
78     }
79 
80     return true;
81 }
82 
CheckSourcePosition(es2panda_Context * ctx)83 bool CheckSourcePosition(es2panda_Context *ctx)
84 {
85     es2panda_SourcePosition *pos = g_impl->CreateSourcePosition(ctx, 3, 5);
86     size_t origPosIndex {3};
87     size_t origPosLine {5};
88     size_t posIndex = g_impl->SourcePositionIndex(ctx, pos);
89     if (posIndex != origPosIndex) {
90         return false;
91     }
92     size_t posLine = g_impl->SourcePositionLine(ctx, pos);
93     if (posLine != origPosLine) {
94         return false;
95     }
96 
97     es2panda_SourcePosition *leftPos = g_impl->CreateSourcePosition(ctx, 4, 1);
98     es2panda_SourcePosition *rightPos = g_impl->CreateSourcePosition(ctx, 4, 5);
99     es2panda_SourceRange *posRange = g_impl->CreateSourceRange(ctx, leftPos, rightPos);
100     if (!IsSourcePositionEqual(ctx, leftPos, g_impl->SourceRangeStart(ctx, posRange))) {
101         return false;
102     }
103     if (!IsSourcePositionEqual(ctx, rightPos, g_impl->SourceRangeEnd(ctx, posRange))) {
104         return false;
105     }
106     return true;
107 }
108 
CheckNumberLiteral(es2panda_Context * ctx)109 bool CheckNumberLiteral(es2panda_Context *ctx)
110 {
111     auto *int32AstNode = g_impl->CreateNumberLiteral(ctx, 0);
112     if (int32AstNode == nullptr) {
113         return false;
114     }
115     auto *int64AstNode = g_impl->CreateNumberLiteral1(ctx, 1);
116     if (int64AstNode == nullptr) {
117         return false;
118     }
119     auto *doubleAstNode = g_impl->CreateNumberLiteral2(ctx, 2.0);
120     if (doubleAstNode == nullptr) {
121         return false;
122     }
123     auto *floatAstNode = g_impl->CreateNumberLiteral3(ctx, 3.0);
124     if (floatAstNode == nullptr) {
125         return false;
126     }
127 
128     auto *updatedInt32AstNode = g_impl->UpdateNumberLiteral(ctx, int32AstNode, 4);
129     if (updatedInt32AstNode == nullptr) {
130         return false;
131     }
132     auto *updatedInt64AstNode = g_impl->UpdateNumberLiteral1(ctx, int64AstNode, 5);
133     if (updatedInt64AstNode == nullptr) {
134         return false;
135     }
136     auto *updatedDoubleAstNode = g_impl->UpdateNumberLiteral2(ctx, doubleAstNode, 6.0);
137     if (updatedDoubleAstNode == nullptr) {
138         return false;
139     }
140     auto *updatedFloatAstNode = g_impl->UpdateNumberLiteral3(ctx, floatAstNode, 7.0);
141     if (updatedFloatAstNode == nullptr) {
142         return false;
143     }
144 
145     bool setInt32Result = g_impl->NumberLiteralSetInt(updatedInt32AstNode, 8);
146     bool setInt64Result = g_impl->NumberLiteralSetLong(updatedInt64AstNode, 9);
147     bool setDoubleResult = g_impl->NumberLiteralSetDouble(updatedDoubleAstNode, 10.0);
148     bool setFloatResult = g_impl->NumberLiteralSetFloat(updatedFloatAstNode, 11.0);
149     return setInt32Result && setInt64Result && setDoubleResult && setFloatResult;
150 }
151 
CheckEnumStringConversion(es2panda_Context * ctx)152 bool CheckEnumStringConversion(es2panda_Context *ctx)
153 {
154     auto enumNodeHasParent =
155         g_impl->Es2pandaEnumFromString(ctx, g_impl->Es2pandaEnumToString(ctx, Es2pandaEnum::ENUM_NODE_HAS_PARENT));
156     if (enumNodeHasParent != Es2pandaEnum::ENUM_NODE_HAS_PARENT) {
157         return false;
158     }
159 
160     auto enumFirst = g_impl->Es2pandaEnumFromString(ctx, g_impl->Es2pandaEnumToString(ctx, Es2pandaEnum::ENUM_FIRST));
161     if (enumFirst != Es2pandaEnum::ENUM_FIRST) {
162         return false;
163     }
164 
165     return true;
166 }
167 
CheckExternalSource(es2panda_Context * ctx)168 bool CheckExternalSource(es2panda_Context *ctx)
169 {
170     auto *program = g_impl->ContextProgram(ctx);
171     g_impl->ProceedToState(ctx, ES2PANDA_STATE_BOUND);
172 
173     size_t externalSourceCnt {0};
174     auto **externalSourceList = g_impl->ProgramExternalSources(ctx, program, &externalSourceCnt);
175     if (externalSourceList == nullptr) {
176         return false;
177     }
178 
179     auto externalSourceName = g_impl->ExternalSourceName(externalSourceList[0]);
180     if (externalSourceName == nullptr) {
181         return false;
182     }
183 
184     size_t externalProgramCount {0};
185     auto **programList = g_impl->ExternalSourcePrograms(externalSourceList[0], &externalProgramCount);
186     if (programList == nullptr) {
187         return false;
188     }
189 
190     return true;
191 }
192 
main(int argc,char ** argv)193 int main(int argc, char **argv)
194 {
195     if (argc < MIN_ARGC) {
196         return INVALID_ARGC_ERROR_CODE;
197     }
198     g_impl = GetImpl();
199     if (g_impl == nullptr) {
200         return NULLPTR_IMPL_ERROR_CODE;
201     }
202     auto config = g_impl->CreateConfig(argc - 1, argv + 1);
203     auto src = std::string("function foo(builder: () => void) {}\nfoo(() => {})");
204     auto context = g_impl->CreateContextFromString(config, src.c_str(), argv[argc - 1]);
205     if (context == nullptr) {
206         std::cerr << "FAILED TO CREATE CONTEXT" << std::endl;
207         return NULLPTR_CONTEXT_ERROR_CODE;
208     }
209 
210     if (!CheckSourcePosition(context)) {
211         return SOURCE_POSITION_FAIL_CODE;
212     }
213 
214     if (!CheckNumberLiteral(context)) {
215         return NUMBER_LITERAL_FAIL_CODE;
216     }
217 
218     if (!CheckEnumStringConversion(context)) {
219         return ENUM_STRING_CONVERSION_FAIL_CODE;
220     }
221 
222     if (!CheckExternalSource(context)) {
223         return EXTERNAL_SOURCE_FAIL_CODE;
224     }
225 
226     g_impl->DestroyContext(context);
227     g_impl->DestroyConfig(config);
228 
229     return 0;
230 }
231 
232 // NOLINTEND