Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,10 @@ dependencies {
implementation(libs.lsp4j)
implementation(libs.lsp4jdebug)
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
testImplementation(libs.junit)
testImplementation(libs.junit.jupiter.api)
testImplementation(libs.openTest4J)
testRuntimeOnly(libs.junit.jupiter.engine)
testRuntimeOnly(libs.junit.vintage.engine)

psScriptAnalyzer(
group = "PSScriptAnalyzer",
Expand Down Expand Up @@ -138,6 +140,10 @@ tasks {
defaultCharacterEncoding = "UTF-8"
}

withType<Test> {
useJUnitPlatform()
}

withType<JavaCompile> {
dependsOn(generateLexer, generateParser)

Expand Down
5 changes: 4 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
[versions]
intellij = "251.23774.318-EAP-SNAPSHOT"
intellijPreview = "251.23774.318-EAP-SNAPSHOT"
junit5 = "5.10.3"
junixsocket = "2.10.1"
lsp4j = "0.24.0"

[libraries]
junit = "junit:junit:4.13.2"
junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit5" }
junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit5" }
junit-vintage-engine = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit5" }
junixsocket-common = { module = "com.kohlschutter.junixsocket:junixsocket-common", version.ref = "junixsocket" }
junixsocket-native-common = { module = "com.kohlschutter.junixsocket:junixsocket-native-common", version.ref = "junixsocket" }
lsp4j = {module = "org.eclipse.lsp4j:org.eclipse.lsp4j", version.ref = "lsp4j"}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import com.intellij.plugin.powershell.ide.MessagesBundle
import com.intellij.plugin.powershell.lang.lsp.LSPInitMain
import com.intellij.plugin.powershell.lang.lsp.PowerShellSettings
import com.intellij.plugin.powershell.lang.lsp.languagehost.PSLanguageHostUtils.getEditorServicesModuleVersion
import com.intellij.plugin.powershell.lang.lsp.languagehost.PSLanguageHostUtils.getEditorServicesStartupScript
import com.intellij.plugin.powershell.lang.lsp.languagehost.PSLanguageHostUtils.getPSExtensionModulesDir
Expand Down Expand Up @@ -76,5 +76,5 @@ object FormUIUtil {
}

val globalSettingsExecutablePath: String?
get() = LSPInitMain.getInstance().state.powerShellExePath
get() = PowerShellSettings.getInstance().state.powerShellExePath
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.plugin.powershell.lang.lsp.LSPInitMain;
import com.intellij.plugin.powershell.lang.lsp.PowerShellSettings;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -49,8 +49,8 @@ public boolean isModified() {

@Override
public void reset() {
LSPInitMain lspInitMain = LSPInitMain.getInstance();
LSPInitMain.PowerShellInfo powerShellInfo = lspInitMain.getState();
PowerShellSettings powerShellSettings = PowerShellSettings.getInstance();
PowerShellSettings.PowerShellInfo powerShellInfo = powerShellSettings.getState();
String psEsPathFromSettings = powerShellInfo.getPowerShellExtensionPath();
String exePathFromSettings = powerShellInfo.getPowerShellExePath();
boolean isEnabledInSettings = powerShellInfo.isUseLanguageServer();
Expand All @@ -65,8 +65,8 @@ public void apply() throws ConfigurationException {
String psExtensionPath = getPSExtensionPathFromForm();
String powerShellExePath = getPowerShellExePathFromForm();
boolean isEnabled = getPSJpanel().getIsUseLanguageServer();
LSPInitMain lspInitMain = LSPInitMain.getInstance();
LSPInitMain.PowerShellInfo powerShellInfo = lspInitMain.getState();
PowerShellSettings powerShellSettings = PowerShellSettings.getInstance();
PowerShellSettings.PowerShellInfo powerShellInfo = powerShellSettings.getState();
FormUIUtil.validatePowerShellExecutablePath(powerShellExePath);
String powerShellVersion = getPSJpanel().getPowerShellVersionValue();
if (StringUtil.isEmpty(powerShellVersion)) throw new ConfigurationException("Can not detect PowerShell version");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.plugin.powershell.ide.MessagesBundle;
import com.intellij.plugin.powershell.lang.lsp.LSPInitMain;
import com.intellij.plugin.powershell.lang.lsp.PowerShellSettings;
import com.intellij.plugin.powershell.lang.lsp.languagehost.PSLanguageHostUtils;
import com.intellij.ui.components.JBTextField;
import org.jetbrains.annotations.NotNull;
Expand All @@ -23,7 +23,7 @@ public class PowerShellExecutableChooserPanel extends JComponent {
private JPanel myJpanel;

public PowerShellExecutableChooserPanel(@Nullable String executablePath) {
String globalSettingsPath = LSPInitMain.getInstance().getState().getPowerShellExePath();
String globalSettingsPath = PowerShellSettings.getInstance().getState().getPowerShellExePath();
updateExecutablePath(StringUtil.isEmpty(executablePath) ? globalSettingsPath : executablePath);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.plugin.powershell.ide.MessagesBundle;
import com.intellij.plugin.powershell.lang.lsp.LSPInitMain;
import com.intellij.plugin.powershell.lang.lsp.PowerShellSettings;
import com.intellij.plugin.powershell.lang.lsp.languagehost.PSLanguageHostUtils;
import com.intellij.plugin.powershell.lang.lsp.languagehost.PowerShellNotInstalled;
import com.intellij.ui.HyperlinkAdapter;
Expand Down Expand Up @@ -177,7 +177,7 @@ private void setBundledPowerShellExtensionPath() throws ConfigurationException {
Companion.setUseBundledPowerShellExtension(true);
}

void fillPowerShellInfo(@NotNull LSPInitMain.PowerShellInfo powerShellInfo) {
void fillPowerShellInfo(@NotNull PowerShellSettings.PowerShellInfo powerShellInfo) {
setEditorServicesVersionLabelValue(powerShellInfo.getEditorServicesModuleVersion());
setPowerShellExtensionPath(powerShellInfo.getPowerShellExtensionPath());
setPowerShellExePath(powerShellInfo.getPowerShellExePath());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.Task
import com.intellij.plugin.powershell.PowerShellIcons
import com.intellij.plugin.powershell.lang.lsp.LSPInitMain
import com.intellij.plugin.powershell.lang.lsp.LanguageServer

class PowerShellConsoleAction : AnAction(PowerShellIcons.FILE) {

override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return
val server = LSPInitMain.getServerWithConsoleProcess(project)
val server = LanguageServer.getInstance(project).serverWithConsoleProcess.value
ProgressManager.getInstance().run(object : Task.Backgroundable(project, "Starting PowerShell terminal console", false) {
override fun run(indicator: ProgressIndicator) {
indicator.text = "Starting PowerShell terminal console..."
server.start()
}
})
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.eclipse.lsp4j.debug.*
import org.eclipse.lsp4j.debug.services.IDebugProtocolServer
import org.jetbrains.concurrency.await
import java.nio.file.Path
import kotlin.io.path.pathString

class PowerShellDebugSession(
client: PSDebugClient, val server: IDebugProtocolServer,
Expand Down Expand Up @@ -50,21 +51,23 @@ class PowerShellDebugSession(
}

fun setBreakpoint(filePath: Path, breakpoint: XLineBreakpoint<XBreakpointProperties<*>>) {
val path = filePath.toRealPath()
coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) {
breakpointsMapMutex.withLock {
if (!breakpointMap.containsKey(filePath))
breakpointMap[filePath] = mutableMapOf()
val bpMap = breakpointMap[filePath]!!
if (!breakpointMap.containsKey(path))
breakpointMap[path] = mutableMapOf()
val bpMap = breakpointMap[path]!!
bpMap[breakpoint.line] = breakpoint
sendBreakpointRequest()
}
}
}

fun removeBreakpoint(filePath: Path, breakpoint: XLineBreakpoint<XBreakpointProperties<*>>) {
val path = filePath.toRealPath()
coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) {
breakpointsMapMutex.withLock {
val bpMap = breakpointMap[filePath] ?: return@launch
val bpMap = breakpointMap[path] ?: return@launch
if (!bpMap.containsKey(breakpoint.line))
return@launch
bpMap.remove(breakpoint.line)
Expand Down Expand Up @@ -124,35 +127,35 @@ class PowerShellDebugSession(
}

private suspend fun sendBreakpointRequest(breakpointMap: Map<Path, MutableMap<Int, XLineBreakpoint<XBreakpointProperties<*>>>>) {
for (breakpointMapEntry in breakpointMap) {
for ((file, breakpointsInFile) in breakpointMap) {
val breakpointArgs = SetBreakpointsArguments()
val source = Source()
source.path = breakpointMapEntry.key.toString()
source.path = file.pathString
breakpointArgs.source = source

breakpointArgs.breakpoints = breakpointMapEntry.value.map {
val bp = it.value
breakpointArgs.breakpoints = breakpointsInFile.map {
val breakpoint = it.value
SourceBreakpoint().apply {
line = bp.line + 1 // ide breakpoints line numbering starts from 0, while PSES start from 1
condition = bp.conditionExpression?.expression
logMessage = bp.logExpressionObject?.expression
line = breakpoint.line + 1 // ide breakpoints line numbering starts from 0, while PSES start from 1
condition = breakpoint.conditionExpression?.expression
logMessage = breakpoint.logExpressionObject?.expression
}
}.toTypedArray()
try {
val setBreakpointsResponse = server.setBreakpoints(breakpointArgs).await()
val responseMap = setBreakpointsResponse.breakpoints.associateBy { x -> x.line - 1 }
breakpointMapEntry.value.forEach {
breakpointsInFile.forEach {
val bp = responseMap[it.value.line]
if (bp?.isVerified == true) {
session.setBreakpointVerified(it.value)
logger.info("Set breakpoint at ${breakpointMapEntry.key}:${bp.line} successfully.")
logger.info("Set breakpoint at $file:${bp.line} successfully.")
} else {
session.setBreakpointInvalid(
it.value,
bp?.message.nullize(nullizeSpaces = true)
?: MessagesBundle.message("powershell.debugger.breakpoints.invalidBreakPoint")
)
logger.info("Invalid breakpoint at ${breakpointMapEntry.key}:${bp?.line}: ${bp?.message}")
logger.info("Invalid breakpoint at $file:${bp?.line}: ${bp?.message}")
}
}
} catch (e: Throwable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.rd.util.toPromise
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.plugin.powershell.ide.MessagesBundle
import com.intellij.plugin.powershell.ide.PluginProjectRoot
import com.intellij.plugin.powershell.ide.debugger.EditorServicesDebuggerHostStarter
Expand All @@ -43,6 +42,7 @@ import org.jetbrains.concurrency.Promise
import java.nio.file.Path
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.io.path.Path
import kotlin.io.path.pathString

class PowerShellProgramDebugRunner : AsyncProgramRunner<RunnerSettings>() {

Expand Down Expand Up @@ -158,15 +158,13 @@ private suspend fun initializeBreakpoints(
) {
if (!debugSession.areBreakpointsMuted()) {
breakpoints.filter { it.sourcePosition != null && it.sourcePosition!!.file.exists() && it.sourcePosition!!.file.isValid && it.isEnabled }
.groupBy { VfsUtil.virtualToIoFile(it.sourcePosition!!.file).toURI().toASCIIString() }
.forEach { entry ->
val fileURL = entry.key
.groupBy { it.sourcePosition!!.file.toNioPath().toRealPath() }
.forEach { (file, breakpoints) ->
val breakpointArgs = SetBreakpointsArguments()
val source = Source()
source.path = fileURL
source.path = file.pathString
breakpointArgs.source = source
val bps = entry.value
breakpointArgs.breakpoints = bps.map {
breakpointArgs.breakpoints = breakpoints.map {
val bp = it
SourceBreakpoint().apply {
line = bp.line + 1 // ide breakpoints line numbering starts from 0, while PSES start from 1
Expand All @@ -185,12 +183,13 @@ private suspend fun launchDebuggee(scriptPath: Path, remoteProxy: IDebugProtocol

val launchArgs: MutableMap<String, Any> = HashMap()
launchArgs["terminal"] = "none"
launchArgs["script"] = scriptPath.toString()
val scriptPathString = scriptPath.toRealPath().pathString
launchArgs["script"] = scriptPathString
launchArgs["noDebug"] = false
launchArgs["__sessionId"] = "sessionId"
launchArgs["Args"] = runtimeArgs
launchArgs["Env"] = envs
logger.info("Starting script file \"$scriptPath\" in a debug session.")
logger.info("Starting script file \"$scriptPathString\" in a debug session.")
remoteProxy.launch(launchArgs).await()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import com.intellij.openapi.util.io.NioFiles.toPath
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.plugin.powershell.ide.runAndLogException
import com.intellij.plugin.powershell.lang.lsp.LSPInitMain
import com.intellij.plugin.powershell.lang.lsp.PowerShellSettings
import com.intellij.plugin.powershell.lang.lsp.languagehost.PowerShellNotInstalled
import com.intellij.terminal.TerminalExecutionConsole
import com.intellij.util.text.nullize
Expand Down Expand Up @@ -54,7 +54,7 @@ class PowerShellScriptCommandLineState(
private fun startProcess(): ProcessHandler {
try {
val command = buildCommand(
runConfiguration.executablePath ?: LSPInitMain.getInstance().getPowerShellExecutable(),
runConfiguration.executablePath ?: PowerShellSettings.getInstance().getPowerShellExecutable(),
runConfiguration.scriptPath,
runConfiguration.getCommandOptions(),
runConfiguration.scriptParameters
Expand Down
Loading