diff --git a/org.eclipse.jdt.debug.jdi.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug.jdi.tests/META-INF/MANIFEST.MF index f322a599c6..96f671ae0c 100644 --- a/org.eclipse.jdt.debug.jdi.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.debug.jdi.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: JDI Tests Bundle-SymbolicName: org.eclipse.jdt.debug.jdi.tests; singleton:=true -Bundle-Version: 1.2.0.qualifier +Bundle-Version: 1.2.100.qualifier Bundle-ClassPath: . Bundle-Vendor: Eclipse Require-Bundle: org.junit, diff --git a/org.eclipse.jdt.debug.jdi.tests/forceQualifierUpdate.txt b/org.eclipse.jdt.debug.jdi.tests/forceQualifierUpdate.txt new file mode 100644 index 0000000000..9bcdb69a5a --- /dev/null +++ b/org.eclipse.jdt.debug.jdi.tests/forceQualifierUpdate.txt @@ -0,0 +1,2 @@ + +https://github.com/eclipse-platform/eclipse.platform.releng.aggregator/issues/3137 \ No newline at end of file diff --git a/org.eclipse.jdt.debug.jdi.tests/pom.xml b/org.eclipse.jdt.debug.jdi.tests/pom.xml index ec0492497e..2724fd0570 100644 --- a/org.eclipse.jdt.debug.jdi.tests/pom.xml +++ b/org.eclipse.jdt.debug.jdi.tests/pom.xml @@ -18,7 +18,7 @@ org.eclipse.jdt org.eclipse.jdt.debug.jdi.tests - 1.2.0-SNAPSHOT + 1.2.100-SNAPSHOT eclipse-test-plugin ${project.artifactId} diff --git a/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF index c95cd608dd..3da93ba225 100644 --- a/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.debug.tests; singleton:=true -Bundle-Version: 3.12.650.qualifier +Bundle-Version: 3.12.750.qualifier Bundle-ClassPath: javadebugtests.jar Bundle-Activator: org.eclipse.jdt.debug.testplugin.JavaTestPlugin Bundle-Vendor: %providerName diff --git a/org.eclipse.jdt.debug.tests/pom.xml b/org.eclipse.jdt.debug.tests/pom.xml index 0c8fbfce39..b7f65e5d6e 100644 --- a/org.eclipse.jdt.debug.tests/pom.xml +++ b/org.eclipse.jdt.debug.tests/pom.xml @@ -18,7 +18,7 @@ org.eclipse.jdt org.eclipse.jdt.debug.tests - 3.12.650-SNAPSHOT + 3.12.750-SNAPSHOT eclipse-test-plugin ${project.artifactId} diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/TestUtil.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/TestUtil.java index dc45a32db1..c36239f701 100644 --- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/TestUtil.java +++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/TestUtil.java @@ -25,13 +25,16 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import org.eclipse.core.internal.jobs.JobManager; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.internal.ui.views.console.ProcessConsole; import org.eclipse.jdt.debug.testplugin.JavaTestPlugin; +import org.eclipse.jface.text.reconciler.AbstractReconciler; import org.eclipse.swt.widgets.Display; import org.junit.Assert; @@ -110,6 +113,8 @@ public static void runEventLoop() { /** * Utility for waiting until the execution of jobs of any family has finished or timeout is reached. If no jobs are running, the method waits * given minimum wait time. While this method is waiting for jobs, UI events are processed. + *

+ * Note: This method does not wait for jobs that belong to the families specified in {@link #getUsualJobFamiliesToIgnore()}. * * @param owner * name of the caller which will be logged as prefix if the wait times out @@ -120,7 +125,7 @@ public static void runEventLoop() { * @return true if the method timed out, false if all the jobs terminated before the timeout */ public static boolean waitForJobs(String owner, long minTimeMs, long maxTimeMs) { - return waitForJobs(owner, minTimeMs, maxTimeMs, (Object[]) null); + return waitForJobs(owner, minTimeMs, maxTimeMs, getUsualJobFamiliesToIgnore()); } /** @@ -146,6 +151,15 @@ public static boolean waitForJobs(String owner, Object jobFamily, long minTimeMs if (maxTimeMs < minTimeMs) { throw new IllegalArgumentException("Max time is smaller as min time!"); } + // Not so nice workaround for https://github.com/eclipse-jdt/eclipse.jdt.debug/issues/721 + // After https://github.com/eclipse-platform/eclipse.platform.ui/pull/3025 every opened editor + // means there will be a reconciler job running, which is not what we do NOT want to wait for. + // AbstractReconciler.class is the family object we can check for. + if (excludedFamilies == null) { + excludedFamilies = new Object[] { AbstractReconciler.class }; + } else if (excludedFamilies.length == 1 && excludedFamilies[0] == ProcessConsole.class) { + excludedFamilies = getUsualJobFamiliesToIgnore(); + } wakeUpSleepingJobs(jobFamily); final long startNanos = System.nanoTime(); while (System.nanoTime() - startNanos < minTimeMs * 1_000_000L) { @@ -168,6 +182,7 @@ public static boolean waitForJobs(String owner, Object jobFamily, long minTimeMs // only uninteresting jobs running break; } + jobs.forEach(Job::wakeUp); if (!Collections.disjoint(runningJobs, jobs)) { // There is a job which runs already quite some time, don't wait for it to avoid test timeouts @@ -185,11 +200,20 @@ public static boolean waitForJobs(String owner, Object jobFamily, long minTimeMs return false; } - private static void wakeUpSleepingJobs(Object family) { - List sleepingJobs = getSleepingJobs(family); - for (Job job : sleepingJobs) { - job.wakeUp(); - } + /** + * Returns a list of job families that are usually ignored in tests. + *

+ * This is used to avoid waiting for jobs that are not relevant to the test. + *

+ * + * @return an array of job family classes to ignore + */ + public static Object[] getUsualJobFamiliesToIgnore() { + return new Object[] { ProcessConsole.class, AbstractReconciler.class }; + } + + private static void wakeUpSleepingJobs(Object jobFamily) { + Job.getJobManager().wakeUp(jobFamily); } static Set runningJobs = new LinkedHashSet<>(); @@ -210,6 +234,7 @@ private static String dumpRunningOrWaitingJobs(List jobs) { runningJobs.add(job); sb.append("\n'").append(job.toString()).append("'/"); sb.append(job.getClass().getName()); + sb.append(":").append(JobManager.printState(job)); Thread thread = job.getThread(); if (thread != null) { ThreadInfo[] threadInfos = ManagementFactory.getThreadMXBean().getThreadInfo(new long[] { thread.threadId() }, true, true); @@ -239,17 +264,6 @@ public static List getRunningOrWaitingJobs(Object jobFamily, Object... excl return running; } - private static List getSleepingJobs(Object family) { - List sleeping = new ArrayList<>(); - Job[] jobs = Job.getJobManager().find(family); - for (Job job : jobs) { - if (job.getState() == Job.SLEEPING) { - sleeping.add(job); - } - } - return sleeping; - } - private static boolean isRunningOrWaitingJob(Job job) { int state = job.getState(); return (state == Job.RUNNING || state == Job.WAITING); diff --git a/org.eclipse.jdt.debug.ui/plugin.properties b/org.eclipse.jdt.debug.ui/plugin.properties index f34ade20a4..617d69a556 100644 --- a/org.eclipse.jdt.debug.ui/plugin.properties +++ b/org.eclipse.jdt.debug.ui/plugin.properties @@ -345,4 +345,9 @@ OpenFromClipboardAction.name = Open from Clipboard VariablesView.name = Variables CompareObjects.label=Compare -CompareObjects.tooltip=Compare selected objects \ No newline at end of file +CompareObjects.tooltip=Compare selected objects + +ToggleTriggerpointAction.label=Toggle Triggerpoint +ToggleTriggerpointCommand.description=Creates or removes a triggerpoint +ToggleHitpointAction.label=Toggle Breakpoint with Hit Count +ToggleHitpointCommand.description=Creates or removes a breakpoint with hit count \ No newline at end of file diff --git a/org.eclipse.jdt.debug.ui/plugin.xml b/org.eclipse.jdt.debug.ui/plugin.xml index 04cd9bfb04..91232108a1 100644 --- a/org.eclipse.jdt.debug.ui/plugin.xml +++ b/org.eclipse.jdt.debug.ui/plugin.xml @@ -1056,6 +1056,20 @@ menubarPath="debug" id="org.eclipse.jdt.debug.ui.actions.EnableDisableBreakpointRulerActionDelegate"> + + + + + + + + setExtraction(List selec @SuppressWarnings("nls") public List setElementsExtraction(IJavaObject javaObject1) throws DebugException { List contents = new ArrayList<>(); - IJavaThread thread = (IJavaThread) javaObject1.getDebugTarget().getThreads()[0]; + IJavaThread thread = getSuspendedThread(javaObject1); IJavaValue toArray = javaObject1.sendMessage("toArray", "()[Ljava/lang/Object;", null, thread, false); for (IVariable ob : toArray.getVariables()) { contents.add(objectValueExtraction((IJavaValue) ob.getValue())); @@ -661,7 +663,7 @@ public Map iterableExtraction(List @SuppressWarnings("nls") public List iterableElementsExtraction(IJavaObject javaObject1) throws DebugException { List contents = new ArrayList<>(); - IJavaThread thread = (IJavaThread) javaObject1.getDebugTarget().getThreads()[0]; + IJavaThread thread = getSuspendedThread(javaObject1); IJavaObject iterator = (IJavaObject) javaObject1.sendMessage("iterator", "()Ljava/util/Iterator;", null, thread, false); while (true) { IJavaValue hasNext = iterator.sendMessage("hasNext", "()Z", null, thread, false); @@ -707,7 +709,7 @@ public Map listExtraction(List sele @SuppressWarnings("nls") public List listElementsExtraction(IJavaObject javaObject1) throws DebugException { List contents = new ArrayList<>(); - IJavaThread thread = (IJavaThread) javaObject1.getDebugTarget().getThreads()[0]; + IJavaThread thread = getSuspendedThread(javaObject1); IJavaValue toArray = javaObject1.sendMessage("toArray", "()[Ljava/lang/Object;", null, thread, false); for (IVariable ob : toArray.getVariables()) { contents.add(objectValueExtraction((IJavaValue) ob.getValue())); @@ -766,9 +768,9 @@ public Map stringExtraction(List se @SuppressWarnings("nls") public Map mapElementsExtraction(IJavaVariable selectedObject1) throws DebugException { if (selectedObject1.getValue() instanceof IJavaObject javaObject1) { + IJavaThread thread = getSuspendedThread(javaObject1); Map result = new HashMap<>(); List keySet = new ArrayList<>(); - IJavaThread thread = (IJavaThread) javaObject1.getDebugTarget().getThreads()[0]; IJavaObject keySetObject = (IJavaObject) javaObject1.sendMessage("keySet", "()Ljava/util/Set;", null, thread, false); IJavaValue keyToArray = keySetObject.sendMessage("toArray", "()[Ljava/lang/Object;", null, thread, false); for (IVariable ob : keyToArray.getVariables()) { @@ -854,4 +856,20 @@ public static String checkInterfaces(String className) { } } + /** + * Returns a suspended thread for vm message operation + * + * @param value + * IJavaValue object + * @return returns a suspended IJavaThread object + */ + private IJavaThread getSuspendedThread(IJavaValue value) throws DebugException { + IJavaThread thread = (IJavaThread) value.getDebugTarget().getThreads()[0]; + if (!thread.isSuspended()) { + JDIStackFrame frame = (JDIStackFrame) DebugUITools.getDebugContext(); + thread = (IJavaThread) frame.getThread(); + } + return thread; + } + } diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/AbstractRulerToggleBreakpointActionDelegate.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/AbstractRulerToggleBreakpointActionDelegate.java new file mode 100644 index 0000000000..7bfea8736a --- /dev/null +++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/AbstractRulerToggleBreakpointActionDelegate.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2022 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.debug.ui.actions; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.swt.widgets.Event; +import org.eclipse.ui.IActionDelegate2; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.texteditor.AbstractRulerActionDelegate; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; + +public abstract class AbstractRulerToggleBreakpointActionDelegate extends AbstractRulerActionDelegate implements IActionDelegate2 { + + protected ITextEditor currentEditor; + private IAction dummyAction; + + @Override + protected IAction createAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) { + dummyAction = new Action() { + // empty implementation to make compiler happy + }; + return dummyAction; + } + + @Override + public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) { + if (targetEditor instanceof ITextEditor textEditor) { + currentEditor = textEditor; + } else { + currentEditor = null; + } + } + + @Override + public void init(IAction action) { + } + + @Override + public void dispose() { + currentEditor = null; + dummyAction = null; + super.dispose(); + } + + @Override + public void runWithEvent(IAction action, Event event) { + if (currentEditor == null) { + return; + } + IVerticalRulerInfo rulerInfo = currentEditor.getAdapter(IVerticalRulerInfo.class); + if (rulerInfo == null) { + return; + } + int lineOfLastMouseButtonActivity = rulerInfo.getLineOfLastMouseButtonActivity(); + if (lineOfLastMouseButtonActivity < 0) { + return; + } + IDocument document = getDocument(currentEditor); + if (document == null) { + return; + } + ToggleBreakpointAdapter toggle = new ToggleBreakpointAdapter(); + try { + ITextSelection selection = getTextSelection(currentEditor, document, lineOfLastMouseButtonActivity); + if (toggle.canToggleLineBreakpoints(currentEditor, selection)) { + boolean success = doWork(currentEditor, selection); + if (success) { + toggle.toggleBreakpoints(currentEditor, selection); + } + } + } catch (BadLocationException | CoreException e) { + DebugUIPlugin.log(e); + } + } + + protected static IDocument getDocument(ITextEditor editor) { + IDocumentProvider provider = editor.getDocumentProvider(); + if (provider != null) { + return provider.getDocument(editor.getEditorInput()); + } + IDocument doc = editor.getAdapter(IDocument.class); + if (doc != null) { + return doc; + } + return null; + } + + protected ITextSelection getTextSelection(ITextEditor editor, IDocument document, int line) throws BadLocationException { + IRegion region = document.getLineInformation(line); + ITextSelection textSelection = new TextSelection(document, region.getOffset(), 0); + ISelectionProvider provider = editor.getSite().getSelectionProvider(); + if (provider != null) { + ISelection selection = provider.getSelection(); + if (selection instanceof ITextSelection && ((ITextSelection) selection).getStartLine() <= line + && ((ITextSelection) selection).getEndLine() >= line) { + textSelection = (ITextSelection) selection; + } + } + return textSelection; + } + + abstract protected boolean doWork(ITextEditor editor, ITextSelection selection); +} diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointToggleUtils.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointToggleUtils.java index 903d26ee9a..a45fdbd66c 100644 --- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointToggleUtils.java +++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointToggleUtils.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2022 IBM Corporation and others. + * Copyright (c) 2016, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -24,18 +24,28 @@ */ public class BreakpointToggleUtils { - private static boolean isTracepoint = false; - private static boolean isLambdaEntryBreakpoint = false; + private static boolean isTracepoint; + private static boolean isLambdaEntryBreakpoint; + private static boolean isTriggerpoint; + private static boolean isHitPoint; + private static int hitCount; - - public static void setUnsetTracepoints(boolean tracePoint) { + public static void setUnsetTracepoint(boolean tracePoint) { isTracepoint = tracePoint; } - public static boolean isToggleTracepoints() { + public static boolean isToggleTracepoint() { return isTracepoint; } + public static void setTriggerpoint(boolean triggerPoint) { + isTriggerpoint = triggerPoint; + } + + public static boolean isTriggerpoint() { + return isTriggerpoint; + } + public static void setUnsetLambdaEntryBreakpoint(boolean lambdaEntryBreakpoint) { isLambdaEntryBreakpoint = lambdaEntryBreakpoint; } @@ -44,6 +54,25 @@ public static boolean isToggleLambdaEntryBreakpoint() { return isLambdaEntryBreakpoint; } + public static void setHitpoint(boolean hitcount) { + isHitPoint = hitcount; + if (!hitcount) { + setHitCount(0); + } + } + + public static boolean isHitpoint() { + return isHitPoint; + } + + public static void setHitCount(int hit) { + hitCount = hit; + } + + public static int getHitCount() { + return hitCount; + } + /** * Convenience method for printing messages to the status line * diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/NavigateToVarDeclAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/NavigateToVarDeclAction.java index 3a62fb0df1..d39f151b8c 100644 --- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/NavigateToVarDeclAction.java +++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/NavigateToVarDeclAction.java @@ -17,31 +17,30 @@ import java.util.List; import java.util.stream.Collectors; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.WorkingCopyOwner; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.LambdaExpression; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.debug.core.IJavaStackFrame; import org.eclipse.jdt.debug.core.IJavaVariable; -import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jface.action.IAction; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; @@ -58,10 +57,7 @@ public void run(IAction action) { Object frame = DebugUITools.getDebugContext(); if (frame instanceof IStackFrame jFrame) { if (jFrame instanceof IJavaStackFrame javaStackFrame) { - String type = javaStackFrame.getLaunch().getLaunchConfiguration().getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String) null); - IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(type); - IJavaProject iJavaProject = JavaCore.create(project); - IType iType = iJavaProject.findType(javaStackFrame.getReceivingTypeName()); + int currentLine = javaStackFrame.getLineNumber(); String currentMethod = javaStackFrame.getMethodName(); List frameParams = javaStackFrame.getArgumentTypeNames(); List ref = frameParams.stream().map(e -> { @@ -71,49 +67,112 @@ public void run(IAction action) { } return e; }).collect(Collectors.toList()); - ICompilationUnit cu = iType.getCompilationUnit(); - ASTParser parse = ASTParser.newParser(AST.getJLSLatest()); - parse.setSource(cu); - parse.setKind(ASTParser.K_COMPILATION_UNIT); - parse.setResolveBindings(true); - CompilationUnit ast = (CompilationUnit) parse.createAST(null); - ast.accept(new ASTVisitor() { - boolean meth = false; - boolean found = false; - @Override - public boolean visit(MethodDeclaration node) { - if (node.getName().getIdentifier().equals(currentMethod)) { - List parameters = node.parameters(); - List methodParams = parameters.stream().map(p -> ((SingleVariableDeclaration) p).getType().toString()).toList(); - if (methodParams.equals(ref)) { - meth = true; - for (Object op : node.parameters()) { - SingleVariableDeclaration parm = (SingleVariableDeclaration) op; - if (parm.getName().getIdentifier().equals(name)) { - highlightLine(ast, cu, node.getStartPosition()); - found = true; - return false; + final ICompilationUnit[] cu = { null }; + IWorkbenchWindow window = getWorkbenchWindow(); + IEditorPart editor = window.getActivePage().getActiveEditor(); + IJavaElement element = JavaUI.getEditorInputJavaElement(editor.getEditorInput()); + + if (element instanceof ICompilationUnit icu) { + cu[0] = icu; + } else if (element instanceof IClassFile icf) { + cu[0] = icf.getWorkingCopy(new WorkingCopyOwner() { + }, null); + } else { + cu[0] = null; + } + + ASTParser parser = ASTParser.newParser(AST.getJLSLatest()); + parser.setSource(cu[0]); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + parser.setResolveBindings(true); + + if (parser.createAST(null) instanceof CompilationUnit ast) { + ast.accept(new ASTVisitor() { + boolean meth = false; + boolean found = false; + boolean inTargetContext = false; + @Override + public boolean visit(MethodDeclaration node) { + if (node.getName().getIdentifier().equals(currentMethod)) { + List parameters = node.parameters(); + List methodParams = parameters.stream().map(p -> ((SingleVariableDeclaration) p).getType().toString()).toList(); + int start = node.getStartPosition(); + int end = start + node.getLength(); + int startLine = ast.getLineNumber(start); + int endLine = ast.getLineNumber(end); + if (currentLine >= startLine && currentLine <= endLine) { + inTargetContext = true; + if (methodParams.equals(ref)) { + meth = true; + for (Object op : node.parameters()) { + if (op instanceof SingleVariableDeclaration param) { + if (param.getName().getIdentifier().equals(name)) { + final ICompilationUnit finalCu = cu[0]; + highlightLine(ast, finalCu, param.getStartPosition(), editor); + found = true; + return false; + } + } + } + return true; } } - return true; } + return true; } - return true; - } - @Override - public boolean visit(VariableDeclarationFragment node) { - if (found) { - return false; + @Override + public void endVisit(MethodDeclaration node) { + inTargetContext = false; + } - if (meth && node.getName().getIdentifier().equals(name)) { - found = true; - highlightLine(ast, cu, node.getStartPosition()); - return false; + + @Override + public boolean visit(VariableDeclarationFragment node) { + if (found) { + return false; + } + if ((meth || inTargetContext) && node.getName().getIdentifier().equals(name)) { + found = true; + final ICompilationUnit finalCu = cu[0]; + highlightLine(ast, finalCu, node.getStartPosition(), editor); + return false; + } + return true; } - return true; - } - }); + + @Override + public boolean visit(LambdaExpression node) { + if (found) { + return false; + } + List parameters = node.parameters(); + int start = node.getStartPosition(); + int end = start + node.getLength(); + int startLine = ast.getLineNumber(start); + int endLine = ast.getLineNumber(end); + if (currentLine >= startLine && currentLine <= endLine) { + inTargetContext = true; + for (Object param : parameters) { + if (param instanceof SingleVariableDeclaration svd) { + if (svd.getName().getIdentifier().equals(name)) { + highlightLine(ast, cu[0], svd.getStartPosition(), editor); + found = true; + return false; + } + } + } + } + return true; + } + + @Override + public void endVisit(LambdaExpression node) { + inTargetContext = false; + } + }); + + } } } } @@ -131,19 +190,21 @@ public boolean visit(VariableDeclarationFragment node) { * compilation unit of the code * @param startPos * start position of the code want to highlight + * @param editor + * active editor info */ - private void highlightLine(CompilationUnit ast, ICompilationUnit cu, int startPos) { + private void highlightLine(CompilationUnit ast, ICompilationUnit cu, int startPos, IEditorPart editor) { int line = ast.getLineNumber(startPos); try { - IEditorPart editor = JavaUI.openInEditor(cu); if (editor instanceof ITextEditor txtEd) { IDocumentProvider prov = txtEd.getDocumentProvider(); IDocument doc = prov.getDocument(txtEd.getEditorInput()); - IRegion lineReg = doc.getLineInformation(line - 1); + int adjustedLine = Math.max(0, line - 1); + IRegion lineReg = doc.getLineInformation(adjustedLine); txtEd.selectAndReveal(lineReg.getOffset(), lineReg.getLength()); } } catch (Exception e) { DebugUIPlugin.log(e); } } -} +} \ No newline at end of file diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RetargetToggleTracepointAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RetargetToggleTracepointAction.java index 22aad534bb..494d8a861f 100644 --- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RetargetToggleTracepointAction.java +++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RetargetToggleTracepointAction.java @@ -33,7 +33,7 @@ public class RetargetToggleTracepointAction extends RetargetToggleBreakpointActi */ @Override protected void performAction(Object target, ISelection selection, IWorkbenchPart part) throws CoreException { - BreakpointToggleUtils.setUnsetTracepoints(true); + BreakpointToggleUtils.setUnsetTracepoint(true); super.performAction(target, selection, part); } diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleHitBreakpointActionDelegate.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleHitBreakpointActionDelegate.java new file mode 100644 index 0000000000..8d184e27db --- /dev/null +++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleHitBreakpointActionDelegate.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2025 IBM Corporation + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.debug.ui.actions; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; +import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.texteditor.ITextEditor; + +public class RulerToggleHitBreakpointActionDelegate extends AbstractRulerToggleBreakpointActionDelegate { + + @Override + protected boolean doWork(ITextEditor editor, ITextSelection selection) { + IJavaLineBreakpoint jlp = ToggleBreakpointAdapter.findExistingBreakpoint(currentEditor, selection); + + try { + hitCountDialog(); + if (BreakpointToggleUtils.getHitCount() < 1) { + return false; + } + if (jlp != null) { + ToggleBreakpointAdapter.deleteBreakpoint(jlp, editor, null); + } + BreakpointToggleUtils.setHitpoint(true); + return true; + } catch (CoreException e) { + DebugUIPlugin.log(e); + return false; + } + } + + private void hitCountDialog() { + String title = ActionMessages.BreakpointHitCountAction_Set_Breakpoint_Hit_Count_2; + String message = ActionMessages.BreakpointHitCountAction__Enter_the_new_hit_count_for_the_breakpoint__3; + IInputValidator validator = new IInputValidator() { + int hitCount = -1; + + @Override + public String isValid(String value) { + try { + hitCount = Integer.parseInt(value.trim()); + } catch (NumberFormatException nfe) { + hitCount = -1; + } + if (hitCount < 1) { + return ActionMessages.BreakpointHitCountAction_Value_must_be_positive_integer; + } + // no error + return null; + } + }; + + Shell activeShell = JDIDebugUIPlugin.getActiveWorkbenchShell(); + InputDialog input = new InputDialog(activeShell, title, message, "", validator); //$NON-NLS-1$ + if (input.open() == Window.CANCEL) { + return; + } + String hit = input.getValue(); + if (hit != null && !hit.isEmpty()) { + BreakpointToggleUtils.setHitCount(Integer.parseInt(hit)); + } + } +} \ No newline at end of file diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleLambdaEntryBreakpointActionDelegate.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleLambdaEntryBreakpointActionDelegate.java index df131df145..e3ac4d8d9a 100644 --- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleLambdaEntryBreakpointActionDelegate.java +++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleLambdaEntryBreakpointActionDelegate.java @@ -13,106 +13,14 @@ *******************************************************************************/ package org.eclipse.jdt.internal.debug.ui.actions; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.debug.internal.ui.DebugUIPlugin; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.text.TextSelection; -import org.eclipse.jface.text.source.IVerticalRulerInfo; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.swt.widgets.Event; -import org.eclipse.ui.IActionDelegate2; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.texteditor.AbstractRulerActionDelegate; -import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; -public class RulerToggleLambdaEntryBreakpointActionDelegate extends AbstractRulerActionDelegate implements IActionDelegate2 { - - private IEditorPart currentEditor; - private IAction dummyAction; +public class RulerToggleLambdaEntryBreakpointActionDelegate extends AbstractRulerToggleBreakpointActionDelegate { @Override - protected IAction createAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) { - dummyAction = new Action() { - // empty implementation to make compiler happy - }; - return dummyAction; - } - - @Override - public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) { - currentEditor = targetEditor; - } - - @Override - public void init(IAction action) { - } - - @Override - public void dispose() { - currentEditor = null; - dummyAction = null; - super.dispose(); - } - - @Override - public void runWithEvent(IAction action, Event event) { - if (!(currentEditor instanceof ITextEditor)) { - return; - } - IVerticalRulerInfo rulerInfo = currentEditor.getAdapter(IVerticalRulerInfo.class); - if (rulerInfo == null) { - return; - } - int lineOfLastMouseButtonActivity = rulerInfo.getLineOfLastMouseButtonActivity(); - if (lineOfLastMouseButtonActivity < 0) { - return; - } - IDocument document = getDocument((ITextEditor) currentEditor); - if (document == null) { - return; - } - ToggleBreakpointAdapter toggle = new ToggleBreakpointAdapter(); - try { - ITextSelection selection = getTextSelection(currentEditor, document, lineOfLastMouseButtonActivity); - if (toggle.canToggleLineBreakpoints(currentEditor, selection)) { - BreakpointToggleUtils.setUnsetLambdaEntryBreakpoint(true); - toggle.toggleBreakpoints(currentEditor, selection); - } - } catch (BadLocationException | CoreException e) { - DebugUIPlugin.log(e); - } - } - - private static IDocument getDocument(ITextEditor editor) { - IDocumentProvider provider = editor.getDocumentProvider(); - if (provider != null) { - return provider.getDocument(editor.getEditorInput()); - } - IDocument doc = editor.getAdapter(IDocument.class); - if (doc != null) { - return doc; - } - return null; - } - - private static ITextSelection getTextSelection(IEditorPart editor, IDocument document, int line) throws BadLocationException { - IRegion region = document.getLineInformation(line); - ITextSelection textSelection = new TextSelection(document, region.getOffset(), 0); - ISelectionProvider provider = editor.getSite().getSelectionProvider(); - if (provider != null) { - ISelection selection = provider.getSelection(); - if (selection instanceof ITextSelection && ((ITextSelection) selection).getStartLine() <= line - && ((ITextSelection) selection).getEndLine() >= line) { - textSelection = (ITextSelection) selection; - } - } - return textSelection; + protected boolean doWork(ITextEditor editor, ITextSelection selection) { + BreakpointToggleUtils.setUnsetLambdaEntryBreakpoint(true); + return true; } } diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleTracepointActionDelegate.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleTracepointActionDelegate.java index fbc6c4413c..849f5b10ed 100644 --- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleTracepointActionDelegate.java +++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleTracepointActionDelegate.java @@ -15,93 +15,24 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.internal.ui.DebugUIPlugin; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IRegion; +import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.text.TextSelection; -import org.eclipse.jface.text.source.IVerticalRulerInfo; -import org.eclipse.swt.widgets.Event; -import org.eclipse.ui.IActionDelegate2; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.texteditor.AbstractRulerActionDelegate; -import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; -public class RulerToggleTracepointActionDelegate extends AbstractRulerActionDelegate implements IActionDelegate2 { - - private IEditorPart currentEditor; - private IAction dummyAction; - - @Override - protected IAction createAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) { - dummyAction = new Action() { - // empty implementation to make compiler happy - }; - return dummyAction; - } - - @Override - public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) { - currentEditor = targetEditor; - } - - @Override - public void init(IAction action) { - } +public class RulerToggleTracepointActionDelegate extends AbstractRulerToggleBreakpointActionDelegate { @Override - public void dispose() { - currentEditor = null; - dummyAction = null; - super.dispose(); - } - - @Override - public void runWithEvent(IAction action, Event event) { - if (!(currentEditor instanceof ITextEditor)) { - return; - } - IVerticalRulerInfo rulerInfo = currentEditor.getAdapter(IVerticalRulerInfo.class); - if (rulerInfo == null) { - return; - } - int lineOfLastMouseButtonActivity = rulerInfo.getLineOfLastMouseButtonActivity(); - if (lineOfLastMouseButtonActivity < 0) { - return; - } - IDocument document = getDocument((ITextEditor) currentEditor); - if (document == null) { - return; - } - ToggleBreakpointAdapter toggle = new ToggleBreakpointAdapter(); + protected boolean doWork(ITextEditor editor, ITextSelection selection) { + IJavaLineBreakpoint jlp = ToggleBreakpointAdapter.findExistingBreakpoint(currentEditor, selection); try { - ITextSelection selection = getTextSelection(document, lineOfLastMouseButtonActivity); - if (toggle.canToggleLineBreakpoints(currentEditor, selection)) { - BreakpointToggleUtils.setUnsetTracepoints(true); - toggle.toggleBreakpoints(currentEditor, selection); + if (jlp != null && !jlp.isConditionEnabled()) { + ToggleBreakpointAdapter.deleteBreakpoint(jlp, editor, null); } - } catch (BadLocationException | CoreException e) { + BreakpointToggleUtils.setUnsetTracepoint(true); + return true; + } catch (CoreException e) { DebugUIPlugin.log(e); + return false; } } - - private static IDocument getDocument(ITextEditor editor) { - IDocumentProvider provider = editor.getDocumentProvider(); - if (provider != null) { - return provider.getDocument(editor.getEditorInput()); - } - IDocument doc = editor.getAdapter(IDocument.class); - if (doc != null) { - return doc; - } - return null; - } - - private static ITextSelection getTextSelection(IDocument document, int line) throws BadLocationException { - IRegion region = document.getLineInformation(line); - return new TextSelection(document, region.getOffset(), 0); - } -} +} \ No newline at end of file diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleTriggerBreakpointActionDelegate.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleTriggerBreakpointActionDelegate.java new file mode 100644 index 0000000000..f8c6f8aa1e --- /dev/null +++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RulerToggleTriggerBreakpointActionDelegate.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2025 IBM Corporation + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.debug.ui.actions; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.ui.texteditor.ITextEditor; + +public class RulerToggleTriggerBreakpointActionDelegate extends AbstractRulerToggleBreakpointActionDelegate { + + @Override + protected boolean doWork(ITextEditor editor, ITextSelection selection) { + IJavaLineBreakpoint jlp = ToggleBreakpointAdapter.findExistingBreakpoint(currentEditor, selection); + try { + if (jlp != null && !jlp.isTriggerPoint()) { + ToggleBreakpointAdapter.deleteBreakpoint(jlp, editor, null); + } + BreakpointToggleUtils.setTriggerpoint(true); + return true; + } catch (CoreException e) { + DebugUIPlugin.log(e); + return false; + } + } +} \ No newline at end of file diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ToggleBreakpointAdapter.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ToggleBreakpointAdapter.java index f8747cf2a7..f7a8d6dca8 100644 --- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ToggleBreakpointAdapter.java +++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ToggleBreakpointAdapter.java @@ -239,7 +239,7 @@ protected IStatus run(IProgressMonitor monitor) { } catch (CoreException e) { return e.getStatus(); } finally { - BreakpointToggleUtils.setUnsetTracepoints(false); + BreakpointToggleUtils.setUnsetTracepoint(false); } } }; @@ -260,7 +260,7 @@ protected IStatus run(IProgressMonitor monitor) { } catch (CoreException e) { return e.getStatus(); } finally { - BreakpointToggleUtils.setUnsetTracepoints(false); + BreakpointToggleUtils.setUnsetTracepoint(false); } } }; @@ -281,7 +281,7 @@ protected IStatus run(IProgressMonitor monitor) { } catch (CoreException e) { return e.getStatus(); } finally { - BreakpointToggleUtils.setUnsetTracepoints(false); + BreakpointToggleUtils.setUnsetTracepoint(false); } } }; @@ -398,9 +398,9 @@ private static void doToggleMethodBreakpoint(IMethod member, IWorkbenchPart part private static void doToggleMethodBreakpoint(IMethod member, String lambdaMethodName, String lambdaMethodSignature, IWorkbenchPart part, ISelection finalSelection, IProgressMonitor monitor) throws CoreException { IJavaBreakpoint breakpoint = getMethodBreakpoint(member); if (breakpoint != null) { - if (BreakpointToggleUtils.isToggleTracepoints()) { + if (BreakpointToggleUtils.isToggleTracepoint()) { deleteTracepoint(breakpoint, part, monitor); - BreakpointToggleUtils.setUnsetTracepoints(false); + BreakpointToggleUtils.setUnsetTracepoint(false); } else { if (ValidBreakpointLocationLocator.LOCATION_METHOD_CLOSE) { ValidBreakpointLocationLocator.LOCATION_METHOD_CLOSE = false; @@ -437,7 +437,7 @@ private static void doToggleMethodBreakpoint(IMethod member, String lambdaMethod IResource resource = BreakpointUtils.getBreakpointResource(member); String qualifiedName = getQualifiedName(type); IJavaMethodBreakpoint methodBreakpoint = JDIDebugModel.createMethodBreakpoint(resource, qualifiedName, mname, signature, true, false, false, -1, start, end, 0, true, attributes); - if (BreakpointToggleUtils.isToggleTracepoints() && finalSelection instanceof ITextSelection && part instanceof JavaEditor) { + if (BreakpointToggleUtils.isToggleTracepoint() && finalSelection instanceof ITextSelection && part instanceof JavaEditor) { String pattern = getCodeTemplate((ITextSelection) finalSelection, (JavaEditor) part); if (pattern != null) { pattern = pattern.trim(); @@ -446,13 +446,27 @@ private static void doToggleMethodBreakpoint(IMethod member, String lambdaMethod methodBreakpoint.setConditionEnabled(true); methodBreakpoint.setConditionSuspendOnTrue(true); } - BreakpointToggleUtils.setUnsetTracepoints(false); + BreakpointToggleUtils.setUnsetTracepoint(false); } if (ValidBreakpointLocationLocator.LOCATION_METHOD_CLOSE) { methodBreakpoint.setEntry(false); methodBreakpoint.setExit(true); ValidBreakpointLocationLocator.LOCATION_METHOD_CLOSE = false; } + + if (BreakpointToggleUtils.isTriggerpoint() && finalSelection instanceof ITextSelection && part instanceof JavaEditor) { + + methodBreakpoint.setTriggerPoint(true); + BreakpointToggleUtils.setTriggerpoint(false); + + } + + if (BreakpointToggleUtils.isHitpoint() && finalSelection instanceof ITextSelection && part instanceof JavaEditor) { + + methodBreakpoint.setHitCount(BreakpointToggleUtils.getHitCount()); + BreakpointToggleUtils.setHitpoint(false); + + } } /** @@ -499,7 +513,7 @@ static IStatus doLineBreakpointToggle(ISelection selection, IWorkbenchPart part, Display.getDefault().asyncExec(() -> ErrorDialog.openError(JDIDebugUIPlugin.getShell(), ActionMessages.ToggleBreakpointAdapter_ErrorTitle, null, status)); return status; } - if (locator == null && BreakpointToggleUtils.isToggleTracepoints()) { + if (locator == null && BreakpointToggleUtils.isToggleTracepoint()) { CompilationUnit cUnit = parseCompilationUnit(type.getTypeRoot()); locator = new ValidBreakpointLocationLocator(cUnit, tsel.getStartLine() + 1, true, bestMatch); cUnit.accept(locator); @@ -518,9 +532,15 @@ static IStatus doLineBreakpointToggle(ISelection selection, IWorkbenchPart part, int lnumber = locator == null ? tsel.getStartLine() + 1 : locator.getLineLocation(); IJavaLineBreakpoint existingBreakpoint = JDIDebugModel.lineBreakpointExists(resource, tname, lnumber); if (existingBreakpoint != null) { - if (BreakpointToggleUtils.isToggleTracepoints()) { + if (BreakpointToggleUtils.isToggleTracepoint()) { deleteTracepoint(existingBreakpoint, editor, monitor); - BreakpointToggleUtils.setUnsetTracepoints(false); + BreakpointToggleUtils.setUnsetTracepoint(false); + } else if (BreakpointToggleUtils.isTriggerpoint()) { + deleteBreakpoint(existingBreakpoint, editor, monitor); + BreakpointToggleUtils.setTriggerpoint(false); + } else if (BreakpointToggleUtils.isHitpoint()) { + deleteBreakpoint(existingBreakpoint, editor, monitor); + BreakpointToggleUtils.setHitpoint(false); } else { deleteBreakpoint(existingBreakpoint, editor, monitor); } @@ -542,28 +562,41 @@ static IStatus doLineBreakpointToggle(ISelection selection, IWorkbenchPart part, } BreakpointUtils.addJavaBreakpointAttributes(attributes, type); IJavaLineBreakpoint breakpoint = JDIDebugModel.createLineBreakpoint(resource, tname, lnumber, charstart, charend, 0, true, attributes); - if (BreakpointToggleUtils.isToggleTracepoints() && selection instanceof ITextSelection && part instanceof JavaEditor) { - String pattern = getCodeTemplate((ITextSelection) selection, (JavaEditor) part); - if (pattern != null) { - pattern = pattern.trim(); - pattern = pattern.replaceAll("\\\t", ""); //$NON-NLS-1$//$NON-NLS-2$ - breakpoint.setCondition(pattern); - breakpoint.setConditionEnabled(true); - breakpoint.setConditionSuspendOnTrue(true); + if (BreakpointToggleUtils.isToggleTracepoint()) { + if (selection instanceof ITextSelection && part instanceof JavaEditor) { + String pattern = getCodeTemplate((ITextSelection) selection, (JavaEditor) part); + if (pattern != null) { + pattern = pattern.trim(); + pattern = pattern.replaceAll("\\\t", ""); //$NON-NLS-1$//$NON-NLS-2$ + breakpoint.setCondition(pattern); + breakpoint.setConditionEnabled(true); + breakpoint.setConditionSuspendOnTrue(true); + } } + BreakpointToggleUtils.setUnsetTracepoint(false); + } - BreakpointToggleUtils.setUnsetTracepoints(false); + if (BreakpointToggleUtils.isTriggerpoint()) { + if (selection instanceof ITextSelection && part instanceof JavaEditor) { + breakpoint.setTriggerPoint(true); + } + BreakpointToggleUtils.setTriggerpoint(false); + } + + if (BreakpointToggleUtils.isHitpoint()) { + if (selection instanceof ITextSelection && part instanceof JavaEditor) { + breakpoint.setHitCount(BreakpointToggleUtils.getHitCount()); + } + BreakpointToggleUtils.setHitpoint(false); } + if (locator == null) { new BreakpointLocationVerifierJob(document, parseCompilationUnit(type.getTypeRoot()), breakpoint, lnumber, tname, type, editor, bestMatch).schedule(); } - if (BreakpointToggleUtils.isToggleTracepoints()) { - BreakpointToggleUtils.setUnsetTracepoints(false); - } } catch (CoreException ce) { return ce.getStatus(); } finally { - BreakpointToggleUtils.setUnsetTracepoints(false); + BreakpointToggleUtils.setUnsetTracepoint(false); } return Status.OK_STATUS; } @@ -625,7 +658,21 @@ static IStatus doToggleClassBreakpoints(IWorkbenchPart part, ISelection selectio } IResource resource = BreakpointUtils.getBreakpointResource(member); String qualifiedName = getQualifiedName(type); - JDIDebugModel.createClassPrepareBreakpoint(resource, qualifiedName, IJavaClassPrepareBreakpoint.TYPE_CLASS, start, end, true, map); + IJavaClassPrepareBreakpoint classBreakpoint = JDIDebugModel.createClassPrepareBreakpoint(resource, qualifiedName, IJavaClassPrepareBreakpoint.TYPE_CLASS, start, end, true, map); + + if (BreakpointToggleUtils.isTriggerpoint()) { + + classBreakpoint.setTriggerPoint(true); + BreakpointToggleUtils.setTriggerpoint(false); + + } + + if (BreakpointToggleUtils.isHitpoint()) { + + classBreakpoint.setHitCount(BreakpointToggleUtils.getHitCount()); + BreakpointToggleUtils.setHitpoint(false); + + } return Status.OK_STATUS; } @@ -1124,7 +1171,22 @@ static IStatus doToggleWatchpoints(IWorkbenchPart part, ISelection finalSelectio BreakpointUtils.addJavaBreakpointAttributes(attributes, javaField); resource = BreakpointUtils.getBreakpointResource(type); } - JDIDebugModel.createWatchpoint(resource, typeName, fieldName, -1, start, end, 0, true, attributes); + + IJavaWatchpoint watchPoint = JDIDebugModel.createWatchpoint(resource, typeName, fieldName, -1, start, end, 0, true, attributes); + + if (BreakpointToggleUtils.isTriggerpoint()) { + + watchPoint.setTriggerPoint(true); + BreakpointToggleUtils.setTriggerpoint(false); + + } + + if (BreakpointToggleUtils.isHitpoint()) { + + watchPoint.setHitCount(BreakpointToggleUtils.getHitCount()); + BreakpointToggleUtils.setHitpoint(false); + + } } return Status.OK_STATUS; } @@ -1468,9 +1530,9 @@ public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws if (mtype == IJavaElement.FIELD || mtype == IJavaElement.METHOD || mtype == IJavaElement.INITIALIZER) { toggleFieldOrMethodBreakpoints(part, selection); } else if (member.getElementType() == IJavaElement.TYPE) { - if (BreakpointToggleUtils.isToggleTracepoints()) { + if (BreakpointToggleUtils.isToggleTracepoint()) { BreakpointToggleUtils.report(ActionMessages.TracepointToggleAction_Unavailable, part); - BreakpointToggleUtils.setUnsetTracepoints(false); + BreakpointToggleUtils.setUnsetTracepoint(false); return; } toggleClassBreakpoints(part, sel); @@ -1480,7 +1542,7 @@ public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws } } - private static IJavaLineBreakpoint findExistingBreakpoint(ITextEditor editor, ITextSelection ts) { + public static IJavaLineBreakpoint findExistingBreakpoint(ITextEditor editor, ITextSelection ts) { IDocumentProvider documentProvider = editor.getDocumentProvider(); if (documentProvider == null) { return null; @@ -1534,13 +1596,27 @@ private void toggleFieldOrMethodBreakpoints(IWorkbenchPart part, ISelection sele // remove line breakpoint if present first IJavaLineBreakpoint breakpoint = findExistingBreakpoint(editor, ts); if (breakpoint != null) { - if (BreakpointToggleUtils.isToggleTracepoints()) { + if (BreakpointToggleUtils.isToggleTracepoint()) { deleteTracepoint(breakpoint, part, null); - BreakpointToggleUtils.setUnsetTracepoints(false); + BreakpointToggleUtils.setUnsetTracepoint(false); + + } else if (BreakpointToggleUtils.isTriggerpoint()) { + + deleteBreakpoint(breakpoint, part, null); + BreakpointToggleUtils.setTriggerpoint(false); + + } else if (BreakpointToggleUtils.isHitpoint()) { + + deleteBreakpoint(breakpoint, part, null); + BreakpointToggleUtils.setHitpoint(false); } else { deleteBreakpoint(breakpoint, part, null); } - return; + if (!BreakpointToggleUtils.isToggleLambdaEntryBreakpoint()) { + return; + } else if (breakpoint instanceof IJavaMethodBreakpoint) { + return; + } } // no breakpoint found: we create new one CompilationUnit unit = parseCompilationUnit(editor); @@ -1565,9 +1641,9 @@ private void toggleFieldOrMethodBreakpoints(IWorkbenchPart part, ISelection sele } else if (loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_METHOD) { toggleMethodBreakpoints(part, ts); } else if (loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_FIELD) { - if (BreakpointToggleUtils.isToggleTracepoints()) { + if (BreakpointToggleUtils.isToggleTracepoint()) { BreakpointToggleUtils.report(ActionMessages.TracepointToggleAction_Unavailable, part); - BreakpointToggleUtils.setUnsetTracepoints(false); + BreakpointToggleUtils.setUnsetTracepoint(false); return; } toggleWatchpoints(part, ts); @@ -1616,10 +1692,10 @@ private static void logBadAnnotation(SimpleMarkerAnnotation annotation, CoreExce * * @param breakpoint the breakpoint to delete * @param part a workbench part, or null if unknown - * @param progressMonitor the progress monitor + * @param monitor the progress monitor * @throws CoreException if the deletion fails */ - private static void deleteBreakpoint(IJavaBreakpoint breakpoint, IWorkbenchPart part, IProgressMonitor monitor) throws CoreException { + public static void deleteBreakpoint(IJavaBreakpoint breakpoint, IWorkbenchPart part, IProgressMonitor monitor) throws CoreException { final Shell shell = part != null ? part.getSite().getShell() : null; final boolean[] result = new boolean[] { true }; diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/JavaPrimitiveRuntimeContext.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/JavaPrimitiveRuntimeContext.java index be0a8290a4..fa71019417 100644 --- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/JavaPrimitiveRuntimeContext.java +++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/JavaPrimitiveRuntimeContext.java @@ -13,6 +13,8 @@ *******************************************************************************/ package org.eclipse.jdt.internal.debug.eval.ast.engine; +import java.util.List; + import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.debug.core.IJavaDebugTarget; @@ -21,6 +23,11 @@ import org.eclipse.jdt.debug.core.IJavaReferenceType; import org.eclipse.jdt.debug.core.IJavaThread; import org.eclipse.jdt.debug.core.IJavaVariable; +import org.eclipse.jdt.internal.debug.core.model.JDIClassType; +import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget; + +import com.sun.jdi.ClassType; +import com.sun.jdi.ReferenceType; public class JavaPrimitiveRuntimeContext extends AbstractRuntimeContext { /** @@ -70,7 +77,11 @@ public IJavaPrimitiveValue getThisPrimitive() { */ @Override public IJavaReferenceType getReceivingType() throws CoreException { - return (IJavaReferenceType) getThisPrimitive().getJavaType(); + JDIDebugTarget target = (JDIDebugTarget) getThisPrimitive().getJavaType().getDebugTarget(); + List ref = target.getVM().classesByName("java.lang.Object"); //$NON-NLS-1$ + ClassType classType = (ClassType) ref.get(0); + JDIClassType jdiClassType = new JDIClassType(target, classType); + return jdiClassType; } /** diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/sourcelookup/advanced/FileHashing.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/sourcelookup/advanced/FileHashing.java index 32837528ab..4e21bd6e3a 100644 --- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/sourcelookup/advanced/FileHashing.java +++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/sourcelookup/advanced/FileHashing.java @@ -128,7 +128,6 @@ private static class HasherImpl implements Hasher { private final Map cache; - @SuppressWarnings("serial") public HasherImpl(int cacheSize) { this.cache = new LinkedHashMap<>() { @Override