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