From beac4780d2285479de38825af91c3682b7b0ba88 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Wed, 18 Mar 2026 16:13:55 +0100 Subject: [PATCH] Breakpoints for lambdas. --- .../api/debugger/jpda/LineBreakpoint.java | 25 +- .../nbproject/project.xml | 8 + .../BreakpointAnnotationProvider.java | 22 +- .../jpda/projectsui/Bundle.properties | 2 + .../DebuggerBreakpointAnnotation.java | 12 +- .../projectsui/LambdaBreakpointManager.java | 279 ++++++++++++++++++ .../resources/DisabledLambdaBreakpoint.xml | 33 +++ .../jpda/resources/LambdaBreakpoint.xml | 36 +++ .../debugger/jpda/resources/mf-layer.xml | 2 + .../jpda/ui/breakpoints/Bundle.properties | 5 + .../ui/breakpoints/LineBreakpointPanel.form | 40 ++- .../ui/breakpoints/LineBreakpointPanel.java | 30 ++ .../jpda/ui/models/BreakpointsNodeModel.java | 21 +- .../debugger/jpda/ui/models/Bundle.properties | 1 + java/debugger.jpda/nbproject/project.xml | 3 +- .../jpda/breakpoints/BreakpointsReader.java | 5 + .../jpda/breakpoints/LineBreakpointImpl.java | 32 ++ java/java.lsp.server/nbproject/project.xml | 15 + .../server/debugging/NbProtocolServer.java | 81 +++++ .../breakpoints/BreakpointsManager.java | 99 +++++-- .../debugging/breakpoints/NbBreakpoint.java | 50 +++- .../NbBreakpointsRequestHandler.java | 4 +- 22 files changed, 758 insertions(+), 47 deletions(-) create mode 100644 java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/LambdaBreakpointManager.java create mode 100644 java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/resources/DisabledLambdaBreakpoint.xml create mode 100644 java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/resources/LambdaBreakpoint.xml diff --git a/java/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/LineBreakpoint.java b/java/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/LineBreakpoint.java index 78726be196d7..d073ac961258 100644 --- a/java/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/LineBreakpoint.java +++ b/java/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/LineBreakpoint.java @@ -67,6 +67,8 @@ public class LineBreakpoint extends JPDABreakpoint { /** Property name constant */ public static final String PROP_LINE_NUMBER = "lineNumber"; // NOI18N /** Property name constant */ + public static final String PROP_LAMBDA_INDEX = "lambdaIndex"; // NOI18N + /** Property name constant */ public static final String PROP_URL = "url"; // NOI18N /** Property name constant. */ public static final String PROP_CONDITION = "condition"; // NOI18N @@ -94,6 +96,7 @@ public class LineBreakpoint extends JPDABreakpoint { private String className = null; private Map instanceFilters; private Map threadFilters; + private int lambdaIndex = -1; //line breakpoint by default private LineBreakpoint (String url) { @@ -182,6 +185,26 @@ public void setLineNumber (int ln) { Integer.valueOf(ln) ); } + + public int getLambdaIndex() { + return lambdaIndex; + } + + public void setLambdaIndex(int li) { + int old; + synchronized (this) { + if (li == lambdaIndex) { + return; + } + old = lambdaIndex; + lambdaIndex = li; + } + firePropertyChange ( + PROP_LAMBDA_INDEX, + Integer.valueOf(old), + Integer.valueOf(li) + ); + } /** * Get the instance filter for a specific debugger session. @@ -423,7 +446,7 @@ public String toString () { if (fileName == null) { fileName = url; } - return "LineBreakpoint " + fileName + " : " + lineNumber; + return "LineBreakpoint " + fileName + " : " + lineNumber + (lambdaIndex >= 0 ? " lambda index: " + lambdaIndex : ""); } private static class LineBreakpointImpl extends LineBreakpoint diff --git a/java/debugger.jpda.projectsui/nbproject/project.xml b/java/debugger.jpda.projectsui/nbproject/project.xml index 561252c26711..6790eca564da 100644 --- a/java/debugger.jpda.projectsui/nbproject/project.xml +++ b/java/debugger.jpda.projectsui/nbproject/project.xml @@ -146,6 +146,14 @@ 1.62 + + org.netbeans.modules.java.source + + + + 0.191 + + org.netbeans.modules.java.source.base diff --git a/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/BreakpointAnnotationProvider.java b/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/BreakpointAnnotationProvider.java index 2ca1022f3580..6f6eb0f76eac 100644 --- a/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/BreakpointAnnotationProvider.java +++ b/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/BreakpointAnnotationProvider.java @@ -139,6 +139,7 @@ private void annotate (final FileObject fo) { } annotatedFiles.add(fo); } + LambdaBreakpointManager.FactoryImpl.doRefresh(fo); //ensure spans of lambda breakpoints are updated } void setBreakpointsActive(boolean active) { @@ -189,6 +190,7 @@ private void refreshAnnotation(JPDABreakpoint b) { breakpointToAnnotations.put(b, Collections.newSetFromMap(new WeakHashMap<>())); for (FileObject fo : annotatedFiles) { addAnnotationTo(b, fo); + LambdaBreakpointManager.FactoryImpl.doRefresh(fo); } } } @@ -207,12 +209,17 @@ private static String getAnnotationType(JPDABreakpoint b, boolean isConditional, boolean active) { boolean isInvalid = b.getValidity() == VALIDITY.INVALID; String annotationType; - if (b instanceof LineBreakpoint) { - annotationType = b.isEnabled () ? - (isConditional ? EditorContext.CONDITIONAL_BREAKPOINT_ANNOTATION_TYPE : - EditorContext.BREAKPOINT_ANNOTATION_TYPE) : - (isConditional ? EditorContext.DISABLED_CONDITIONAL_BREAKPOINT_ANNOTATION_TYPE : - EditorContext.DISABLED_BREAKPOINT_ANNOTATION_TYPE); + if (b instanceof LineBreakpoint lb) { + if (lb.getLambdaIndex() >= 0) { + annotationType = b.isEnabled() ? DebuggerBreakpointAnnotation.LAMBDA_BREAKPOINT + : DebuggerBreakpointAnnotation.DISABLED_LAMBDA_BREAKPOINT; + } else { + annotationType = b.isEnabled () ? + (isConditional ? EditorContext.CONDITIONAL_BREAKPOINT_ANNOTATION_TYPE : + EditorContext.BREAKPOINT_ANNOTATION_TYPE) : + (isConditional ? EditorContext.DISABLED_CONDITIONAL_BREAKPOINT_ANNOTATION_TYPE : + EditorContext.DISABLED_BREAKPOINT_ANNOTATION_TYPE); + } } else if (b instanceof FieldBreakpoint) { annotationType = b.isEnabled () ? EditorContext.FIELD_BREAKPOINT_ANNOTATION_TYPE : @@ -475,6 +482,9 @@ static String getCondition(Breakpoint b) { } } + Set getAnnotationsForBreakpoint(JPDABreakpoint b) { + return breakpointToAnnotations.getOrDefault(b, Set.of()); + } /* // Not used @Override diff --git a/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/Bundle.properties b/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/Bundle.properties index 102e8b85d3a4..f9220ce54e27 100644 --- a/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/Bundle.properties +++ b/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/Bundle.properties @@ -41,6 +41,8 @@ TOOLTIP_DISABLED_METHOD_BREAKPOINT=Disabled Method Breakpoint TOOLTIP_CLASS_BREAKPOINT=Class Breakpoint TOOLTIP_DISABLED_CLASS_BREAKPOINT=Disabled Class Breakpoint TOOLTIP_BREAKPOINT_STROKE=Deactivated breakpoint +TOOLTIP_LAMBDA_BREAKPOINT=Lambda Breakpoint +TOOLTIP_DISABLED_LAMBDA_BREAKPOINT=Lambda Breakpoint # A condition expression follows this message on a next line TOOLTIP_CONDITION=Hits when: # {0} - a number diff --git a/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/DebuggerBreakpointAnnotation.java b/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/DebuggerBreakpointAnnotation.java index 5e0abec4496d..6159bb69bae0 100644 --- a/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/DebuggerBreakpointAnnotation.java +++ b/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/DebuggerBreakpointAnnotation.java @@ -23,7 +23,6 @@ import java.util.List; import org.netbeans.api.debugger.Breakpoint; import org.netbeans.api.debugger.Breakpoint.HIT_COUNT_FILTERING_STYLE; -import org.netbeans.api.debugger.jpda.JPDABreakpoint; import org.netbeans.spi.debugger.jpda.EditorContext; import org.netbeans.spi.debugger.ui.BreakpointAnnotation; @@ -39,6 +38,9 @@ */ public class DebuggerBreakpointAnnotation extends BreakpointAnnotation { + public static final String LAMBDA_BREAKPOINT = "LambdaBreakpoint"; + public static final String DISABLED_LAMBDA_BREAKPOINT = "DisabledLambdaBreakpoint"; + private final Line line; private final String type; private final Breakpoint breakpoint; @@ -163,6 +165,14 @@ private String getShortDescriptionIntern () { if (type == EditorContext.DISABLED_CLASS_BREAKPOINT_ANNOTATION_TYPE) { return NbBundle.getMessage (DebuggerBreakpointAnnotation.class, "TOOLTIP_DISABLED_CLASS_BREAKPOINT"); // NOI18N + } else + if (type == LAMBDA_BREAKPOINT) { + return NbBundle.getMessage + (DebuggerBreakpointAnnotation.class, "TOOLTIP_LAMBDA_BREAKPOINT"); // NOI18N + } else + if (type == DISABLED_LAMBDA_BREAKPOINT) { + return NbBundle.getMessage + (DebuggerBreakpointAnnotation.class, "TOOLTIP_DISABLED_LAMBDA_BREAKPOINT"); // NOI18N } ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, new IllegalStateException("Unknown breakpoint type '"+type+"'.")); return null; diff --git a/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/LambdaBreakpointManager.java b/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/LambdaBreakpointManager.java new file mode 100644 index 000000000000..d394253b8c46 --- /dev/null +++ b/java/debugger.jpda.projectsui/src/org/netbeans/modules/debugger/jpda/projectsui/LambdaBreakpointManager.java @@ -0,0 +1,279 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.netbeans.modules.debugger.jpda.projectsui; + +import com.sun.source.tree.LambdaExpressionTree; +import com.sun.source.tree.LineMap; +import com.sun.source.tree.Tree; +import java.beans.PropertyChangeEvent; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import org.netbeans.api.debugger.Breakpoint; +import org.netbeans.api.debugger.DebuggerEngine; +import org.netbeans.api.debugger.DebuggerManager; +import org.netbeans.api.debugger.DebuggerManagerAdapter; +import org.netbeans.api.debugger.LazyDebuggerManagerListener; +import org.netbeans.api.debugger.jpda.JPDABreakpoint; +import org.netbeans.api.debugger.jpda.JPDADebugger; +import org.netbeans.api.debugger.jpda.LineBreakpoint; +import org.netbeans.api.java.source.CancellableTask; +import org.netbeans.api.java.source.CompilationInfo; +import org.netbeans.api.java.source.JavaSource.Phase; +import org.netbeans.api.java.source.JavaSource.Priority; +import org.netbeans.api.java.source.JavaSourceTaskFactory; +import org.netbeans.api.java.source.support.CancellableTreePathScanner; +import org.netbeans.api.java.source.support.EditorAwareJavaSourceTaskFactory; +import org.netbeans.spi.debugger.DebuggerServiceRegistration; +import org.openide.cookies.LineCookie; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.URLMapper; +import org.openide.text.Annotation; +import org.openide.text.Line; +import org.openide.text.Line.Part; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; +import org.openide.util.lookup.ServiceProvider; + +@DebuggerServiceRegistration(types=LazyDebuggerManagerListener.class) +public class LambdaBreakpointManager extends DebuggerManagerAdapter { + + private static volatile JPDADebugger currentDebugger = null; //XXX: static??? + + @Override + public String[] getProperties() { + return new String[] { DebuggerManager.PROP_BREAKPOINTS, DebuggerManager.PROP_DEBUGGER_ENGINES }; + } + + @Override + public void breakpointAdded(Breakpoint breakpoint) { + refreshAfterChange(breakpoint); + } + + @Override + public void breakpointRemoved(Breakpoint breakpoint) { + refreshAfterChange(breakpoint); + } + + private void refreshAfterChange(Breakpoint breakpoint) { + if (breakpoint instanceof LineBreakpoint lb) { + try { + URL currentURL = new URL(lb.getURL()); + FileObject fo = URLMapper.findFileObject(currentURL); + + if (fo != null) { + FactoryImpl.doRefresh(fo); + } + } catch (MalformedURLException ex) { + Exceptions.printStackTrace(ex); + } + } + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + String propertyName = evt.getPropertyName (); + if (propertyName == null) { + return; + } + if (DebuggerManager.PROP_CURRENT_ENGINE.equals(propertyName)) { + setCurrentDebugger(DebuggerManager.getDebuggerManager().getCurrentEngine()); + } + if ( (!LineBreakpoint.PROP_URL.equals (propertyName)) && + (!LineBreakpoint.PROP_LINE_NUMBER.equals (propertyName)) + ) { + return; + } + JPDABreakpoint b = (JPDABreakpoint) evt.getSource (); + DebuggerManager manager = DebuggerManager.getDebuggerManager(); + Breakpoint[] bkpts = manager.getBreakpoints(); + boolean found = false; + for (int x = 0; x < bkpts.length; x++) { + if (b == bkpts[x]) { + found = true; + break; + } + } + if (!found) { + // breakpoint has been removed + return; + } + } + + private void setCurrentDebugger(DebuggerEngine engine) { + JPDADebugger oldDebugger = currentDebugger; + if (oldDebugger != null) { + oldDebugger.removePropertyChangeListener(JPDADebugger.PROP_BREAKPOINTS_ACTIVE, this); + } + boolean active = true; + JPDADebugger debugger = null; + if (engine != null) { + debugger = engine.lookupFirst(null, JPDADebugger.class); + if (debugger != null) { + debugger.addPropertyChangeListener(JPDADebugger.PROP_BREAKPOINTS_ACTIVE, this); + active = debugger.getBreakpointsActive(); + } + } + currentDebugger = debugger; + } + + //TODO: requires dependency on java.source - maybe try to rewrite to Schedulers! + @ServiceProvider(service=JavaSourceTaskFactory.class) + public static final class FactoryImpl extends EditorAwareJavaSourceTaskFactory { + + private BreakpointAnnotationProvider bap; + + public FactoryImpl() { + super(Phase.PARSED, Priority.BELOW_NORMAL); + } + + private BreakpointAnnotationProvider getAnnotationProvider() { + if (bap == null) { + bap = BreakpointAnnotationProvider.getInstance(); + } + return bap; + } + + @Override + protected CancellableTask createTask(FileObject file) { + return new CancellableTask() { + private final AtomicBoolean canceled = new AtomicBoolean(); + + @Override + public void cancel() { + canceled.set(true); + } + + @Override + public void run(CompilationInfo info) throws Exception { + canceled.set(false); + + String currentFile = info.getFileObject().toURL().toString(); + Map> lines2LambdaIndexes = new HashMap<>(); + + for (Breakpoint b : DebuggerManager.getDebuggerManager().getBreakpoints()) { + if (b instanceof LineBreakpoint lb && currentFile.equals(lb.getURL())) { + lines2LambdaIndexes.computeIfAbsent(lb.getLineNumber(), x -> new HashMap<>()) + .put(lb.getLambdaIndex(), lb); + } + } + + LineMap lineMap = info.getCompilationUnit().getLineMap(); + + new CancellableTreePathScanner(canceled) { + int currentLine = -1; + int currentLambdaIndex = -1; + public Void scan(Tree tree, Void v) { + if (tree != null && tree.getKind() != Tree.Kind.COMPILATION_UNIT) { + long startPos = info.getTrees().getSourcePositions().getStartPosition(getCurrentPath().getCompilationUnit(), tree); + if (startPos != (-1)) { + int line = (int) lineMap.getLineNumber(startPos); + + if (line != currentLine) { + currentLine = line; + currentLambdaIndex = 0; + } + } + } + return super.scan(tree, v); + } + public Void visitLambdaExpression(LambdaExpressionTree tree, Void v) { + long startPos = info.getTrees().getSourcePositions().getStartPosition(getCurrentPath().getCompilationUnit(), tree); + int startLine = (int) lineMap.getLineNumber(startPos); + Map existingLineBreakpoints = lines2LambdaIndexes.get(startLine); + LineBreakpoint existingLineBreakpoint = existingLineBreakpoints != null ? existingLineBreakpoints.remove(currentLambdaIndex) : null; + + if (existingLineBreakpoints != null && existingLineBreakpoints.containsKey(-1)) { + //the line breakpoint exists, ensure the lambda breakpoint exists and is updated + if (existingLineBreakpoint == null) { + LineBreakpoint lb = LineBreakpoint.create(currentFile, startLine); + lb.setLambdaIndex(currentLambdaIndex); + lb.disable(); + DebuggerManager.getDebuggerManager().addBreakpoint(lb); + } else { + long endPos = info.getTrees().getSourcePositions().getEndPosition(getCurrentPath().getCompilationUnit(), tree); + int endLine = (int) lineMap.getLineNumber(endPos); + int startColumn = (int) lineMap.getColumnNumber(startPos) - 1; + int endColumn; + if (startLine == endLine) { + endColumn = (int) lineMap.getColumnNumber(endPos) - 1; + } else { + endColumn = (int) lineMap.getStartPosition(startLine + 1) - 1; + } + + int length = endColumn - startColumn; + + Set annotations = getAnnotationProvider().getAnnotationsForBreakpoint(existingLineBreakpoint); + + for (Annotation ann : annotations) { + if (!(ann.getAttachedAnnotatable() instanceof Part p) || p.getLine().getLineNumber() != startLine || p.getColumn() != startColumn || p.getLength() != length) { + LineCookie lc = info.getFileObject().getLookup().lookup(LineCookie.class); + + if (lc == null) { + continue; + } + + Line line = lc.getLineSet().getCurrent(startLine - 1); + Part part = line.createPart(startColumn, length); + + if (canceled.get()) { + //don't set the part if cancelled - the positions may be wrong + return null; + } + + ann.detach(); + ann.attach(part); + } + } + } + } + + currentLambdaIndex++; + + return super.visitLambdaExpression(tree, v); + } + }.scan(info.getCompilationUnit(), null); + + //remove any stale lambda breakpoints: + for (Breakpoint b : DebuggerManager.getDebuggerManager().getBreakpoints()) { + if (b instanceof LineBreakpoint lb && currentFile.equals(lb.getURL()) && lb.getLambdaIndex() >=0) { + Map staleLambdaBreakpoints = lines2LambdaIndexes.getOrDefault(lb.getLineNumber(), Map.of()); + if (staleLambdaBreakpoints.containsKey(lb.getLambdaIndex()) || !staleLambdaBreakpoints.containsKey(-1)) { + DebuggerManager.getDebuggerManager().removeBreakpoint(lb); + } + } + } + } + }; + } + + public static void doRefresh(FileObject file) { + for (JavaSourceTaskFactory f : Lookup.getDefault().lookupAll(JavaSourceTaskFactory.class)) { + if (f instanceof FactoryImpl impl) { + impl.reschedule(file); + } + } + } + } + +} diff --git a/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/resources/DisabledLambdaBreakpoint.xml b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/resources/DisabledLambdaBreakpoint.xml new file mode 100644 index 000000000000..e841d70ba90b --- /dev/null +++ b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/resources/DisabledLambdaBreakpoint.xml @@ -0,0 +1,33 @@ + + + + + diff --git a/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/resources/LambdaBreakpoint.xml b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/resources/LambdaBreakpoint.xml new file mode 100644 index 000000000000..6a83877f77ba --- /dev/null +++ b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/resources/LambdaBreakpoint.xml @@ -0,0 +1,36 @@ + + + + + diff --git a/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/resources/mf-layer.xml b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/resources/mf-layer.xml index df823ccc2467..4f05e7f2004a 100644 --- a/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/resources/mf-layer.xml +++ b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/resources/mf-layer.xml @@ -91,9 +91,11 @@ + + diff --git a/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/breakpoints/Bundle.properties b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/breakpoints/Bundle.properties index fe41db22e26f..d21a239259c2 100644 --- a/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/breakpoints/Bundle.properties +++ b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/breakpoints/Bundle.properties @@ -229,6 +229,11 @@ ACSD_TF_Line_Breakpoint_Line_Number=Line number TTT_TF_Line_Breakpoint_Line_Number=Line number to stop at + L_Line_Breakpoint_Lambda_Index=Lambda &Index\: + ACSD_L_Line_Breakpoint_Lambda_Index=Lambda Index + ACSD_TF_Line_Breakpoint_Lambda_Index=Lambda Index + TTT_TF_Line_Breakpoint_Lambda_Index=Lambda Index to stop at + L_Line_Breakpoint_Condition=Co&ndition: ACSD_L_Line_Breakpoint_Condition=Condition ACSD_TF_Line_Breakpoint_Condition=Condition diff --git a/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/breakpoints/LineBreakpointPanel.form b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/breakpoints/LineBreakpointPanel.form index 5ea1b1c1ff72..9eb4f7f3a2d4 100644 --- a/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/breakpoints/LineBreakpointPanel.form +++ b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/breakpoints/LineBreakpointPanel.form @@ -1,4 +1,4 @@ - +