Skip to content

Commit e26ac31

Browse files
committed
feat: use another hack to compile a file in sync mode
1 parent bb24059 commit e26ac31

File tree

11 files changed

+106
-137
lines changed

11 files changed

+106
-137
lines changed

playground/simple.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
<?php
22

3+
$a = 2;
4+
35
$var = 1;
46
echo $var;

src/main/kotlin/com/github/xepozz/php_dump/configuration/PhpDumpSettingsService.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,21 @@ import com.intellij.openapi.project.Project
1414
)
1515
class PhpDumpSettingsService : SimplePersistentStateComponent<PhpDumpSettingsService.State>(State()) {
1616
class State : BaseState() {
17-
var debugLevel: Int by property(1)
17+
var debugLevel: String? by string(PhpOpcacheDebugLevel.BEFORE_OPTIMIZATION.value)
1818
var preloadFile: String? by string(null)
1919
var autoRefresh: Boolean by property(true)
2020
var tokensObject: Boolean by property(true)
2121
}
2222

23-
var debugLevel: Int by state::debugLevel
23+
var debugLevel: PhpOpcacheDebugLevel
24+
get() = PhpOpcacheDebugLevel.entries.firstOrNull { it.value == state.debugLevel } ?: PhpOpcacheDebugLevel.BEFORE_OPTIMIZATION
25+
set(value) {
26+
state.debugLevel = value.value
27+
}
2428
var preloadFile: String? by state::preloadFile
2529
var autoRefresh: Boolean by state::autoRefresh
2630

27-
var tokensObject: Boolean by state::autoRefresh
31+
var tokensObject: Boolean by state::tokensObject
2832

2933
companion object {
3034
fun getInstance(project: Project): PhpDumpSettingsService {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.github.xepozz.php_dump.configuration
2+
3+
enum class PhpOpcacheDebugLevel(val value: String) {
4+
BEFORE_OPTIMIZATION("0x10000"),
5+
AFTER_OPTIMIZATION("0x20000"),
6+
CONTEXT_FREE("0x40000"),
7+
SSA_FORM("0x200000"),
8+
}

src/main/kotlin/com/github/xepozz/php_dump/panel/OpcacheSettingsPanel.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class OpcacheSettingsPanel(private val project: Project) :
6666

6767
fun createToolbar() {
6868
val actionGroup = DefaultActionGroup().apply {
69-
add(RefreshAction { refreshData() })
69+
add(RefreshAction { refresh(project, RefreshType.MANUAL) })
7070
addSeparator()
7171
add(ExpandTreeAction(tree))
7272
add(CollapseTreeAction(tree))
@@ -118,10 +118,7 @@ class OpcacheSettingsPanel(private val project: Project) :
118118
val editor = FileEditorManager.getInstance(project).selectedTextEditor ?: return result
119119
val virtualFile = editor.virtualFile ?: return result
120120

121-
val runBlocking = runBlocking { service.dump(virtualFile) }
122-
println("result is $runBlocking")
123-
124-
return runBlocking as? AnyNodeList ?: result
121+
return runBlocking { service.dump(virtualFile) } as? AnyNodeList ?: result
125122
}
126123

127124
override fun refresh(project: Project, type: RefreshType) {

src/main/kotlin/com/github/xepozz/php_dump/panel/OpcodesTerminalPanel.kt

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package com.github.xepozz.php_dump.panel
22

33
import com.github.xepozz.php_dump.PhpDumpIcons
44
import com.github.xepozz.php_dump.actions.ClearConsoleViewAction
5-
import com.github.xepozz.php_dump.actions.RunDumpTokensCommandAction
5+
import com.github.xepozz.php_dump.actions.RefreshAction
66
import com.github.xepozz.php_dump.configuration.PhpDumpSettingsService
7+
import com.github.xepozz.php_dump.configuration.PhpOpcacheDebugLevel
78
import com.github.xepozz.php_dump.services.OpcodesDumperService
89
import com.intellij.execution.filters.TextConsoleBuilderFactory
10+
import com.intellij.execution.ui.ConsoleViewContentType
911
import com.intellij.icons.AllIcons
1012
import com.intellij.openapi.Disposable
1113
import com.intellij.openapi.actionSystem.ActionManager
@@ -30,23 +32,20 @@ class OpcodesTerminalPanel(
3032
val project: Project,
3133
) : SimpleToolWindowPanel(false, false), RefreshablePanel, Disposable {
3234
val viewComponent: JComponent
33-
val service: OpcodesDumperService
35+
val service: OpcodesDumperService = project.getService(OpcodesDumperService::class.java)
3436
val state = PhpDumpSettingsService.getInstance(project)
3537
val consoleView = TextConsoleBuilderFactory.getInstance().createBuilder(project).console
3638

3739
init {
3840
viewComponent = consoleView.component
3941

40-
service = project.getService(OpcodesDumperService::class.java)
41-
service.consoleView = consoleView
42-
4342
createToolBar()
4443
createContent()
4544
}
4645

4746
private fun createToolBar() {
4847
val actionGroup = DefaultActionGroup().apply {
49-
add(RunDumpTokensCommandAction(service, "Dump Opcodes"))
48+
add(RefreshAction { refresh(project, RefreshType.MANUAL) })
5049
add(ClearConsoleViewAction(consoleView))
5150
add(object : AnAction(
5251
"Enable Auto Refresh", "Turns on or off auto refresh of panel context",
@@ -68,32 +67,29 @@ class OpcodesTerminalPanel(
6867
})
6968
addSeparator()
7069
add(DefaultActionGroup("Debug Level", true).apply {
71-
add(object : AnAction("Before Optimization") {
72-
override fun actionPerformed(e: AnActionEvent) {
73-
state.debugLevel = 1
74-
refresh(project, RefreshType.MANUAL)
75-
}
76-
77-
override fun update(e: AnActionEvent) {
78-
e.presentation.icon = when (state.debugLevel) {
79-
1 -> AllIcons.Actions.Checked
80-
else -> null
70+
mapOf(
71+
PhpOpcacheDebugLevel.BEFORE_OPTIMIZATION to "Before Optimization (0x10000)",
72+
PhpOpcacheDebugLevel.AFTER_OPTIMIZATION to "After Optimization (0x20000)",
73+
PhpOpcacheDebugLevel.CONTEXT_FREE to "Context Free (0x40000)",
74+
PhpOpcacheDebugLevel.SSA_FORM to "Static Single Assignment Form (0x200000)",
75+
)
76+
.map { (level, label) ->
77+
object : AnAction(label) {
78+
override fun actionPerformed(e: AnActionEvent) {
79+
state.debugLevel = level
80+
refresh(project, RefreshType.MANUAL)
81+
}
82+
83+
override fun update(e: AnActionEvent) {
84+
e.presentation.icon = when (state.debugLevel) {
85+
level -> AllIcons.Actions.Checked
86+
else -> null
87+
}
88+
}
8189
}
8290
}
83-
})
84-
add(object : AnAction("After Optimization") {
85-
override fun actionPerformed(e: AnActionEvent) {
86-
state.debugLevel = 2
87-
refresh(project, RefreshType.MANUAL)
88-
}
91+
.also { addAll(it) }
8992

90-
override fun update(e: AnActionEvent) {
91-
e.presentation.icon = when (state.debugLevel) {
92-
2 -> AllIcons.Actions.Checked
93-
else -> null
94-
}
95-
}
96-
})
9793
templatePresentation.icon = AllIcons.Actions.ToggleVisibility
9894
})
9995

@@ -144,7 +140,10 @@ class OpcodesTerminalPanel(
144140
val editor = FileEditorManager.getInstance(project).selectedTextEditor ?: return
145141
val virtualFile = editor.virtualFile ?: return
146142

147-
runBlocking { service.dump(virtualFile) }
143+
val result = runBlocking { service.dump(virtualFile) }
144+
145+
consoleView.clear()
146+
consoleView.print(result as? String ?: "No output", ConsoleViewContentType.NORMAL_OUTPUT)
148147
}
149148

150149
override fun dispose() {

src/main/kotlin/com/github/xepozz/php_dump/panel/TokensTerminalPanel.kt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ package com.github.xepozz.php_dump.panel
22

33
import com.github.xepozz.php_dump.PhpDumpIcons
44
import com.github.xepozz.php_dump.actions.ClearConsoleViewAction
5-
import com.github.xepozz.php_dump.actions.RunDumpTokensCommandAction
5+
import com.github.xepozz.php_dump.actions.RefreshAction
66
import com.github.xepozz.php_dump.configuration.PhpDumpSettingsService
77
import com.github.xepozz.php_dump.services.TokensDumperService
88
import com.intellij.execution.filters.TextConsoleBuilderFactory
9+
import com.intellij.execution.ui.ConsoleViewContentType
910
import com.intellij.openapi.actionSystem.ActionManager
1011
import com.intellij.openapi.actionSystem.ActionPlaces
1112
import com.intellij.openapi.actionSystem.AnAction
@@ -27,22 +28,19 @@ class TokensTerminalPanel(
2728
) : SimpleToolWindowPanel(false, false), RefreshablePanel {
2829
var viewComponent: JComponent
2930
val state = PhpDumpSettingsService.getInstance(project)
30-
var service: TokensDumperService
31+
var service: TokensDumperService = project.getService(TokensDumperService::class.java)
3132
val consoleView = TextConsoleBuilderFactory.getInstance().createBuilder(project).console
3233

3334
init {
3435
viewComponent = consoleView.component
3536

36-
service = project.getService(TokensDumperService::class.java)
37-
service.consoleView = consoleView
38-
3937
createToolBar()
4038
createContent()
4139
}
4240

4341
private fun createToolBar() {
4442
val actionGroup = DefaultActionGroup().apply {
45-
add(RunDumpTokensCommandAction(service))
43+
add(RefreshAction { refresh(project, RefreshType.MANUAL) })
4644
add(ClearConsoleViewAction(consoleView))
4745
addSeparator()
4846
add(object : AnAction(
@@ -66,7 +64,8 @@ class TokensTerminalPanel(
6664
})
6765
}
6866

69-
val actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.TOOLWINDOW_TOOLBAR_BAR, actionGroup, false)
67+
val actionToolbar =
68+
ActionManager.getInstance().createActionToolbar(ActionPlaces.TOOLWINDOW_TOOLBAR_BAR, actionGroup, false)
7069
actionToolbar.targetComponent = this
7170

7271
val toolBarPanel = JPanel(GridLayout())
@@ -92,6 +91,9 @@ class TokensTerminalPanel(
9291
val editor = FileEditorManager.getInstance(project).selectedTextEditor ?: return
9392
val virtualFile = editor.virtualFile ?: return
9493

95-
runBlocking { service.dump(virtualFile) }
94+
val result = runBlocking { service.dump(virtualFile) }
95+
96+
consoleView.clear()
97+
consoleView.print(result as? String ?: "No output", ConsoleViewContentType.NORMAL_OUTPUT)
9698
}
9799
}

src/main/kotlin/com/github/xepozz/php_dump/services/DumperServiceInterface.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ package com.github.xepozz.php_dump.services
33
import com.intellij.openapi.vfs.VirtualFile
44

55
interface DumperServiceInterface {
6-
suspend fun dump(file: VirtualFile): Any {
6+
suspend fun dump(file: VirtualFile): Any? {
77
return dump(file.path)
88
}
99

10-
suspend fun dump(file: String): Any
10+
suspend fun dump(file: String): Any?
1111
}

src/main/kotlin/com/github/xepozz/php_dump/services/OpcacheSettingsTreeDumperService.kt

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,14 @@ class OpcacheSettingsTreeDumperService(var project: Project) : DumperServiceInte
4747
return withContext(Dispatchers.IO) {
4848
val output = StringBuilder()
4949

50-
PhpCommandExecutor.execute(
51-
file,
52-
phpSnippet,
53-
project,
54-
object : ProcessAdapter() {
55-
override fun onTextAvailable(event: ProcessEvent, outputType: Key<*>) {
56-
when (outputType) {
57-
ProcessOutputTypes.STDERR -> output.append(event.text)
58-
ProcessOutputTypes.STDOUT -> output.append(event.text)
59-
}
50+
PhpCommandExecutor.execute(file, phpSnippet, project, object : ProcessAdapter() {
51+
override fun onTextAvailable(event: ProcessEvent, outputType: Key<*>) {
52+
when (outputType) {
53+
ProcessOutputTypes.STDERR -> output.append(event.text)
54+
ProcessOutputTypes.STDOUT -> output.append(event.text)
6055
}
61-
},
62-
listOf("-dopcache.enable_cli=1"),
63-
)
56+
}
57+
}, listOf("-dopcache.enable_cli=1"))
6458

6559

6660
val jsonString = output.toString()
Lines changed: 29 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,69 @@
11
package com.github.xepozz.php_dump.services
22

3+
import com.github.xepozz.php_dump.command.PhpCommandExecutor
34
import com.github.xepozz.php_dump.configuration.PhpDumpSettingsService
45
import com.intellij.execution.configurations.GeneralCommandLine
5-
import com.intellij.execution.process.KillableColoredProcessHandler
66
import com.intellij.execution.process.ProcessAdapter
77
import com.intellij.execution.process.ProcessEvent
88
import com.intellij.execution.process.ProcessOutputTypes
9-
import com.intellij.execution.ui.ConsoleView
10-
import com.intellij.execution.ui.ConsoleViewContentType
11-
import com.intellij.openapi.Disposable
129
import com.intellij.openapi.components.Service
1310
import com.intellij.openapi.project.Project
1411
import com.intellij.openapi.util.Key
1512
import com.jetbrains.php.config.PhpProjectConfigurationFacade
1613
import com.jetbrains.php.config.interpreters.PhpInterpretersManagerImpl
17-
import kotlinx.coroutines.CoroutineScope
1814
import kotlinx.coroutines.Dispatchers
19-
import kotlinx.coroutines.launch
2015
import kotlinx.coroutines.withContext
2116

2217
@Service(Service.Level.PROJECT)
23-
class OpcodesDumperService(var project: Project) : Disposable, DumperServiceInterface {
24-
var consoleView: ConsoleView? = null
25-
18+
class OpcodesDumperService(var project: Project) : DumperServiceInterface {
2619
val state = PhpDumpSettingsService.getInstance(project)
27-
28-
override fun dispose() {
29-
consoleView?.dispose()
30-
}
31-
32-
override suspend fun dump(file: String) {
20+
override suspend fun dump(file: String): Any? {
3321
val interpretersManager = PhpInterpretersManagerImpl.getInstance(project)
3422
val interpreter = PhpProjectConfigurationFacade.getInstance(project).interpreter
35-
?: interpretersManager.interpreters.firstOrNull() ?: return
23+
?: interpretersManager.interpreters.firstOrNull() ?: return null
3624

37-
//php -l \
38-
// -ddisplay_errors=0 \
39-
// -derror_reporting=0 \
40-
// -dopcache.enable_cli=1 \
41-
// -dopcache.save_comments=1 \
42-
// -dopcache.opt_debug_level=0x10000 \
43-
// -dopcache.optimization_level=0 \
44-
// playground/test.php \
45-
// 1>/dev/null
46-
47-
val interpreterPath = interpreter.pathToPhpExecutable ?: return
48-
val debugLevel = maxOf(1, minOf(2, state.debugLevel))
25+
val interpreterPath = interpreter.pathToPhpExecutable ?: return null
26+
val debugLevel = state.debugLevel.value
4927
val preloadFile = state.preloadFile
50-
51-
val commandArgs = buildList {
28+
val command = GeneralCommandLine(buildList {
5229
add(interpreterPath)
5330
add("-l")
5431
add("-ddisplay_errors=0")
5532
add("-derror_reporting=0")
5633

5734
add("-dopcache.enable_cli=1")
5835
add("-dopcache.save_comments=1")
59-
add("-dopcache.opt_debug_level=0x${debugLevel}0000")
60-
add("-dopcache.optimization_level=0")
36+
add("-dopcache.opt_debug_level=${debugLevel}")
6137
if (preloadFile != null) {
6238
add("-dopcache.preload=${preloadFile}")
6339
}
6440

41+
add("1>/dev/null")
6542
add(file)
66-
}
43+
}).commandLineString
44+
6745

68-
CoroutineScope(Dispatchers.IO).launch {
69-
executeCommand(commandArgs)
70-
}
71-
}
7246

73-
private suspend fun executeCommand(commandArgs: List<String>) = withContext(Dispatchers.IO) {
74-
val command = GeneralCommandLine(commandArgs)
75-
command.withRedirectErrorStream(false)
47+
// language=injectablephp
48+
val phpSnippet = $$"""
49+
opcache_compile_file($argv[1]);
50+
passthru('$$command');
51+
""".trimIndent()
7652

77-
// println("running command ${command.commandLineString}")
78-
val processHandler = KillableColoredProcessHandler.Silent(command)
79-
processHandler.setShouldKillProcessSoftly(false)
80-
processHandler.setShouldDestroyProcessRecursively(true)
81-
processHandler.addProcessListener(object : ProcessAdapter() {
82-
override fun onTextAvailable(event: ProcessEvent, outputType: Key<*>) {
83-
if (outputType == ProcessOutputTypes.STDERR) {
84-
consoleView?.print(event.text, ConsoleViewContentType.NORMAL_OUTPUT)
53+
return withContext(Dispatchers.IO) {
54+
val output = StringBuilder()
55+
56+
PhpCommandExecutor.execute(file, phpSnippet, project, object : ProcessAdapter() {
57+
override fun onTextAvailable(event: ProcessEvent, outputType: Key<*>) {
58+
when (outputType) {
59+
ProcessOutputTypes.STDERR -> output.append(event.text)
60+
ProcessOutputTypes.STDOUT -> output.append(event.text)
61+
}
8562
}
86-
}
87-
})
63+
}, listOf("-dopcache.enable_cli=1"))
8864

89-
consoleView?.clear()
90-
// consoleView?.attachToProcess(processHandler)
91-
// consoleView?.requestScrollingToEnd()
9265

93-
processHandler.startNotify()
66+
return@withContext output.toString()
67+
}
9468
}
95-
}
69+
}

0 commit comments

Comments
 (0)