mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-28 17:16:29 +03:00
WIP trying to support vscode-js-debug.
This commit is contained in:
@@ -238,6 +238,44 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "node",
|
||||
"url": "https://github.com/microsoft/vscode-js-debug",
|
||||
"type": "pwa-node",
|
||||
"run": {
|
||||
"command": "node",
|
||||
"command_arguments": [
|
||||
"${env:VSCODE_JS_DEBUG_PATH}/src/dapDebugServer.js",
|
||||
"${randPort}",
|
||||
"127.0.0.1"
|
||||
]
|
||||
},
|
||||
"languages": ["javascript", "typescript"],
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch Node.js program",
|
||||
"request": "launch",
|
||||
"arguments": {
|
||||
"type": "pwa-node",
|
||||
"program": "${file}",
|
||||
"args": "${args}",
|
||||
"cwd": "${cwd}",
|
||||
"env": "${env}",
|
||||
"runtimeExecutable": "node",
|
||||
"console": "externalConsole"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Attach to Node.js process",
|
||||
"request": "attach",
|
||||
"arguments": {
|
||||
"type": "pwa-node",
|
||||
"processId": "${command:pickProcess}",
|
||||
"cwd": "${cwd}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 16.0.2, 2025-06-04T20:36:12. -->
|
||||
<!-- Written by QtCreator 16.0.2, 2025-06-20T02:09:36. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
@@ -125,7 +125,7 @@
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{388e5431-b31b-42b3-b9ad-9002d279d75d}</value>
|
||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">10</value>
|
||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">12</value>
|
||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">19</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">../../make/linux</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
@@ -1199,6 +1199,7 @@
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
||||
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">true</value>
|
||||
<value type="QString" key="RunConfiguration.Arguments">--text-shaper</value>
|
||||
<value type="int" key="RunConfiguration.UseCppDebugger">0</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">false</value>
|
||||
<value type="int" key="RunConfiguration.UseQmlDebugger">1</value>
|
||||
|
||||
@@ -193,10 +193,38 @@ void DebuggerClientListener::stateChanged( DebuggerClient::State state ) {
|
||||
void DebuggerClientListener::sendBreakpoints() {
|
||||
Lock l( mPlugin->mBreakpointsMutex );
|
||||
for ( const auto& fileBps : mPlugin->mBreakpoints ) {
|
||||
mClient->setBreakpoints( fileBps.first, fromSet( fileBps.second ) );
|
||||
if ( isRemote() && !mLocalRoot.empty() && !mRemoteRoot.empty() &&
|
||||
String::startsWith( fileBps.first, mLocalRoot ) ) {
|
||||
auto remoteRoot = mRemoteRoot;
|
||||
auto localRoot = mLocalRoot;
|
||||
FileSystem::dirAddSlashAtEnd( localRoot );
|
||||
FileSystem::dirAddSlashAtEnd( remoteRoot );
|
||||
auto remotePath = fileBps.first;
|
||||
FileSystem::filePathRemoveBasePath( mLocalRoot, remotePath );
|
||||
remotePath = remoteRoot + remotePath;
|
||||
mClient->setBreakpoints( remotePath, fromSet( fileBps.second ) );
|
||||
} else {
|
||||
mClient->setBreakpoints( fileBps.first, fromSet( fileBps.second ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& DebuggerClientListener::localRoot() const {
|
||||
return mLocalRoot;
|
||||
}
|
||||
|
||||
void DebuggerClientListener::setLocalRoot( const std::string& newLocalRoot ) {
|
||||
mLocalRoot = newLocalRoot;
|
||||
}
|
||||
|
||||
const std::string& DebuggerClientListener::remoteRoot() const {
|
||||
return mRemoteRoot;
|
||||
}
|
||||
|
||||
void DebuggerClientListener::setRemoteRoot( const std::string& newRemoteRoot ) {
|
||||
mRemoteRoot = newRemoteRoot;
|
||||
}
|
||||
|
||||
void DebuggerClientListener::initialized() {
|
||||
sendBreakpoints();
|
||||
}
|
||||
|
||||
@@ -73,6 +73,14 @@ class DebuggerClientListener : public DebuggerClient::Listener {
|
||||
|
||||
const ProcessInfo& getProcessInfo() const { return mProcessInfo; }
|
||||
|
||||
const std::string& localRoot() const;
|
||||
|
||||
void setLocalRoot( const std::string& newLocalRoot );
|
||||
|
||||
const std::string& remoteRoot() const;
|
||||
|
||||
void setRemoteRoot( const std::string& newRemoteRoot );
|
||||
|
||||
protected:
|
||||
DebuggerClient* mClient{ nullptr };
|
||||
DebuggerPlugin* mPlugin{ nullptr };
|
||||
@@ -87,6 +95,8 @@ class DebuggerClientListener : public DebuggerClient::Listener {
|
||||
std::shared_ptr<VariablesHolder> mVariablesHolder;
|
||||
std::unordered_map<int, Scope> mScopeRef;
|
||||
ProcessInfo mProcessInfo;
|
||||
std::string mLocalRoot;
|
||||
std::string mRemoteRoot;
|
||||
|
||||
StatusDebuggerController* getStatusDebuggerController() const;
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ static constexpr auto REQUEST_TYPE_ATTACH = "attach";
|
||||
namespace ecode {
|
||||
|
||||
static constexpr auto INPUT_PATTERN = "%$%{input%:([%w_]+)%}"sv;
|
||||
static constexpr auto ENV_PATTERN = "%$%{env%:([%w_]+)%}"sv;
|
||||
static constexpr auto COMMAND_PATTERN = "%$%{command%:([%w_]+)%}"sv;
|
||||
static constexpr auto CMD_PICK_PROCESS = "${command:pickProcess}"sv;
|
||||
static constexpr auto CMD_PROMPT_STRING = "${command:promptString}"sv;
|
||||
@@ -44,12 +45,14 @@ static constexpr auto CMD_PICK_FILE = "${command:pickFile}"sv;
|
||||
|
||||
static LuaPattern inputPtrn( INPUT_PATTERN );
|
||||
static LuaPattern commandPtrn( COMMAND_PATTERN );
|
||||
static LuaPattern envPtrn( ENV_PATTERN );
|
||||
static constexpr auto KEY_FILE = "${file}";
|
||||
static constexpr auto KEY_ARGS = "${args}";
|
||||
static constexpr auto KEY_CWD = "${cwd}";
|
||||
static constexpr auto KEY_ENV = "${env}";
|
||||
static constexpr auto KEY_STOPONENTRY = "${stopOnEntry}";
|
||||
static constexpr auto KEY_WORKSPACEFOLDER = "${workspaceFolder}";
|
||||
static constexpr auto KEY_WORKSPACEROOT = "${workspaceRoot}";
|
||||
static constexpr auto KEY_FILEDIRNAME = "${fileDirname}";
|
||||
static constexpr auto KEY_RANDPORT = "${randPort}";
|
||||
static constexpr auto KEY_PID = "${pid}";
|
||||
@@ -70,6 +73,46 @@ static constexpr auto KEY_DEFAULT_BUILD_TASK = "${defaultBuildTask}";
|
||||
static constexpr auto KEY_PATH_SEPARATOR = "${pathSeparator}";
|
||||
static constexpr auto KEY_PATH_SEPARATOR_ABBR = "${/}";
|
||||
|
||||
static constexpr auto KEY_DEBUG_SERVER = "debugServer";
|
||||
|
||||
static void replaceExecutableArgs( std::string& arg ) {
|
||||
LuaPattern ptrn( "%$%b()" );
|
||||
PatternMatcher::Range match[4];
|
||||
while ( ptrn.matches( arg, match ) ) {
|
||||
auto cmd = arg.substr( match[0].start, match[0].end - match[0].start );
|
||||
if ( cmd.size() > 3 ) {
|
||||
auto rcmd = cmd.substr( 2, cmd.size() - 3 );
|
||||
std::string out;
|
||||
Process p;
|
||||
if ( p.create( rcmd ) ) {
|
||||
p.readAllStdOut( out );
|
||||
String::trimInPlace( out, '\n' );
|
||||
String::trimInPlace( out, '\t' );
|
||||
String::replaceAll( arg, cmd, out );
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void replaceEnvVars( std::string& arg ) {
|
||||
PatternMatcher::Range match[4];
|
||||
while ( envPtrn.matches( arg, match ) ) {
|
||||
auto envCall = arg.substr( match[0].start, match[0].end - match[0].start );
|
||||
if ( envCall.size() > 6 ) {
|
||||
auto envName = envCall.substr( 6, envCall.size() - 7 );
|
||||
const char* env = getenv( envName.c_str() );
|
||||
if ( env ) {
|
||||
std::string out{ env };
|
||||
String::trimInPlace( out, '\n' );
|
||||
String::trimInPlace( out, '\t' );
|
||||
String::replaceAll( arg, envCall, out );
|
||||
} else {
|
||||
arg = "";
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Mouse Hover Tooltip
|
||||
static Action::UniqueID getMouseMoveHash( UICodeEditor* editor ) {
|
||||
return hashCombine( String::hash( "DebuggerPlugin::onMouseMove-" ),
|
||||
@@ -1103,6 +1146,7 @@ void DebuggerPlugin::replaceInVal( std::string& val,
|
||||
}
|
||||
|
||||
String::replaceAll( val, KEY_WORKSPACEFOLDER, mProjectPath );
|
||||
String::replaceAll( val, KEY_WORKSPACEROOT, mProjectPath );
|
||||
String::replaceAll( val, KEY_USER_HOME, Sys::getUserDirectory() );
|
||||
String::replaceAll( val, KEY_WORKSPACEFOLDER_BASENAME,
|
||||
FileSystem::fileNameFromPath( mProjectPath ) );
|
||||
@@ -1122,6 +1166,8 @@ void DebuggerPlugin::replaceInVal( std::string& val,
|
||||
|
||||
if ( String::contains( val, KEY_RANDPORT ) )
|
||||
String::replaceAll( val, KEY_RANDPORT, String::toString( randomPort ) );
|
||||
|
||||
replaceEnvVars( val );
|
||||
}
|
||||
|
||||
std::vector<std::string> DebuggerPlugin::replaceKeyInString(
|
||||
@@ -1828,7 +1874,7 @@ void DebuggerPlugin::prepareAndRun( DapTool debugger, DapConfig config,
|
||||
protocolSettings.runTarget = config.runTarget;
|
||||
auto args = config.args;
|
||||
replaceKeysInJson( args, randomPort, solvedInputs );
|
||||
protocolSettings.launchArgs = args;
|
||||
protocolSettings.launchArgs = std::move( args );
|
||||
protocolSettings.redirectStdout = debugger.redirectStdout;
|
||||
protocolSettings.redirectStderr = debugger.redirectStderr;
|
||||
protocolSettings.supportsSourceRequest = debugger.supportsSourceRequest;
|
||||
@@ -1838,7 +1884,7 @@ void DebuggerPlugin::prepareAndRun( DapTool debugger, DapConfig config,
|
||||
for ( auto& arg : debugger.run.args ) {
|
||||
auto res( replaceKeyInString( arg, randomPort, solvedInputs ) );
|
||||
if ( res.size() == 1 && res[0] != arg ) {
|
||||
if ( arg == KEY_RANDPORT )
|
||||
if ( String::contains( arg, KEY_RANDPORT ) )
|
||||
usesPorts = true;
|
||||
arg = res[0];
|
||||
}
|
||||
@@ -1853,6 +1899,14 @@ void DebuggerPlugin::prepareAndRun( DapTool debugger, DapConfig config,
|
||||
debugger.run.args.emplace_back( arg );
|
||||
}
|
||||
|
||||
if ( protocolSettings.launchArgs.contains( KEY_DEBUG_SERVER ) &&
|
||||
( protocolSettings.launchArgs[KEY_DEBUG_SERVER].is_number_integer() ||
|
||||
( protocolSettings.launchArgs[KEY_DEBUG_SERVER].is_string() &&
|
||||
String::isNumber(
|
||||
protocolSettings.launchArgs[KEY_DEBUG_SERVER].get<std::string>() ) ) ) ) {
|
||||
usesPorts = true;
|
||||
}
|
||||
|
||||
mThreadPool->run(
|
||||
[this, protocolSettings = std::move( protocolSettings ), randomPort,
|
||||
debugger = std::move( debugger ), forceUseProgram, usesPorts]() mutable {
|
||||
@@ -2021,10 +2075,43 @@ void DebuggerPlugin::run( const std::string& debugger, ProtocolSettings&& protoc
|
||||
|
||||
Command cmd = std::move( *cmdOpt );
|
||||
bool isRemote = false;
|
||||
bool runsDapServer = false;
|
||||
|
||||
for ( auto& arg : cmd.arguments )
|
||||
replaceExecutableArgs( arg );
|
||||
|
||||
int port = randPort;
|
||||
if ( protocolSettings.launchArgs.contains( KEY_DEBUG_SERVER ) &&
|
||||
( protocolSettings.launchArgs[KEY_DEBUG_SERVER].is_number_integer() ||
|
||||
( protocolSettings.launchArgs[KEY_DEBUG_SERVER].is_string() &&
|
||||
String::isNumber(
|
||||
protocolSettings.launchArgs[KEY_DEBUG_SERVER].get<std::string>() ) ) ) ) {
|
||||
runsDapServer = true;
|
||||
if ( protocolSettings.launchArgs[KEY_DEBUG_SERVER].is_string() ) {
|
||||
String::fromString( port,
|
||||
protocolSettings.launchArgs[KEY_DEBUG_SERVER].get<std::string>() );
|
||||
} else if ( protocolSettings.launchArgs[KEY_DEBUG_SERVER].is_number_integer() ) {
|
||||
port = protocolSettings.launchArgs.value( KEY_DEBUG_SERVER, randPort );
|
||||
}
|
||||
} else if ( protocolSettings.launchArgs.contains( "port" ) &&
|
||||
protocolSettings.launchArgs["port"].is_number_integer() ) {
|
||||
port = protocolSettings.launchArgs.value( "port", randPort );
|
||||
}
|
||||
|
||||
std::string localRoot = mProjectPath;
|
||||
std::string remoteRoot;
|
||||
|
||||
if ( protocolSettings.launchRequestType == REQUEST_TYPE_LAUNCH ) {
|
||||
auto bus = std::make_unique<BusProcess>( cmd );
|
||||
mDebugger = std::make_unique<DebuggerClientDap>( protocolSettings, std::move( bus ) );
|
||||
if ( usesPorts ) {
|
||||
Connection con;
|
||||
con.host = protocolSettings.launchArgs.value( "host", "localhost" );
|
||||
con.port = port;
|
||||
auto bus = std::make_unique<BusSocketProcess>( cmd, con );
|
||||
mDebugger = std::make_unique<DebuggerClientDap>( protocolSettings, std::move( bus ) );
|
||||
} else {
|
||||
auto bus = std::make_unique<BusProcess>( cmd );
|
||||
mDebugger = std::make_unique<DebuggerClientDap>( protocolSettings, std::move( bus ) );
|
||||
}
|
||||
} else if ( protocolSettings.launchRequestType == REQUEST_TYPE_ATTACH ) {
|
||||
auto mode = protocolSettings.launchArgs.value( "mode", "" );
|
||||
if ( mode.empty() )
|
||||
@@ -2032,7 +2119,7 @@ void DebuggerPlugin::run( const std::string& debugger, ProtocolSettings&& protoc
|
||||
|
||||
Connection con;
|
||||
con.host = protocolSettings.launchArgs.value( "host", "localhost" );
|
||||
con.port = protocolSettings.launchArgs.value( "port", 0 );
|
||||
con.port = port;
|
||||
bool useSocket = !con.host.empty() && con.port != 0;
|
||||
if ( ( protocolSettings.launchArgs.contains( "host" ) ||
|
||||
protocolSettings.launchArgs.contains( "port" ) ) &&
|
||||
@@ -2057,7 +2144,20 @@ void DebuggerPlugin::run( const std::string& debugger, ProtocolSettings&& protoc
|
||||
!protocolSettings.launchArgs.value( "program", "" ).empty() );
|
||||
|
||||
if ( mode == "local" ) {
|
||||
if ( useSocket ) {
|
||||
if ( runsDapServer ) {
|
||||
if ( protocolSettings.launchArgs.contains( "remoteRoot" ) &&
|
||||
protocolSettings.launchArgs["remoteRoot"].is_string() ) {
|
||||
isRemote = true;
|
||||
remoteRoot = protocolSettings.launchArgs["remoteRoot"].get<std::string>();
|
||||
}
|
||||
if ( protocolSettings.launchArgs.contains( "localRoot" ) &&
|
||||
protocolSettings.launchArgs["localRoot"].is_string() ) {
|
||||
localRoot = protocolSettings.launchArgs["localRoot"].get<std::string>();
|
||||
}
|
||||
auto bus = std::make_unique<BusSocketProcess>( cmd, con );
|
||||
mDebugger =
|
||||
std::make_unique<DebuggerClientDap>( protocolSettings, std::move( bus ) );
|
||||
} else if ( useSocket ) {
|
||||
auto bus = std::make_unique<BusSocketProcess>( cmd, con );
|
||||
mDebugger =
|
||||
std::make_unique<DebuggerClientDap>( protocolSettings, std::move( bus ) );
|
||||
@@ -2089,6 +2189,12 @@ void DebuggerPlugin::run( const std::string& debugger, ProtocolSettings&& protoc
|
||||
|
||||
mListener = std::make_unique<DebuggerClientListener>( mDebugger.get(), this );
|
||||
mListener->setIsRemote( isRemote );
|
||||
|
||||
if ( isRemote ) {
|
||||
// mListener->setLocalRoot( localRoot );
|
||||
// mListener->setRemoteRoot( remoteRoot );
|
||||
}
|
||||
|
||||
mDebugger->addListener( mListener.get() );
|
||||
mDebugger->setSilent( mSilence );
|
||||
|
||||
@@ -2105,6 +2211,7 @@ void DebuggerPlugin::run( const std::string& debugger, ProtocolSettings&& protoc
|
||||
UITerminal* term =
|
||||
getPluginContext()->getTerminalManager()->createTerminalInSplitter(
|
||||
cwd, cmd, args, false );
|
||||
term->getTerm()->setKeepAlive( false );
|
||||
|
||||
doneFn( term && term->getTerm() && term->getTerm()->getTerminal() &&
|
||||
term->getTerm()->getTerminal()->getProcess()
|
||||
|
||||
Reference in New Issue
Block a user