Added support for breakpoint in external source.
Improved the breakpoint location verifier process.
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties
index 40a4a88..d46d046 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties
@@ -143,3 +143,6 @@
ObjectActionDelegate.Unable_to_display_type_hierarchy._The_selected_source_element_is_not_contained_in_the_workspace._1=Unable to display type hierarchy. The selected source element is not contained in the workspace.
ManageBreakpointRulerAction.Breakpoints_can_only_be_created_within_the_type_associated_with_the_editor__{0}._1=Breakpoints can only be created within the type associated with the editor: {0}.
+ManageBreakpointActionDelegate.breakpoint_location=Breakpoint location validation
+ManageBreakpointActionDelegate.not_valid_location=Breakpoint cannot be set at the given position
+ManageBreakpointActionDelegate.breakpoint_set=Breakpoint set
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointLocationVerifierJob.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointLocationVerifierJob.java
new file mode 100644
index 0000000..b157eb4
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointLocationVerifierJob.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.debug.ui.actions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+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.jdt.core.IType;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
+import org.eclipse.jdt.debug.core.JDIDebugModel;
+import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
+import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Job used to verify the position of a breakpoint
+ */
+public class BreakpointLocationVerifierJob extends Job {
+
+ /**
+ * The document which contains the code source.
+ */
+ private IDocument fDocument;
+
+ /**
+ * The offset in the document where the breakpoint has been requested
+ */
+ private int fOffset;
+
+ /**
+ * The temporary breakpoint that has been set. Can be <code>null</code> if the callee was not able
+ * to check if a breakpoint was already set at this position.
+ */
+ private IJavaLineBreakpoint fBreakpoint;
+
+ /**
+ * The number of the line where the breakpoint has been requested.
+ */
+ private int fLineNumber;
+
+ /**
+ * The qualified type name of the class where the temporary breakpoint as been set.
+ * Can be <code>null</code> if fBreakpoint is null.
+ */
+ private String fTypeName;
+
+ /**
+ * The type in which should be set the breakpoint.
+ */
+ private IType fType;
+
+ /**
+ * The resource in which should be set the breakpoint.
+ */
+ private IResource fResource;
+
+ public BreakpointLocationVerifierJob(IDocument document, int offset, IJavaLineBreakpoint breakpoint, int lineNumber, String typeName, IType type, IResource resource) {
+ super(ActionMessages.getString("ManageBreakpointActionDelegate.breakpoint_location")); //$NON-NLS-1$
+ fDocument= document;
+ fOffset= offset;
+ fBreakpoint= breakpoint;
+ fLineNumber= lineNumber;
+ fTypeName= typeName;
+ fType= type;
+ fResource= resource;
+ }
+
+ public IStatus run(IProgressMonitor monitor) {
+ CompilationUnit compilationUnit= AST.parseCompilationUnit(fDocument.get().toCharArray());
+ ValidBreakpointLocationLocator locator= new ValidBreakpointLocationLocator(compilationUnit, fOffset);
+ compilationUnit.accept(locator);
+ int lineNumber= locator.getValidLocation();
+ String typeName= locator.getFullyQualifiedTypeName();
+
+ try {
+ if (lineNumber == -1) {
+ // cannot found a valid line
+ Display.getCurrent().beep();
+ if (fBreakpoint != null) {
+ DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(fBreakpoint, true);
+ }
+ return new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, ActionMessages.getString("ManageBreakpointActionDelegate.not_valid_location"), null); //$NON-NLS-1$
+ }
+ boolean differentLineNumber= lineNumber != fLineNumber;
+ IJavaLineBreakpoint breakpoint= JDIDebugModel.lineBreakpointExists(typeName, lineNumber);
+ boolean breakpointExist= breakpoint != null;
+ if (fBreakpoint == null) {
+ if (breakpointExist) {
+ if (differentLineNumber) {
+ // There is already a breakpoint on the valid line.
+ beep();
+ return new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, ActionMessages.getString("ManageBreakpointActionDelegate.not_valid_location"), null); //$NON-NLS-1$
+ } else {
+ // There is already a breakpoint on the valid line, but it's also the requested line.
+ // Removing the existing breakpoint.
+ DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(breakpoint, true);
+ return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, "Breakpoint removed.", null); //$NON-NLS-1$
+ }
+ }
+ createNewBreakpoint(lineNumber, typeName);
+ return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.OK, ActionMessages.getString("ManageBreakpointActionDelegate.breakpoint_set"), null); //$NON-NLS-1$
+ } else {
+ if (differentLineNumber) {
+ if (breakpointExist) {
+ // there is already a breakpoint on the valid line.
+ beep();
+ DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(fBreakpoint, true);
+ return new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, ActionMessages.getString("ManageBreakpointActionDelegate.not_valid_location"), null); //$NON-NLS-1$
+ }
+ replaceBreakpoint(lineNumber, typeName);
+ return new Status(IStatus.WARNING, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.WARNING, "The breakpoint has been moved to a valid position.", null); //$NON-NLS-1$
+ }
+ if (!typeName.equals(fTypeName)) {
+ replaceBreakpoint(lineNumber, typeName);
+ return new Status(IStatus.WARNING, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.WARNING, "The breakpoint has been set to the right type.", null); //$NON-NLS-1$
+ }
+ }
+ } catch (CoreException e) {
+ JDIDebugUIPlugin.log(e);
+ }
+ return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.OK, ActionMessages.getString("ManageBreakpointActionDelegate.breakpoint_set"), null); //$NON-NLS-1$
+ }
+
+ /**
+ * Remove the temporary breakpoint and create a new breakpoint at the right position.
+ */
+ private void replaceBreakpoint(int lineNumber, String typeName) throws CoreException {
+ createNewBreakpoint(lineNumber, typeName);
+ DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(fBreakpoint, true);
+ }
+
+ /**
+ * Create a new breakpoint at the right position.
+ */
+ private void createNewBreakpoint(int lineNumber, String typeName) throws CoreException {
+ Map newAttributes = new HashMap(10);
+ if (fType != null) {
+ try {
+ IRegion line= fDocument.getLineInformation(lineNumber - 1);
+ int start= line.getOffset();
+ int end= start + line.getLength() - 1;
+ BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(newAttributes, fType, start, end);
+ } catch (BadLocationException ble) {
+ JDIDebugUIPlugin.log(ble);
+ }
+ }
+ JDIDebugModel.createLineBreakpoint(fResource, typeName, lineNumber, -1, -1, 0, true, newAttributes);
+ }
+
+ private void beep() {
+ JDIDebugUIPlugin.getStandardDisplay().asyncExec(new Runnable() {
+ public void run() {
+ Display.getCurrent().beep();
+ }
+ });
+ }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointActionDelegate.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointActionDelegate.java
index 4b28c1c..bd244b4 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointActionDelegate.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointActionDelegate.java
@@ -11,11 +11,15 @@
package org.eclipse.jdt.internal.debug.ui.actions;
+import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
@@ -28,14 +32,17 @@
import org.eclipse.jdt.internal.debug.ui.snippeteditor.JavaSnippetEditor;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IStatusLineManager;
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.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
@@ -65,7 +72,8 @@
*/
protected void manageBreakpoint(IEditorInput editorInput) {
ISelectionProvider sp= getTextEditor().getSelectionProvider();
- if (sp == null || getType() == null) {
+ IType type = getType();
+ if (sp == null) {
report(ActionMessages.getString("ManageBreakpointActionDelegate.No_Breakpoint")); //$NON-NLS-1$
return;
}
@@ -73,28 +81,65 @@
ISelection selection= sp.getSelection();
if (selection instanceof ITextSelection) {
IDocument document= getTextEditor().getDocumentProvider().getDocument(editorInput);
- BreakpointLocationVerifier bv = new BreakpointLocationVerifier();
- int lineNumber = bv.getValidBreakpointLocation(document, ((ITextSelection)selection).getStartLine());
- if (lineNumber > -1) {
- try {
- IJavaLineBreakpoint breakpoint= JDIDebugModel.lineBreakpointExists(getType().getFullyQualifiedName(), lineNumber);
- if (breakpoint != null) {
- DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(breakpoint, true);
- } else {
- try {
- IRegion line= document.getLineInformation(lineNumber - 1);
- Map attributes = new HashMap(10);
- int start= line.getOffset();
- int end= start + line.getLength() - 1;
- BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, getType(), start, end);
- JDIDebugModel.createLineBreakpoint(BreakpointUtils.getBreakpointResource(getType()), getType().getFullyQualifiedName(), lineNumber, -1, -1, 0, true, attributes);
- } catch (BadLocationException ble) {
- JDIDebugUIPlugin.log(ble);
+
+ int lineNumber= ((ITextSelection)selection).getStartLine() + 1;
+
+
+ int offset= ((ITextSelection)selection).getOffset();
+ try {
+ if (type == null) {
+ IClassFile classFile= (IClassFile)editorInput.getAdapter(IClassFile.class);
+ if (classFile != null) {
+ type= classFile.getType();
+ // bug 34856 - if this is an inner type, ensure the breakpoint is not
+ // being added to the outer type
+ if (type.getDeclaringType() != null) {
+ ISourceRange sourceRange= type.getSourceRange();
+ int start= sourceRange.getOffset();
+ int end= start + sourceRange.getLength();
+ if (offset < start || offset > end) {
+ // not in the inner type
+ IStatusLineManager manager= getTextEditor().getEditorSite().getActionBars().getStatusLineManager();
+ manager.setErrorMessage(MessageFormat.format(ActionMessages.getString("ManageBreakpointRulerAction.Breakpoints_can_only_be_created_within_the_type_associated_with_the_editor__{0}._1"), new String[] { type.getTypeQualifiedName()})); //$NON-NLS-1$
+ Display.getCurrent().beep();
+ return;
+ }
}
}
- } catch (CoreException ce) {
- ExceptionHandler.handle(ce, ActionMessages.getString("ManageBreakpointActionDelegate.error.title1"), ActionMessages.getString("ManageBreakpointActionDelegate.error.message1")); //$NON-NLS-1$ //$NON-NLS-2$
}
+
+ String typeName= null;
+ IResource resource;
+ IJavaLineBreakpoint breakpoint= null;
+ if (type == null) {
+ if (editorInput instanceof IFileEditorInput) {
+ resource= ((IFileEditorInput)editorInput).getFile();
+ } else {
+ resource= ResourcesPlugin.getWorkspace().getRoot();
+ }
+ } else {
+ typeName= type.getFullyQualifiedName();
+ IJavaLineBreakpoint existingBreakpoint= JDIDebugModel.lineBreakpointExists(typeName, lineNumber);
+ if (existingBreakpoint != null) {
+ DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(existingBreakpoint, true);
+ return;
+ }
+ resource= BreakpointUtils.getBreakpointResource(type);
+ Map attributes = new HashMap(10);
+ try {
+ IRegion line= document.getLineInformation(lineNumber - 1);
+ int start= line.getOffset();
+ int end= start + line.getLength() - 1;
+ BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, type, start, end);
+ } catch (BadLocationException ble) {
+ JDIDebugUIPlugin.log(ble);
+ }
+ breakpoint= JDIDebugModel.createLineBreakpoint(resource, typeName, lineNumber, -1, -1, 0, true, attributes);
+ }
+ new BreakpointLocationVerifierJob(document, offset, breakpoint, lineNumber, typeName, type, resource).schedule();
+ } catch (CoreException ce) {
+ ExceptionHandler.handle(ce, ActionMessages.getString("ManageBreakpointActionDelegate.error.title1"), ActionMessages.getString("ManageBreakpointActionDelegate.error.message1")); //$NON-NLS-1$ //$NON-NLS-2$
+ return;
}
}
}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointRulerAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointRulerAction.java
index 274a4e2..921c44f 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointRulerAction.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointRulerAction.java
@@ -35,6 +35,7 @@
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
@@ -213,64 +214,70 @@
IEditorInput editorInput= getTextEditor().getEditorInput();
- IDocument document= getDocument();
- int rulerLine= getVerticalRulerInfo().getLineOfLastMouseButtonActivity();
-
try {
- BreakpointLocationVerifier bv = new BreakpointLocationVerifier();
- int lineNumber = bv.getValidBreakpointLocation(document, rulerLine);
- if (lineNumber > 0) {
-
- IRegion line= document.getLineInformation(lineNumber - 1);
-
- IType type = null;
- IClassFile classFile= (IClassFile) editorInput.getAdapter(IClassFile.class);
- if (classFile != null) {
- type= classFile.getType();
- // bug 34856 - if this is an inner type, ensure the breakpoint is not
- // being added to the outer type
- if (type.getDeclaringType() != null) {
- ISourceRange sourceRange = type.getSourceRange();
- int offset = line.getOffset();
- int start = sourceRange.getOffset();
- int end = start + sourceRange.getLength();
- if (offset < start || offset > end) {
- // not in the inner type
- IStatusLineManager manager = getTextEditor().getEditorSite().getActionBars().getStatusLineManager();
- manager.setErrorMessage(MessageFormat.format(ActionMessages.getString("ManageBreakpointRulerAction.Breakpoints_can_only_be_created_within_the_type_associated_with_the_editor__{0}._1"), new String[]{type.getTypeQualifiedName()})); //$NON-NLS-1$
- Display.getCurrent().beep();
- return;
- }
- }
- } else if (editorInput instanceof IFileEditorInput) {
- IWorkingCopyManager manager= JavaUI.getWorkingCopyManager();
- ICompilationUnit unit= manager.getWorkingCopy(editorInput);
- if (unit != null) {
- synchronized (unit) {
- unit.reconcile();
- }
- IJavaElement e = unit.getElementAt(line.getOffset());
- if (e instanceof IType) {
- type= (IType)e;
- } else if (e instanceof IMember) {
- type= ((IMember)e).getDeclaringType();
- }
+ IDocument document= getDocument();
+ IRegion line= document.getLineInformation(getVerticalRulerInfo().getLineOfLastMouseButtonActivity());
+
+ IType type= null;
+ IClassFile classFile= (IClassFile)editorInput.getAdapter(IClassFile.class);
+ if (classFile != null) {
+ type= classFile.getType();
+ // bug 34856 - if this is an inner type, ensure the breakpoint is not
+ // being added to the outer type
+ if (type.getDeclaringType() != null) {
+ ISourceRange sourceRange = type.getSourceRange();
+ int offset = line.getOffset();
+ int start = sourceRange.getOffset();
+ int end = start + sourceRange.getLength();
+ if (offset < start || offset > end) {
+ // not in the inner type
+ IStatusLineManager manager = getTextEditor().getEditorSite().getActionBars().getStatusLineManager();
+ manager.setErrorMessage(MessageFormat.format(ActionMessages.getString("ManageBreakpointRulerAction.Breakpoints_can_only_be_created_within_the_type_associated_with_the_editor__{0}._1"), new String[]{type.getTypeQualifiedName()})); //$NON-NLS-1$
+ Display.getCurrent().beep();
+ return;
}
}
-
- if (type != null) {
- IJavaProject project= type.getJavaProject();
- if (type.exists() && project != null && project.isOnClasspath(type)) {
- if (JDIDebugModel.lineBreakpointExists(type.getFullyQualifiedName(),lineNumber) == null) {
- Map attributes = new HashMap(10);
- int start= line.getOffset();
- int end= start + line.getLength() - 1;
- BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, type, start, end);
- JDIDebugModel.createLineBreakpoint(getBreakpointResource(type), type.getFullyQualifiedName(), lineNumber, -1, -1, 0, true, attributes);
- }
+ } else if (editorInput instanceof IFileEditorInput) {
+ IWorkingCopyManager manager= JavaUI.getWorkingCopyManager();
+ ICompilationUnit unit= manager.getWorkingCopy(editorInput);
+ if (unit != null) {
+ synchronized (unit) {
+ unit.reconcile();
+ }
+ IJavaElement e= unit.getElementAt(line.getOffset());
+ if (e instanceof IType) {
+ type= (IType)e;
+ } else if (e instanceof IMember) {
+ type= ((IMember)e).getDeclaringType();
}
}
}
+
+ Map attributes= new HashMap(10);
+ IResource resource;
+ String typeName= null;
+ int lineNumber= getVerticalRulerInfo().getLineOfLastMouseButtonActivity();
+ IJavaLineBreakpoint breakpoint= null;
+ if (type == null) {
+ if (editorInput instanceof IFileEditorInput) {
+ resource= ((IFileEditorInput)editorInput).getFile();
+ } else {
+ resource= ResourcesPlugin.getWorkspace().getRoot();
+ }
+ } else {
+ IJavaProject project= type.getJavaProject();
+ typeName= type.getFullyQualifiedName();
+ if (type.exists() && project != null && project.isOnClasspath(type)) {
+ if (JDIDebugModel.lineBreakpointExists(typeName, lineNumber) == null) {
+ int start= line.getOffset();
+ int end= start + line.getLength() - 1;
+ BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, type, start, end);
+ }
+ }
+ resource= BreakpointUtils.getBreakpointResource(type);
+ breakpoint= JDIDebugModel.createLineBreakpoint(resource, typeName, lineNumber, -1, -1, 0, true, attributes);
+ }
+ new BreakpointLocationVerifierJob(document, line.getOffset(), breakpoint, lineNumber, typeName, type, resource).schedule();
} catch (DebugException e) {
JDIDebugUIPlugin.errorDialog(ActionMessages.getString("ManageBreakpointRulerAction.error.adding.message1"), e); //$NON-NLS-1$
} catch (CoreException e) {
@@ -293,27 +300,4 @@
}
}
- /**
- * Returns the resource on which a breakpoint marker should
- * be created for the given member. The resource returned is the
- * associated file, or project in the case of a class file in
- * a jar.
- *
- * @param member member in which a breakpoint is being created
- * @return resource the resource on which a breakpoint marker
- * should be created
- * @exception CoreException if an exception occurs accessing the
- * underlying resource or Java model elements
- */
- public IResource getBreakpointResource(IMember member) throws CoreException {
- ICompilationUnit cu = member.getCompilationUnit();
- if (cu != null && cu.isWorkingCopy()) {
- member = (IMember)cu.getOriginal(member);
- }
- IResource res = member.getUnderlyingResource();
- if (res == null) {
- res = member.getJavaProject().getProject();
- }
- return res;
- }
}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ValidBreakpointLocationLocator.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ValidBreakpointLocationLocator.java
new file mode 100644
index 0000000..7dd150a
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ValidBreakpointLocationLocator.java
@@ -0,0 +1,637 @@
+/*******************************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.debug.ui.actions;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.ArrayAccess;
+import org.eclipse.jdt.core.dom.ArrayCreation;
+import org.eclipse.jdt.core.dom.ArrayInitializer;
+import org.eclipse.jdt.core.dom.ArrayType;
+import org.eclipse.jdt.core.dom.AssertStatement;
+import org.eclipse.jdt.core.dom.Assignment;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.BooleanLiteral;
+import org.eclipse.jdt.core.dom.BreakStatement;
+import org.eclipse.jdt.core.dom.CastExpression;
+import org.eclipse.jdt.core.dom.CatchClause;
+import org.eclipse.jdt.core.dom.CharacterLiteral;
+import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.ConditionalExpression;
+import org.eclipse.jdt.core.dom.ConstructorInvocation;
+import org.eclipse.jdt.core.dom.ContinueStatement;
+import org.eclipse.jdt.core.dom.DoStatement;
+import org.eclipse.jdt.core.dom.EmptyStatement;
+import org.eclipse.jdt.core.dom.ExpressionStatement;
+import org.eclipse.jdt.core.dom.FieldAccess;
+import org.eclipse.jdt.core.dom.FieldDeclaration;
+import org.eclipse.jdt.core.dom.ForStatement;
+import org.eclipse.jdt.core.dom.IfStatement;
+import org.eclipse.jdt.core.dom.ImportDeclaration;
+import org.eclipse.jdt.core.dom.InfixExpression;
+import org.eclipse.jdt.core.dom.Initializer;
+import org.eclipse.jdt.core.dom.InstanceofExpression;
+import org.eclipse.jdt.core.dom.Javadoc;
+import org.eclipse.jdt.core.dom.LabeledStatement;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.NullLiteral;
+import org.eclipse.jdt.core.dom.NumberLiteral;
+import org.eclipse.jdt.core.dom.PackageDeclaration;
+import org.eclipse.jdt.core.dom.ParenthesizedExpression;
+import org.eclipse.jdt.core.dom.PostfixExpression;
+import org.eclipse.jdt.core.dom.PrefixExpression;
+import org.eclipse.jdt.core.dom.PrimitiveType;
+import org.eclipse.jdt.core.dom.QualifiedName;
+import org.eclipse.jdt.core.dom.ReturnStatement;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.SimpleType;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
+import org.eclipse.jdt.core.dom.StringLiteral;
+import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
+import org.eclipse.jdt.core.dom.SuperFieldAccess;
+import org.eclipse.jdt.core.dom.SuperMethodInvocation;
+import org.eclipse.jdt.core.dom.SwitchCase;
+import org.eclipse.jdt.core.dom.SwitchStatement;
+import org.eclipse.jdt.core.dom.SynchronizedStatement;
+import org.eclipse.jdt.core.dom.ThisExpression;
+import org.eclipse.jdt.core.dom.ThrowStatement;
+import org.eclipse.jdt.core.dom.TryStatement;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
+import org.eclipse.jdt.core.dom.TypeLiteral;
+import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
+import org.eclipse.jdt.core.dom.WhileStatement;
+
+/**
+ * Compute a valid location where to put a breakpoint from an JDOM CompilationUnit.
+ * The result is the first valid location with a line number greater or equals than the given position.
+ */
+public class ValidBreakpointLocationLocator extends ASTVisitor {
+
+ private CompilationUnit fCompilationUnit;
+ private int fPosition;
+ private int fPositionLine;
+
+ private int fLocation;
+ private boolean fLocationFound;
+ private String fTypeName;
+
+ /**
+ * @param compilationUnit the JDOM CompilationUnit of the source code.
+ * @param position the offset in the source code where to put the breakpoint.
+ */
+ public ValidBreakpointLocationLocator(CompilationUnit compilationUnit, int position) {
+ fCompilationUnit= compilationUnit;
+ fPosition= position;
+ fPositionLine= fCompilationUnit.lineNumber(fPosition);
+ fLocationFound= false;
+ }
+
+ /**
+ * Return the line number of the computed valid location, or -1 if no valid location has been found.
+ */
+ public int getValidLocation() {
+ if (fLocationFound) {
+ return fLocation;
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * Return of the type where the valid location is, or null if no valid location has been found.
+ */
+ public String getFullyQualifiedTypeName() {
+ return fTypeName;
+ }
+
+ /**
+ * Compute the name of the type which contains this node.
+ * Result will be the name of the type or the inner type which contains this node, but not of the local or anonymous type.
+ */
+ private void computeTypeName(ASTNode node) {
+ while (!(node instanceof CompilationUnit)) {
+ if (node instanceof TypeDeclaration) {
+ String identifier= ((TypeDeclaration)node).getName().getIdentifier();
+ if (fTypeName == null) {
+ fTypeName= identifier;
+ } else {
+ fTypeName= identifier + "$" + fTypeName; //$NON-NLS-1$
+ }
+ } else {
+ fTypeName= null;
+ }
+ node= node.getParent();
+ }
+ PackageDeclaration packageDecl= ((CompilationUnit)node).getPackage();
+ String packageIdentifier= ""; //$NON-NLS-1$
+ if (packageDecl != null) {
+ Name packageName= packageDecl.getName();
+ while (packageName.isQualifiedName()) {
+ QualifiedName qualifiedName= (QualifiedName) packageName;
+ packageIdentifier= qualifiedName.getName().getIdentifier() + "." + packageIdentifier; //$NON-NLS-1$
+ packageName= qualifiedName.getQualifier();
+ }
+ packageIdentifier= ((SimpleName)packageName).getIdentifier() + "." + packageIdentifier; //$NON-NLS-1$
+ }
+ fTypeName= packageIdentifier + fTypeName;
+ }
+
+ /**
+ * @param node the node.
+ * @param isCode true indicated that the first line of the given node always contains some executable code, even if split in multiple lines.
+ * @return
+ */
+ private boolean visit(ASTNode node, boolean isCode) {
+ int startPosition= node.getStartPosition();
+ int endPosition = startPosition + node.getLength();
+ // if we already found a correct location, or if the position is not in this part of the code,
+ // no need to check the element inside.
+ if (fLocationFound || endPosition < fPosition) {
+ return false;
+ }
+ int startLine = fCompilationUnit.lineNumber(startPosition);
+ // if it is a structure, or there is more than one line of code, go in
+ if (isCode && (fPositionLine == startLine || startLine == fCompilationUnit.lineNumber(endPosition))) {
+ fLocation= startLine;
+ fLocationFound= true;
+ computeTypeName(node);
+ return false;
+ }
+ return true;
+ }
+
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AnonymousClassDeclaration)
+ */
+ public boolean visit(AnonymousClassDeclaration node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayAccess)
+ */
+ public boolean visit(ArrayAccess node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayCreation)
+ */
+ public boolean visit(ArrayCreation node) {
+ return visit(node, node.getInitializer() == null);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayInitializer)
+ */
+ public boolean visit(ArrayInitializer node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayType)
+ */
+ public boolean visit(ArrayType node) {
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AssertStatement)
+ */
+ public boolean visit(AssertStatement node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Assignment)
+ */
+ public boolean visit(Assignment node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Block)
+ */
+ public boolean visit(Block node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.BooleanLiteral)
+ */
+ public boolean visit(BooleanLiteral node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.BreakStatement)
+ */
+ public boolean visit(BreakStatement node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CastExpression)
+ */
+ public boolean visit(CastExpression node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CatchClause)
+ */
+ public boolean visit(CatchClause node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CharacterLiteral)
+ */
+ public boolean visit(CharacterLiteral node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ClassInstanceCreation)
+ */
+ public boolean visit(ClassInstanceCreation node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CompilationUnit)
+ */
+ public boolean visit(CompilationUnit node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ConditionalExpression)
+ */
+ public boolean visit(ConditionalExpression node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ConstructorInvocation)
+ */
+ public boolean visit(ConstructorInvocation node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ContinueStatement)
+ */
+ public boolean visit(ContinueStatement node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.DoStatement)
+ */
+ public boolean visit(DoStatement node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EmptyStatement)
+ */
+ public boolean visit(EmptyStatement node) {
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ExpressionStatement)
+ */
+ public boolean visit(ExpressionStatement node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.FieldAccess)
+ */
+ public boolean visit(FieldAccess node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.FieldDeclaration)
+ */
+ public boolean visit(FieldDeclaration node) {
+ if (visit(node, false)) {
+ // visit only the variable declaration fragments, no the variable names.
+ List fragments= node.fragments();
+ for (Iterator iter= fragments.iterator(); iter.hasNext();) {
+ ((VariableDeclarationFragment)iter.next()).accept(this);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ForStatement)
+ */
+ public boolean visit(ForStatement node) {
+ // in case on a "for(;;)", the breakpoint can be set on the first token of the node.
+ return visit(node, node.initializers().isEmpty() && node.getExpression() == null && node.updaters().isEmpty());
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.IfStatement)
+ */
+ public boolean visit(IfStatement node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ImportDeclaration)
+ */
+ public boolean visit(ImportDeclaration node) {
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.InfixExpression)
+ */
+ public boolean visit(InfixExpression node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Initializer)
+ */
+ public boolean visit(Initializer node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.InstanceofExpression)
+ */
+ public boolean visit(InstanceofExpression node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Javadoc)
+ */
+ public boolean visit(Javadoc node) {
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.LabeledStatement)
+ */
+ public boolean visit(LabeledStatement node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration)
+ */
+ public boolean visit(MethodDeclaration node) {
+ if (visit(node, false)) {
+ // visit only the body
+ node.getBody().accept(this);
+ }
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodInvocation)
+ */
+ public boolean visit(MethodInvocation node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NullLiteral)
+ */
+ public boolean visit(NullLiteral node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NumberLiteral)
+ */
+ public boolean visit(NumberLiteral node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PackageDeclaration)
+ */
+ public boolean visit(PackageDeclaration node) {
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ParenthesizedExpression)
+ */
+ public boolean visit(ParenthesizedExpression node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PostfixExpression)
+ */
+ public boolean visit(PostfixExpression node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PrefixExpression)
+ */
+ public boolean visit(PrefixExpression node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PrimitiveType)
+ */
+ public boolean visit(PrimitiveType node) {
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.QualifiedName)
+ */
+ public boolean visit(QualifiedName node) {
+ visit(node, true);
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ReturnStatement)
+ */
+ public boolean visit(ReturnStatement node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SimpleName)
+ */
+ public boolean visit(SimpleName node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SimpleType)
+ */
+ public boolean visit(SimpleType node) {
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SingleVariableDeclaration)
+ */
+ public boolean visit(SingleVariableDeclaration node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.StringLiteral)
+ */
+ public boolean visit(StringLiteral node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperConstructorInvocation)
+ */
+ public boolean visit(SuperConstructorInvocation node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperFieldAccess)
+ */
+ public boolean visit(SuperFieldAccess node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperMethodInvocation)
+ */
+ public boolean visit(SuperMethodInvocation node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SwitchCase)
+ */
+ public boolean visit(SwitchCase node) {
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SwitchStatement)
+ */
+ public boolean visit(SwitchStatement node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SynchronizedStatement)
+ */
+ public boolean visit(SynchronizedStatement node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ThisExpression)
+ */
+ public boolean visit(ThisExpression node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ThrowStatement)
+ */
+ public boolean visit(ThrowStatement node) {
+ return visit(node, true);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TryStatement)
+ */
+ public boolean visit(TryStatement node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeDeclaration)
+ */
+ public boolean visit(TypeDeclaration node) {
+ if (visit(node, false)) {
+ // visit only the elements of the type declaration
+ List bodyDeclaration= node.bodyDeclarations();
+ for (Iterator iter= bodyDeclaration.iterator(); iter.hasNext();) {
+ ((BodyDeclaration)iter.next()).accept(this);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeDeclarationStatement)
+ */
+ public boolean visit(TypeDeclarationStatement node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeLiteral)
+ */
+ public boolean visit(TypeLiteral node) {
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.VariableDeclarationExpression)
+ */
+ public boolean visit(VariableDeclarationExpression node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.VariableDeclarationFragment)
+ */
+ public boolean visit(VariableDeclarationFragment node) {
+ return visit(node, node.getInitializer() != null);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.VariableDeclarationStatement)
+ */
+ public boolean visit(VariableDeclarationStatement node) {
+ return visit(node, false);
+ }
+
+ /**
+ * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.WhileStatement)
+ */
+ public boolean visit(WhileStatement node) {
+ return visit(node, false);
+ }
+
+}
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/DirectorySourceLocation.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/DirectorySourceLocation.java
index f915f36..9778851 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/DirectorySourceLocation.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/DirectorySourceLocation.java
@@ -18,7 +18,10 @@
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
+
import org.apache.xerces.dom.DocumentImpl;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
@@ -85,6 +88,10 @@
String typeName = pathStr;
do {
IPath filePath = root.append(new Path(typeName + ".java")); //$NON-NLS-1$
+ IFile workspaceFile= ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(filePath);
+ if (workspaceFile != null) {
+ return workspaceFile;
+ }
File file = filePath.toFile();
if (file.exists()) {
return new LocalFileStorage(file);