Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qv4debugservice.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qv4debugservice.h"
5#include "qv4debugjob.h"
6#include "qqmlengine.h"
7
8#include <private/qv4engine_p.h>
9#include <private/qv4function_p.h>
10#include <private/qqmldebugconnector_p.h>
11#include <private/qversionedpacket_p.h>
12
13#include <QtCore/QJsonArray>
14#include <QtCore/QJsonDocument>
15#include <QtCore/QJsonObject>
16#include <QtCore/QJsonValue>
17
18const char *const V4_CONNECT = "connect";
19const char *const V4_DISCONNECT = "disconnect";
20const char *const V4_BREAK_ON_SIGNAL = "breakonsignal";
21const char *const V4_PAUSE = "interrupt";
22
23#define NO_PROTOCOL_TRACING
24#ifdef NO_PROTOCOL_TRACING
25# define TRACE_PROTOCOL(x)
26#else
27#include <QtCore/QDebug>
28# define TRACE_PROTOCOL(x) x
29#endif
30
32
35
36using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
37
38int QV4DebugServiceImpl::sequence = 0;
39
41{
42public:
46
48 {}
49
50 QString command() const { return cmd; }
51
53 {
54 TRACE_PROTOCOL(qDebug() << "handling command" << command() << "...");
55
56 req = request;
57 seq = req.value(QLatin1String("seq"));
59
61 if (!response.isEmpty()) {
62 response[QLatin1String("type")] = QStringLiteral("response");
64 }
65
66 debugService = nullptr;
67 seq = QJsonValue();
68 req = QJsonObject();
70 }
71
72 virtual void handleRequest() = 0;
73
74protected:
75 void addCommand() { response.insert(QStringLiteral("command"), cmd); }
77 void addSuccess(bool success) { response.insert(QStringLiteral("success"), success); }
78 void addBody(const QJsonValue &body)
79 {
80 response.insert(QStringLiteral("body"), body);
81 }
82
87
89 {
93 addSuccess(false);
94 addRunning();
95 response.insert(QStringLiteral("message"), msg);
96 }
97
99 { return seq.toInt(-1); }
100
101protected:
107};
108
110{
111public:
113
114 void handleRequest() override
115 {
116 QString msg = QLatin1String("unimplemented command \"")
117 + req.value(QLatin1String("command")).toString()
118 + QLatin1Char('"');
120 }
121};
122
123namespace {
124class V4VersionRequest: public V4CommandHandler
125{
126public:
127 V4VersionRequest(): V4CommandHandler(QStringLiteral("version")) {}
128
129 void handleRequest() override
130 {
131 addCommand();
132 addRequestSequence();
133 addSuccess(true);
134 addRunning();
135 QJsonObject body;
136 body.insert(QStringLiteral("V8Version"),
137 QLatin1String("this is not V8, this is V4 in Qt " QT_VERSION_STR));
138 body.insert(QStringLiteral("UnpausedEvaluate"), true);
139 body.insert(QStringLiteral("ContextEvaluate"), true);
140 body.insert(QStringLiteral("ChangeBreakpoint"), true);
141 addBody(body);
142 }
143};
144
145class V4BreakPointRequest: public V4CommandHandler
146{
147public:
148 V4BreakPointRequest(const QString &name): V4CommandHandler(name) {}
149
150 void handleRequest() final
151 {
152 // Other types are currently not supported
153 m_type = QStringLiteral("scriptRegExp");
154
155 // decypher the payload:
156 m_args = req.value(QLatin1String("arguments")).toObject();
157 if (m_args.isEmpty()) {
158 createErrorResponse(QStringLiteral("breakpoint request with empty arguments object"));
159 return;
160 }
161
162 const int id = handleBreakPointRequest();
163 if (id < 0) {
164 createErrorResponse(m_error);
165 } else {
166 // response:
167 addCommand();
168 addRequestSequence();
169 addSuccess(true);
170 addRunning();
171 QJsonObject body;
172 body.insert(QStringLiteral("type"), m_type);
173 body.insert(QStringLiteral("breakpoint"), id);
174 addBody(body);
175 }
176 }
177
178protected:
179 virtual int handleBreakPointRequest() = 0;
180
181 QJsonObject m_args;
182 QString m_type;
183 QString m_error;
184};
185
186class V4SetBreakPointRequest: public V4BreakPointRequest
187{
188public:
189 V4SetBreakPointRequest(): V4BreakPointRequest(QStringLiteral("setbreakpoint")) {}
190
191 int handleBreakPointRequest() final
192 {
193 // decypher the payload:
194 const QString type = m_args.value(QLatin1String("type")).toString();
195 if (type != QLatin1String("scriptRegExp")) {
196 m_error = QStringLiteral("breakpoint type \"%1\" is not implemented").arg(type);
197 return -1;
198 }
199
200 const QString fileName = m_args.value(QLatin1String("target")).toString();
201 if (fileName.isEmpty()) {
202 m_error = QStringLiteral("breakpoint has no file name");
203 return -1;
204 }
205
206
207 const int line = m_args.value(QLatin1String("line")).toInt(-1);
208 if (line < 0) {
209 m_error = QStringLiteral("breakpoint has an invalid line number");
210 return -1;
211 }
212
213 const bool enabled = m_args.value(QStringLiteral("enabled")).toBool(true);
214 const QString condition = m_args.value(QStringLiteral("condition")).toString();
215
216 // set the break point:
217 return debugService->debuggerAgent.addBreakPoint(fileName, line + 1, enabled, condition);
218
219 // It's undocumented, but V8 sends back an actual_locations array too. However, our
220 // Debugger currently doesn't tell us when it resolved a breakpoint, so we'll leave them
221 // pending until the breakpoint is hit for the first time.
222 }
223};
224
225class V4ClearBreakPointRequest: public V4BreakPointRequest
226{
227public:
228 V4ClearBreakPointRequest(): V4BreakPointRequest(QStringLiteral("clearbreakpoint")) {}
229
230 int handleBreakPointRequest() final
231 {
232 const int id = m_args.value(QLatin1String("breakpoint")).toInt(-1);
233 if (id < 0)
234 m_error = QStringLiteral("breakpoint has an invalid number");
235 else // remove the break point:
236 debugService->debuggerAgent.removeBreakPoint(id);
237
238 return id;
239 }
240};
241
242class V4ChangeBreakPointRequest: public V4BreakPointRequest
243{
244public:
245 V4ChangeBreakPointRequest(): V4BreakPointRequest(QStringLiteral("changebreakpoint")) {}
246
247 int handleBreakPointRequest() final
248 {
249 const int id = m_args.value(QLatin1String("breakpoint")).toInt(-1);
250 if (id < 0) {
251 m_error = QStringLiteral("breakpoint has an invalid number");
252 return id;
253 }
254
255 const QJsonValue enabled = m_args.value(QLatin1String("enabled"));
256 if (!enabled.isBool()) {
257 m_error = QStringLiteral("missing bool \"enabled\" in breakpoint change request");
258 return -1;
259 }
260
261 // enable or disable the break point:
262 debugService->debuggerAgent.enableBreakPoint(id, enabled.toBool());
263 return id;
264 }
265};
266
267class V4BacktraceRequest: public V4CommandHandler
268{
269public:
270 V4BacktraceRequest(): V4CommandHandler(QStringLiteral("backtrace")) {}
271
272 void handleRequest() override
273 {
274 // decypher the payload:
275
276 QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
277 int fromFrame = arguments.value(QLatin1String("fromFrame")).toInt(0);
278 int toFrame = arguments.value(QLatin1String("toFrame")).toInt(fromFrame + 10);
279 // no idea what the bottom property is for, so we'll ignore it.
280
281 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
282 if (!debugger) {
283 createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve backtraces."));
284 return;
285 }
286
287 BacktraceJob job(debugger->collector(), fromFrame, toFrame);
288 debugger->runInEngine(&job);
289
290 // response:
291 addCommand();
292 addRequestSequence();
293 addSuccess(true);
294 addRunning();
295 addBody(job.returnValue());
296 }
297};
298
299class V4FrameRequest: public V4CommandHandler
300{
301public:
302 V4FrameRequest(): V4CommandHandler(QStringLiteral("frame")) {}
303
304 void handleRequest() override
305 {
306 // decypher the payload:
307 QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
308 const int frameNr = arguments.value(QLatin1String("number")).toInt(
309 debugService->selectedFrame());
310
311 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
312 if (!debugger) {
313 createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve frames."));
314 return;
315 }
316
317 if (frameNr < 0) {
318 createErrorResponse(QStringLiteral("frame command has invalid frame number"));
319 return;
320 }
321
322 FrameJob job(debugger->collector(), frameNr);
323 debugger->runInEngine(&job);
324 if (!job.wasSuccessful()) {
325 createErrorResponse(QStringLiteral("frame retrieval failed"));
326 return;
327 }
328
329 debugService->selectFrame(frameNr);
330
331 // response:
332 addCommand();
333 addRequestSequence();
334 addSuccess(true);
335 addRunning();
336 addBody(job.returnValue());
337 }
338};
339
340class V4ScopeRequest: public V4CommandHandler
341{
342public:
343 V4ScopeRequest(): V4CommandHandler(QStringLiteral("scope")) {}
344
345 void handleRequest() override
346 {
347 // decypher the payload:
348 QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
349 const int frameNr = arguments.value(QLatin1String("frameNumber")).toInt(
350 debugService->selectedFrame());
351 const int scopeNr = arguments.value(QLatin1String("number")).toInt(0);
352
353 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
354 if (!debugger) {
355 createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve scope."));
356 return;
357 }
358
359 if (frameNr < 0) {
360 createErrorResponse(QStringLiteral("scope command has invalid frame number"));
361 return;
362 }
363 if (scopeNr < 0) {
364 createErrorResponse(QStringLiteral("scope command has invalid scope number"));
365 return;
366 }
367
368 ScopeJob job(debugger->collector(), frameNr, scopeNr);
369 debugger->runInEngine(&job);
370 if (!job.wasSuccessful()) {
371 createErrorResponse(QStringLiteral("scope retrieval failed"));
372 return;
373 }
374
375 // response:
376 addCommand();
377 addRequestSequence();
378 addSuccess(true);
379 addRunning();
380 addBody(job.returnValue());
381 }
382};
383
384class V4LookupRequest: public V4CommandHandler
385{
386public:
387 V4LookupRequest(): V4CommandHandler(QStringLiteral("lookup")) {}
388
389 void handleRequest() override
390 {
391 // decypher the payload:
392 QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
393 QJsonArray handles = arguments.value(QLatin1String("handles")).toArray();
394
395 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
396 if (!debugger) {
397 const QList<QV4Debugger *> &debuggers = debugService->debuggerAgent.debuggers();
398 if (debuggers.size() > 1) {
399 createErrorResponse(QStringLiteral("Cannot lookup values if multiple debuggers are running and none is paused"));
400 return;
401 } else if (debuggers.size() == 0) {
402 createErrorResponse(QStringLiteral("No debuggers available to lookup values"));
403 return;
404 }
405 debugger = debuggers.first();
406 }
407
408 ValueLookupJob job(handles, debugger->collector());
409 debugger->runInEngine(&job);
410 if (!job.exceptionMessage().isEmpty()) {
411 createErrorResponse(job.exceptionMessage());
412 } else {
413 // response:
414 addCommand();
415 addRequestSequence();
416 addSuccess(true);
417 addRunning();
418 addBody(job.returnValue());
419 }
420 }
421};
422
423class V4ContinueRequest: public V4CommandHandler
424{
425public:
426 V4ContinueRequest(): V4CommandHandler(QStringLiteral("continue")) {}
427
428 void handleRequest() override
429 {
430 // decypher the payload:
431 QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
432
433 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
434 if (!debugger) {
435 createErrorResponse(QStringLiteral("Debugger has to be paused in order to continue."));
436 return;
437 }
438 debugService->debuggerAgent.clearAllPauseRequests();
439
440 if (arguments.empty()) {
442 } else {
443 QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
444 QString stepAction = arguments.value(QLatin1String("stepaction")).toString();
445 const int stepcount = arguments.value(QLatin1String("stepcount")).toInt(1);
446 if (stepcount != 1)
447 qWarning() << "Step count other than 1 is not supported.";
448
449 if (stepAction == QLatin1String("in")) {
450 debugger->resume(QV4Debugger::StepIn);
451 } else if (stepAction == QLatin1String("out")) {
452 debugger->resume(QV4Debugger::StepOut);
453 } else if (stepAction == QLatin1String("next")) {
454 debugger->resume(QV4Debugger::StepOver);
455 } else {
456 createErrorResponse(QStringLiteral("continue command has invalid stepaction"));
457 return;
458 }
459 }
460
461 // response:
462 addCommand();
463 addRequestSequence();
464 addSuccess(true);
465 addRunning();
466 }
467};
468
469class V4DisconnectRequest: public V4CommandHandler
470{
471public:
472 V4DisconnectRequest(): V4CommandHandler(QStringLiteral("disconnect")) {}
473
474 void handleRequest() override
475 {
476 debugService->debuggerAgent.removeAllBreakPoints();
477 debugService->debuggerAgent.resumeAll();
478
479 // response:
480 addCommand();
481 addRequestSequence();
482 addSuccess(true);
483 addRunning();
484 }
485};
486
487class V4SetExceptionBreakRequest: public V4CommandHandler
488{
489public:
490 V4SetExceptionBreakRequest(): V4CommandHandler(QStringLiteral("setexceptionbreak")) {}
491
492 void handleRequest() override
493 {
494 bool wasEnabled = debugService->debuggerAgent.breakOnThrow();
495
496 //decypher the payload:
497 QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
499 bool enabled = arguments.value(QLatin1String("number")).toBool(!wasEnabled);
500
501 if (type == QLatin1String("all")) {
502 // that's fine
503 } else if (type == QLatin1String("uncaught")) {
504 createErrorResponse(QStringLiteral("breaking only on uncaught exceptions is not supported yet"));
505 return;
506 } else {
507 createErrorResponse(QStringLiteral("invalid type for break on exception"));
508 return;
509 }
510
511 // do it:
512 debugService->debuggerAgent.setBreakOnThrow(enabled);
513
514 QJsonObject body;
515 body[QLatin1String("type")] = type;
516 body[QLatin1String("enabled")] = debugService->debuggerAgent.breakOnThrow();
517
518 // response:
519 addBody(body);
520 addRunning();
521 addSuccess(true);
522 addRequestSequence();
523 addCommand();
524 }
525};
526
527class V4ScriptsRequest: public V4CommandHandler
528{
529public:
530 V4ScriptsRequest(): V4CommandHandler(QStringLiteral("scripts")) {}
531
532 void handleRequest() override
533 {
534 //decypher the payload:
535 QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
536 int types = arguments.value(QLatin1String("types")).toInt(-1);
537 if (types < 0 || types > 7) {
538 createErrorResponse(QStringLiteral("invalid types value in scripts command"));
539 return;
540 } else if (types != 4) {
541 createErrorResponse(QStringLiteral("unsupported types value in scripts command"));
542 return;
543 }
544
545 // do it:
546 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
547 if (!debugger) {
548 createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve scripts."));
549 return;
550 }
551
552 GatherSourcesJob job(debugger->engine());
553 debugger->runInEngine(&job);
554
555 QJsonArray body;
556 for (const QString &source : job.result()) {
558 src[QLatin1String("name")] = source;
559 src[QLatin1String("scriptType")] = 4;
560 body.append(src);
561 }
562
563 addSuccess(true);
564 addRunning();
565 addBody(body);
566 addCommand();
567 addRequestSequence();
568 }
569};
570
571// Request:
572// {
573// "seq": 4,
574// "type": "request",
575// "command": "evaluate",
576// "arguments": {
577// "expression": "a",
578// "frame": 0
579// }
580// }
581//
582// Response:
583// {
584// "body": {
585// "handle": 3,
586// "type": "number",
587// "value": 1
588// },
589// "command": "evaluate",
590// "refs": [],
591// "request_seq": 4,
592// "running": false,
593// "seq": 5,
594// "success": true,
595// "type": "response"
596// }
597//
598// The "value" key in "body" is the result of evaluating the expression in the request.
599class V4EvaluateRequest: public V4CommandHandler
600{
601public:
602 V4EvaluateRequest(): V4CommandHandler(QStringLiteral("evaluate")) {}
603
604 void handleRequest() override
605 {
606 QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
607 QString expression = arguments.value(QLatin1String("expression")).toString();
608 int context = arguments.value(QLatin1String("context")).toInt(-1);
609 int frame = -1;
610
611 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
612 if (!debugger) {
613 const QList<QV4Debugger *> &debuggers = debugService->debuggerAgent.debuggers();
614 if (debuggers.size() > 1) {
615 createErrorResponse(QStringLiteral("Cannot evaluate expressions if multiple debuggers are running and none is paused"));
616 return;
617 } else if (debuggers.size() == 0) {
618 createErrorResponse(QStringLiteral("No debuggers available to evaluate expressions"));
619 return;
620 }
621 debugger = debuggers.first();
622 } else {
623 frame = arguments.value(QLatin1String("frame")).toInt(0);
624 }
625
626 ExpressionEvalJob job(debugger->engine(), frame, context, expression,
627 debugger->collector());
628 debugger->runInEngine(&job);
629 if (job.hasExeption()) {
630 createErrorResponse(job.exceptionMessage());
631 } else {
632 addCommand();
633 addRequestSequence();
634 addSuccess(true);
635 addRunning();
636 addBody(job.returnValue());
637 }
638 }
639};
640} // anonymous namespace
641
642void QV4DebugServiceImpl::addHandler(V4CommandHandler* handler)
643{
644 handlers[handler->command()] = handler;
645}
646
647V4CommandHandler *QV4DebugServiceImpl::v4CommandHandler(const QString &command) const
648{
649 V4CommandHandler *handler = handlers.value(command, 0);
650 if (handler)
651 return handler;
652 else
653 return unknownV4CommandHandler.data();
654}
655
658 debuggerAgent(this), theSelectedFrame(0),
659 unknownV4CommandHandler(new UnknownV4CommandHandler)
660{
661 addHandler(new V4VersionRequest);
662 addHandler(new V4SetBreakPointRequest);
663 addHandler(new V4ClearBreakPointRequest);
664 addHandler(new V4ChangeBreakPointRequest);
665 addHandler(new V4BacktraceRequest);
666 addHandler(new V4FrameRequest);
667 addHandler(new V4ScopeRequest);
668 addHandler(new V4LookupRequest);
669 addHandler(new V4ContinueRequest);
670 addHandler(new V4DisconnectRequest);
671 addHandler(new V4SetExceptionBreakRequest);
672 addHandler(new V4ScriptsRequest);
673 addHandler(new V4EvaluateRequest);
674}
675
680
698
700{
702 if (engine){
703 const QV4::ExecutionEngine *ee = engine->handle();
704 if (ee) {
705 QV4Debugger *debugger = qobject_cast<QV4Debugger *>(ee->debugger());
706 if (debugger)
708 }
709 }
711}
712
714{
716 if (state == Enabled) {
717 const auto debuggers = debuggerAgent.debuggers();
718 for (QV4Debugger *debugger : debuggers) {
719 QV4::ExecutionEngine *ee = debugger->engine();
720 if (!ee->debugger())
721 ee->setDebugger(debugger);
722 }
723 }
725}
726
728{
729 //This function is only called by QQmlBoundSignal
730 //only if there is a slot connected to the signal. Hence, there
731 //is no need for additional check.
732
733 //Parse just the name and remove the class info
734 //Normalize to Lower case.
735 QString signalName = signal.left(signal.indexOf(QLatin1Char('('))).toLower();
736
737 for (const QString &signal : std::as_const(breakOnSignals)) {
738 if (signal == signalName) {
739 // TODO: pause debugger
740 break;
741 }
742 }
743}
744
746{
748
751 ms >> header;
752
753 TRACE_PROTOCOL(qDebug() << "received message with header" << header);
754
755 if (header == "V8DEBUG") {
757 QByteArray payload;
758 ms >> type >> payload;
759 TRACE_PROTOCOL(qDebug() << "... type:" << type);
760
761 if (type == V4_CONNECT) {
762 QJsonObject parameters = QJsonDocument::fromJson(payload).object();
763 Q_UNUSED(parameters); // For future protocol changes
764
765 emit messageToClient(name(), packMessage(type));
766 stopWaiting();
767 } else if (type == V4_PAUSE) {
770 } else if (type == V4_BREAK_ON_SIGNAL) {
772 bool enabled;
773 ms >> signal >> enabled;
774 //Normalize to lower case.
775 QString signalName(QString::fromUtf8(signal).toLower());
776 if (enabled)
777 breakOnSignals.append(signalName);
778 else
779 breakOnSignals.removeOne(signalName);
780 } else if (type == "v8request") {
781 handleV4Request(payload);
782 } else if (type == V4_DISCONNECT) {
783 TRACE_PROTOCOL(qDebug() << "... payload:" << payload.constData());
784 handleV4Request(payload);
785 } else {
787 }
788 }
789}
790
791void QV4DebugServiceImpl::sendSomethingToSomebody(const char *type, int magicNumber)
792{
794 rs << QByteArray(type)
795 << QByteArray::number(int(version())) << QByteArray::number(magicNumber);
796 emit messageToClient(name(), packMessage(type, rs.data()));
797}
798
799void QV4DebugServiceImpl::handleV4Request(const QByteArray &payload)
800{
801 TRACE_PROTOCOL(qDebug() << "v8request, payload:" << payload.constData());
802
804 QJsonObject o = request.object();
805 QJsonValue type = o.value(QLatin1String("type"));
806 if (type.toString() == QLatin1String("request")) {
807 QJsonValue command = o.value(QLatin1String("command"));
808 V4CommandHandler *h = v4CommandHandler(command.toString());
809 if (h)
810 h->handle(o, this);
811 }
812}
813
814QByteArray QV4DebugServiceImpl::packMessage(const QByteArray &command, const QByteArray &message)
815{
817 static const QByteArray cmd("V8DEBUG");
818 rs << cmd << command << message;
819 return rs.data();
820}
821
823{
824 v4Payload[QLatin1String("seq")] = sequence++;
825 QJsonDocument doc;
826 doc.setObject(v4Payload);
827#ifdef NO_PROTOCOL_TRACING
828 QByteArray responseData = doc.toJson(QJsonDocument::Compact);
829#else
830 QByteArray responseData = doc.toJson(QJsonDocument::Indented);
831#endif
832
833 TRACE_PROTOCOL(qDebug() << "sending response for:" << responseData.constData() << endl);
834
835 emit messageToClient(name(), packMessage("v8message", responseData));
836}
837
839{
840 theSelectedFrame = frameNr;
841}
842
844{
845 return theSelectedFrame;
846}
847
849
850#include "moc_qv4debugservice.cpp"
\inmodule QtCore
Definition qbytearray.h:57
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
T value(const Key &key) const noexcept
Definition qhash.h:1054
The QJSEngine class provides an environment for evaluating JavaScript code.
Definition qjsengine.h:26
QV4::ExecutionEngine * handle() const
Definition qjsengine.h:298
\inmodule QtCore\reentrant
Definition qjsonarray.h:18
void append(const QJsonValue &value)
Inserts value at the end of the array.
\inmodule QtCore\reentrant
QByteArray toJson(JsonFormat format=Indented) const
void setObject(const QJsonObject &object)
Sets object as the main object of this document.
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error=nullptr)
Parses json as a UTF-8 encoded JSON document, and creates a QJsonDocument from it.
\inmodule QtCore\reentrant
Definition qjsonobject.h:20
iterator insert(const QString &key, const QJsonValue &value)
Inserts a new item with the key key and a value of value.
QJsonValue value(const QString &key) const
Returns a QJsonValue representing the value for the key key.
bool isEmpty() const
Returns true if the object is empty.
\inmodule QtCore\reentrant
Definition qjsonvalue.h:25
int toInt(int defaultValue=0) const
QString toString() const
Converts the value to a QString and returns it.
bool empty() const noexcept
Definition qlist.h:685
T value(qsizetype i) const
Definition qlist.h:664
\inmodule QtCore
Definition qmutex.h:313
\inmodule QtCore
Definition qobject.h:103
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1598
bool moveToThread(QThread *thread QT6_DECL_NEW_OVERLOAD_TAIL)
Changes the thread affinity for this object and its children and returns true on success.
Definition qobject.cpp:1643
static QQmlDebugConnector * instance()
T * data() const noexcept
Returns the value of the pointer referenced by this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
int toInt(bool *ok=nullptr, int base=10) const
Returns the string converted to an int using base base, which is 10 by default and must be between 2 ...
Definition qstring.h:731
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
void send(QJsonObject v4Payload)
void engineAboutToBeRemoved(QJSEngine *engine) override
QV4DebuggerAgent debuggerAgent
void messageReceived(const QByteArray &) override
QV4DebugServiceImpl(QObject *parent=nullptr)
void stateAboutToBeChanged(State state) override
void signalEmitted(const QString &signal) override
void sendSomethingToSomebody(const char *type, int magicNumber=1)
void engineAdded(QJSEngine *engine) override
void selectFrame(int frameNr)
const QList< QV4Debugger * > & debuggers()
void addDebugger(QV4Debugger *debugger)
void removeDebugger(QV4Debugger *debugger)
void runInEngine(QV4DebugJob *job)
QV4::ExecutionEngine * engine() const
void resume(Speed speed)
const QV4DataCollector * collector() const
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
virtual ~V4CommandHandler()
int requestSequenceNr() const
QV4DebugServiceImpl * debugService
void addSuccess(bool success)
void createErrorResponse(const QString &msg)
void addBody(const QJsonValue &body)
V4CommandHandler(const QString &command)
virtual void handleRequest()=0
void handle(const QJsonObject &request, QV4DebugServiceImpl *s)
QString command() const
#define this
Definition dialogs.cpp:9
qDeleteAll(list.begin(), list.end())
auto signal
QList< QVariant > arguments
else opt state
[0]
Combined button and popup list for selecting options.
static void * context
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage return DBusPendingCall DBusPendingCall return DBusPendingCall return dbus_int32_t return DBusServer * server
static QString header(const QString &name)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
#define qDebug
[1]
Definition qlogging.h:164
#define qWarning
Definition qlogging.h:166
GLenum condition
GLsizei GLenum GLenum * types
GLenum GLuint id
[7]
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLenum src
GLenum type
GLuint GLsizei const GLchar * message
GLuint name
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLchar * source
GLdouble s
[6]
Definition qopenglext.h:235
GLuint64EXT * result
[6]
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
#define emit
#define Q_UNUSED(x)
const char *const V4_CONNECT
const char *const V4_BREAK_ON_SIGNAL
const char *const V4_DISCONNECT
#define TRACE_PROTOCOL(x)
const char *const V4_PAUSE
#define enabled
QReadWriteLock lock
[0]
QFrame frame
[0]
QNetworkRequest request(url)
QJSEngine engine
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18
QV4::Debugging::Debugger * debugger() const
void setDebugger(Debugging::Debugger *)