1+ package com.github.xepozz.php_dump.services
2+
3+ import com.intellij.execution.configurations.GeneralCommandLine
4+ import com.intellij.execution.process.KillableColoredProcessHandler
5+ import com.intellij.execution.process.ProcessAdapter
6+ import com.intellij.execution.process.ProcessEvent
7+ import com.intellij.execution.process.ProcessOutputTypes
8+ import com.intellij.execution.ui.ConsoleView
9+ import com.intellij.execution.ui.ConsoleViewContentType
10+ import com.intellij.openapi.Disposable
11+ import com.intellij.openapi.components.Service
12+ import com.intellij.openapi.project.Project
13+ import com.intellij.openapi.util.Key
14+ import com.jetbrains.php.config.PhpProjectConfigurationFacade
15+ import com.jetbrains.php.config.interpreters.PhpInterpretersManagerImpl
16+ import kotlinx.coroutines.CoroutineScope
17+ import kotlinx.coroutines.Dispatchers
18+ import kotlinx.coroutines.launch
19+ import kotlinx.coroutines.withContext
20+
21+ @Service(Service .Level .PROJECT )
22+ class TokensDumperService (var project : Project ) : Disposable {
23+ var consoleView: ConsoleView ? = null
24+
25+ override fun dispose () {
26+ consoleView?.dispose()
27+ }
28+
29+ fun dump (file : String , callback : () -> Unit ) {
30+ val interpretersManager = PhpInterpretersManagerImpl .getInstance(project)
31+ val interpreter = PhpProjectConfigurationFacade .getInstance(project).interpreter
32+ ? : interpretersManager.interpreters.firstOrNull() ? : return
33+
34+ // php -l \
35+ // -ddisplay_errors=0 \
36+ // -derror_reporting=0 \
37+ // -dopcache.enable_cli=1 \
38+ // -dopcache.save_comments=1 \
39+ // -dopcache.opt_debug_level=0x10000 \
40+ // -dopcache.optimization_level=0 \
41+ // playground/test.php \
42+ // 1>/dev/null
43+
44+ // language=injectablephp
45+ val phpSnippet = $$"""
46+ print_r(
47+ array_map(
48+ function ($token ) {
49+ return [
50+ 'line' => $isArray = is_array($token ) ? $token [2] : null,
51+ 'name' => $isArray ? token_name($token [0]) : null,
52+ 'value' => $isArray ? $token [1] : $token ,
53+ ];
54+ },
55+ token_get_all(
56+ file_get_contents($argv [1])
57+ ),
58+ )
59+ );
60+ """ .trimIndent()
61+
62+ val commandArgs = buildList {
63+ interpreter.apply {
64+ println (" interpreter: $this " )
65+ add(this .pathToPhpExecutable!! )
66+ }
67+ add(" -r" )
68+ add(phpSnippet)
69+
70+ add(file)
71+ }
72+
73+ CoroutineScope (Dispatchers .IO ).launch {
74+ executeCommand(commandArgs)
75+ callback()
76+ }
77+ }
78+
79+ private suspend fun executeCommand (commandArgs : List <String >) = withContext(Dispatchers .IO ) {
80+ val command = GeneralCommandLine (commandArgs)
81+ command.withRedirectErrorStream(false )
82+
83+ println (" running command ${command.commandLineString} " )
84+ val processHandler = KillableColoredProcessHandler .Silent (command)
85+ processHandler.setShouldKillProcessSoftly(false )
86+ processHandler.setShouldDestroyProcessRecursively(true )
87+ processHandler.addProcessListener(object : ProcessAdapter () {
88+ override fun onTextAvailable (event : ProcessEvent , outputType : Key <* >) {
89+ when (outputType) {
90+ ProcessOutputTypes .STDERR -> consoleView?.print (event.text, ConsoleViewContentType .ERROR_OUTPUT )
91+ ProcessOutputTypes .STDOUT -> consoleView?.print (event.text, ConsoleViewContentType .NORMAL_OUTPUT )
92+ }
93+ }
94+ })
95+
96+ consoleView?.clear()
97+ // consoleView?.attachToProcess(processHandler)
98+ // consoleView?.requestScrollingToEnd()
99+
100+ processHandler.startNotify()
101+ }
102+ }
0 commit comments