| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Threading.Tasks;
|
| | | using QtVsTools.SyntaxAnalysis;
|
| | | using static QtVsTools.SyntaxAnalysis.RegExpr;
|
| | | using RegExprParser = QtVsTools.SyntaxAnalysis.RegExpr.Parser;
|
| | |
|
| | | namespace QtVsTools.Qml.Debug
|
| | | {
|
| | | using Common;
|
| | | using SyntaxAnalysis;
|
| | | using V4;
|
| | |
|
| | | using RegExprParser = SyntaxAnalysis.RegExpr.Parser;
|
| | |
|
| | | using static SyntaxAnalysis.RegExpr;
|
| | |
|
| | | struct FrameInfo
|
| | | {
|
| | |
| | |
|
| | | class QmlDebugger : Disposable, IMessageEventSink
|
| | | {
|
| | | static LazyFactory StaticLazy { get; } = new LazyFactory();
|
| | |
|
| | | IDebuggerEventSink sink;
|
| | | ProtocolDriver driver;
|
| | | string connectionHostName;
|
| | |
| | | List<Request> outbox;
|
| | | Dictionary<int, IBreakpoint> breakpoints;
|
| | |
|
| | | public bool Started { get; private set; }
|
| | | private bool Started { get; set; }
|
| | |
|
| | | public bool Running { get; private set; }
|
| | | private bool Running { get; set; }
|
| | |
|
| | | public string Version { get; private set; }
|
| | | private string Version { get; set; }
|
| | |
|
| | | public uint? ThreadId { get { return driver.ThreadId; } }
|
| | |
|
| | |
| | | if (!Started) {
|
| | | Running = Started = true;
|
| | | LeaveCriticalSection();
|
| | | Task.Run(() => ConnectToDebugger());
|
| | | _ = Task.Run(() => ConnectToDebugger());
|
| | |
|
| | | } else if (!Running) {
|
| | | Running = true;
|
| | |
| | | setBreakpoint.Arguments.Line = (int)breakpoint.Line;
|
| | | setBreakpoint.Tag = breakpoint;
|
| | | if (driver.ConnectionState == DebugClientState.Connected)
|
| | | setBreakpoint.SendAsync();
|
| | | setBreakpoint.SendRequest();
|
| | | else
|
| | | ThreadSafe(() => outbox.Add(setBreakpoint));
|
| | | }
|
| | |
| | |
|
| | | var reqClearBreak = Message.Create<ClearBreakpointRequest>(driver);
|
| | | reqClearBreak.Arguments.Breakpoint = breakpointNum[breakpoint];
|
| | | reqClearBreak.SendAsync();
|
| | | reqClearBreak.SendRequest();
|
| | | }
|
| | |
|
| | | void RefreshFrames()
|
| | |
| | |
|
| | | } else {
|
| | | foreach (int breakpointId in evtBreak.Body.Breakpoints) {
|
| | | IBreakpoint breakpoint;
|
| | | if (!breakpoints.TryGetValue(breakpointId, out breakpoint))
|
| | | if (!breakpoints.TryGetValue(breakpointId, out IBreakpoint breakpoint))
|
| | | continue;
|
| | | breakpoint.NotifyBreak();
|
| | | }
|
| | |
| | | {
|
| | | if (oldState != DebugClientState.Unavailable
|
| | | && newState == DebugClientState.Disconnected) {
|
| | | Task.Run(() => sink.NotifyClientDisconnected());
|
| | | _ = Task.Run(() => sink.NotifyClientDisconnected());
|
| | | }
|
| | | }
|
| | |
|
| | | void IMessageEventSink.NotifyRequestResponded(Request msgRequest)
|
| | | {
|
| | | if (msgRequest is SetBreakpointRequest)
|
| | | Task.Run(() => SetBreakpointResponded(msgRequest as SetBreakpointRequest));
|
| | | _ = Task.Run(() => SetBreakpointResponded(msgRequest as SetBreakpointRequest));
|
| | | }
|
| | |
|
| | | void IMessageEventSink.NotifyEvent(Event msgEvent)
|
| | | {
|
| | | if (msgEvent is BreakEvent)
|
| | | Task.Run(() => BreakNotified(msgEvent as BreakEvent));
|
| | | _ = Task.Run(() => BreakNotified(msgEvent as BreakEvent));
|
| | | }
|
| | |
|
| | | void IMessageEventSink.NotifyMessage(Message msg)
|
| | |
| | |
|
| | | public static bool CheckCommandLine(string execPath, string args)
|
| | | {
|
| | | ushort portFrom;
|
| | | ushort portTo;
|
| | | string hostName;
|
| | | string fileName;
|
| | | bool block;
|
| | | return ParseCommandLine(
|
| | | execPath, args, out portFrom, out portTo, out hostName, out fileName, out block);
|
| | | return ParseCommandLine(execPath, args, out _, out _, out _, out _, out _);
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | |
| | | /// <summary>
|
| | | /// Regex-based parser for QML debug connection parameters
|
| | | /// </summary>
|
| | | static RegExprParser ConnectParamsParser => _ConnectParamsParser ?? (
|
| | | _ConnectParamsParser = new Token(TokenId.ConnectParams, RxConnectParams)
|
| | | static RegExprParser ConnectParamsParser => StaticLazy.Get(() =>
|
| | | ConnectParamsParser, () => new Token(TokenId.ConnectParams, RxConnectParams)
|
| | | {
|
| | | new Rule<ConnectParams>
|
| | | {
|
| | |
| | | }
|
| | | }
|
| | | .Render());
|
| | | static RegExprParser _ConnectParamsParser;
|
| | |
|
| | | /// <summary>
|
| | | /// Regular expression for parsing connection parameters string in the form:
|