diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java index 91696653318b..a2cfbdad5c45 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java @@ -334,7 +334,7 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio } @Nullable - private PsiFile getPsiFileByLocation(final Project project, final Location location) { + protected PsiFile getPsiFileByLocation(final Project project, final Location location) { if (location == null) { return null; } diff --git a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchPositionManager.java b/java/execution/impl/src/com/intellij/execution/impl/JavaScratchPositionManager.java new file mode 100644 index 000000000000..86318a45ddf9 --- /dev/null +++ b/java/execution/impl/src/com/intellij/execution/impl/JavaScratchPositionManager.java @@ -0,0 +1,81 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.execution.impl; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.PositionManagerImpl; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.PsiManager; +import com.sun.jdi.Location; +import com.sun.jdi.ReferenceType; +import org.jetbrains.annotations.Nullable; + +/** + * @author Eugene Zhuravlev + * Date: 11-Sep-15 + */ +public class JavaScratchPositionManager extends PositionManagerImpl{ + private final VirtualFile myScratchFile; + + public JavaScratchPositionManager(DebugProcessImpl debugProcess, VirtualFile scratchFile) { + super(debugProcess); + myScratchFile = scratchFile; + } + + @Nullable + @Override + protected PsiFile getPsiFileByLocation(Project project, Location location) { + if (location == null) { + return null; + } + final ReferenceType refType = location.declaringType(); + if (refType == null) { + return null; + } + final PsiFile psiFile = PsiManager.getInstance(project).findFile(myScratchFile); + if (!(psiFile instanceof PsiJavaFile)) { + return null; + } + final PsiClass[] classes = ((PsiJavaFile)psiFile).getClasses(); + if (classes.length == 0) { + return null; + } + + final String originalQName = refType.name(); + for (PsiClass aClass : classes) { + if (StringUtil.equals(originalQName, aClass.getQualifiedName())) { + return psiFile; + } + } + + final int dollar = originalQName.indexOf('$'); + final String alternativeQName = dollar > 0? originalQName.substring(0, dollar) : null; + if (!StringUtil.isEmpty(alternativeQName)) { + for (PsiClass aClass : classes) { + if (StringUtil.equals(alternativeQName, aClass.getQualifiedName())) { + return psiFile; + } + } + } + + return null; + } +} diff --git a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java b/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java index b63a3fd86a33..d8c1a40a14bb 100644 --- a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java +++ b/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java @@ -15,14 +15,16 @@ */ package com.intellij.execution.impl; +import com.intellij.debugger.DebuggerManager; +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.debugger.engine.DebugProcessAdapter; +import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.execution.ExecutionException; import com.intellij.execution.Location; import com.intellij.execution.RunConfigurationExtension; import com.intellij.execution.application.ApplicationConfiguration; -import com.intellij.execution.configurations.JavaParameters; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.configurations.RunConfigurationBase; -import com.intellij.execution.configurations.RunnerSettings; +import com.intellij.execution.configurations.*; +import com.intellij.execution.process.ProcessHandler; import com.intellij.ide.scratch.ScratchFileType; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.compiler.CompilerManager; @@ -80,6 +82,24 @@ public class JavaScratchRunConfigurationExtension extends RunConfigurationExtens } } + @Override + protected void attachToProcess(@NotNull final RunConfigurationBase configuration, @NotNull final ProcessHandler handler, @Nullable RunnerSettings runnerSettings) { + if (runnerSettings instanceof DebuggingRunnerData && getScratchFileId(configuration) >= 0) { + final VirtualFile vFile = getScratchVirtualFile(configuration); + if (vFile != null) { + DebuggerManager.getInstance(configuration.getProject()).addDebugProcessListener(handler, new DebugProcessAdapter() { + @Override + public void processAttached(DebugProcess process) { + if (vFile.isValid()) { + process.appendPositionManager(new JavaScratchPositionManager((DebugProcessImpl)process, vFile)); + } + process.removeDebugProcessListener(this); + } + }); + } + } + } + @NotNull protected String getSerializationId() { return "java-scratch-properties"; @@ -87,12 +107,17 @@ public class JavaScratchRunConfigurationExtension extends RunConfigurationExtens @Nullable public static String getScratchFileUrl(RunConfiguration configuration) { + final VirtualFile vFile = getScratchVirtualFile(configuration); + return vFile != null? vFile.getUrl() : null; + } + + @Nullable + private static VirtualFile getScratchVirtualFile(RunConfiguration configuration) { int id = getScratchFileId(configuration); if (id < 0) { return null; } - final VirtualFile vFile = ManagingFS.getInstance().findFileById(id); - return vFile != null? vFile.getUrl() : null; + return ManagingFS.getInstance().findFileById(id); } private static int getScratchFileId(RunConfiguration configuration) {