• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "tooling/client/manager/source_manager.h"
17 
18 #include "common/log_wrapper.h"
19 #include "tooling/client/session/session.h"
20 
21 using PtJson = panda::ecmascript::tooling::PtJson;
22 using Result = panda::ecmascript::tooling::Result;
23 namespace OHOS::ArkCompiler::Toolchain {
SendRequeSource(int scriptId)24 void SourceManager::SendRequeSource(int scriptId)
25 {
26     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
27     uint32_t id = session->GetMessageId();
28     scriptIdMap_.emplace(std::make_pair(id, scriptId));
29 
30     std::unique_ptr<PtJson> request = PtJson::CreateObject();
31     request->Add("id", id);
32     request->Add("method", "Debugger.getScriptSource");
33 
34     std::unique_ptr<PtJson> params = PtJson::CreateObject();
35     params->Add("scriptId", std::to_string(scriptId).c_str());
36     request->Add("params", params);
37 
38     std::string message = request->Stringify();
39     if (session->ClientSendReq(message)) {
40         session->GetDomainManager().SetDomainById(id, "Debugger");
41     }
42     return;
43 }
44 
EnableReply(const std::unique_ptr<PtJson> json)45 void SourceManager::EnableReply(const std::unique_ptr<PtJson> json)
46 {
47     if (json == nullptr) {
48         LOGE("arkdb: json parse error");
49         return;
50     }
51 
52     if (!json->IsObject()) {
53         LOGE("arkdb: json parse format error");
54         json->ReleaseRoot();
55         return;
56     }
57 
58     std::unique_ptr<PtJson> params;
59     Result ret = json->GetObject("params", &params);
60     if (ret != Result::SUCCESS) {
61         LOGE("arkdb: find params error");
62         return;
63     }
64 
65     std::string scriptIdStr;
66     ret = params->GetString("scriptId", &scriptIdStr);
67     if (ret != Result::SUCCESS) {
68         LOGE("arkdb: find scriptId error");
69         return;
70     }
71 
72     std::string fileName;
73     ret = params->GetString("url", &fileName);
74     if (ret != Result::SUCCESS) {
75         LOGE("arkdb: find fileName error");
76         return;
77     }
78     int scriptId = std::atoi(scriptIdStr.c_str());
79     SetFileName(scriptId, fileName);
80     SendRequeSource(scriptId);
81     return;
82 }
83 
SetFileName(int scriptId,const std::string & fileName)84 void SourceManager::SetFileName(int scriptId, const std::string& fileName)
85 {
86     fileSource_.insert(std::make_pair(scriptId, std::make_pair(fileName, std::vector<std::string> {})));
87     return;
88 }
89 
GetFileName()90 void SourceManager::GetFileName()
91 {
92     for (auto it = fileSource_.begin(); it != fileSource_.end(); it++) {
93         std::cout << "scriptID : " << it->first;
94         std::cout << " fileName : " << it->second.first <<std::endl;
95     }
96     return;
97 }
98 
SetFileSource(int scriptIdIndex,const std::string & fileSource)99 void SourceManager::SetFileSource(int scriptIdIndex, const std::string& fileSource)
100 {
101     const int IGNOR_NEWLINE_FLAG = 2;
102     auto scriptIdIt = scriptIdMap_.find(scriptIdIndex);
103     if (scriptIdIt == scriptIdMap_.end()) {
104         return;
105     }
106     int scriptId = scriptIdIt->second;
107 
108     auto it = fileSource_.find(scriptId);
109     if (it != fileSource_.end() && it->second.second.empty()) {
110         std::string::size_type startPos = 0;
111         std::string::size_type endPos = fileSource.find("\r\n");
112         while (endPos != std::string::npos) {
113             std::string line = fileSource.substr(startPos, endPos - startPos);
114             it->second.second.push_back(line);
115             startPos = endPos + IGNOR_NEWLINE_FLAG;  // ignore "\r\n"
116             endPos = fileSource.find("\r\n", startPos);
117         }
118         it->second.second.push_back(fileSource.substr(startPos));
119     }
120     return;
121 }
122 
GetFileSource(int scriptId)123 std::vector<std::string> SourceManager::GetFileSource(int scriptId)
124 {
125     int linNum = 0;
126     auto it = fileSource_.find(scriptId);
127     if (it != fileSource_.end()) {
128         std::cout << "fileSource : " <<std::endl;
129         for (const std::string& value : it->second.second) {
130             std::cout << ++linNum << "    " << value << std::endl;
131         }
132         return it->second.second;
133     }
134     return std::vector<std::string> {};
135 }
136 
GetDebugSources(const std::unique_ptr<PtJson> json)137 void SourceManager::GetDebugSources(const std::unique_ptr<PtJson> json)
138 {
139     std::string funcName;
140     Result ret = json->GetString("functionName", &funcName);
141     if (ret != Result::SUCCESS) {
142         LOGE("arkdb: get functionName error");
143         return;
144     }
145 
146     std::unique_ptr<PtJson> location;
147     ret = json->GetObject("location", &location);
148     if (ret != Result::SUCCESS) {
149         LOGE("arkdb: get location error");
150         return;
151     }
152 
153     std::string scriptIdStr;
154     ret = location->GetString("scriptId", &scriptIdStr);
155     if (ret != Result::SUCCESS) {
156         LOGE("arkdb: get scriptId error");
157         return;
158     }
159     scriptId_ = std::atoi(scriptIdStr.c_str());
160 
161     ret = location->GetInt("lineNumber", &debugLineNum_);
162     if (ret != Result::SUCCESS) {
163         LOGE("arkdb: get lineNumber error");
164         return;
165     }
166 
167     LOGE("arkdb: callFrames : funcName %{public}s, scriptid %{public}s, lineNum %{public}d",
168         funcName.c_str(), scriptIdStr.c_str(), debugLineNum_);
169     auto it = fileSource_.find(scriptId_);
170     if (it != fileSource_.end()) {
171         std::cout << (debugLineNum_ + 1) << "    " << it->second.second[debugLineNum_] << std::endl;
172         std::cout << ">>> ";
173         fflush(stdout);
174     }
175     return;
176 }
177 
ListSourceCodeWithParameters(int startLine,int endLine)178 void SourceManager::ListSourceCodeWithParameters(int startLine, int endLine)
179 {
180     const int BLANK_LINE = std::numeric_limits<int>::max();
181     const int STATR_LINE_OFFSET = 6;
182     const int END_LINE_OFFSET = 4;
183     const int END_LINE = 10;
184     if (startLine != BLANK_LINE && endLine == BLANK_LINE) {
185         auto it = fileSource_.find(scriptId_);
186         if (it == fileSource_.end()) {
187             LOGE("arkdb: get file source error");
188             return;
189         }
190         if (startLine >= static_cast<int>(it->second.second.size()) + STATR_LINE_OFFSET ||
191             startLine < 0) {
192             std::cout << "Line number out of range, this file has " <<
193             static_cast<int>(it->second.second.size()) << " lines" << std::endl;
194             return;
195         }
196         int showLine = startLine - STATR_LINE_OFFSET;
197         if (showLine < 0) {
198             showLine = 0;
199             endLine = END_LINE;
200         } else {
201             endLine = startLine + END_LINE_OFFSET;
202         }
203         if (endLine > static_cast<int>(it->second.second.size())) {
204             endLine = static_cast<int>(it->second.second.size());
205         }
206         for (; showLine < endLine; showLine++) {
207             std::cout << (showLine + 1) << "    " << it->second.second[showLine] << std::endl;
208         }
209     } else if (startLine != BLANK_LINE && endLine != BLANK_LINE) {
210         auto it = fileSource_.find(scriptId_);
211         if (it == fileSource_.end()) {
212             LOGE("arkdb: get file source error");
213             return;
214         }
215         if (startLine > static_cast<int>(it->second.second.size()) ||
216             endLine > static_cast<int>(it->second.second.size()) || startLine < 1) {
217             std::cout << "Line number out of range, this file has " <<
218             static_cast<int>(it->second.second.size()) << " lines" << std::endl;
219             return;
220         }
221         if (endLine > static_cast<int>(it->second.second.size())) {
222             endLine = static_cast<int>(it->second.second.size());
223         }
224         for (int showLine = startLine - 1; showLine < endLine; showLine++) {
225             std::cout << (showLine + 1) << "    " << it->second.second[showLine] << std::endl;
226         }
227     }
228 }
229 
ListSource(int startLine,int endLine)230 void SourceManager::ListSource(int startLine, int endLine)
231 {
232     const int BLANK_LINE = std::numeric_limits<int>::max();
233     const int STATR_LINE_OFFSET = 6;
234     const int END_LINE_OFFSET = 4;
235     const int END_LINE = 10;
236     if (startLine == BLANK_LINE && endLine == BLANK_LINE) {
237         auto it = fileSource_.find(scriptId_);
238         if (it == fileSource_.end()) {
239             LOGE("arkdb: get file source error");
240             return;
241         }
242         int showLine = (debugLineNum_ + 1) - STATR_LINE_OFFSET;
243         if (showLine < 0) {
244             showLine = 0;
245             endLine = END_LINE;
246         } else {
247             endLine = debugLineNum_ + END_LINE_OFFSET;
248         }
249         if (endLine > static_cast<int>(it->second.second.size())) {
250             endLine = static_cast<int>(it->second.second.size());
251         }
252         for (; showLine <= endLine; showLine++) {
253             std::cout << (showLine + 1) << "    " << it->second.second[showLine] << std::endl;
254         }
255     } else {
256         ListSourceCodeWithParameters(startLine, endLine);
257     }
258 }
259 
GetListSource(std::string startLine,std::string endLine)260 void SourceManager::GetListSource(std::string startLine, std::string endLine)
261 {
262     const int BLANK_LINE = std::numeric_limits<int>::max();
263     int startline = startLine.empty() ? BLANK_LINE : std::stoi(startLine);
264     int endline = endLine.empty() ? BLANK_LINE : std::stoi(endLine);
265     ListSource(startline, endline);
266     return;
267 }
268 }