1 /*
2 * Copyright (c) 2024-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 <gtest/gtest.h>
16 #include <string>
17 #include <utility>
18 #include <vector>
19 #include "assembly-program.h"
20 #include "test/unit/annotations/annotations_emit_test.h"
21
22 namespace ark::es2panda::compiler::test {
23
24 class MutipleAnnotationsforFunction : public AnnotationEmitTest {
25 public:
26 MutipleAnnotationsforFunction() = default;
27
28 ~MutipleAnnotationsforFunction() override = default;
29
RunAnnotationEmitTest(const std::string_view text)30 void RunAnnotationEmitTest(const std::string_view text)
31 {
32 auto program = GetCurrentProgram(text);
33 ASSERT_NE(program, nullptr);
34
35 CheckAnnotations(program.get());
36 CheckFunctionAnnotations(program.get());
37 CheckLiteralArrayTable(program.get());
38 }
39
CheckAnnotations(pandasm::Program * program)40 void CheckAnnotations(pandasm::Program *program)
41 {
42 const std::string annoName0 = "Anno1";
43 const std::vector<std::pair<std::string, std::string>> expectedAnnotation0 = {
44 {
45 {"param", "1"},
46 },
47 };
48 AnnotationEmitTest::CheckAnnoDecl(program, annoName0, expectedAnnotation0);
49
50 const std::string annoName1 = "Anno2";
51 const std::vector<std::pair<std::string, std::string>> expectedAnnotation1 = {
52 {
53 {"param", "ETSGLOBAL$Anno2$param$0"},
54 },
55 };
56 AnnotationEmitTest::CheckAnnoDecl(program, annoName1, expectedAnnotation1);
57
58 const std::string annoName2 = "Anno3";
59 const std::vector<std::pair<std::string, std::string>> expectedAnnotation2 = {
60 {
61 {"param", "ETSGLOBAL$Anno3$param$10"},
62 },
63 };
64 AnnotationEmitTest::CheckAnnoDecl(program, annoName2, expectedAnnotation2);
65 }
66
CheckFunctionAnnotations(pandasm::Program * program)67 void CheckFunctionAnnotations(pandasm::Program *program)
68 {
69 const std::string functionName1 = "ETSGLOBAL.foo:void;";
70 const std::string functionName2 = "ETSGLOBAL.foo1:void;";
71 const AnnotationMap expectedFuncAnnotations1 = {{"Anno1",
72 {
73 {"value", "2"},
74 }},
75 {"Anno2",
76 {
77 {"value", "ETSGLOBAL.foo:void;$Anno2$value$11"},
78 }},
79 {"Anno3",
80 {
81 {"param", "ETSGLOBAL.foo:void;$Anno3$param$21"},
82 }}};
83 const AnnotationMap expectedFuncAnnotations2 = {{"Anno1",
84 {
85 {"value", "2"},
86 }}};
87 AnnotationEmitTest::CheckFunctionAnnotations(program, functionName1, true, expectedFuncAnnotations1);
88 AnnotationEmitTest::CheckFunctionAnnotations(program, functionName2, true, expectedFuncAnnotations2);
89 }
90
CheckLiteralArrayTable(pandasm::Program * program)91 void CheckLiteralArrayTable(pandasm::Program *program)
92 {
93 std::vector<std::pair<std::string, std::vector<AnnotationValueType>>> expectedLiteralArrayTable = {
94 {"ETSGLOBAL$Anno2$param$0", std::vector<AnnotationValueType> {VALUE_1, VALUE_2, VALUE_3, VALUE_4}},
95 {"ETSGLOBAL$Anno3$param$1", std::vector<AnnotationValueType> {VALUE_1}},
96 {"ETSGLOBAL$Anno3$param$2", std::vector<AnnotationValueType> {VALUE_2}},
97 {"ETSGLOBAL$Anno3$param$3", std::vector<AnnotationValueType> {std::string("ETSGLOBAL$Anno3$param$1"),
98 std::string("ETSGLOBAL$Anno3$param$2")}},
99 {"ETSGLOBAL$Anno3$param$4", std::vector<AnnotationValueType> {VALUE_2}},
100 {"ETSGLOBAL$Anno3$param$5", std::vector<AnnotationValueType> {VALUE_3}},
101 {"ETSGLOBAL$Anno3$param$6", std::vector<AnnotationValueType> {std::string("ETSGLOBAL$Anno3$param$4"),
102 std::string("ETSGLOBAL$Anno3$param$5")}},
103 {"ETSGLOBAL$Anno3$param$7", std::vector<AnnotationValueType> {VALUE_3}},
104 {"ETSGLOBAL$Anno3$param$8", std::vector<AnnotationValueType> {VALUE_4}},
105 {"ETSGLOBAL$Anno3$param$9", std::vector<AnnotationValueType> {std::string("ETSGLOBAL$Anno3$param$7"),
106 std::string("ETSGLOBAL$Anno3$param$8")}},
107 {"ETSGLOBAL$Anno3$param$10", std::vector<AnnotationValueType> {std::string("ETSGLOBAL$Anno3$param$3"),
108 std::string("ETSGLOBAL$Anno3$param$6"),
109 std::string("ETSGLOBAL$Anno3$param$9")}},
110 {"ETSGLOBAL.foo:void;$Anno2$value$11",
111 std::vector<AnnotationValueType> {VALUE_4, VALUE_5, VALUE_6, VALUE_7}},
112 {"ETSGLOBAL.foo:void;$Anno3$param$12", std::vector<AnnotationValueType> {VALUE_1}},
113 {"ETSGLOBAL.foo:void;$Anno3$param$13", std::vector<AnnotationValueType> {VALUE_2}},
114 {"ETSGLOBAL.foo:void;$Anno3$param$14",
115 std::vector<AnnotationValueType> {std::string("ETSGLOBAL.foo:void;$Anno3$param$12"),
116 std::string("ETSGLOBAL.foo:void;$Anno3$param$13")}},
117 {"ETSGLOBAL.foo:void;$Anno3$param$15", std::vector<AnnotationValueType> {VALUE_2}},
118 {"ETSGLOBAL.foo:void;$Anno3$param$16", std::vector<AnnotationValueType> {VALUE_3}},
119 {"ETSGLOBAL.foo:void;$Anno3$param$17",
120 std::vector<AnnotationValueType> {std::string("ETSGLOBAL.foo:void;$Anno3$param$15"),
121 std::string("ETSGLOBAL.foo:void;$Anno3$param$16")}},
122 {"ETSGLOBAL.foo:void;$Anno3$param$18", std::vector<AnnotationValueType> {VALUE_3}},
123 {"ETSGLOBAL.foo:void;$Anno3$param$19", std::vector<AnnotationValueType> {VALUE_4}},
124 {"ETSGLOBAL.foo:void;$Anno3$param$20",
125 std::vector<AnnotationValueType> {std::string("ETSGLOBAL.foo:void;$Anno3$param$18"),
126 std::string("ETSGLOBAL.foo:void;$Anno3$param$19")}},
127 {"ETSGLOBAL.foo:void;$Anno3$param$21",
128 std::vector<AnnotationValueType> {std::string("ETSGLOBAL.foo:void;$Anno3$param$14"),
129 std::string("ETSGLOBAL.foo:void;$Anno3$param$17"),
130 std::string("ETSGLOBAL.foo:void;$Anno3$param$20")}},
131 };
132
133 AnnotationEmitTest::CheckLiteralArrayTable(program, expectedLiteralArrayTable);
134 }
135
136 private:
137 NO_COPY_SEMANTIC(MutipleAnnotationsforFunction);
138 NO_MOVE_SEMANTIC(MutipleAnnotationsforFunction);
139 };
140
TEST_F(MutipleAnnotationsforFunction,mutiple_annotations_for_function)141 TEST_F(MutipleAnnotationsforFunction, mutiple_annotations_for_function)
142 {
143 std::string_view text = R"(
144 @interface Anno1 {
145 param: int = 1
146 }
147
148 @interface Anno2 {
149 param: int[] = [1, 2, 3, 4]
150 }
151
152 @interface Anno3 {
153 param: int[][][] = [[[1], [2]], [[2], [3]], [[3], [4]]]
154 }
155
156 @Anno1(2)
157 @Anno2([4, 5, 6, 7])
158 @Anno3
159 function foo() {}
160 @Anno1(2)
161 native function foo1(): void
162 )";
163
164 RunAnnotationEmitTest(text);
165 }
166
167 } // namespace ark::es2panda::compiler::test