• 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 
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