KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > dom > NodeFinder


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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 org.eclipse.jdt.internal.corext.dom;
12
13 import org.eclipse.jdt.core.ICompilationUnit;
14 import org.eclipse.jdt.core.ISourceRange;
15 import org.eclipse.jdt.core.JavaModelException;
16 import org.eclipse.jdt.core.ToolFactory;
17 import org.eclipse.jdt.core.compiler.IScanner;
18 import org.eclipse.jdt.core.compiler.ITerminalSymbols;
19 import org.eclipse.jdt.core.compiler.InvalidInputException;
20 import org.eclipse.jdt.core.dom.ASTNode;
21 /**
22  * For a give range finds the node covered and the node covering.
23  *
24  * @since 2.1
25  */

26 public class NodeFinder extends GenericVisitor {
27
28     /**
29      * A visitor that maps a selection to a given ASTNode. The result node is
30      * determined as follows:
31      * <ul>
32      * <li>first the visitor tries to find a node with the exact start and length</li>
33      * <li>if no such node exists than the node that encloses the range defined by
34      * start and end is returned.</li>
35      * <li>if the length is zero than also nodes are considered where the node's
36      * start or end position matches <code>start</code>.</li>
37      * <li>otherwise <code>null</code> is returned.</li>
38      * </ul>
39      *
40      * @param root the root node from which the search starts
41      * @param start the start offset
42      * @param length the length
43      *
44      * @return the result node
45      *
46      * @since 2.1
47      */

48     public static ASTNode perform(ASTNode root, int start, int length) {
49         NodeFinder finder= new NodeFinder(start, length);
50         root.accept(finder);
51         ASTNode result= finder.getCoveredNode();
52         if (result == null || result.getStartPosition() != start || result.getLength() != length) {
53             return finder.getCoveringNode();
54         }
55         return result;
56     }
57     
58     public static ASTNode perform(ASTNode root, ISourceRange range) {
59         return perform(root, range.getOffset(), range.getLength());
60     }
61     
62     /**
63      * A visitor that maps a selection to a given ASTNode. The result node is
64      * determined as follows:
65      * <ul>
66      * <li>first the visitor tries to find a node that is covered by <code>start</code> and
67      * <code>length</code> where either <code>start</code> and <code>length</code> exactly
68      * matches the node or where the text covered before and after the node only consists
69      * of white spaces or comments.</li>
70      * <li>if no such node exists than the node that encloses the range defined by
71      * start and end is returned.</li>
72      * <li>if the length is zero than also nodes are considered where the node's
73      * start or end position matches <code>start</code>.</li>
74      * <li>otherwise <code>null</code> is returned.</li>
75      * </ul>
76      *
77      * @param root the root node from which the search starts
78      * @param start the start offset
79      * @param length the length
80      * @param source the source of the compilation unit
81      *
82      * @return the result node
83      * @throws JavaModelException if an error occurs in the Java model
84      *
85      * @since 3.0
86      */

87     public static ASTNode perform(ASTNode root, int start, int length, ICompilationUnit source) throws JavaModelException {
88         NodeFinder finder= new NodeFinder(start, length);
89         root.accept(finder);
90         ASTNode result= finder.getCoveredNode();
91         if (result == null)
92             return null;
93         Selection selection= Selection.createFromStartLength(start, length);
94         if (selection.covers(result)) {
95             IScanner scanner= ToolFactory.createScanner(false, false, false, false);
96             scanner.setSource(source.getBuffer().getText(start, length).toCharArray());
97             try {
98                 int token= scanner.getNextToken();
99                 if (token != ITerminalSymbols.TokenNameEOF) {
100                     int tStart= scanner.getCurrentTokenStartPosition();
101                     if (tStart == result.getStartPosition() - start) {
102                         scanner.resetTo(tStart + result.getLength(), length - 1);
103                         token= scanner.getNextToken();
104                         if (token == ITerminalSymbols.TokenNameEOF)
105                             return result;
106                     }
107                 }
108             } catch (InvalidInputException e) {
109             }
110         }
111         return finder.getCoveringNode();
112     }
113
114     private int fStart;
115     private int fEnd;
116     
117     private ASTNode fCoveringNode;
118     private ASTNode fCoveredNode;
119     
120     public NodeFinder(int offset, int length) {
121         super(true); // include Javadoc tags
122
fStart= offset;
123         fEnd= offset + length;
124     }
125
126     protected boolean visitNode(ASTNode node) {
127         int nodeStart= node.getStartPosition();
128         int nodeEnd= nodeStart + node.getLength();
129         if (nodeEnd < fStart || fEnd < nodeStart) {
130             return false;
131         }
132         if (nodeStart <= fStart && fEnd <= nodeEnd) {
133             fCoveringNode= node;
134         }
135         if (fStart <= nodeStart && nodeEnd <= fEnd) {
136             if (fCoveringNode == node) { // nodeStart == fStart && nodeEnd == fEnd
137
fCoveredNode= node;
138                 return true; // look further for node with same length as parent
139
} else if (fCoveredNode == null) { // no better found
140
fCoveredNode= node;
141             }
142             return false;
143         }
144         return true;
145     }
146
147     /**
148      * Returns the covered node. If more than one nodes are covered by the selection, the
149      * returned node is first covered node found in a top-down traversal of the AST
150      * @return ASTNode
151      */

152     public ASTNode getCoveredNode() {
153         return fCoveredNode;
154     }
155
156     /**
157      * Returns the covering node. If more than one nodes are covering the selection, the
158      * returned node is last covering node found in a top-down traversal of the AST
159      * @return ASTNode
160      */

161     public ASTNode getCoveringNode() {
162         return fCoveringNode;
163     }
164     
165 }
166
Popular Tags