From d2e588b90023165ce5b70c3721bdd2c38bdf9924 Mon Sep 17 00:00:00 2001 From: incastrix Date: Wed, 23 Jan 2008 22:47:14 +0000 Subject: [PATCH] Merge xdebug 1.3.x --- .../phpeclipse/xdebug/php/model/IClassFile.java | 153 +++ .../phpeclipse/xdebug/php/model/ITypeRoot.java | 108 ++ .../xdebug/php/model/IXDebugBreakpoint.java | 121 ++ .../php/model/ValidBreakpointLocationLocator.java | 1158 +++++++++++++++++++ .../xdebug/php/model/XDebugBreakpoint.java | 1178 ++++++++++++++++++++ .../php/model/XDebugConditionalBreakpoint.java | 107 ++ 6 files changed, 2825 insertions(+), 0 deletions(-) create mode 100644 net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/IClassFile.java create mode 100644 net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/ITypeRoot.java create mode 100644 net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/IXDebugBreakpoint.java create mode 100644 net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/ValidBreakpointLocationLocator.java create mode 100644 net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugBreakpoint.java create mode 100644 net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugConditionalBreakpoint.java diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/IClassFile.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/IClassFile.java new file mode 100644 index 0000000..f9ba82b --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/IClassFile.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.xdebug.php.model; + +import net.sourceforge.phpdt.core.IBufferFactory; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IProblemRequestor; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.WorkingCopyOwner; + +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * Represents an entire binary type (single .class file). + * A class file has a single child of type IType. + * Class file elements need to be opened before they can be navigated. + * If a class file cannot be parsed, its structure remains unknown. Use + * IJavaElement.isStructureKnown to determine whether this is the + * case. + *

+ * Note: IClassFile extends ISourceReference. + * Source can be obtained for a class file if and only if source has been attached to this + * class file. The source associated with a class file is the source code of + * the compilation unit it was (nominally) generated from. + *

+ *

+ * This interface is not intended to be implemented by clients. + *

+ * + * @see IPackageFragmentRoot#attachSource(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, IProgressMonitor) + */ + +public interface IClassFile extends ITypeRoot { + +/** + * Changes this class file handle into a working copy. A new {@link IBuffer} is + * created using the given owner. Uses the primary owner if null is + * specified. + *

+ * When switching to working copy mode, problems are reported to the given + * {@link IProblemRequestor}. Note that once in working copy mode, the given + * {@link IProblemRequestor} is ignored. Only the original {@link IProblemRequestor} + * is used to report subsequent problems. + *

+ *

+ * Once in working copy mode, changes to this working copy or its children are done in memory. + * Only the new buffer is affected. + *

+ *

+ * Using {@link ICompilationUnit#commitWorkingCopy(boolean, IProgressMonitor)} on the working copy + * will throw a JavaModelException as a class file is implicetly read-only. + *

+ *

+ * If this class file was already in working copy mode, an internal counter is incremented and no + * other action is taken on this working copy. To bring this working copy back into the original mode + * (where it reflects the underlying resource), {@link ICompilationUnit#discardWorkingCopy} must be call as many + * times as {@link #becomeWorkingCopy(IProblemRequestor, WorkingCopyOwner, IProgressMonitor)}. + *

+ *

+ * The primary compilation unit of a class file's working copy does not exist if the class file is not + * in working copy mode (classFileWorkingCopy.getPrimary().exists() == false). + *

+ *

+ * The resource of a class file's working copy is null if the class file is in an external jar file. + *

+ * + * @param problemRequestor a requestor which will get notified of problems detected during + * reconciling as they are discovered. The requestor can be set to null indicating + * that the client is not interested in problems. + * @param owner the given {@link WorkingCopyOwner}, or null for the primary owner + * @param monitor a progress monitor used to report progress while opening this compilation unit + * or null if no progress should be reported + * @return a working copy for this class file + * @throws JavaModelException if this compilation unit could not become a working copy. + * @see ICompilationUnit#discardWorkingCopy() + * @since 3.2 + * @deprecated Use {@link ITypeRoot#getWorkingCopy(WorkingCopyOwner, IProgressMonitor)} instead. + * Note that if this deprecated method is used, problems will be reported to the given problem requestor + * as well as the problem requestor returned by the working copy owner (if not null). + */ +ICompilationUnit becomeWorkingCopy(IProblemRequestor problemRequestor, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException; +/** + * Returns the bytes contained in this class file. + * + * @return the bytes contained in this class file + * + * @exception JavaModelException if this element does not exist or if an + * exception occurs while accessing its corresponding resource + * @since 3.3 + */ +byte[] getBytes() throws JavaModelException; +/** + * Returns the type contained in this class file. + * This is a handle-only method. The type may or may not exist. + * + * @return the type contained in this class file + */ +IType getType(); +/** + * Returns a working copy on the source associated with this class file using the given + * factory to create the buffer, or null if there is no source associated + * with the class file. + *

+ * The buffer will be automatically initialized with the source of the class file + * upon creation. + *

+ * The only valid operations on this working copy are getBuffer() or getOriginalElement. + * + * @param monitor a progress monitor used to report progress while opening this compilation unit + * or null if no progress should be reported + * @param factory the factory that creates a buffer that is used to get the content of the working copy + * or null if the internal factory should be used + * @return a a working copy on the source associated with this class file + * @exception JavaModelException if the source of this class file can + * not be determined. Reasons include: + *

+ * @since 2.0 + * @deprecated Use {@link ITypeRoot#getWorkingCopy(WorkingCopyOwner, IProgressMonitor)} instead + */ +IJavaElement getWorkingCopy(IProgressMonitor monitor, IBufferFactory factory) throws JavaModelException; +/** + * Returns whether this type represents a class. This is not guaranteed to be + * instantaneous, as it may require parsing the underlying file. + * + * @return true if the class file represents a class. + * + * @exception JavaModelException if this element does not exist or if an + * exception occurs while accessing its corresponding resource + */ +boolean isClass() throws JavaModelException; +/** + * Returns whether this type represents an interface. This is not guaranteed to + * be instantaneous, as it may require parsing the underlying file. + * + * @return true if the class file represents an interface. + * + * @exception JavaModelException if this element does not exist or if an + * exception occurs while accessing its corresponding resource + */ +boolean isInterface() throws JavaModelException; +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/ITypeRoot.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/ITypeRoot.java new file mode 100644 index 0000000..7acec03 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/ITypeRoot.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.xdebug.php.model; + +import net.sourceforge.phpdt.core.ICodeAssist; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IOpenable; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IParent; +import net.sourceforge.phpdt.core.ISourceReference; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.WorkingCopyOwner; + +import org.eclipse.core.runtime.IProgressMonitor; + + +/** + * Represents an entire Java type root (either an ICompilationUnit + * or an IClassFile). + * + *

+ * This interface is not intended to be implemented by clients. + *

+ * + * @see ICompilationUnit Note that methods {@link #findPrimaryType()} and {@link #getElementAt(int)} + * were already implemented in this interface respectively since version 3.0 and version 1.0. + * @see IClassFile Note that method {@link #getWorkingCopy(WorkingCopyOwner, IProgressMonitor)} + * was already implemented in this interface since version 3.0. + * @since 3.3 + */ +public interface ITypeRoot extends IJavaElement, IParent, IOpenable, ISourceReference, ICodeAssist { + +/** + * Finds the primary type of this Java type root (that is, the type with the same name as the + * compilation unit, or the type of a class file), or null if no such a type exists. + * + * @return the found primary type of this Java type root, or null if no such a type exists + */ +IType findPrimaryType(); + +/** + * Returns the smallest element within this Java type root that + * includes the given source position (that is, a method, field, etc.), or + * null if there is no element other than the Java type root + * itself at the given position, or if the given position is not + * within the source range of the source of this Java type root. + * + * @param position a source position inside the Java type root + * @return the innermost Java element enclosing a given source position or null + * if none (excluding the Java type root). + * @throws JavaModelException if the Java type root does not exist or if an + * exception occurs while accessing its corresponding resource + */ +IJavaElement getElementAt(int position) throws JavaModelException; + +/** + * Returns a shared working copy on this compilation unit or class file using the given working copy owner to create + * the buffer. If this is already a working copy of the given owner, the element itself is returned. + * This API can only answer an already existing working copy if it is based on the same + * original Java type root AND was using the same working copy owner (that is, as defined by {@link Object#equals}). + *

+ * The life time of a shared working copy is as follows: + *

+ * So users of this method must discard exactly once the working copy. + *

+ * Note that the working copy owner will be used for the life time of the shared working copy, that is if the + * working copy is closed then reopened, this owner will be used. + * The buffer will be automatically initialized with the original's Java type root content upon creation. + *

+ * When the shared working copy instance is created, an ADDED IJavaElementDelta is reported on this + * working copy. + *

+ * A working copy can be created on a not-yet existing compilation unit. + * In particular, such a working copy can then be committed in order to create + * the corresponding compilation unit. + *

+ * Note that possible problems of this working copy are reported using this method only + * if the given working copy owner returns a problem requestor for this working copy + * (see {@link WorkingCopyOwner#getProblemRequestor(ICompilationUnit)}). + *

+ * + * @param owner the working copy owner that creates a buffer that is used to get the content + * of the working copy + * @param monitor a progress monitor used to report progress while opening this compilation unit + * or null if no progress should be reported + * @throws JavaModelException if the contents of this element can + * not be determined. + * @return a new working copy of this Java type root using the given owner to create + * the buffer, or this Java type root if it is already a working copy + */ +ICompilationUnit getWorkingCopy(WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException; + +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/IXDebugBreakpoint.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/IXDebugBreakpoint.java new file mode 100644 index 0000000..f68342b --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/IXDebugBreakpoint.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.xdebug.php.model; + + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.model.IBreakpoint; + +/** + * A breakpoint specific to the Java debug model. A Java breakpoint + * supports: + * + *

+ * Clients are not intended to implement this interface + *

+ * @since 2.0 + */ +public interface IXDebugBreakpoint extends IBreakpoint { + + /** + * Returns whether this breakpoint is installed in at least + * one debug target. + * + * @return whether this breakpoint is installed + * @exception CoreException if unable to access the property + * on this breakpoint's underlying marker + */ + public boolean isInstalled() throws CoreException; + /** + * Returns the fully qualified name of the type this breakpoint + * is located in, or null if this breakpoint + * is not located in a specific type - for example, a pattern breakpoint. + * + * @return the fully qualified name of the type this breakpoint + * is located in, or null + * @exception CoreException if unable to access the property + * from this breakpoint's underlying marker + */ + public String getTypeName() throws CoreException; + /** + * Returns this breakpoint's hit count or, -1 if this + * breakpoint does not have a hit count. + * + * @return this breakpoint's hit count, or -1 + * @exception CoreException if unable to access the property + * from this breakpoint's underlying marker + */ + public int getHitCount() throws CoreException; + /** + * Sets the hit count attribute of this breakpoint. + * If this breakpoint is currently disabled and the hit count + * is set greater than -1, this breakpoint is automatically enabled. + * + * @param count the new hit count + * @exception CoreException if unable to set the property + * on this breakpoint's underlying marker + */ + public void setHitCount(int count) throws CoreException; + + /** + * Adds the given object to the list of objects in which this + * breakpoint is restricted to suspend execution. Has no effect + * if the object has already been added. Note that clients should + * first ensure that a breakpoint supports instance filters. + *

+ * Note: This implementation will add more than one filter. However, if there is + * more than one instance filter for a debug target, the breakpoint will never be hit + * in that target, as the current context cannot be two different instances at the + * same time. + *

+ * + * @param object instance filter to add + * @exception CoreException if unable to add the given instance filter + * @since 2.1 + */ + //public void addInstanceFilter(/*IJava*/Object object) throws CoreException; + + /** + * Removes the given object from the list of objects in which this + * breakpoint is restricted to suspend execution. Has no effect if the + * object has not yet been added as an instance filter. + * + * @param object instance filter to remove + * @exception CoreException if unable to remove the given instance filter + * @since 2.1 + */ + //public void removeInstanceFilter(/*IJava*/Object object) throws CoreException; + + /** + * Returns whether this breakpoints supports instance filters. + * + * @return whether this breakpoints supports instance filters + * @since 3.0 + */ + //public boolean supportsInstanceFilters(); + + /** + * Returns the current set of active instance filters. + * + * @return the current set of active instance filters. + * @exception CoreException if unable to retrieve the list + * @since 2.1 + */ + //public IJavaObject[] getInstanceFilters() throws CoreException; +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/ValidBreakpointLocationLocator.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/ValidBreakpointLocationLocator.java new file mode 100644 index 0000000..145a534 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/ValidBreakpointLocationLocator.java @@ -0,0 +1,1158 @@ +/******************************************************************************* + * Copyright (c) 2003, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.xdebug.php.model; +/*org.eclipse.jdt.internal.debug.ui.actions;*/ + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import net.sourceforge.phpdt.internal.core.CompilationUnit; +//import net.sourceforge.phpdt.internal.compiler.batch.CompilationUnit; + +import net.sourceforge.phpdt.internal.compiler.ast.ASTNode; +import net.sourceforge.phpdt.internal.compiler.ASTVisitor; +/*import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; +import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; +import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration; +import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; +import org.eclipse.jdt.core.dom.ArrayAccess; +import org.eclipse.jdt.core.dom.ArrayCreation;*/ +import net.sourceforge.phpdt.internal.compiler.ast.ArrayInitializer; +/*import org.eclipse.jdt.core.dom.ArrayType;*/ +import net.sourceforge.phpdt.internal.compiler.ast.AssertStatement; +import net.sourceforge.phpdt.internal.compiler.ast.Assignment; +import net.sourceforge.phpdt.internal.compiler.ast.Block; +import net.sourceforge.phpdt.internal.compiler.ast.ThrowStatement; + +/*import org.eclipse.jdt.core.dom.BlockComment; +import org.eclipse.jdt.core.dom.BodyDeclaration; +import org.eclipse.jdt.core.dom.BooleanLiteral;*/ +import net.sourceforge.phpdt.internal.compiler.ast.BreakStatement; +import net.sourceforge.phpdt.internal.compiler.ast.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 net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression; +/*import org.eclipse.jdt.core.dom.ConstructorInvocation;*/ +import net.sourceforge.phpdt.internal.compiler.ast.ContinueStatement; +import net.sourceforge.phpdt.internal.compiler.ast.DoStatement; +import net.sourceforge.phpdt.internal.compiler.ast.EmptyStatement; +/*import org.eclipse.jdt.core.dom.EnhancedForStatement; +import org.eclipse.jdt.core.dom.EnumConstantDeclaration; +import org.eclipse.jdt.core.dom.EnumDeclaration; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.ExpressionStatement; +import org.eclipse.jdt.core.dom.FieldAccess;*/ +import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.ForStatement; +/*import org.eclipse.jdt.core.dom.IBinding; +import org.eclipse.jdt.core.dom.IVariableBinding;*/ +import net.sourceforge.phpdt.internal.compiler.ast.IfStatement; +/*import org.eclipse.jdt.core.dom.ImportDeclaration; +import org.eclipse.jdt.core.dom.InfixExpression;*/ +import net.sourceforge.phpdt.internal.compiler.ast.Initializer; +import net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression; +/*import org.eclipse.jdt.core.dom.Javadoc;*/ +import net.sourceforge.phpdt.internal.compiler.ast.LabeledStatement; +/*import org.eclipse.jdt.core.dom.LineComment; +import org.eclipse.jdt.core.dom.MarkerAnnotation; +import org.eclipse.jdt.core.dom.MemberRef; +import org.eclipse.jdt.core.dom.MemberValuePair;*/ +import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration; +/*import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.MethodRef; +import org.eclipse.jdt.core.dom.MethodRefParameter; +import org.eclipse.jdt.core.dom.Modifier; +import org.eclipse.jdt.core.dom.Name; +import org.eclipse.jdt.core.dom.NormalAnnotation;*/ +import net.sourceforge.phpdt.internal.compiler.ast.NullLiteral; +import net.sourceforge.phpdt.internal.compiler.ast.NumberLiteral; +/*import org.eclipse.jdt.core.dom.PackageDeclaration; +import org.eclipse.jdt.core.dom.ParameterizedType; +import org.eclipse.jdt.core.dom.ParenthesizedExpression;*/ +import net.sourceforge.phpdt.internal.compiler.ast.PostfixExpression; +import net.sourceforge.phpdt.internal.compiler.ast.PrefixExpression; +/*import org.eclipse.jdt.core.dom.PrimitiveType; +import org.eclipse.jdt.core.dom.QualifiedName; +import org.eclipse.jdt.core.dom.QualifiedType;*/ +import net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement; +/*import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.SimpleType; +import org.eclipse.jdt.core.dom.SingleMemberAnnotation; +import org.eclipse.jdt.core.dom.SingleVariableDeclaration;*/ +import net.sourceforge.phpdt.internal.compiler.ast.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 net.sourceforge.phpdt.internal.compiler.ast.SwitchStatement; +/*import org.eclipse.jdt.core.dom.SynchronizedStatement; +import org.eclipse.jdt.core.dom.TagElement; +import org.eclipse.jdt.core.dom.TextElement; +import org.eclipse.jdt.core.dom.ThisExpression;*/ +import net.sourceforge.phpdt.internal.compiler.ast.ThrowStatement; +import net.sourceforge.phpdt.internal.compiler.ast.TryStatement; +import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration; +/*import org.eclipse.jdt.core.dom.TypeDeclarationStatement; +import org.eclipse.jdt.core.dom.TypeLiteral; +import org.eclipse.jdt.core.dom.TypeParameter; +import org.eclipse.jdt.core.dom.VariableDeclarationExpression; +import org.eclipse.jdt.core.dom.VariableDeclarationFragment; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement;*/ +import net.sourceforge.phpdt.internal.compiler.ast.WhileStatement; +/*import org.eclipse.jdt.core.dom.WildcardType; +import org.eclipse.jdt.core.dom.PrefixExpression.Operator;*/ + + +/** + * 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 { + + public static final int LOCATION_NOT_FOUND= 0; + public static final int LOCATION_LINE= 1; + public static final int LOCATION_METHOD= 2; + public static final int LOCATION_FIELD= 3; + + private CompilationUnit fCompilationUnit; + private int fLineNumber; + private boolean fBindingsResolved; + private boolean fNeedBindings = false; + private boolean fBestMatch; + + private int fLocationType; + private boolean fLocationFound; + private String fTypeName; + private int fLineLocation; + private int fMemberOffset; + private List fLabels; + + /** + * @param compilationUnit the JDOM CompilationUnit of the source code. + * @param lineNumber the line number in the source code where to put the breakpoint. + * @param bestMatch if true look for the best match, otherwise look only for a valid line + */ + public ValidBreakpointLocationLocator(CompilationUnit compilationUnit, int lineNumber, boolean bindingsResolved, boolean bestMatch) { + fCompilationUnit= compilationUnit; + fLineNumber= lineNumber; + fBindingsResolved= bindingsResolved; + fBestMatch= bestMatch; + fLocationFound= false; + } + + /** + * Returns whether binding information would be helpful in validating a breakpoint + * location. If this locator makes a pass of the tree and determines that binding + * information would be helpful but was not available, this method returns + * true. + * + * @return whether binding information would be helpful in validating a breakpoint location + */ + public boolean isBindingsRequired() { + return fNeedBindings; + } + + /** + * Return the type of the valid location found + * @return one of LOCATION_NOT_FOUND, LOCATION_LINE, LOCATION_METHOD or LOCATION_FIELD + */ + public int getLocationType() { + return fLocationType; + } + + /** + * Return of the type where the valid location is. + */ + public String getFullyQualifiedTypeName() { + return fTypeName; + } + + /** + * Return the line number of the computed valid location, if the location type is LOCATION_LINE. + */ + public int getLineLocation() { + if (fLocationType == LOCATION_LINE) { + return fLineLocation; + } + return -1; + } + + /** + * Return the offset of the member which is the valid location, + * if the location type is LOCATION_METHOD or LOCATION_FIELD. + */ + public int getMemberOffset() { + return fMemberOffset; + } + + /** + * 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. + */ + /*static protected String computeTypeName(ASTNode node) { + String typeName = null; + while (!(node instanceof CompilationUnit)) { + if (node instanceof AbstractTypeDeclaration) { + String identifier= ((AbstractTypeDeclaration)node).getName().getIdentifier(); + if (typeName == null) { + typeName= identifier; + } else { + typeName= identifier + "$" + typeName; //$NON-NLS-1$ + } + } + 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$ + } + return packageIdentifier + typeName; + }*/ + + /** + * Return true if this node children may contain a valid location + * for the breakpoint. + * @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. + */ + /*private boolean visit(ASTNode node, boolean isCode) { + // if we already found a correct location + // no need to check the element inside. + if (fLocationFound) { + return false; + } + int startPosition= node.getStartPosition(); + int endLine= lineNumber(startPosition + node.getLength() - 1); + // if the position is not in this part of the code + // no need to check the element inside. + if (endLine < fLineNumber) { + return false; + } + // if the first line of this node always represents some executable code and the + // breakpoint is requested on this line or on a previous line, this is a valid + // location + int startLine = lineNumber(startPosition); + if (isCode && (fLineNumber <= startLine)) { + fLineLocation= startLine; + fLocationFound= true; + fLocationType= LOCATION_LINE; + fTypeName= computeTypeName(node); + return false; + } + return true; + }*/ + + /*private boolean isReplacedByConstantValue(Expression node) { + switch (node.getNodeType()) { + // litterals are constant + case ASTNode.BOOLEAN_LITERAL: + case ASTNode.CHARACTER_LITERAL: + case ASTNode.NUMBER_LITERAL: + case ASTNode.STRING_LITERAL: + return true; + case ASTNode.SIMPLE_NAME: + case ASTNode.QUALIFIED_NAME: + return isReplacedByConstantValue((Name)node); + case ASTNode.FIELD_ACCESS: + return isReplacedByConstantValue((FieldAccess)node); + case ASTNode.SUPER_FIELD_ACCESS: + return isReplacedByConstantValue((SuperFieldAccess)node); + case ASTNode.INFIX_EXPRESSION: + return isReplacedByConstantValue((InfixExpression)node); + case ASTNode.PREFIX_EXPRESSION: + return isReplacedByConstantValue((PrefixExpression)node); + case ASTNode.CAST_EXPRESSION: + return isReplacedByConstantValue(((CastExpression)node).getExpression()); + default: + return false; + } + }*/ + + /*private boolean isReplacedByConstantValue(InfixExpression node) { + // if all operands are constant value, the expression is replaced by a constant value + if (!(isReplacedByConstantValue(node.getLeftOperand()) && isReplacedByConstantValue(node.getRightOperand()))) { + return false; + } + if (node.hasExtendedOperands()) { + for (Iterator iter = node.extendedOperands().iterator(); iter.hasNext(); ) { + if (!isReplacedByConstantValue((Expression) iter.next())) { + return false; + } + } + } + return true; + }*/ + + /*private boolean isReplacedByConstantValue(PrefixExpression node) { + // for '-', '+', '~' and '!', if the operand is a constant value, + // the expression is replaced by a constant value + Operator operator = node.getOperator(); + if (operator != PrefixExpression.Operator.INCREMENT && operator != PrefixExpression.Operator.DECREMENT) { + return isReplacedByConstantValue(node.getOperand()); + } + return false; + }*/ + + /*private boolean isReplacedByConstantValue(Name node) { + if (!fBindingsResolved) { + fNeedBindings = true; + return false; + } + // if node is a variable with a constant value (static final field) + IBinding binding= node.resolveBinding(); + if (binding != null && binding.getKind() == IBinding.VARIABLE) { + return ((IVariableBinding)binding).getConstantValue() != null; + } + return false; + }*/ + + /*private boolean isReplacedByConstantValue(FieldAccess node) { + if (!fBindingsResolved) { + fNeedBindings = true; + return false; + } + // if the node is 'this.', and the field is static final + Expression expression= node.getExpression(); + IVariableBinding binding= node.resolveFieldBinding(); + if (binding != null && expression.getNodeType() == ASTNode.THIS_EXPRESSION) { + return binding.getConstantValue() != null; + } + return false; + }*/ + + /*private boolean isReplacedByConstantValue(SuperFieldAccess node) { + if (!fBindingsResolved) { + fNeedBindings = true; + return false; + } + // if the field is static final + IVariableBinding binding= node.resolveFieldBinding(); + if (binding != null) { + return binding.getConstantValue() != null; + } + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration) + */ + /*public boolean visit(AnnotationTypeDeclaration node) { + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration) + */ + /*public boolean visit(AnnotationTypeMemberDeclaration node) { + return false; + }*/ + + /** + * @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) { + if (visit(node, false)) { + // if the left hand side represent a local variable, or a static field + // and the breakpoint was requested on a line before the line where + // starts the assigment, set the location to be the first executable + // instruction of the right hand side, as it will be the first part of + // this assigment to be executed + Expression leftHandSide= node.getLeftHandSide(); + if (leftHandSide instanceof Name) { + int startLine = lineNumber(node.getStartPosition()); + if (fLineNumber < startLine) { + if (fBindingsResolved) { + IVariableBinding binding= (IVariableBinding)((Name)leftHandSide).resolveBinding(); + if (binding != null && (!binding.isField() || Modifier.isStatic(binding.getModifiers()))) { + node.getRightHandSide().accept(this); + } + } else { + fNeedBindings = true; + } + } + } + return true; + } + return false; + }*/ + + /** + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Block) + */ + /*public boolean visit(Block node) { + if (visit(node, false)) { + if (node.statements().isEmpty() && node.getParent().getNodeType() == ASTNode.METHOD_DECLARATION) { + // in case of an empty method, set the breakpoint on the last line of the empty block. + fLineLocation= lineNumber(node.getStartPosition() + node.getLength() - 1); + fLocationFound= true; + fLocationType= LOCATION_LINE; + fTypeName= computeTypeName(node); + return false; + } + return true; + } + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.BlockComment) + */ + /*public boolean visit(BlockComment node) { + return 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; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnhancedForStatement) + */ + /*public boolean visit(EnhancedForStatement node) { + if (visit(node, false)) { + node.getExpression().accept(this); + node.getBody().accept(this); + } + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnumConstantDeclaration) + */ + /*public boolean visit(EnumConstantDeclaration node) { + if (visit(node, false)) { + List arguments= node.arguments(); + for (Iterator iter= arguments.iterator(); iter.hasNext();) { + ((Expression)iter.next()).accept(this); + } + AnonymousClassDeclaration decl= node.getAnonymousClassDeclaration(); + if (decl != null) { + decl.accept(this); + } + } + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnumDeclaration) + */ + /*public boolean visit(EnumDeclaration node) { + if (visit(node, false)) { + List enumConstants= node.enumConstants(); + for (Iterator iter = enumConstants.iterator(); iter.hasNext();) { + ((EnumConstantDeclaration) iter.next()).accept(this); + } + 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.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)) { + if (fBestMatch) { + // check if the line contains a single field declaration. + List fragments = node.fragments(); + if (fragments.size() == 1) { + int offset= ((VariableDeclarationFragment)fragments.get(0)).getName().getStartPosition(); + // check if the breakpoint is to be set on the line which contains the name of the field + if (lineNumber(offset) == fLineNumber) { + fMemberOffset= offset; + fLocationType= LOCATION_FIELD; + fLocationFound= true; + return 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) { + // if the breakpoint is to be set on a constant operand, the breakpoint needs to be + // set on the first constant operand after the previous non-constant operand + // (or the beginning of the expression, if there is no non-constant operand before). + // ex: foo() + // previous non-constant operand + // 1 + // breakpoint set here + // 2 // breakpoint asked to be set here + if (visit(node, false)) { + Expression leftOperand= node.getLeftOperand(); + Expression firstConstant= null; + if (visit(leftOperand, false)) { + leftOperand.accept(this); + return false; + } + if (isReplacedByConstantValue(leftOperand)) { + firstConstant= leftOperand; + } + Expression rightOperand= node.getRightOperand(); + if (visit(rightOperand, false)) { + if (firstConstant == null || !isReplacedByConstantValue(rightOperand)) { + rightOperand.accept(this); + return false; + } + } else { + if (isReplacedByConstantValue(rightOperand)) { + if (firstConstant == null) { + firstConstant= rightOperand; + } + } else { + firstConstant= null; + } + List extendedOperands= node.extendedOperands(); + for (Iterator iter= extendedOperands.iterator(); iter.hasNext();) { + Expression operand= (Expression) iter.next(); + if (visit(operand, false)) { + if (firstConstant == null || !isReplacedByConstantValue(operand)) { + operand.accept(this); + return false; + } + break; + } + if (isReplacedByConstantValue(operand)) { + if (firstConstant == null) { + firstConstant= operand; + } + } else { + firstConstant= null; + } + + } + } + fLineLocation= lineNumber(firstConstant.getStartPosition()); + fLocationFound= true; + fLocationType= LOCATION_LINE; + fTypeName= computeTypeName(firstConstant); + } + return false; + }*/ + + /** + * @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) { + nestLabel(node.getLabel().getFullyQualifiedName()); + return visit(node, false); + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#endVisit(org.eclipse.jdt.core.dom.LabeledStatement) + */ + /*public void endVisit(LabeledStatement node) { + popLabel(); + super.endVisit(node); + }*/ + + private String getLabel() { + if (fLabels == null || fLabels.isEmpty()) { + return null; + } + return (String) fLabels.get(fLabels.size() - 1); + } + + private void nestLabel(String label) { + if (fLabels == null) { + fLabels = new ArrayList(); + } + fLabels.add(label); + } + + private void popLabel() { + if (fLabels == null || fLabels.isEmpty()) { + return; + } + fLabels.remove(fLabels.size() - 1); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.LineComment) + */ + /*public boolean visit(LineComment node) { + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MarkerAnnotation) + */ + /*public boolean visit(MarkerAnnotation node) { + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MemberRef) + */ + /*public boolean visit(MemberRef node) { + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MemberValuePair) + */ + /*public boolean visit(MemberValuePair node) { + return false; + }*/ + + /** + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration) + */ + public boolean visit(MethodDeclaration node) { + if (visit(node/*, false*/)) { + if (fBestMatch) { + // check if we are on the line which contains the method name + int nameOffset= node.sourceStart; // node.getName().getStartPosition(); + if (lineNumber(nameOffset) == fLineNumber) { + fMemberOffset= nameOffset; + fLocationType= LOCATION_METHOD; + fLocationFound= true; + return false; + } + } + // visit only the body + /*Block body = node.getBody(); + if (body != null) { // body is null for abstract methods + body.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); + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodRef) + */ + /*public boolean visit(MethodRef node) { + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodRefParameter) + */ + /*public boolean visit(MethodRefParameter node) { + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Modifier) + */ + /*public boolean visit(Modifier node) { + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NormalAnnotation) + */ + /*public boolean visit(NormalAnnotation node) { + return false; + }*/ + + /** + * @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; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ParameterizedType) + */ + /*public boolean visit(ParameterizedType 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) { + if (visit(node, false)) { + if (isReplacedByConstantValue(node)) { + fLineLocation= lineNumber(node.getStartPosition()); + fLocationFound= true; + fLocationType= LOCATION_LINE; + fTypeName= computeTypeName(node); + return false; + } + return true; + } + return false; + }*/ + + /** + * @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; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.QualifiedType) + */ + /*public boolean visit(QualifiedType node) { + 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) { + // the name is only code if its not the current label (if any) + return visit(node, !node.getFullyQualifiedName().equals(getLabel())); + }*/ + + /** + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SimpleType) + */ + /*public boolean visit(SimpleType node) { + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SingleMemberAnnotation) + */ + /*public boolean visit(SingleMemberAnnotation 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); + }*/ + + + + // CaseStatment + /** + * @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); + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TagElement) + */ + /*public boolean visit(TagElement node) { + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TextElement) + */ + /*public boolean visit(TextElement node) { + return 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); + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeParameter) + */ + /*public boolean visit(TypeParameter node) { + return 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) { + Expression initializer = node.getInitializer(); + if (visit(node, false) && initializer != null) { + int startLine = lineNumber(node.getName().getStartPosition()); + + if (fLineNumber == startLine) { + fLineLocation= startLine; + fLocationFound= true; + fLocationType= LOCATION_LINE; + fTypeName= computeTypeName(node); + return false; + } + initializer.accept(this); + } + return false; + }*/ + + private int lineNumber(int offset) { + //int lineNumber = fCompilationUnit.getLineNumber(offset); + return 10; //lineNumber < 1 ? 1 : lineNumber; + } + + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.WildcardType) + */ + /*public boolean visit(WildcardType node) { + return false; + }*/ + + /** + * @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); + }*/ + +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugBreakpoint.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugBreakpoint.java new file mode 100644 index 0000000..23aecf7 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugBreakpoint.java @@ -0,0 +1,1178 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.xdebug.php.model; + + +import java.util.ArrayList; +//import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +//import java.util.Iterator; +import java.util.List; +//import java.util.Map; +import java.util.Set; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; +//import org.eclipse.core.runtime.MultiStatus; +//import org.eclipse.core.runtime.Preferences; +//import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugPlugin; +//import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.model.Breakpoint; +//import org.eclipse.debug.core.model.IDebugTarget; +import net.sourceforge.phpeclipse.xdebug.php.model.IXDebugBreakpoint; + +//import org.eclipse.jdt.debug.core.IJavaDebugTarget; +import net.sourceforge.phpeclipse.xdebug.php.model.XDebugTarget; + +//import org.eclipse.jdt.debug.core.IJavaThread; +//import net.sourceforge.phpeclipse.xdebug.php.model.XDebugThread; + +//import org.eclipse.jdt.debug.core.IJavaObject; +//import org.eclipse.jdt.debug.core.IJavaType; +//import org.eclipse.jdt.debug.core.JDIDebugModel; +//import org.eclipse.jdt.internal.debug.core.IJDIEventListener; +//import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin; +//import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget; +/*import org.eclipse.jdt.internal.debug.core.model.JDIObjectValue; +import org.eclipse.jdt.internal.debug.core.model.JDIThread; +import org.eclipse.jdt.internal.debug.core.model.JDIType;*/ + +//import com.ibm.icu.text.MessageFormat; +//import com.sun.jdi.ObjectReference; +//import com.sun.jdi.ReferenceType; +/*import com.sun.jdi.ThreadReference; +import com.sun.jdi.VMDisconnectedException; +import com.sun.jdi.event.ClassPrepareEvent; +import com.sun.jdi.event.Event; +import com.sun.jdi.event.LocatableEvent; +import com.sun.jdi.request.ClassPrepareRequest; +import com.sun.jdi.request.EventRequest; +import com.sun.jdi.request.EventRequestManager; +*/ +public abstract class XDebugBreakpoint extends Breakpoint implements IXDebugBreakpoint/*,*/ /*IJDIEventListener,*/ /*IDebugEventSetListener*/ { + + /** + * Breakpoint attribute storing the expired value (value "org.eclipse.jdt.debug.core.expired"). + * This attribute is stored as a boolean. Once a hit count has + * been reached, a breakpoint is considered to be "expired". + */ + protected static final String EXPIRED = "org.eclipse.jdt.debug.core.expired"; //$NON-NLS-1$ + /** + * Breakpoint attribute storing a breakpoint's hit count value + * (value "org.eclipse.jdt.debug.core.hitCount"). This attribute is stored as an + * int. + */ + protected static final String HIT_COUNT = "net.sourceforge.phpeclipse.xdebug.php.model.hitCount"; //$NON-NLS-1$ + /** + * Breakpoint attribute storing the number of debug targets a + * breakpoint is installed in (value "org.eclipse.jdt.debug.core.installCount"). + * This attribute is a int. + */ + protected static final String INSTALL_COUNT = "org.eclipse.jdt.debug.core.installCount"; //$NON-NLS-1$ + + /** + * Breakpoint attribute storing the fully qualified name of the type + * this breakpoint is located in. + * (value "org.eclipse.jdt.debug.core.typeName"). This attribute is a String. + */ + protected static final String TYPE_NAME = "org.eclipse.jdt.debug.core.typeName"; //$NON-NLS-1$ + + /** + * Stores the collection of requests that this breakpoint has installed in + * debug targets. + * key: a debug target + * value: the requests this breakpoint has installed in that target + */ + protected HashMap fRequestsByTarget; + + /** + * The list of threads (ThreadReference objects) in which this breakpoint will suspend, + * associated with the target in which each thread exists (JDIDebugTarget). + * key: targets the debug targets (IJavaDebugTarget) + * value: thread the filtered thread (IJavaThread) in the given target + */ + //protected Map fFilteredThreadsByTarget; + + /** + * Stores the type name that this breakpoint was last installed + * in. When a breakpoint is created, the TYPE_NAME attribute assigned to it + * is that of its top level enclosing type. When installed, the type + * may actually be an inner type. We need to keep track of the type + * type the breakpoint was installed in, in case we need to re-install + * the breakpoint for HCR (i.e. in case an inner type is HCR'd). + */ + protected String fInstalledTypeName = null; + + /** + * List of targets in which this breakpoint is installed. + * Used to prevent firing of more than one install notification + * when a breakpoint's requests are re-created. + */ + protected Set fInstalledTargets = null; + + /** + * List of active instance filters for this breakpoint + * (list of IJavaObject). + */ + protected List fInstanceFilters = null; + + /** + * Empty instance filters array. + */ + protected static final /*IJava*/Object[] fgEmptyInstanceFilters = new /*IJava*/Object[0]; + + /** + * Property identifier for a breakpoint object on an event request + */ + public static final String JAVA_BREAKPOINT_PROPERTY = "org.eclipse.jdt.debug.breakpoint"; //$NON-NLS-1$ + + /** + * JavaBreakpoint attributes + */ + protected static final String[] fgExpiredEnabledAttributes= new String[]{EXPIRED, ENABLED}; + + public XDebugBreakpoint() { + fRequestsByTarget = new HashMap(1); + //fFilteredThreadsByTarget= new HashMap(1); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IBreakpoint#getModelIdentifier() + */ + public String getModelIdentifier() { + return "asd"; //JDIDebugModel.getPluginIdentifier(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.Breakpoint#setMarker(org.eclipse.core.resources.IMarker) + */ + public void setMarker(IMarker marker) throws CoreException { + super.setMarker(marker); + configureAtStartup(); + } + + /** + * Add this breakpoint to the breakpoint manager, + * or sets it as unregistered. + */ + protected void register(boolean register) throws CoreException { + DebugPlugin plugin = DebugPlugin.getDefault(); + if (plugin != null && register) { + plugin.getBreakpointManager().addBreakpoint(this); + } else { + setRegistered(false); + } + } + + /** + * Add the given event request to the given debug target. If + * the request is the breakpoint request associated with this + * breakpoint, increment the install count. + */ + /*protected void registerRequest(EventRequest request, XDebugTarget target) throws CoreException { + if (request == null) { + return; + } + List reqs = getRequests(target); + if (reqs.isEmpty()) { + fRequestsByTarget.put(target, reqs); + } + reqs.add(request); + target.addJDIEventListener(this, request); + // update the install attribute on the breakpoint + if (!(request instanceof ClassPrepareRequest)) { + incrementInstallCount(); + // notification + fireInstalled(target); + } + }*/ + + /** + * Returns a String corresponding to the reference type + * name to the top enclosing type in which this breakpoint + * is located or null if no reference type could be + * found. + */ + /*protected String getEnclosingReferenceTypeName() throws CoreException { + String name= getTypeName(); + int index = name.indexOf('$'); + if (index == -1) { + return name; + } + return name.substring(0, index); + }*/ + + /** + * Returns the requests that this breakpoint has installed + * in the given target. + */ + protected ArrayList getRequests(XDebugTarget target) { + ArrayList list= (ArrayList)fRequestsByTarget.get(target); + if (list == null) { + list= new ArrayList(2); + } + return list; + } + + /** + * Remove the given request from the given target. If the request + * is the breakpoint request associated with this breakpoint, + * decrement the install count. + */ + /*protected void deregisterRequest(EventRequest request, XDebugTarget target) throws CoreException { + target.removeJDIEventListener(this, request); + // A request may be getting de-registered because the breakpoint has + // been deleted. It may be that this occurred because of a marker deletion. + // Don't try updating the marker (decrementing the install count) if + // it no longer exists. + if (!(request instanceof ClassPrepareRequest) && getMarker().exists()) { + decrementInstallCount(); + } + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.debug.core.IJDIEventListener#handleEvent(com.sun.jdi.event.Event, org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget) + */ + /*public boolean handleEvent(Event event, XDebugTarget target) { + if (event instanceof ClassPrepareEvent) { + return handleClassPrepareEvent((ClassPrepareEvent)event, target); + } + ThreadReference threadRef= ((LocatableEvent)event).thread(); + XDebugThread thread= target.findThread(threadRef); + if (thread == null || thread.isIgnoringBreakpoints()) { + return true; + } + return handleBreakpointEvent(event, target, thread); + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.debug.core.IJDIEventListener#wonSuspendVote(com.sun.jdi.event.Event, org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget) + */ + /*public void wonSuspendVote(Event event, XDebugTarget target) { + ThreadReference threadRef = null; + if (event instanceof ClassPrepareEvent) { + threadRef = ((ClassPrepareEvent)event).thread(); + } else if (event instanceof LocatableEvent) { + threadRef = ((LocatableEvent)event).thread(); + } + if (threadRef == null) { + return; + } + XDebugThread thread= target.findThread(threadRef); + if (thread == null || thread.isIgnoringBreakpoints()) { + return; + } + thread.wonSuspendVote(this); + }*/ + + /** + * Handle the given class prepare event, which was generated by the + * class prepare event installed in the given target by this breakpoint. + * + * If the class which has been loaded is a class in which this breakpoint + * should install, create a breakpoint request for that class. + */ + /*public boolean handleClassPrepareEvent(ClassPrepareEvent event, XDebugTarget target) { + try { + if (!installableReferenceType(event.referenceType(), target)) { + // Don't install this breakpoint in an + // inappropriate type + return true; + } + createRequest(target, event.referenceType()); + } catch (CoreException e) { + XDebugCorePlugin.log(e); + } + return true; + }*/ + + /** + * @see IJDIEventListener#handleEvent(Event, JDIDebugTarget) + * + * Handle the given event, which was generated by the breakpoint request + * installed in the given target by this breakpoint. + */ + /*public boolean handleBreakpointEvent(Event event, XDebugTarget target, XDebugThread thread) { + expireHitCount(event); + return !suspend(thread); // Resume if suspend fails + }*/ + + /** + * Delegates to the given thread to suspend, and + * returns whether the thread suspended + * It is possible that the thread will not suspend + * as directed by a Java breakpoint listener. + * + * @see IJavaBreakpointListener#breakpointHit(IJavaThread, IJavaBreakpoint) + */ + /*protected boolean suspend(XDebugThread thread) { + return thread.handleSuspendForBreakpoint(this, true); + }*/ + + /** + * Returns whether the given reference type is appropriate for this + * breakpoint to be installed in the given target. Query registered + * breakpoint listeners. + */ + /*protected boolean installableReferenceType(ReferenceType type, XDebugTarget target) throws CoreException { + String installableType= getTypeName(); + String queriedType= type.name(); + if (installableType == null || queriedType == null) { + return false; + } + int index= queriedType.indexOf('<'); + if (index != -1) { + queriedType= queriedType.substring(0, index); + } + if (installableType.equals(queriedType)) { + return queryInstallListeners(target, type); + } + index= queriedType.indexOf('$', 0); + if (index == -1) { + return false; + } + if (installableType.regionMatches(0, queriedType, 0, index)) { + return queryInstallListeners(target, type); + } + return false; + }*/ + + /** + * Called when a breakpoint event is encountered. Expires the + * hit count in the event's request and updates the marker. + * @param event the event whose request should have its hit count + * expired or null to only update the breakpoint marker. + */ + /*protected void expireHitCount(Event event) { + Integer requestCount= null; + EventRequest request= null; + if (event != null) { + request= event.request(); + requestCount= (Integer) request.getProperty(HIT_COUNT); + } + if (requestCount != null) { + if (request != null) { + request.putProperty(EXPIRED, Boolean.TRUE); + } + try { + setAttributes(fgExpiredEnabledAttributes, new Object[]{Boolean.TRUE, Boolean.FALSE}); + // make a note that we auto-disabled this breakpoint. + } catch (CoreException ce) { + XDebugCorePlugin.log(ce); + } + } + }*/ + + /** + * Returns whether this breakpoint should be "skipped". Breakpoints + * are skipped if the breakpoint manager is disabled and the breakpoint + * is registered with the manager + * + * @return whether this breakpoint should be skipped + */ + public boolean shouldSkipBreakpoint() throws CoreException { + DebugPlugin plugin = DebugPlugin.getDefault(); + return plugin != null && isRegistered() && !plugin.getBreakpointManager().isEnabled(); + } + + /** + * Attempts to create a breakpoint request for this breakpoint in the given + * reference type in the given target. + * + * @return Whether a request was created + */ + /*protected boolean createRequest(XDebugTarget target, ReferenceType type) throws CoreException { + if (shouldSkipBreakpoint()) { + return false; + } + EventRequest[] requests= newRequests(target, type); + if (requests == null) { + return false; + } + fInstalledTypeName = type.name(); + for (int i = 0; i < requests.length; i++) { + EventRequest request = requests[i]; + registerRequest(request, target); + } + return true; + }*/ + + /** + * Configure a breakpoint request with common properties: + * + * and sets the suspend policy of the request to suspend + * the event thread. + */ + /*protected void configureRequest(EventRequest request, XDebugTarget target) throws CoreException { + request.setSuspendPolicy(getJDISuspendPolicy()); + request.putProperty(JAVA_BREAKPOINT_PROPERTY, this); + configureRequestThreadFilter(request, target); + configureRequestHitCount(request); + configureInstanceFilters(request, target); + // Important: only enable a request after it has been configured + updateEnabledState(request, target); + }*/ + + /** + * Adds an instance filter to the given request. Since the implementation is + * request specific, subclasses must override. + * + * @param request + * @param object instance filter + */ + //protected abstract void addInstanceFilter(EventRequest request, ObjectReference object); + + /** + * Configure the thread filter property of the given request. + */ + /*protected void configureRequestThreadFilter(EventRequest request, XDebugTarget target) { + IJavaThread thread= (IJavaThread)fFilteredThreadsByTarget.get(target); + if (thread == null || (!(thread instanceof JDIThread))) { + return; + } + setRequestThreadFilter(request, ((JDIThread)thread).getUnderlyingThread()); + }*/ + + /** + * Configure the given request's hit count + */ + /*protected void configureRequestHitCount(EventRequest request) throws CoreException { + int hitCount= getHitCount(); + if (hitCount > 0) { + request.addCountFilter(hitCount); + request.putProperty(HIT_COUNT, new Integer(hitCount)); + } + }*/ + + /*protected void configureInstanceFilters(EventRequest request, XDebugTarget target) { + if (fInstanceFilters != null && !fInstanceFilters.isEmpty()) { + Iterator iter = fInstanceFilters.iterator(); + while (iter.hasNext()) {*/ + /*IJava*//*Object object = (*//*IJava*//*Object)iter.next(); + if (object.getDebugTarget().equals(target)) { + addInstanceFilter(request, ((JDIObjectValue)object).getUnderlyingObject()); + } + } + } + }*/ + + /** + * Creates, installs, and returns all event requests for this breakpoint + * in the given reference type and and target. + * + * @return the event requests created or null if creation failed + */ + //protected abstract EventRequest[] newRequests(XDebugTarget target, ReferenceType type) throws CoreException; + + /** + * Add this breakpoint to the given target. After it has been + * added to the given target, this breakpoint will suspend + * execution of that target as appropriate. + */ + /*public void addToTarget(XDebugTarget target) throws CoreException { + fireAdding(target); + createRequests(target); + }*/ + + /** + * Creates event requests for the given target + */ + /*protected void createRequests(XDebugTarget target) throws CoreException { + if (target.isTerminated() || shouldSkipBreakpoint()) { + return; + } + String referenceTypeName= getTypeName(); + String enclosingTypeName= getEnclosingReferenceTypeName(); + if (referenceTypeName == null || enclosingTypeName == null) { + return; + } + // create request to listen to class loads + if (referenceTypeName.indexOf('$') == -1) { + registerRequest(target.createClassPrepareRequest(enclosingTypeName), target); + //register to ensure we hear about local and anonymous inner classes + registerRequest(target.createClassPrepareRequest(enclosingTypeName + "$*"), target); //$NON-NLS-1$ + } else { + registerRequest(target.createClassPrepareRequest(referenceTypeName), target); + //register to ensure we hear about local and anonymous inner classes + registerRequest(target.createClassPrepareRequest(enclosingTypeName + "$*", referenceTypeName), target); //$NON-NLS-1$ + } + + // create breakpoint requests for each class currently loaded + List classes= target.jdiClassesByName(referenceTypeName); + if (classes.isEmpty() && enclosingTypeName.equals(referenceTypeName)) { + return; + } + + boolean success= false; + Iterator iter = classes.iterator(); + while (iter.hasNext()) { + ReferenceType type= (ReferenceType) iter.next(); + if (createRequest(target, type)) { + success= true; + } + } + + if (!success) { + addToTargetForLocalType(target, enclosingTypeName); + } + }*/ + + /** + * Local types (types defined in methods) are handled specially due to the + * different types that the local type is associated with as well as the + * performance problems of using ReferenceType#nestedTypes. From the Java + * model perspective a local type is defined within a method of a type. + * Therefore the type of a breakpoint placed in a local type is the type + * that encloses the method where the local type was defined. + * The local type is enclosed within the top level type according + * to the VM. + * So if "normal" attempts to create a request when a breakpoint is + * being added to a target fail, we must be dealing with a local type and therefore resort + * to looking up all of the nested types of the top level enclosing type. + */ + /*protected void addToTargetForLocalType(XDebugTarget target, String enclosingTypeName) throws CoreException { + List classes= target.jdiClassesByName(enclosingTypeName); + if (!classes.isEmpty()) { + Iterator iter = classes.iterator(); + while (iter.hasNext()) { + ReferenceType type= (ReferenceType) iter.next(); + Iterator nestedTypes= type.nestedTypes().iterator(); + while (nestedTypes.hasNext()) { + ReferenceType nestedType= (ReferenceType) nestedTypes.next(); + if (createRequest(target, nestedType)) { + break; + } + } + } + } + }*/ + + /** + * Returns the JDI suspend policy that corresponds to this + * breakpoint's suspend policy + * + * @return the JDI suspend policy that corresponds to this + * breakpoint's suspend policy + * @exception CoreException if unable to access this breakpoint's + * suspend policy setting + */ + /*protected int getJDISuspendPolicy() throws CoreException { + int breakpointPolicy = getSuspendPolicy(); + if (breakpointPolicy == IXDebugBreakpoint.SUSPEND_THREAD) { + return EventRequest.SUSPEND_EVENT_THREAD; + } + return EventRequest.SUSPEND_ALL; + }*/ + + /** + * returns the default suspend policy based on the pref setting on the + * Java-Debug pref page + * @return the default suspend policy + * @since 3.2 + */ + /*protected int getDefaultSuspendPolicy() { + Preferences store = JDIDebugModel.getPreferences(); + return store.getInt(JDIDebugPlugin.PREF_DEFAULT_BREAKPOINT_SUSPEND_POLICY); + }*/ + + + /** + * Returns whether the hitCount of this breakpoint is equal to the hitCount of + * the associated request. + */ + /*protected boolean hasHitCountChanged(EventRequest request) throws CoreException { + int hitCount= getHitCount(); + Integer requestCount= (Integer) request.getProperty(HIT_COUNT); + int oldCount = -1; + if (requestCount != null) { + oldCount = requestCount.intValue(); + } + return hitCount != oldCount; + }*/ + + /** + * Removes this breakpoint from the given target. + */ + /*public void removeFromTarget(final XDebugTarget target) throws CoreException { + removeRequests(target); + Object removed = fFilteredThreadsByTarget.remove(target); + boolean changed = removed != null; + boolean markerExists = markerExists(); + if (!markerExists || (markerExists && getInstallCount() == 0)) { + fInstalledTypeName = null; + } + + // remove instance filters + if (fInstanceFilters != null && !fInstanceFilters.isEmpty()) { + for (int i = 0; i < fInstanceFilters.size(); i++) { + IJavaObject object = (IJavaObject)fInstanceFilters.get(i); + if (object.getDebugTarget().equals(target)) { + fInstanceFilters.remove(i); + changed = true; + } + } + } + + // fire change notification if required + if (changed) { + fireChanged(); + } + + // notification + fireRemoved(target); + } */ + + /** + * Remove all requests that this breakpoint has installed in the given + * debug target. + */ + /*protected void removeRequests(final XDebugTarget target) throws CoreException { + // removing was previously done is a workspace runnable, but that is + // not possible since it can be a resource callback (marker deletion) that + // causes a breakpoint to be removed + ArrayList requests= (ArrayList)getRequests(target).clone(); + // Iterate over a copy of the requests since this list of requests + // can be changed in other threads which would cause an ConcurrentModificationException + Iterator iter = requests.iterator(); + EventRequest req; + while (iter.hasNext()) { + req = (EventRequest)iter.next(); + try { + if (target.isAvailable() && !isExpired(req)) { // cannot delete an expired request + EventRequestManager manager = target.getEventRequestManager(); + if (manager != null) { + manager.deleteEventRequest(req); // disable & remove + } + } + } catch (VMDisconnectedException e) { + if (target.isAvailable()) { + JDIDebugPlugin.log(e); + } + } catch (RuntimeException e) { + target.internalError(e); + } finally { + deregisterRequest(req, target); + } + } + fRequestsByTarget.remove(target); + }*/ + + /** + * Update the enabled state of the given request in the given target, which is associated + * with this breakpoint. Set the enabled state of the request + * to the enabled state of this breakpoint. + */ + /*protected void updateEnabledState(EventRequest request, XDebugTarget target) throws CoreException { + internalUpdateEnabledState(request, isEnabled(), target); + }*/ + + /** + * Set the enabled state of the given request to the given + * value, also taking into account instance filters. + */ + /*protected void internalUpdateEnabledState(EventRequest request, boolean enabled, XDebugTarget target) { + if (request.isEnabled() != enabled) { + // change the enabled state + try { + // if the request has expired, do not disable. + // BreakpointRequests that have expired cannot be deleted. + if (!isExpired(request)) { + request.setEnabled(enabled); + } + //} catch (VMDisconnectedException e) { + } catch (RuntimeException e) { + //target.internalError(e); + } + } + }*/ + + /** + * Returns whether this breakpoint has expired. + */ + public boolean isExpired() throws CoreException { + return ensureMarker().getAttribute(EXPIRED, false); + } + + /** + * Returns whether the given request is expired + */ + /*protected boolean isExpired(EventRequest request) { + Boolean requestExpired= (Boolean) request.getProperty(EXPIRED); + if (requestExpired == null) { + return false; + } + return requestExpired.booleanValue(); + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#isInstalled() + */ + public boolean isInstalled() throws CoreException { + return ensureMarker().getAttribute(INSTALL_COUNT, 0) > 0; + } + + /** + * Increments the install count of this breakpoint + */ + protected void incrementInstallCount() throws CoreException { + int count = getInstallCount(); + setAttribute(INSTALL_COUNT, count + 1); + } + + /** + * Returns the INSTALL_COUNT attribute of this breakpoint + * or 0 if the attribute is not set. + */ + public int getInstallCount() throws CoreException { + return ensureMarker().getAttribute(INSTALL_COUNT, 0); + } + + /** + * Decrements the install count of this breakpoint. + */ + protected void decrementInstallCount() throws CoreException { + int count= getInstallCount(); + if (count > 0) { + setAttribute(INSTALL_COUNT, count - 1); + } + if (count == 1) { + if (isExpired()) { + // if breakpoint was auto-disabled, re-enable it + setAttributes(fgExpiredEnabledAttributes, + new Object[]{Boolean.FALSE, Boolean.TRUE}); + } + } + } + + /** + * Sets the type name in which to install this breakpoint. + */ + protected void setTypeName(String typeName) throws CoreException { + setAttribute(TYPE_NAME, typeName); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getTypeName() + */ + public String getTypeName() throws CoreException { + if (fInstalledTypeName == null) { + return ensureMarker().getAttribute(TYPE_NAME, null); + } + return fInstalledTypeName; + } + + /** + * Resets the install count attribute on this breakpoint's marker + * to "0". Resets the expired attribute on all breakpoint markers to false. + * Resets the enabled attribute on the breakpoint marker to true. + * If a workbench crashes, the attributes could have been persisted + * in an incorrect state. + */ + private void configureAtStartup() throws CoreException { + List attributes= null; + List values= null; + if (isInstalled()) { + attributes= new ArrayList(3); + values= new ArrayList(3); + attributes.add(INSTALL_COUNT); + values.add(new Integer(0)); + } + if (isExpired()) { + if (attributes == null) { + attributes= new ArrayList(3); + values= new ArrayList(3); + } + // if breakpoint was auto-disabled, re-enable it + attributes.add(EXPIRED); + values.add(Boolean.FALSE); + attributes.add(ENABLED); + values.add(Boolean.TRUE); + } + if (attributes != null) { + String[] strAttributes= new String[attributes.size()]; + setAttributes((String[])attributes.toArray(strAttributes), values.toArray()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getHitCount() + */ + public int getHitCount() throws CoreException { + return ensureMarker().getAttribute(HIT_COUNT, -1); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#setHitCount(int) + */ + public void setHitCount(int count) throws CoreException { + if (getHitCount() != count) { + if (!isEnabled() && count > -1) { + setAttributes(new String []{ENABLED, HIT_COUNT, EXPIRED}, + new Object[]{Boolean.TRUE, new Integer(count), Boolean.FALSE}); + } else { + setAttributes(new String[]{HIT_COUNT, EXPIRED}, + new Object[]{new Integer(count), Boolean.FALSE}); + } + ///recreate(); + } + } + + protected String getMarkerMessage(int hitCount, int suspendPolicy) { + StringBuffer buff= new StringBuffer(); + /*if (hitCount > 0){ + buff.append(MessageFormat.format(JDIDebugBreakpointMessages.JavaBreakpoint___Hit_Count___0___1, new Object[]{Integer.toString(hitCount)})); + buff.append(' '); + } + String suspendPolicyString; + if (suspendPolicy == IJavaBreakpoint.SUSPEND_THREAD) { + suspendPolicyString= JDIDebugBreakpointMessages.JavaBreakpoint__suspend_policy__thread__1; + } else { + suspendPolicyString= JDIDebugBreakpointMessages.JavaBreakpoint__suspend_policy__VM__2; + } + + buff.append(suspendPolicyString);*/ + return buff.toString(); + } + + /** + * Sets whether this breakpoint's hit count has expired. + */ + public void setExpired(boolean expired) throws CoreException { + setAttribute(EXPIRED, expired); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getSuspendPolicy() + */ + /*public int getSuspendPolicy() throws CoreException { + return ensureMarker().getAttribute(SUSPEND_POLICY, IJavaBreakpoint.SUSPEND_THREAD); + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#setSuspendPolicy(int) + */ + /*public void setSuspendPolicy(int suspendPolicy) throws CoreException { + if(getSuspendPolicy() != suspendPolicy) { + setAttribute(SUSPEND_POLICY, suspendPolicy); + recreate(); + } + }*/ + + /** + * Notifies listeners this breakpoint is to be added to the + * given target. + * + * @param target debug target + */ + /*protected void fireAdding(XDebugTarget target) { + XDebugCorePlugin plugin = XDebugCorePlugin.getDefault(); + if (plugin != null) + plugin.fireBreakpointAdding(target, this); + }*/ + + /** + * Notifies listeners this breakpoint has been removed from the + * given target. + * + * @param target debug target + */ + /*protected void fireRemoved(XDebugTarget target) { + XDebugCorePlugin plugin = XDebugCorePlugin.getDefault(); + if (plugin != null) { + plugin.fireBreakpointRemoved(target, this); + setInstalledIn(target, false); + } + }*/ + + /** + * Notifies listeners this breakpoint has been installed in the + * given target. + * + * @param target debug target + */ + /*protected void fireInstalled(XDebugTarget target) { + XDebugCorePlugin plugin = XDebugCorePlugin.getDefault(); + if (plugin!= null && !isInstalledIn(target)) { + plugin.fireBreakpointInstalled(target, this); + setInstalledIn(target, true); + } + } */ + + /** + * Returns whether this breakpoint is installed in the given target. + * + * @param target + * @return whether this breakpoint is installed in the given target + */ + protected boolean isInstalledIn(XDebugTarget target) { + return fInstalledTargets != null && fInstalledTargets.contains(target); + } + + /** + * Sets this breakpoint as installed in the given target + * + * @param target + * @param installed whether installed + */ + protected void setInstalledIn(XDebugTarget target, boolean installed) { + if (installed) { + if (fInstalledTargets == null) { + fInstalledTargets = new HashSet(); + } + fInstalledTargets.add(target); + } else { + if (fInstalledTargets != null) { + fInstalledTargets.remove(target); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#setThreadFilter(org.eclipse.jdt.debug.core.IJavaThread) + */ + /*public void setThreadFilter(IJavaThread thread) throws CoreException { + if (!(thread.getDebugTarget() instanceof JDIDebugTarget) || !(thread instanceof JDIThread)) { + return; + } + JDIDebugTarget target= (JDIDebugTarget)thread.getDebugTarget(); + if (thread != fFilteredThreadsByTarget.put(target, thread) ) { + // recreate the breakpoint only if it is not the same thread + + // Other breakpoints set attributes on the underlying + // marker and the marker changes are eventually + // propagated to the target. The target then asks the + // breakpoint to update its request. Since thread filters + // are transient properties, they are not set on + // the marker. Thus we must update the request + // here. + recreate(target); + fireChanged(); + } + }*/ + + /* (non-Javadoc) + * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[]) + */ + /*public void handleDebugEvents(DebugEvent[] events) { + for (int i = 0; i < events.length; i++) { + DebugEvent event = events[i]; + if (event.getKind() == DebugEvent.TERMINATE) { + Object source= event.getSource(); + if (!(source instanceof JDIThread)) { + return; + } + try { + cleanupForThreadTermination((JDIThread)source); + } catch (VMDisconnectedException exception) { + // Thread death often occurs at shutdown. + // A VMDisconnectedException trying to + // update the breakpoint request is + // acceptable. + } + } + } + }*/ + + /** + * Removes cached information relevant to this thread which has + * terminated. + * + * Remove thread filters for terminated threads + * + * Subclasses may override but need to call super. + */ + /*protected void cleanupForThreadTermination(JDIThread thread) { + JDIDebugTarget target= (JDIDebugTarget)thread.getDebugTarget(); + try { + if (thread == getThreadFilter(target)) { + removeThreadFilter(target); + } + } catch (CoreException exception) { + JDIDebugPlugin.log(exception); + } + }*/ + + /** + * EventRequest does not support thread filters, so they + * can't be set generically here. However, each of the breakpoint + * subclasses of EventRequest do support thread filters. So + * subclasses can set thread filters on their specific + * request type. + */ + //protected abstract void setRequestThreadFilter(EventRequest request, ThreadReference thread); + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getThreadFilter(org.eclipse.jdt.debug.core.IJavaDebugTarget) + */ + /*public IJavaThread getThreadFilter(IJavaDebugTarget target) { + return (IJavaThread)fFilteredThreadsByTarget.get(target); + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getThreadFilters() + */ + /*public IJavaThread[] getThreadFilters() { + IJavaThread[] threads= null; + Collection values= fFilteredThreadsByTarget.values(); + threads= new IJavaThread[values.size()]; + values.toArray(threads); + return threads; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#removeThreadFilter(org.eclipse.jdt.debug.core.IJavaDebugTarget) + */ + /*public void removeThreadFilter(XDebugTarget javaTarget) throws CoreException { + if (!(javaTarget instanceof XDebugTarget)) { + return; + } + XDebugTarget target= (XDebugTarget)javaTarget; + if (fFilteredThreadsByTarget.remove(target) != null) { + recreate(target); + fireChanged(); + } + }*/ + + /** + * Returns whether this breakpoint should be installed in the given reference + * type in the given target according to registered breakpoint listeners. + * + * @param target debug target + * @param type reference type or null if this breakpoint is + * not installed in a specific type + */ + /*protected boolean queryInstallListeners(XDebugTarget target, ReferenceType type) { + XDebugCorePlugin plugin = XDebugCorePlugin.getDefault(); + if (plugin != null) { + IJavaType jt = null; + if (type != null) { + jt = JDIType.createType(target, type); + } + return plugin.fireInstalling(target, this, jt); + } + return false; + }*/ + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#addInstanceFilter(org.eclipse.jdt.debug.core.IJavaObject) + */ + public void addInstanceFilter(/*IJava*/Object object) throws CoreException { + if (fInstanceFilters == null) { + fInstanceFilters= new ArrayList(); + } + if (!fInstanceFilters.contains(object)) { + fInstanceFilters.add(object); + ///recreate((XDebugTarget)object.getDebugTarget()); + fireChanged(); + } + } + + /** + * Change notification when there are no marker changes. If the marker + * does not exist, do not fire a change notification (the marker may not + * exist if the associated project was closed). + */ + protected void fireChanged() { + DebugPlugin plugin = DebugPlugin.getDefault(); + if (plugin != null && markerExists()) { + plugin.getBreakpointManager().fireBreakpointChanged(this); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getInstanceFilters() + */ + public /*IJava*/Object[] getInstanceFilters() { + if (fInstanceFilters == null || fInstanceFilters.isEmpty()) { + return fgEmptyInstanceFilters; + } + return (/*IJava*/Object[])fInstanceFilters.toArray(new /*IJava*/Object[fInstanceFilters.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#removeInstanceFilter(org.eclipse.jdt.debug.core.IJavaObject) + */ + public void removeInstanceFilter(/*IJava*/Object object) throws CoreException { + if (fInstanceFilters == null) { + return; + } + if (fInstanceFilters.remove(object)) { + ///recreate((XDebugTarget)object.getDebugTarget()); + fireChanged(); + } + } + + /** + * An attribute of this breakpoint has changed - recreate event requests in + * all targets. + */ + /*protected void recreate() throws CoreException { + DebugPlugin plugin = DebugPlugin.getDefault(); + if (plugin != null) { + IDebugTarget[] targets = plugin.getLaunchManager().getDebugTargets(); + for (int i = 0; i < targets.length; i++) { + IDebugTarget target = targets[i]; + MultiStatus multiStatus = new MultiStatus(XDebugCorePlugin.getUniqueIdentifier(), JDIDebugPlugin.ERROR, JDIDebugBreakpointMessages.JavaBreakpoint_Exception, null); + IJavaDebugTarget jdiTarget = (IJavaDebugTarget) target.getAdapter(IJavaDebugTarget.class); + if (jdiTarget instanceof JDIDebugTarget) { + try { + recreate((JDIDebugTarget) jdiTarget); + } catch (CoreException e) { + multiStatus.add(e.getStatus()); + } + } + if (!multiStatus.isOK()) { + throw new CoreException(multiStatus); + } + } + } + }*/ + + /** + * Recreate this breakpoint in the given target, as long as the + * target already contains this breakpoint. + * + * @param target the target in which to re-create the breakpoint + */ + /*protected void recreate(XDebugTarget target) throws CoreException { + if (target.isAvailable() && target.getBreakpoints().contains(this)) { + removeRequests(target); + createRequests(target); + } + }*/ + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.Breakpoint#setEnabled(boolean) + */ + public void setEnabled(boolean enabled) throws CoreException { + super.setEnabled(enabled); + //recreate(); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#supportsInstanceFilters() + */ + public boolean supportsInstanceFilters() { + return true; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#supportsThreadFilters() + */ + /*public boolean supportsThreadFilters() { + return true; + }*/ +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugConditionalBreakpoint.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugConditionalBreakpoint.java new file mode 100644 index 0000000..b612c35 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugConditionalBreakpoint.java @@ -0,0 +1,107 @@ + +/* + * Created on 25.11.2004 + * + * TODO To change the template for this generated file go to + * Window - Preferences - Java - Code Style - Code Templates + */ +package net.sourceforge.phpeclipse.xdebug.php.model; + + +import java.util.HashMap; +import java.util.Map; + +//import net.sourceforge.phpeclipse.xdebug.php.launching.IXDebugConstants; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +//import org.eclipse.debug.core.DebugPlugin; +//import org.eclipse.debug.core.model.Breakpoint; +import org.eclipse.debug.core.model.IBreakpoint; +//import org.eclipse.debug.core.model.ILineBreakpoint; +//import org.eclipse.debug.core.model.LineBreakpoint; + + +/** + * @author Axel + * + * TODO To change the template for this generated type comment go to + * Window - Preferences - Java - Code Style - Code Templates + */ +public class XDebugConditionalBreakpoint extends XDebugLineBreakpoint /*implements ILineBreakpoint*/ /*extends LineBreakpoint*/ { + + /** + * Default constructor is required for the breakpoint manager + * to re-create persisted breakpoints. After instantiating a breakpoint, + * the setMarker(...) method is called to restore + * this breakpoint's attributes. + */ + private static final String XDEBUG_CONDITIONAL_BREAKPOINT = "net.sourceforge.phpeclipse.xdebug.core.XDebugLineBreakpoint"; //$NON-NLS-1$ + + /** + * Breakpoint attribute storing the fully qualified name of the type + * this breakpoint is located in. + * (value "net.sourceforge.phpeclipse.debug.typeName"). This attribute is a String. + */ + protected static final String TYPE_NAME = "net.sourceforge.phpeclipse.debug.typeName"; //$NON-NLS-1$ + + public static final String BREAKPOINT_ID ="XDebugConditionalBreakpointID"; + +/* public XDebugConditionalBreakpoint() { + }*/ + + /** + * Constructs a line breakpoint on the given resource at the given + * line number. The line number is 1-based (i.e. the first line of a + * file is line number 1). + * + * @param resource file on which to set the breakpoint + * @param lineNumber 1-based line number of the breakpoint + * @throws CoreException if unable to create the breakpoint + */ + public XDebugConditionalBreakpoint(final IResource resource, final int lineNumber) throws CoreException { + IWorkspaceRunnable wr = new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + + // create the marker + setMarker(resource.createMarker(XDEBUG_CONDITIONAL_BREAKPOINT)); + + // add attributes + Map attributes = new HashMap(10); + addLineBreakpointAttributes(attributes, getModelIdentifier(), true, lineNumber, -1, -1); + + // set attributes + ensureMarker().setAttributes(attributes); + + // add to breakpoint manager if requested + register(true); + } + }; + run(getMarkerRule(resource), wr); + + } + + /*protected void register(boolean register) throws CoreException { + if (register) { + DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(this); + } else { + setRegistered(false); + } + }*/ + + public void addLineBreakpointAttributes(Map attributes, String modelIdentifier, boolean enabled, int lineNumber, int charStart, int charEnd) { + attributes.put(IBreakpoint.ID, modelIdentifier); + attributes.put(IBreakpoint.ENABLED, new Boolean(enabled)); + attributes.put(IMarker.LINE_NUMBER, new Integer(lineNumber)); + if (charStart!=-1) + { + attributes.put(IMarker.CHAR_START, new Integer(charStart)); + attributes.put(IMarker.CHAR_END, new Integer(charEnd)); + } + attributes.put(TYPE_NAME, "typeName"); + attributes.put(BREAKPOINT_ID,new Integer(-1)); + } +} \ No newline at end of file -- 1.7.1