Skip to content

Commit 6b98e63

Browse files
committed
feat: dump opcache for a selected file
1 parent e945df0 commit 6b98e63

11 files changed

Lines changed: 245 additions & 116 deletions

File tree

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ platformVersion = 2025.1.1
1818
# Example: platformPlugins = com.jetbrains.php:203.4449.22, org.intellij.scala:2023.3.27@EAP
1919
platformPlugins=com.jetbrains.php:251.23774.318,com.jetbrains.hackathon.indices.viewer:1.30
2020
# Example: platformBundledPlugins = com.intellij.java
21-
platformBundledPlugins=
21+
platformBundledPlugins=com.jetbrains.sh
2222

2323
# Gradle Releases -> https://github.com/gradle/gradle/releases
2424
gradleVersion = 8.13
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.github.xepozz.php_opcodes
2+
3+
import com.github.xepozz.php_opcodes.panel.OpcodesTerminalPanel
4+
import com.github.xepozz.php_opcodes.services.OpcodesDumperService
5+
import com.intellij.execution.filters.TextConsoleBuilderFactory
6+
import com.intellij.execution.filters.UrlFilter
7+
import com.intellij.openapi.project.DumbAware
8+
import com.intellij.openapi.project.Project
9+
import com.intellij.openapi.wm.ToolWindow
10+
import com.intellij.openapi.wm.ToolWindowFactory
11+
import com.intellij.ui.content.ContentFactory
12+
import com.intellij.ui.jcef.JBCefBrowser
13+
14+
open class CompositeWindowFactory : ToolWindowFactory, DumbAware {
15+
override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
16+
val browser = JBCefBrowser.createBuilder()
17+
.setEnableOpenDevToolsMenuItem(true)
18+
.build()
19+
20+
val consoleView = TextConsoleBuilderFactory.getInstance().createBuilder(project).console
21+
consoleView.addMessageFilter(UrlFilter())
22+
23+
val contentFactory = ContentFactory.getInstance()
24+
val contentManager = toolWindow.contentManager
25+
26+
val opcodesDumperService = toolWindow.project.getService(OpcodesDumperService::class.java)
27+
opcodesDumperService.browser = browser
28+
opcodesDumperService.consoleView = consoleView
29+
30+
val terminalLayout = OpcodesTerminalPanel(consoleView.component)
31+
32+
contentFactory.apply {
33+
this.createContent(terminalLayout, "Opcodes", false).apply {
34+
contentManager.addContent(
35+
this.apply {
36+
this.isPinnable = true
37+
this.isCloseable = false
38+
}
39+
)
40+
}
41+
}
42+
}
43+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.github.xepozz.php_opcodes.actions
2+
3+
import com.github.xepozz.php_opcodes.services.OpcodesDumperService
4+
import com.intellij.icons.AllIcons
5+
import com.intellij.openapi.actionSystem.ActionUpdateThread
6+
import com.intellij.openapi.actionSystem.AnAction
7+
import com.intellij.openapi.actionSystem.AnActionEvent
8+
import com.intellij.openapi.editor.EditorFactory
9+
import com.intellij.openapi.fileEditor.FileEditorManager
10+
11+
class RunDumpCommandAction() : AnAction("Dump Opcodes in Terminal", null, AllIcons.Actions.Execute) {
12+
override fun actionPerformed(e: AnActionEvent) {
13+
val project = e.project ?: return
14+
println("project $project")
15+
val basePath = project.basePath ?: return
16+
println("basePath $basePath")
17+
val editorFactory = EditorFactory.getInstance()
18+
val editors = editorFactory.allEditors
19+
println("editors $editors")
20+
21+
val editor = FileEditorManager.getInstance(project).selectedTextEditor ?: return
22+
val file = editor.virtualFile ?: return
23+
println("file $file")
24+
25+
val service = project.getService(OpcodesDumperService::class.java)
26+
27+
service.dump(file.path, {
28+
println("dumping $basePath")
29+
});
30+
31+
}
32+
33+
override fun getActionUpdateThread() = ActionUpdateThread.BGT
34+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.github.xepozz.php_opcodes.panel
2+
3+
import com.github.xepozz.php_opcodes.actions.RunDumpCommandAction
4+
import com.intellij.openapi.actionSystem.ActionManager
5+
import com.intellij.openapi.actionSystem.DefaultActionGroup
6+
import com.intellij.openapi.ui.SimpleToolWindowPanel
7+
import java.awt.BorderLayout
8+
import java.awt.GridLayout
9+
import java.awt.event.ComponentAdapter
10+
import java.awt.event.ComponentEvent
11+
import javax.swing.JComponent
12+
import javax.swing.JPanel
13+
14+
class OpcodesTerminalPanel(
15+
val terminalViewComponent: JComponent,
16+
) : SimpleToolWindowPanel(false, false) {
17+
init {
18+
createToolBar()
19+
createContent()
20+
}
21+
22+
private fun createToolBar() {
23+
val actionGroup = DefaultActionGroup()
24+
actionGroup.add(RunDumpCommandAction())
25+
actionGroup.addSeparator()
26+
// actionGroup.add(OpenSettingsAction())
27+
28+
val actionToolbar = ActionManager.getInstance().createActionToolbar("Opcodes Toolbar", actionGroup, false)
29+
actionToolbar.targetComponent = this
30+
31+
val toolBarPanel = JPanel(GridLayout())
32+
toolBarPanel.add(actionToolbar.component)
33+
34+
toolbar = toolBarPanel
35+
}
36+
37+
private fun createContent() {
38+
val responsivePanel = JPanel(BorderLayout())
39+
responsivePanel.add(terminalViewComponent, BorderLayout.CENTER)
40+
responsivePanel.addComponentListener(object : ComponentAdapter() {
41+
override fun componentResized(e: ComponentEvent?) {
42+
terminalViewComponent.revalidate()
43+
terminalViewComponent.repaint()
44+
}
45+
})
46+
47+
setContent(responsivePanel)
48+
}
49+
}

src/main/kotlin/com/github/xepozz/php_opcodes/services/MyProjectService.kt

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.github.xepozz.php_opcodes.services
2+
3+
import com.intellij.execution.configurations.GeneralCommandLine
4+
import com.intellij.execution.process.KillableColoredProcessHandler
5+
import com.intellij.execution.ui.ConsoleView
6+
import com.intellij.openapi.Disposable
7+
import com.intellij.openapi.components.Service
8+
import com.intellij.openapi.project.Project
9+
import com.intellij.ui.jcef.JBCefBrowser
10+
import com.jetbrains.php.config.PhpProjectConfigurationFacade
11+
import com.jetbrains.php.config.interpreters.PhpInterpretersManagerImpl
12+
import kotlinx.coroutines.CoroutineScope
13+
import kotlinx.coroutines.Dispatchers
14+
import kotlinx.coroutines.launch
15+
import kotlinx.coroutines.withContext
16+
17+
@Service(Service.Level.PROJECT)
18+
class OpcodesDumperService(var project: Project) : Disposable {
19+
var browser: JBCefBrowser? = null
20+
var consoleView: ConsoleView? = null
21+
22+
override fun dispose() {
23+
consoleView?.dispose()
24+
browser?.dispose()
25+
}
26+
27+
fun dump(file: String, callback: () -> Unit) {
28+
val interpretersManager = PhpInterpretersManagerImpl.getInstance(project)
29+
val interpreter = PhpProjectConfigurationFacade.getInstance(project).interpreter
30+
?: interpretersManager.interpreters.firstOrNull() ?: return
31+
32+
//php -l \
33+
// -ddisplay_errors=0 \
34+
// -derror_reporting=0 \
35+
// -dopcache.enable_cli=1 \
36+
// -dopcache.save_comments=1 \
37+
// -dopcache.opt_debug_level=0x10000 \
38+
// -dopcache.optimization_level=0 \
39+
// playground/test.php \
40+
// 1>/dev/null
41+
42+
val commandArgs = buildList {
43+
interpreter.apply {
44+
println("interpreter: $this")
45+
add(this.pathToPhpExecutable!!)
46+
}
47+
add("-l")
48+
add("-ddisplay_errors=0")
49+
add("-derror_reporting=0")
50+
51+
add("-dopcache.enable_cli=1")
52+
add("-dopcache.save_comments=1")
53+
add("-dopcache.opt_debug_level=0x10000")
54+
add("-dopcache.optimization_level=0")
55+
56+
add(file)
57+
}
58+
59+
CoroutineScope(Dispatchers.IO).launch {
60+
executeCommand(commandArgs)
61+
callback()
62+
}
63+
}
64+
65+
private suspend fun executeCommand(commandArgs: List<String>) = withContext(Dispatchers.IO) {
66+
val command = GeneralCommandLine(commandArgs)
67+
command.withRedirectErrorStream(false)
68+
69+
val commandLine = command.commandLineString + " 1>/dev/null"
70+
val processHandler = KillableColoredProcessHandler.Silent(command.createProcess(), commandLine, command.charset, emptySet())
71+
processHandler.setShouldKillProcessSoftly(false)
72+
processHandler.setShouldDestroyProcessRecursively(true)
73+
74+
consoleView?.clear()
75+
consoleView?.attachToProcess(processHandler)
76+
// consoleView?.requestScrollingToEnd()
77+
78+
processHandler.startNotify()
79+
}
80+
}

src/main/kotlin/com/github/xepozz/php_opcodes/startup/MyProjectActivity.kt

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.github.xepozz.php_opcodes.startup
2+
3+
import com.github.xepozz.php_opcodes.services.OpcodesDumperService
4+
import com.intellij.openapi.fileEditor.FileEditorManagerEvent
5+
import com.intellij.openapi.fileEditor.FileEditorManagerListener
6+
import com.intellij.openapi.project.Project
7+
8+
class ProjectFileEditorListener(val project: Project) : FileEditorManagerListener {
9+
// override fun fileClosed(source: FileEditorManager, file: VirtualFile) {
10+
// super.fileClosed(source, file)
11+
// println("file closed $source, $file")
12+
// }
13+
// override fun fileOpened(source: FileEditorManager, file: VirtualFile) {
14+
// super.fileOpened(source, file)
15+
// println("file opened $source, $file")
16+
// }
17+
18+
override fun selectionChanged(event: FileEditorManagerEvent) {
19+
super.selectionChanged(event)
20+
println("selection changed $event")
21+
22+
val virtualFile = event.newFile ?: return
23+
24+
val service = project.getService(OpcodesDumperService::class.java)
25+
26+
service.dump(virtualFile.path) {
27+
println("dump in selection changed ")
28+
}
29+
}
30+
}

src/main/kotlin/com/github/xepozz/php_opcodes/toolWindow/MyToolWindowFactory.kt

Lines changed: 0 additions & 45 deletions
This file was deleted.

src/main/resources/META-INF/plugin.xml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@
66

77
<depends>com.intellij.modules.platform</depends>
88
<depends>com.jetbrains.php</depends>
9+
<depends>com.jetbrains.sh</depends>
910

1011
<resource-bundle>messages.MyBundle</resource-bundle>
1112

1213
<extensions defaultExtensionNs="com.intellij">
13-
<toolWindow factoryClass="com.github.xepozz.php_opcodes.toolWindow.MyToolWindowFactory" id="MyToolWindow"/>
14-
<postStartupActivity implementation="com.github.xepozz.php_opcodes.startup.MyProjectActivity" />
14+
<toolWindow
15+
factoryClass="com.github.xepozz.php_opcodes.CompositeWindowFactory"
16+
id="PHP File Dump" anchor="right" secondary="false"/>
1517
</extensions>
18+
<projectListeners>
19+
<listener class="com.github.xepozz.php_opcodes.startup.ProjectFileEditorListener"
20+
topic="com.intellij.openapi.fileEditor.FileEditorManagerListener" />
21+
</projectListeners>
1622
</idea-plugin>

0 commit comments

Comments
 (0)