diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/SmartStepIntoActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java similarity index 50% rename from java/debugger/impl/src/com/intellij/debugger/actions/SmartStepIntoActionHandler.java rename to java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java index 3786d50a9f8c..294718ee7843 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/SmartStepIntoActionHandler.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -15,75 +15,33 @@ */ package com.intellij.debugger.actions; -import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.SourcePosition; -import com.intellij.debugger.engine.RequestHint; -import com.intellij.debugger.engine.SuspendContextImpl; -import com.intellij.debugger.impl.DebuggerContextImpl; -import com.intellij.debugger.impl.DebuggerSession; -import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.fileEditor.FileEditor; -import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.fileEditor.TextEditor; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.popup.JBPopupFactory; -import com.intellij.openapi.ui.popup.ListPopup; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; -import com.intellij.ui.awt.RelativePoint; import com.intellij.util.containers.OrderedSet; import com.intellij.util.text.CharArrayUtil; -import com.intellij.xdebugger.impl.actions.DebuggerActionHandler; -import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import gnu.trove.TObjectHashingStrategy; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; -public class SmartStepIntoActionHandler extends DebuggerActionHandler { - public void perform(@NotNull final Project project, final AnActionEvent event) { - final DebuggerContextImpl debuggerContext = (DebuggerManagerEx.getInstanceEx(project)).getContext(); - doStep(project, debuggerContext.getSourcePosition(), debuggerContext.getDebuggerSession()); +/** + * User: Alexander Podkhalyuzin + * Date: 22.11.11 + */ +public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler { + @Override + public boolean isAvailable(final SourcePosition position) { + final PsiFile file = position.getFile(); + return file.getLanguage().isKindOf(JavaLanguage.INSTANCE); } - - private static void doStep(final @NotNull Project project, final @Nullable SourcePosition position, final @NotNull DebuggerSession session) { - final VirtualFile file = position != null ? position.getFile().getVirtualFile() : null; - final FileEditor fileEditor = file != null? FileEditorManager.getInstance(project).getSelectedEditor(file) : null; - if (fileEditor instanceof TextEditor) { - final List methods = findReferencedMethods(position); - if (methods.size() > 0) { - if (methods.size() == 1) { - session.stepInto(true, createSmartStepFilter(methods.get(0))); - } - else { - final PsiMethodListPopupStep popupStep = new PsiMethodListPopupStep(methods, new PsiMethodListPopupStep.OnChooseRunnable() { - public void execute(PsiMethod chosenMethod) { - session.stepInto(true, createSmartStepFilter(chosenMethod)); - } - }); - final ListPopup popup = JBPopupFactory.getInstance().createListPopup(popupStep); - final RelativePoint point = DebuggerUIUtil.calcPopupLocation(((TextEditor)fileEditor).getEditor(), position.getLine()); - popup.show(point); - } - return; - } - } - session.stepInto(true, null); - } - - @Nullable - private static RequestHint.SmartStepFilter createSmartStepFilter(final PsiMethod method) { - return new RequestHint.SmartStepFilter(method); - } - - - private static List findReferencedMethods(final SourcePosition position) { + @Override + public List findReferencedMethods(final SourcePosition position) { final int line = position.getLine(); if (line < 0) { return Collections.emptyList(); // the document has been changed @@ -95,8 +53,9 @@ public class SmartStepIntoActionHandler extends DebuggerActionHandler { // the file is not physical return Collections.emptyList(); } - + final Document doc = FileDocumentManager.getInstance().getDocument(vFile); + if (doc == null) return Collections.emptyList(); if (line >= doc.getLineCount()) { return Collections.emptyList(); // the document has been changed } @@ -144,13 +103,4 @@ public class SmartStepIntoActionHandler extends DebuggerActionHandler { } return Collections.emptyList(); } - - public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) { - final DebuggerContextImpl context = (DebuggerManagerEx.getInstanceEx(project)).getContext(); - DebuggerSession debuggerSession = context.getDebuggerSession(); - final boolean isPaused = debuggerSession != null && debuggerSession.isPaused(); - final SuspendContextImpl suspendContext = context.getSuspendContext(); - final boolean hasCurrentThread = suspendContext != null && suspendContext.getThread() != null; - return isPaused && hasCurrentThread; - } } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoActionHandler.java new file mode 100644 index 000000000000..512ab134c392 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoActionHandler.java @@ -0,0 +1,74 @@ +/* + * Copyright 2000-2009 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.debugger.actions; + +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.RequestHint; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.ListPopup; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.util.containers.OrderedSet; +import com.intellij.util.text.CharArrayUtil; +import com.intellij.xdebugger.impl.actions.DebuggerActionHandler; +import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; +import gnu.trove.TObjectHashingStrategy; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; + +public class JvmSmartStepIntoActionHandler extends DebuggerActionHandler { + public void perform(@NotNull final Project project, final AnActionEvent event) { + final DebuggerContextImpl debuggerContext = (DebuggerManagerEx.getInstanceEx(project)).getContext(); + doStep(project, debuggerContext.getSourcePosition(), debuggerContext.getDebuggerSession()); + } + + private static void doStep(final @NotNull Project project, final @Nullable SourcePosition position, final @NotNull DebuggerSession session) { + final VirtualFile file = position != null ? position.getFile().getVirtualFile() : null; + final FileEditor fileEditor = file != null? FileEditorManager.getInstance(project).getSelectedEditor(file) : null; + if (fileEditor instanceof TextEditor) { + for (JvmSmartStepIntoHandler handler : Extensions.getExtensions(JvmSmartStepIntoHandler.EP_NAME)) { + if (handler.isAvailable(position) && handler.doSmartStep(position, session, (TextEditor)fileEditor)) return; + } + } + session.stepInto(true, null); + } + + public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) { + final DebuggerContextImpl context = (DebuggerManagerEx.getInstanceEx(project)).getContext(); + DebuggerSession debuggerSession = context.getDebuggerSession(); + final boolean isPaused = debuggerSession != null && debuggerSession.isPaused(); + final SuspendContextImpl suspendContext = context.getSuspendContext(); + final boolean hasCurrentThread = suspendContext != null && suspendContext.getThread() != null; + return isPaused && hasCurrentThread; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoHandler.java new file mode 100644 index 000000000000..d02029d7bf1b --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoHandler.java @@ -0,0 +1,79 @@ +/* + * Copyright 2000-2011 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.debugger.actions; + +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.RequestHint; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.ListPopup; +import com.intellij.psi.PsiMethod; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * User: Alexander Podkhalyuzin + * Date: 22.11.11 + */ +public abstract class JvmSmartStepIntoHandler { + public static ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.debugger.jvmSmartStepIntoHandler"); + + public abstract List findReferencedMethods(SourcePosition position); + + public abstract boolean isAvailable(SourcePosition position); + + /** + * Override this if you haven't PsiMethod, like in Kotlin. + * @param position + * @param session + * @param fileEditor + * @return false to continue for another handler or for default action (step into) + */ + public boolean doSmartStep(SourcePosition position, final DebuggerSession session, TextEditor fileEditor) { + final List methods = findReferencedMethods(position); + if (methods.size() > 0) { + if (methods.size() == 1) { + session.stepInto(true, getSmartStepFilter(methods.get(0))); + } + else { + final PsiMethodListPopupStep popupStep = new PsiMethodListPopupStep(methods, new PsiMethodListPopupStep.OnChooseRunnable() { + public void execute(PsiMethod chosenMethod) { + session.stepInto(true, getSmartStepFilter(chosenMethod)); + } + }); + final ListPopup popup = JBPopupFactory.getInstance().createListPopup(popupStep); + final RelativePoint point = DebuggerUIUtil.calcPopupLocation(((TextEditor)fileEditor).getEditor(), position.getLine()); + popup.show(point); + } + return true; + } + return false; + } + + /** + * Override in case if your JVMNames slightly different then it can be provided by getJvmSignature method. + * @param method + * @return SmartStepFilter + */ + protected RequestHint.SmartStepFilter getSmartStepFilter(PsiMethod method) { + return new RequestHint.SmartStepFilter(method); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java index 0a8eaa55aa8b..3408858cec81 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java @@ -64,7 +64,7 @@ public class JavaDebuggerSupport extends DebuggerSupport { private final QuickEvaluateActionHandler myQuickEvaluateHandler = new QuickEvaluateActionHandler(); private final JavaDebuggerSettingsPanelProvider myDebuggerSettingsPanelProvider = new JavaDebuggerSettingsPanelProvider(); private final MuteBreakpointsActionHandler myMuteBreakpointsHandler = new MuteBreakpointsActionHandler(); - private final DebuggerActionHandler mySmartStepIntoHandler = new SmartStepIntoActionHandler(); + private final DebuggerActionHandler mySmartStepIntoHandler = new JvmSmartStepIntoActionHandler(); private final DebuggerActionHandler myAddToWatchedActionHandler = new AddToWatchActionHandler(); private JavaMarkObjectActionHandler myMarkObjectActionHandler = new JavaMarkObjectActionHandler(); diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 9853b3fe4eb9..35a81ac95aa2 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -89,6 +89,8 @@ + @@ -1160,6 +1162,7 @@ +