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
16 #include <string>
17 #include <vector>
18 #include <utility>
19
20 #include "os/library_loader.h"
21
22 #include "public/es2panda_lib.h"
23 #include "util.h"
24
25 // NOLINTBEGIN
26
27 static es2panda_Impl *impl = nullptr;
28
29 static constexpr size_t START_INDEX = 101;
30 static constexpr size_t START_LINE = 4;
31 static constexpr size_t END_INDEX = 110;
32 static constexpr size_t END_LINE = 4;
33
34 static std::string source = R"(
35 @interface Component {}
36
37 // expected annotationUsage location: start: 'C', end: 't' of @Component.
38 @Component
39 class A {
40 name: string = "Tom";
41 }
42 )";
43
44 static std::vector<es2panda_AstNode *> classDeclarations;
45
CollectDeclarations(es2panda_AstNode * node)46 static void CollectDeclarations(es2panda_AstNode *node)
47 {
48 if (impl->IsClassDeclaration(node)) {
49 classDeclarations.push_back(node);
50 }
51 }
52
GetAnnotationUsage(es2panda_Context * context,es2panda_AstNode * classDecl)53 static es2panda_AstNode *GetAnnotationUsage(es2panda_Context *context, es2panda_AstNode *classDecl)
54 {
55 size_t n;
56 auto *classDef = impl->ClassDeclarationDefinition(context, classDecl);
57 auto **annotations = impl->ClassDefinitionAnnotations(context, classDef, &n);
58 if (n != 1) {
59 return nullptr;
60 }
61 return impl->AnnotationUsageIrExpr(context, annotations[0]);
62 }
63
ValidateAnnotationSourceRange(es2panda_Context * context)64 static bool ValidateAnnotationSourceRange(es2panda_Context *context)
65 {
66 auto *classDel = classDeclarations.front();
67 auto *annotationUsage = GetAnnotationUsage(context, classDel);
68 auto range = impl->AstNodeRangeConst(context, annotationUsage);
69 auto start = impl->SourceRangeStart(context, const_cast<es2panda_SourceRange *>(range));
70 auto end = impl->SourceRangeEnd(context, const_cast<es2panda_SourceRange *>(range));
71 if (start == nullptr || end == nullptr) {
72 return false;
73 }
74 if (START_INDEX != impl->SourcePositionIndex(context, start) ||
75 START_LINE != impl->SourcePositionLine(context, start) ||
76 END_INDEX != impl->SourcePositionIndex(context, end) || END_LINE != impl->SourcePositionLine(context, end)) {
77 return false;
78 }
79 return true;
80 }
81
main(int argc,char ** argv)82 int main(int argc, char **argv)
83 {
84 if (argc < MIN_ARGC) {
85 return INVALID_ARGC_ERROR_CODE;
86 }
87
88 impl = GetImpl();
89 if (impl == nullptr) {
90 return NULLPTR_IMPL_ERROR_CODE;
91 }
92 auto config = impl->CreateConfig(argc - 1, argv + 1);
93 auto context = impl->CreateContextFromString(config, source.data(), argv[argc - 1]);
94 if (context == nullptr) {
95 std::cerr << "FAILED TO CREATE CONTEXT" << std::endl;
96 return NULLPTR_CONTEXT_ERROR_CODE;
97 }
98
99 impl->ProceedToState(context, ES2PANDA_STATE_PARSED);
100
101 auto *ast = impl->ProgramAst(context, impl->ContextProgram(context));
102 impl->AstNodeIterateConst(context, ast, CollectDeclarations);
103
104 if (!ValidateAnnotationSourceRange(context)) {
105 impl->DestroyContext(context);
106 impl->DestroyConfig(config);
107 return PROCEED_ERROR_CODE;
108 }
109
110 impl->ProceedToState(context, ES2PANDA_STATE_CHECKED);
111 if (impl->ContextState(context) == ES2PANDA_STATE_ERROR) {
112 return PROCEED_ERROR_CODE;
113 }
114
115 impl->AstNodeRecheck(context, ast);
116
117 impl->ProceedToState(context, ES2PANDA_STATE_BIN_GENERATED);
118 if (impl->ContextState(context) == ES2PANDA_STATE_ERROR) {
119 return PROCEED_ERROR_CODE;
120 }
121
122 impl->DestroyContext(context);
123 impl->DestroyConfig(config);
124
125 return 0;
126 }
127
128 // NOLINTEND