145a534e56a6681de95a30f624b68fb75f3f0322
[phpeclipse.git] /
1 /*******************************************************************************
2  * Copyright (c) 2003, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpeclipse.xdebug.php.model;
12 /*org.eclipse.jdt.internal.debug.ui.actions;*/
13
14 import java.util.ArrayList;
15 import java.util.Iterator;
16 import java.util.List;
17
18 import net.sourceforge.phpdt.internal.core.CompilationUnit;
19 //import net.sourceforge.phpdt.internal.compiler.batch.CompilationUnit;
20
21 import net.sourceforge.phpdt.internal.compiler.ast.ASTNode;
22 import net.sourceforge.phpdt.internal.compiler.ASTVisitor;
23 /*import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
24 import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
25 import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
26 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
27 import org.eclipse.jdt.core.dom.ArrayAccess;
28 import org.eclipse.jdt.core.dom.ArrayCreation;*/
29 import net.sourceforge.phpdt.internal.compiler.ast.ArrayInitializer;
30 /*import org.eclipse.jdt.core.dom.ArrayType;*/
31 import net.sourceforge.phpdt.internal.compiler.ast.AssertStatement;
32 import net.sourceforge.phpdt.internal.compiler.ast.Assignment;
33 import net.sourceforge.phpdt.internal.compiler.ast.Block;
34 import net.sourceforge.phpdt.internal.compiler.ast.ThrowStatement;
35
36 /*import org.eclipse.jdt.core.dom.BlockComment;
37 import org.eclipse.jdt.core.dom.BodyDeclaration;
38 import org.eclipse.jdt.core.dom.BooleanLiteral;*/
39 import net.sourceforge.phpdt.internal.compiler.ast.BreakStatement;
40 import net.sourceforge.phpdt.internal.compiler.ast.CastExpression;
41 /*import org.eclipse.jdt.core.dom.CatchClause;
42 import org.eclipse.jdt.core.dom.CharacterLiteral;
43 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
44 import org.eclipse.jdt.core.dom.CompilationUnit;*/
45 import net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression;
46 /*import org.eclipse.jdt.core.dom.ConstructorInvocation;*/
47 import net.sourceforge.phpdt.internal.compiler.ast.ContinueStatement;
48 import net.sourceforge.phpdt.internal.compiler.ast.DoStatement;
49 import net.sourceforge.phpdt.internal.compiler.ast.EmptyStatement;
50 /*import org.eclipse.jdt.core.dom.EnhancedForStatement;
51 import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
52 import org.eclipse.jdt.core.dom.EnumDeclaration;
53 import org.eclipse.jdt.core.dom.Expression;
54 import org.eclipse.jdt.core.dom.ExpressionStatement;
55 import org.eclipse.jdt.core.dom.FieldAccess;*/
56 import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
57 import net.sourceforge.phpdt.internal.compiler.ast.ForStatement;
58 /*import org.eclipse.jdt.core.dom.IBinding;
59 import org.eclipse.jdt.core.dom.IVariableBinding;*/
60 import net.sourceforge.phpdt.internal.compiler.ast.IfStatement;
61 /*import org.eclipse.jdt.core.dom.ImportDeclaration;
62 import org.eclipse.jdt.core.dom.InfixExpression;*/
63 import net.sourceforge.phpdt.internal.compiler.ast.Initializer;
64 import net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression;
65 /*import org.eclipse.jdt.core.dom.Javadoc;*/
66 import net.sourceforge.phpdt.internal.compiler.ast.LabeledStatement;
67 /*import org.eclipse.jdt.core.dom.LineComment;
68 import org.eclipse.jdt.core.dom.MarkerAnnotation;
69 import org.eclipse.jdt.core.dom.MemberRef;
70 import org.eclipse.jdt.core.dom.MemberValuePair;*/
71 import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration;
72 /*import org.eclipse.jdt.core.dom.MethodInvocation;
73 import org.eclipse.jdt.core.dom.MethodRef;
74 import org.eclipse.jdt.core.dom.MethodRefParameter;
75 import org.eclipse.jdt.core.dom.Modifier;
76 import org.eclipse.jdt.core.dom.Name;
77 import org.eclipse.jdt.core.dom.NormalAnnotation;*/
78 import net.sourceforge.phpdt.internal.compiler.ast.NullLiteral;
79 import net.sourceforge.phpdt.internal.compiler.ast.NumberLiteral;
80 /*import org.eclipse.jdt.core.dom.PackageDeclaration;
81 import org.eclipse.jdt.core.dom.ParameterizedType;
82 import org.eclipse.jdt.core.dom.ParenthesizedExpression;*/
83 import net.sourceforge.phpdt.internal.compiler.ast.PostfixExpression;
84 import net.sourceforge.phpdt.internal.compiler.ast.PrefixExpression;
85 /*import org.eclipse.jdt.core.dom.PrimitiveType;
86 import org.eclipse.jdt.core.dom.QualifiedName;
87 import org.eclipse.jdt.core.dom.QualifiedType;*/
88 import net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement;
89 /*import org.eclipse.jdt.core.dom.SimpleName;
90 import org.eclipse.jdt.core.dom.SimpleType;
91 import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
92 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;*/
93 import net.sourceforge.phpdt.internal.compiler.ast.StringLiteral;
94 /*import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
95 import org.eclipse.jdt.core.dom.SuperFieldAccess;
96 import org.eclipse.jdt.core.dom.SuperMethodInvocation;
97 import org.eclipse.jdt.core.dom.SwitchCase;*/
98 import net.sourceforge.phpdt.internal.compiler.ast.SwitchStatement;
99 /*import org.eclipse.jdt.core.dom.SynchronizedStatement;
100 import org.eclipse.jdt.core.dom.TagElement;
101 import org.eclipse.jdt.core.dom.TextElement;
102 import org.eclipse.jdt.core.dom.ThisExpression;*/
103 import net.sourceforge.phpdt.internal.compiler.ast.ThrowStatement;
104 import net.sourceforge.phpdt.internal.compiler.ast.TryStatement;
105 import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
106 /*import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
107 import org.eclipse.jdt.core.dom.TypeLiteral;
108 import org.eclipse.jdt.core.dom.TypeParameter;
109 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
110 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
111 import org.eclipse.jdt.core.dom.VariableDeclarationStatement;*/
112 import net.sourceforge.phpdt.internal.compiler.ast.WhileStatement;
113 /*import org.eclipse.jdt.core.dom.WildcardType;
114 import org.eclipse.jdt.core.dom.PrefixExpression.Operator;*/
115
116
117 /**
118  * Compute a valid location where to put a breakpoint from an JDOM CompilationUnit.
119  * The result is the first valid location with a line number greater or equals than the given position.
120  */
121 public class ValidBreakpointLocationLocator extends ASTVisitor {
122         
123         public static final int LOCATION_NOT_FOUND= 0;
124         public static final int LOCATION_LINE= 1;
125         public static final int LOCATION_METHOD= 2;
126         public static final int LOCATION_FIELD= 3;
127         
128         private CompilationUnit fCompilationUnit;
129         private int fLineNumber;
130         private boolean fBindingsResolved;
131         private boolean fNeedBindings = false;
132         private boolean fBestMatch;
133
134         private int fLocationType;
135         private boolean fLocationFound;
136         private String fTypeName;
137         private int fLineLocation;
138         private int fMemberOffset;
139     private List fLabels;
140
141         /**
142          * @param compilationUnit the JDOM CompilationUnit of the source code.
143          * @param lineNumber the line number in the source code where to put the breakpoint.
144          * @param bestMatch if <code>true</code> look for the best match, otherwise look only for a valid line
145          */
146         public ValidBreakpointLocationLocator(CompilationUnit compilationUnit, int lineNumber, boolean bindingsResolved, boolean bestMatch) {
147                 fCompilationUnit= compilationUnit;
148                 fLineNumber= lineNumber;
149                 fBindingsResolved= bindingsResolved;
150                 fBestMatch= bestMatch;
151                 fLocationFound= false;
152         }
153         
154         /**
155          * Returns whether binding information would be helpful in validating a breakpoint
156          * location. If this locator makes a pass of the tree and determines that binding
157          * information would be helpful but was not available, this method returns
158          * <code>true</code>.
159          * 
160          * @return whether binding information would be helpful in validating a breakpoint location
161          */
162         public boolean isBindingsRequired() {
163                 return fNeedBindings;
164         }
165         
166         /**
167          * Return the type of the valid location found
168          * @return one of LOCATION_NOT_FOUND, LOCATION_LINE, LOCATION_METHOD or LOCATION_FIELD
169          */
170         public int getLocationType() {
171                 return fLocationType;
172         }
173         
174         /**
175          * Return of the type where the valid location is.
176          */
177         public String getFullyQualifiedTypeName() {
178                 return fTypeName;
179         }
180         
181         /**
182          * Return the line number of the computed valid location, if the location type is LOCATION_LINE.
183          */
184         public int getLineLocation() {
185                 if (fLocationType == LOCATION_LINE) {
186                         return fLineLocation;
187                 }
188                 return -1;
189         }
190         
191         /**
192          * Return the offset of the member which is the valid location,
193          * if the location type is LOCATION_METHOD or LOCATION_FIELD.
194          */
195         public int getMemberOffset() {
196                 return fMemberOffset;
197         }
198         
199         /**
200          * Compute the name of the type which contains this node.
201          * Result will be the name of the type or the inner type which contains this node, but not of the local or anonymous type.
202          */
203         /*static protected String computeTypeName(ASTNode node) {
204                 String typeName = null;
205                 while (!(node instanceof CompilationUnit)) {
206                         if (node instanceof AbstractTypeDeclaration) {
207                                 String identifier= ((AbstractTypeDeclaration)node).getName().getIdentifier();
208                                 if (typeName == null) {
209                                         typeName= identifier;
210                                 } else {
211                                         typeName= identifier + "$" + typeName; //$NON-NLS-1$
212                                 }
213                         }
214                         node= node.getParent();
215                 }
216                 PackageDeclaration packageDecl= ((CompilationUnit)node).getPackage();
217                 String packageIdentifier= ""; //$NON-NLS-1$
218                 if (packageDecl != null) {
219                         Name packageName= packageDecl.getName();
220                         while (packageName.isQualifiedName()) {
221                                 QualifiedName qualifiedName= (QualifiedName) packageName;
222                                 packageIdentifier= qualifiedName.getName().getIdentifier() + "." + packageIdentifier; //$NON-NLS-1$
223                                 packageName= qualifiedName.getQualifier();
224                         }
225                         packageIdentifier= ((SimpleName)packageName).getIdentifier() + "." + packageIdentifier; //$NON-NLS-1$
226                 }
227                 return packageIdentifier + typeName;
228         }*/
229
230         /**
231          * Return <code>true</code> if this node children may contain a valid location
232          * for the breakpoint.
233          * @param node the node.
234          * @param isCode true indicated that the first line of the given node always
235          *      contains some executable code, even if split in multiple lines.
236          */
237         /*private boolean visit(ASTNode node, boolean isCode) {
238                 // if we already found a correct location
239                 // no need to check the element inside.
240                 if (fLocationFound) {
241                         return false;
242                 }
243                 int startPosition= node.getStartPosition();
244                 int endLine= lineNumber(startPosition + node.getLength() - 1);
245                 // if the position is not in this part of the code
246                 // no need to check the element inside.
247                 if (endLine < fLineNumber) {
248                         return false;
249                 }
250                 // if the first line of this node always represents some executable code and the
251                 // breakpoint is requested on this line or on a previous line, this is a valid 
252                 // location
253                 int startLine = lineNumber(startPosition);
254                 if (isCode && (fLineNumber <= startLine)) {
255                         fLineLocation= startLine;
256                         fLocationFound= true;
257                         fLocationType= LOCATION_LINE;
258                         fTypeName= computeTypeName(node);
259                         return false;
260                 }
261                 return true;
262         }*/
263         
264         /*private boolean isReplacedByConstantValue(Expression node) {
265                 switch (node.getNodeType()) {
266                         // litterals are constant
267                         case ASTNode.BOOLEAN_LITERAL:
268                         case ASTNode.CHARACTER_LITERAL:
269                         case ASTNode.NUMBER_LITERAL:
270                         case ASTNode.STRING_LITERAL:
271                                 return true;
272                         case ASTNode.SIMPLE_NAME:
273                         case ASTNode.QUALIFIED_NAME:
274                                 return isReplacedByConstantValue((Name)node);
275                         case ASTNode.FIELD_ACCESS:
276                                 return isReplacedByConstantValue((FieldAccess)node);
277                         case ASTNode.SUPER_FIELD_ACCESS:
278                                 return isReplacedByConstantValue((SuperFieldAccess)node);
279                         case ASTNode.INFIX_EXPRESSION:
280                                 return isReplacedByConstantValue((InfixExpression)node);
281                         case ASTNode.PREFIX_EXPRESSION:
282                                 return isReplacedByConstantValue((PrefixExpression)node);
283                         case ASTNode.CAST_EXPRESSION:
284                                 return isReplacedByConstantValue(((CastExpression)node).getExpression());
285                         default:
286                                 return false;
287                 }
288         }*/
289         
290         /*private boolean isReplacedByConstantValue(InfixExpression node) {
291                 // if all operands are constant value, the expression is replaced by a constant value
292                 if (!(isReplacedByConstantValue(node.getLeftOperand()) && isReplacedByConstantValue(node.getRightOperand()))) {
293                         return false;
294                 }
295                 if (node.hasExtendedOperands()) {
296                         for (Iterator iter = node.extendedOperands().iterator(); iter.hasNext(); ) {
297                                 if (!isReplacedByConstantValue((Expression) iter.next())) {
298                                         return false;
299                                 }
300                         }
301                 }
302                 return true;
303         }*/
304         
305         /*private boolean isReplacedByConstantValue(PrefixExpression node) {
306                 // for '-', '+', '~' and '!', if the operand is a constant value,
307                 // the expression is replaced by a constant value
308                 Operator operator = node.getOperator();
309                 if (operator != PrefixExpression.Operator.INCREMENT && operator != PrefixExpression.Operator.DECREMENT) {
310                         return isReplacedByConstantValue(node.getOperand());
311                 }
312                 return false;
313         }*/
314         
315         /*private boolean isReplacedByConstantValue(Name node) {
316                 if (!fBindingsResolved) {
317                         fNeedBindings = true;
318                         return false;
319                 }
320                 // if node is a variable with a constant value (static final field)
321                 IBinding binding= node.resolveBinding();
322                 if (binding != null && binding.getKind() == IBinding.VARIABLE) {
323                         return ((IVariableBinding)binding).getConstantValue() != null;
324                 }
325                 return false;
326         }*/
327         
328         /*private boolean isReplacedByConstantValue(FieldAccess node) {
329                 if (!fBindingsResolved) {
330                         fNeedBindings = true;
331                         return false;
332                 }
333                 // if the node is 'this.<field>', and the field is static final
334                 Expression expression= node.getExpression();
335                 IVariableBinding binding= node.resolveFieldBinding();
336                 if (binding != null && expression.getNodeType() == ASTNode.THIS_EXPRESSION) {
337                         return binding.getConstantValue() != null;
338                 }
339                 return false;
340         }*/
341         
342         /*private boolean isReplacedByConstantValue(SuperFieldAccess node) {
343                 if (!fBindingsResolved) {
344                         fNeedBindings = true;
345                         return false;
346                 }
347                 // if the field is static final
348                 IVariableBinding binding= node.resolveFieldBinding();
349                 if (binding != null) {
350                         return binding.getConstantValue() != null;
351                 }
352                 return false;
353         }*/
354
355         /* (non-Javadoc)
356          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration)
357          */
358         /*public boolean visit(AnnotationTypeDeclaration node) {
359                 return false;
360         }*/
361
362         /* (non-Javadoc)
363          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration)
364          */
365         /*public boolean visit(AnnotationTypeMemberDeclaration node) {
366                 return false;
367         }*/
368
369         /**
370          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AnonymousClassDeclaration)
371          */
372         /*public boolean visit(AnonymousClassDeclaration node) {
373                 return visit(node, false);
374         }*/
375
376         /**
377          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayAccess)
378          */
379         /*public boolean visit(ArrayAccess node) {
380                 return visit(node, true);
381         }*/
382
383         /**
384          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayCreation)
385          */
386         /*public boolean visit(ArrayCreation node) {
387                 return visit(node, node.getInitializer() == null);
388         }*/
389
390         /**
391          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayInitializer)
392          */
393         /*public boolean visit(ArrayInitializer node) {
394                 return visit(node, true);
395         }*/
396
397         /**
398          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayType)
399          */
400         /*public boolean visit(ArrayType node) {
401                 return false;
402         }*/
403
404         /**
405          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AssertStatement)
406          */
407         /*public boolean visit(AssertStatement node) {
408                 return visit(node, true);
409         }*/
410
411         /**
412          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Assignment)
413          */
414         /*public boolean visit(Assignment node) {
415                 if (visit(node, false)) {
416                         // if the left hand side represent a local variable, or a static field
417                         // and the breakpoint was requested on a line before the line where
418                         // starts the assigment, set the location to be the first executable
419                         // instruction of the right hand side, as it will be the first part of
420                         // this assigment to be executed
421                         Expression leftHandSide= node.getLeftHandSide();
422                         if (leftHandSide instanceof Name) {
423                                 int startLine = lineNumber(node.getStartPosition());
424                                 if (fLineNumber < startLine) {
425                                         if (fBindingsResolved) {
426                                                 IVariableBinding binding= (IVariableBinding)((Name)leftHandSide).resolveBinding();
427                                                 if (binding != null && (!binding.isField() || Modifier.isStatic(binding.getModifiers())))  {
428                                                         node.getRightHandSide().accept(this);
429                                                 }
430                                         } else {
431                                                 fNeedBindings = true;
432                                         }
433                                 }
434                         }
435                         return true;
436                 }
437                 return false;
438         }*/
439
440         /**
441          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Block)
442          */
443         /*public boolean visit(Block node) {
444                 if (visit(node, false)) {
445                         if (node.statements().isEmpty() && node.getParent().getNodeType() == ASTNode.METHOD_DECLARATION) {
446                                 // in case of an empty method, set the breakpoint on the last line of the empty block.
447                                 fLineLocation= lineNumber(node.getStartPosition() + node.getLength() - 1);
448                                 fLocationFound= true;
449                                 fLocationType= LOCATION_LINE;
450                                 fTypeName= computeTypeName(node);
451                                 return false;
452                         }
453                         return true;
454                 }
455                 return false;
456         }*/
457
458         /* (non-Javadoc)
459          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.BlockComment)
460          */
461         /*public boolean visit(BlockComment node) {
462                 return false;
463         }*/
464         
465         /**
466          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.BooleanLiteral)
467          */
468         /*public boolean visit(BooleanLiteral node) {
469                 return visit(node, true);
470         }*/
471
472         /**
473          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.BreakStatement)
474          */
475         /*public boolean visit(BreakStatement node) {
476                 return visit(node, true);
477         }*/
478
479         /**
480          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CastExpression)
481          */
482         /*public boolean visit(CastExpression node) {
483                 return visit(node, true);
484         }*/
485
486         /**
487          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CatchClause)
488          */
489         /*public boolean visit(CatchClause node) {
490                 return visit(node, false);
491         }*/
492
493         /**
494          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CharacterLiteral)
495          */
496         /*public boolean visit(CharacterLiteral node) {
497                 return visit(node, true);
498         }*/
499
500         /**
501          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ClassInstanceCreation)
502          */
503         /*public boolean visit(ClassInstanceCreation node) {
504                 return visit(node, true);
505         }*/
506
507         /**
508          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CompilationUnit)
509          */
510         /*public boolean visit(CompilationUnit node) {
511                 return visit(node, false);
512         }*/
513
514         /**
515          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ConditionalExpression)
516          */
517         /*public boolean visit(ConditionalExpression node) {
518                 return visit(node, true);
519         }*/
520
521         /**
522          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ConstructorInvocation)
523          */
524         /*public boolean visit(ConstructorInvocation node) {
525                 return visit(node, true);
526         }*/
527
528         /**
529          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ContinueStatement)
530          */
531         /*public boolean visit(ContinueStatement node) {
532                 return visit(node, true);
533         }*/
534
535         /**
536          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.DoStatement)
537          */
538         /*public boolean visit(DoStatement node) {
539                 return visit(node, false);
540         }*/
541
542         /**
543          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EmptyStatement)
544          */
545         public boolean visit(EmptyStatement node) {
546                 return false;
547         }
548
549         /* (non-Javadoc)
550          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnhancedForStatement)
551          */
552         /*public boolean visit(EnhancedForStatement node) {
553                 if (visit(node, false)) {
554                         node.getExpression().accept(this);
555                         node.getBody().accept(this);
556                 }
557                 return false;
558         }*/
559         
560         /* (non-Javadoc)
561          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnumConstantDeclaration)
562          */
563         /*public boolean visit(EnumConstantDeclaration node) {
564                 if (visit(node, false)) {
565                         List arguments= node.arguments();
566                         for (Iterator iter= arguments.iterator(); iter.hasNext();) {
567                                 ((Expression)iter.next()).accept(this);
568                         }
569                         AnonymousClassDeclaration decl= node.getAnonymousClassDeclaration();
570                         if (decl != null) {
571                                 decl.accept(this);
572                         }
573                 }
574                 return false;
575         }*/
576         
577         /* (non-Javadoc)
578          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnumDeclaration)
579          */
580         /*public boolean visit(EnumDeclaration node) {
581                 if (visit(node, false)) {
582                         List enumConstants= node.enumConstants();
583                         for (Iterator iter = enumConstants.iterator(); iter.hasNext();) {
584                                 ((EnumConstantDeclaration) iter.next()).accept(this);
585                         }
586                         List bodyDeclaration= node.bodyDeclarations();
587                         for (Iterator iter= bodyDeclaration.iterator(); iter.hasNext();) {
588                                 ((BodyDeclaration)iter.next()).accept(this);
589                         }
590                 }
591                 return false;
592         }*/
593         
594         /**
595          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ExpressionStatement)
596          */
597         /*public boolean visit(ExpressionStatement node) {
598                 return visit(node, false);
599         }*/
600
601         /**
602          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.FieldAccess)
603          */
604         /*public boolean visit(FieldAccess node) {
605                 return visit(node, false);
606         }*/
607
608         /**
609          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.FieldDeclaration)
610          */
611         /*public boolean visit(FieldDeclaration node) {
612                 if (visit(node, false)) {
613                         if (fBestMatch) {
614                                 // check if the line contains a single field declaration.
615                                 List fragments = node.fragments();
616                                 if (fragments.size() == 1) {
617                                         int offset= ((VariableDeclarationFragment)fragments.get(0)).getName().getStartPosition();
618                                         // check if the breakpoint is to be set on the line which contains the name of the field
619                                         if (lineNumber(offset) == fLineNumber) {
620                                                 fMemberOffset= offset;
621                                                 fLocationType= LOCATION_FIELD;
622                                                 fLocationFound= true;
623                                                 return false;
624                                         }
625                                 }
626                         }
627                         // visit only the variable declaration fragments, no the variable names.
628                         List fragments= node.fragments();
629                         for (Iterator iter= fragments.iterator(); iter.hasNext();) {
630                                 ((VariableDeclarationFragment)iter.next()).accept(this);
631                         }
632                 }
633                 return false;
634         }*/
635
636         /**
637          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ForStatement)
638          */
639         /*public boolean visit(ForStatement node) {
640                 // in case on a "for(;;)", the breakpoint can be set on the first token of the node.
641                 return visit(node, node.initializers().isEmpty() && node.getExpression() == null && node.updaters().isEmpty());
642         }*/
643
644         /**
645          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.IfStatement)
646          */
647         /*public boolean visit(IfStatement node) {
648                 return visit(node, false);
649         }*/
650
651         /**
652          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ImportDeclaration)
653          */
654         /*public boolean visit(ImportDeclaration node) {
655                 return false;
656         }*/
657
658         /**
659          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.InfixExpression)
660          */
661         /*public boolean visit(InfixExpression node) {
662                 // if the breakpoint is to be set on a constant operand, the breakpoint needs to be
663                 // set on the first constant operand after the previous non-constant operand
664                 // (or the beginning of the expression, if there is no non-constant operand before).
665                 // ex:   foo() +    // previous non-constant operand
666                 //       1 +        // breakpoint set here
667                 //       2          // breakpoint asked to be set here
668                 if (visit(node, false)) {
669                         Expression leftOperand= node.getLeftOperand();
670                         Expression firstConstant= null;
671                         if (visit(leftOperand, false)) {
672                                 leftOperand.accept(this);
673                                 return false;
674                         } 
675                         if (isReplacedByConstantValue(leftOperand)) {
676                                 firstConstant= leftOperand;
677                         }
678                         Expression rightOperand= node.getRightOperand();
679                         if (visit(rightOperand, false)) {
680                                 if (firstConstant == null || !isReplacedByConstantValue(rightOperand)) {
681                                         rightOperand.accept(this);
682                                         return false;
683                                 }
684                         } else {
685                                 if (isReplacedByConstantValue(rightOperand)) {
686                                         if (firstConstant == null) {
687                                                 firstConstant= rightOperand;
688                                         }
689                                 } else {
690                                         firstConstant= null;
691                                 }
692                                 List extendedOperands= node.extendedOperands();
693                                 for (Iterator iter= extendedOperands.iterator(); iter.hasNext();) {
694                                         Expression operand= (Expression) iter.next();
695                                         if (visit(operand, false)) {
696                                                 if (firstConstant == null || !isReplacedByConstantValue(operand)) {
697                                                         operand.accept(this);
698                                                         return false;
699                                                 }
700                                                 break;
701                                         } 
702                                         if (isReplacedByConstantValue(operand)) {
703                                                 if (firstConstant == null) {
704                                                         firstConstant= operand;
705                                                 }
706                                         } else {
707                                                 firstConstant= null;
708                                         }
709                                         
710                                 }
711                         }
712                         fLineLocation= lineNumber(firstConstant.getStartPosition());
713                         fLocationFound= true;
714                         fLocationType= LOCATION_LINE;
715                         fTypeName= computeTypeName(firstConstant);
716                 }
717                 return false;
718         }*/
719
720         /**
721          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Initializer)
722          */
723         /*public boolean visit(Initializer node) {
724                 return visit(node, false);
725         }*/
726
727         /**
728          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.InstanceofExpression)
729          */
730         /*public boolean visit(InstanceofExpression node) {
731                 return visit(node, true);
732         }*/
733
734         /**
735          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Javadoc)
736          */
737         /*public boolean visit(Javadoc node) {
738                 return false;
739         }*/
740
741         /**
742          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.LabeledStatement)
743          */
744         /*public boolean visit(LabeledStatement node) {
745         nestLabel(node.getLabel().getFullyQualifiedName());
746                 return visit(node, false);
747         }*/
748     
749         /* (non-Javadoc)
750          * @see org.eclipse.jdt.core.dom.ASTVisitor#endVisit(org.eclipse.jdt.core.dom.LabeledStatement)
751          */
752         /*public void endVisit(LabeledStatement node) {
753         popLabel();
754         super.endVisit(node);
755     }*/
756     
757     private String getLabel() {
758         if (fLabels == null || fLabels.isEmpty()) {
759             return null;
760         }
761         return (String) fLabels.get(fLabels.size() - 1);
762     }
763     
764     private void nestLabel(String label) {
765         if (fLabels == null) {
766             fLabels = new ArrayList();
767         }
768         fLabels.add(label);
769     }
770     
771     private void popLabel() {
772         if (fLabels == null || fLabels.isEmpty()) {
773             return;
774         }
775         fLabels.remove(fLabels.size() - 1);
776     }
777
778     /* (non-Javadoc)
779          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.LineComment)
780          */
781         /*public boolean visit(LineComment node) {
782                 return false;
783         }*/
784
785         /* (non-Javadoc)
786          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MarkerAnnotation)
787          */
788         /*public boolean visit(MarkerAnnotation node) {
789                 return false;
790         }*/
791
792         /* (non-Javadoc)
793          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MemberRef)
794          */
795         /*public boolean visit(MemberRef node) {
796                 return false;
797         }*/
798         
799         /* (non-Javadoc)
800          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MemberValuePair)
801          */
802         /*public boolean visit(MemberValuePair node) {
803                 return false;
804         }*/
805         
806         /**
807          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration)
808          */
809         public boolean visit(MethodDeclaration node) {
810                 if (visit(node/*, false*/)) {
811                         if (fBestMatch) {
812                                 // check if we are on the line which contains the method name
813                                 int nameOffset= node.sourceStart; // node.getName().getStartPosition();
814                                 if (lineNumber(nameOffset) == fLineNumber) {
815                                         fMemberOffset= nameOffset;
816                                         fLocationType= LOCATION_METHOD;
817                                         fLocationFound= true;
818                                         return false;
819                                 }
820                         }
821                         // visit only the body
822                         /*Block body = node.getBody();
823                         if (body != null) { // body is null for abstract methods
824                                 body.accept(this);
825                         }*/
826                 }
827                 return false;
828         }
829
830         /**
831          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodInvocation)
832          */
833         /*public boolean visit(MethodInvocation node) {
834                 return visit(node, true);
835         }*/
836
837         /* (non-Javadoc)
838          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodRef)
839          */
840         /*public boolean visit(MethodRef node) {
841                 return false;
842         }*/
843         
844         /* (non-Javadoc)
845          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodRefParameter)
846          */
847         /*public boolean visit(MethodRefParameter node) {
848                 return false;
849         }*/
850         
851         /* (non-Javadoc)
852          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Modifier)
853          */
854         /*public boolean visit(Modifier node) {
855                 return false;
856         }*/
857         
858         /* (non-Javadoc)
859          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NormalAnnotation)
860          */
861         /*public boolean visit(NormalAnnotation node) {
862                 return false;
863         }*/
864         
865         /**
866          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NullLiteral)
867          */
868         /*public boolean visit(NullLiteral node) {
869                 return visit(node, true);
870         }*/
871
872         /**
873          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NumberLiteral)
874          */
875         /*public boolean visit(NumberLiteral node) {
876                 return visit(node, true);
877         }*/
878
879         /**
880          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PackageDeclaration)
881          */
882         /*public boolean visit(PackageDeclaration node) {
883                 return false;
884         }*/
885
886         /* (non-Javadoc)
887          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ParameterizedType)
888          */
889         /*public boolean visit(ParameterizedType node) {
890                 return false;
891         }*/
892         
893         /**
894          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ParenthesizedExpression)
895          */
896         /*public boolean visit(ParenthesizedExpression node) {
897                 return visit(node, false);
898         }*/
899
900         /**
901          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PostfixExpression)
902          */
903         /*public boolean visit(PostfixExpression node) {
904                 return visit(node, true);
905         }*/
906
907         /**
908          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PrefixExpression)
909          */
910         /*public boolean visit(PrefixExpression node) {
911                 if (visit(node, false)) {
912                         if (isReplacedByConstantValue(node)) {
913                                 fLineLocation= lineNumber(node.getStartPosition());
914                                 fLocationFound= true;
915                                 fLocationType= LOCATION_LINE;
916                                 fTypeName= computeTypeName(node);
917                                 return false;
918                         }
919                         return true;
920                 }
921                 return false;
922         }*/
923
924         /**
925          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PrimitiveType)
926          */
927         /*public boolean visit(PrimitiveType node) {
928                 return false;
929         }*/
930
931         /**
932          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.QualifiedName)
933          */
934         /*public boolean visit(QualifiedName node) {
935                 visit(node, true);
936                 return false;
937         }*/
938
939         /* (non-Javadoc)
940          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.QualifiedType)
941          */
942         /*public boolean visit(QualifiedType node) {
943                 return false;
944         }*/
945         
946         /**
947          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ReturnStatement)
948          */
949         /*public boolean visit(ReturnStatement node) {
950                 return visit(node, true);
951         }*/
952
953         /**
954          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SimpleName)
955          */
956         /*public boolean visit(SimpleName node) {
957         // the name is only code if its not the current label (if any)
958                 return visit(node, !node.getFullyQualifiedName().equals(getLabel()));
959         }*/
960
961         /**
962          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SimpleType)
963          */
964         /*public boolean visit(SimpleType node) {
965                 return false;
966         }*/
967
968         /* (non-Javadoc)
969          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SingleMemberAnnotation)
970          */
971         /*public boolean visit(SingleMemberAnnotation node) {
972                 return false;
973         }*/
974         
975         /**
976          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SingleVariableDeclaration)
977          */
978         /*public boolean visit(SingleVariableDeclaration node) {
979                 return visit(node, false);
980         }*/
981
982         /**
983          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.StringLiteral)
984          */
985         /*public boolean visit(StringLiteral node) {
986                 return visit(node, true);
987         }*/
988
989         /**
990          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperConstructorInvocation)
991          */
992         /*public boolean visit(SuperConstructorInvocation node) {
993                 return visit(node, true);
994         }*/
995
996         /**
997          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperFieldAccess)
998          */
999         /*public boolean visit(SuperFieldAccess node) {
1000                 return visit(node, true);
1001         }*/
1002
1003         /**
1004          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperMethodInvocation)
1005          */
1006         /*public boolean visit(SuperMethodInvocation node) {
1007                 return visit(node, true);
1008         }*/
1009
1010         
1011         
1012         // CaseStatment
1013         /**
1014          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SwitchCase)
1015          */
1016         /*public boolean visit(SwitchCase node) {
1017                 return false;
1018         }*/
1019
1020         /**
1021          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SwitchStatement)
1022          */
1023         /*public boolean visit(SwitchStatement node) {
1024                 return visit(node, false);
1025         }*/
1026
1027         /**
1028          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SynchronizedStatement)
1029          */
1030         /*public boolean visit(SynchronizedStatement node) {
1031                 return visit(node, false);
1032         }*/
1033
1034         /* (non-Javadoc)
1035          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TagElement)
1036          */
1037         /*public boolean visit(TagElement node) {
1038                 return false;
1039         }*/
1040         
1041         /* (non-Javadoc)
1042          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TextElement)
1043          */
1044         /*public boolean visit(TextElement node) {
1045                 return false;
1046         }*/
1047         
1048         /**
1049          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ThisExpression)
1050          */
1051         /*public boolean visit(ThisExpression node) {
1052                 return visit(node, true);
1053         }*/
1054
1055         /**
1056          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ThrowStatement)
1057          */
1058         /*public boolean visit(ThrowStatement node) {
1059                 return visit(node, true);
1060         }*/
1061
1062         /**
1063          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TryStatement)
1064          */
1065         /*public boolean visit(TryStatement node) {
1066                 return visit(node, false);
1067         }*/
1068
1069         /**
1070          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeDeclaration)
1071          */
1072         /*public boolean visit(TypeDeclaration node) {
1073                 if (visit(node, false)) {
1074                         // visit only the elements of the type declaration
1075                         List bodyDeclaration= node.bodyDeclarations();
1076                         for (Iterator iter= bodyDeclaration.iterator(); iter.hasNext();) {
1077                                 ((BodyDeclaration)iter.next()).accept(this);
1078                         }
1079                 }
1080                 return false;
1081         }*/
1082
1083         /**
1084          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeDeclarationStatement)
1085          */
1086         /*public boolean visit(TypeDeclarationStatement node) {
1087                 return visit(node, false);
1088         }*/
1089
1090         /* (non-Javadoc)
1091          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeParameter)
1092          */
1093         /*public boolean visit(TypeParameter node) {
1094                 return false;
1095         }*/
1096         
1097         /**
1098          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeLiteral)
1099          */
1100         /*public boolean visit(TypeLiteral node) {
1101                 return false;
1102         }*/
1103
1104         /**
1105          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.VariableDeclarationExpression)
1106          */
1107         /*public boolean visit(VariableDeclarationExpression node) {
1108                 return visit(node, false);
1109         }*/
1110
1111         /**
1112          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.VariableDeclarationFragment)
1113          */
1114         /*public boolean visit(VariableDeclarationFragment node) {
1115                 Expression initializer = node.getInitializer();
1116                 if (visit(node, false) && initializer != null) {
1117                         int startLine = lineNumber(node.getName().getStartPosition());
1118             
1119                         if (fLineNumber == startLine) {
1120                                 fLineLocation= startLine;
1121                                 fLocationFound= true;
1122                                 fLocationType= LOCATION_LINE;
1123                                 fTypeName= computeTypeName(node);
1124                                 return false;
1125                         }
1126                         initializer.accept(this);
1127                 }
1128                 return false;
1129         }*/
1130     
1131     private int lineNumber(int offset) {
1132         //int lineNumber = fCompilationUnit.getLineNumber(offset);
1133         return 10; //lineNumber < 1 ? 1 : lineNumber;
1134     }
1135         
1136
1137         /* (non-Javadoc)
1138          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.WildcardType)
1139          */
1140         /*public boolean visit(WildcardType node) {
1141                 return false;
1142         }*/
1143         
1144         /**
1145          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.VariableDeclarationStatement)
1146          */
1147         /*public boolean visit(VariableDeclarationStatement node) {
1148                 return visit(node, false);
1149         }*/
1150
1151         /**
1152          * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.WhileStatement)
1153          */
1154         /*public boolean visit(WhileStatement node) {
1155                 return visit(node, false);
1156         }*/
1157
1158 }