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 <algorithm>
16 #include <cassert>
17 #include <cstddef>
18 #include <cstdint>
19 #include <ctime>
20 #include <iostream>
21 #include <ostream>
22 #include <string>
23 #include <vector>
24
25 #include "get_class_property_info.h"
26 #include "compiler/lowering/util.h"
27 #include "macros.h"
28
29 namespace ark::es2panda::lsp {
30
GeneratePropertyModifiers(const ir::ClassProperty * property)31 std::vector<std::string> GeneratePropertyModifiers(const ir::ClassProperty *property)
32 {
33 std::vector<std::string> modifiers;
34
35 if (property->IsPublic()) {
36 modifiers.emplace_back("public");
37 } else if (property->IsPrivate()) {
38 modifiers.emplace_back("private");
39 } else if (property->IsProtected()) {
40 modifiers.emplace_back("protected");
41 }
42
43 if (property->IsStatic()) {
44 modifiers.emplace_back("static");
45 }
46
47 if (property->IsReadonly()) {
48 modifiers.emplace_back("readonly");
49 }
50
51 return modifiers;
52 }
53
CollectClassProperties(const ir::AstNode * classNode,std::vector<FieldsInfo> & result)54 void CollectClassProperties(const ir::AstNode *classNode, std::vector<FieldsInfo> &result)
55 {
56 if (classNode == nullptr || !classNode->IsClassDeclaration()) {
57 return;
58 }
59
60 FieldsInfo classInfo;
61 classInfo.name = GetIdentifierName(const_cast<ir::AstNode *>(classNode));
62
63 auto classBody = classNode->AsClassDeclaration()->Definition()->Body();
64 for (auto node : classBody) {
65 if (!node->IsClassProperty()) {
66 continue;
67 }
68
69 auto property = node->AsClassProperty();
70 auto modifiers = GeneratePropertyModifiers(property);
71 std::optional<std::vector<std::string>> modifiersOpt(modifiers);
72
73 std::string name = GetIdentifierName(property);
74
75 constexpr auto K_PROPERTY_PREFIX = "<property>";
76 constexpr std::size_t K_PROPERTY_PREFIX_LENGTH = std::char_traits<char>::length(K_PROPERTY_PREFIX);
77 if (name.size() >= K_PROPERTY_PREFIX_LENGTH &&
78 name.compare(0, K_PROPERTY_PREFIX_LENGTH, K_PROPERTY_PREFIX) == 0) {
79 name.erase(0, K_PROPERTY_PREFIX_LENGTH);
80 }
81
82 FieldListProperty propertyInfo("classField", std::move(modifiersOpt), name, property->Start().index,
83 property->End().index);
84
85 classInfo.properties.push_back(propertyInfo);
86 }
87
88 result.push_back(classInfo);
89 }
90
CollectInheritedProperties(const ir::AstNode * classNode,std::vector<FieldsInfo> & result)91 void CollectInheritedProperties(const ir::AstNode *classNode, std::vector<FieldsInfo> &result)
92 {
93 while (classNode != nullptr) {
94 auto superClass = ark::es2panda::lsp::GetEffectiveBaseTypeNode(classNode);
95 if (superClass != nullptr) {
96 CollectClassProperties(superClass, result);
97 }
98 classNode = superClass;
99 }
100 }
101
GetClassPropertyInfo(es2panda_Context * context,size_t pos,bool shouldCollectInherited)102 std::vector<FieldsInfo> GetClassPropertyInfo(es2panda_Context *context, size_t pos, bool shouldCollectInherited)
103 {
104 std::vector<FieldsInfo> result;
105 auto classNode = ark::es2panda::lsp::GetTargetDeclarationNodeByPosition(context, pos);
106 if (classNode == nullptr) {
107 return result;
108 }
109 CollectClassProperties(classNode, result);
110 if (shouldCollectInherited) {
111 CollectInheritedProperties(classNode, result);
112 }
113 return result;
114 }
115 } // namespace ark::es2panda::lsp