KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > search > matching > MatchingNodeSet


1 /*******************************************************************************
2  * Copyright (c) 2000, 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 org.eclipse.jdt.internal.core.search.matching;
12
13 import java.util.ArrayList JavaDoc;
14
15 import org.eclipse.jdt.core.search.SearchMatch;
16 import org.eclipse.jdt.core.search.SearchPattern;
17 import org.eclipse.jdt.internal.compiler.ast.*;
18 import org.eclipse.jdt.internal.compiler.util.HashtableOfLong;
19 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
20 import org.eclipse.jdt.internal.compiler.util.SimpleSet;
21 import org.eclipse.jdt.internal.core.util.Util;
22
23 /**
24  * A set of matches and possible matches, which need to be resolved.
25  */

26 public class MatchingNodeSet {
27
28 /**
29  * Map of matching ast nodes that don't need to be resolved to their accuracy level.
30  * Each node is removed as it is reported.
31  */

32 SimpleLookupTable matchingNodes = new SimpleLookupTable(3); // node -> accuracy
33
private HashtableOfLong matchingNodesKeys = new HashtableOfLong(3); // sourceRange -> node
34
static Integer JavaDoc EXACT_MATCH = new Integer JavaDoc(SearchMatch.A_ACCURATE);
35 static Integer JavaDoc POTENTIAL_MATCH = new Integer JavaDoc(SearchMatch.A_INACCURATE);
36 static Integer JavaDoc ERASURE_MATCH = new Integer JavaDoc(SearchPattern.R_ERASURE_MATCH);
37
38 /**
39  * Tell whether locators need to resolve or not for current matching node set.
40  */

41 public boolean mustResolve;
42
43 /**
44  * Set of possible matching ast nodes. They need to be resolved
45  * to determine if they really match the search pattern.
46  */

47 SimpleSet possibleMatchingNodesSet = new SimpleSet(7);
48 private HashtableOfLong possibleMatchingNodesKeys = new HashtableOfLong(7);
49
50
51 public MatchingNodeSet(boolean mustResolvePattern) {
52     super();
53     mustResolve = mustResolvePattern;
54 }
55
56 public int addMatch(ASTNode node, int matchLevel) {
57     int maskedLevel = matchLevel & PatternLocator.MATCH_LEVEL_MASK;
58     switch (maskedLevel) {
59         case PatternLocator.INACCURATE_MATCH:
60             if (matchLevel != maskedLevel) {
61                 addTrustedMatch(node, new Integer JavaDoc(SearchMatch.A_INACCURATE+(matchLevel & PatternLocator.FLAVORS_MASK)));
62             } else {
63                 addTrustedMatch(node, POTENTIAL_MATCH);
64             }
65             break;
66         case PatternLocator.POSSIBLE_MATCH:
67             addPossibleMatch(node);
68             break;
69         case PatternLocator.ERASURE_MATCH:
70             if (matchLevel != maskedLevel) {
71                 addTrustedMatch(node, new Integer JavaDoc(SearchPattern.R_ERASURE_MATCH+(matchLevel & PatternLocator.FLAVORS_MASK)));
72             } else {
73                 addTrustedMatch(node, ERASURE_MATCH);
74             }
75             break;
76         case PatternLocator.ACCURATE_MATCH:
77             if (matchLevel != maskedLevel) {
78                 addTrustedMatch(node, new Integer JavaDoc(SearchMatch.A_ACCURATE+(matchLevel & PatternLocator.FLAVORS_MASK)));
79             } else {
80                 addTrustedMatch(node, EXACT_MATCH);
81             }
82             break;
83     }
84     return matchLevel;
85 }
86 public void addPossibleMatch(ASTNode node) {
87     // remove existing node at same position from set
88
// (case of recovery that created the same node several time
89
// see http://bugs.eclipse.org/bugs/show_bug.cgi?id=29366)
90
long key = (((long) node.sourceStart) << 32) + node.sourceEnd;
91     ASTNode existing = (ASTNode) this.possibleMatchingNodesKeys.get(key);
92     if (existing != null && existing.getClass().equals(node.getClass()))
93         this.possibleMatchingNodesSet.remove(existing);
94
95     // add node to set
96
this.possibleMatchingNodesSet.add(node);
97     this.possibleMatchingNodesKeys.put(key, node);
98 }
99 public void addTrustedMatch(ASTNode node, boolean isExact) {
100     addTrustedMatch(node, isExact ? EXACT_MATCH : POTENTIAL_MATCH);
101     
102 }
103 void addTrustedMatch(ASTNode node, Integer JavaDoc level) {
104     // remove existing node at same position from set
105
// (case of recovery that created the same node several time
106
// see http://bugs.eclipse.org/bugs/show_bug.cgi?id=29366)
107
long key = (((long) node.sourceStart) << 32) + node.sourceEnd;
108     ASTNode existing = (ASTNode) this.matchingNodesKeys.get(key);
109     if (existing != null && existing.getClass().equals(node.getClass()))
110         this.matchingNodes.removeKey(existing);
111     
112     // map node to its accuracy level
113
this.matchingNodes.put(node, level);
114     this.matchingNodesKeys.put(key, node);
115 }
116 protected boolean hasPossibleNodes(int start, int end) {
117     Object JavaDoc[] nodes = this.possibleMatchingNodesSet.values;
118     for (int i = 0, l = nodes.length; i < l; i++) {
119         ASTNode node = (ASTNode) nodes[i];
120         if (node != null && start <= node.sourceStart && node.sourceEnd <= end)
121             return true;
122     }
123     nodes = this.matchingNodes.keyTable;
124     for (int i = 0, l = nodes.length; i < l; i++) {
125         ASTNode node = (ASTNode) nodes[i];
126         if (node != null && start <= node.sourceStart && node.sourceEnd <= end)
127             return true;
128     }
129     return false;
130 }
131 /**
132  * Returns the matching nodes that are in the given range in the source order.
133  */

134 protected ASTNode[] matchingNodes(int start, int end) {
135     ArrayList JavaDoc nodes = null;
136     Object JavaDoc[] keyTable = this.matchingNodes.keyTable;
137     for (int i = 0, l = keyTable.length; i < l; i++) {
138         ASTNode node = (ASTNode) keyTable[i];
139         if (node != null && start <= node.sourceStart && node.sourceEnd <= end) {
140             if (nodes == null) nodes = new ArrayList JavaDoc();
141             nodes.add(node);
142         }
143     }
144     if (nodes == null) return null;
145
146     ASTNode[] result = new ASTNode[nodes.size()];
147     nodes.toArray(result);
148
149     // sort nodes by source starts
150
Util.Comparer comparer = new Util.Comparer() {
151         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
152             return ((ASTNode) o1).sourceStart - ((ASTNode) o2).sourceStart;
153         }
154     };
155     Util.sort(result, comparer);
156     return result;
157 }
158 public Object JavaDoc removePossibleMatch(ASTNode node) {
159     long key = (((long) node.sourceStart) << 32) + node.sourceEnd;
160     ASTNode existing = (ASTNode) this.possibleMatchingNodesKeys.get(key);
161     if (existing == null) return null;
162
163     this.possibleMatchingNodesKeys.put(key, null);
164     return this.possibleMatchingNodesSet.remove(node);
165 }
166 public Object JavaDoc removeTrustedMatch(ASTNode node) {
167     long key = (((long) node.sourceStart) << 32) + node.sourceEnd;
168     ASTNode existing = (ASTNode) this.matchingNodesKeys.get(key);
169     if (existing == null) return null;
170
171     this.matchingNodesKeys.put(key, null);
172     return this.matchingNodes.removeKey(node);
173 }
174 public String JavaDoc toString() {
175     // TODO (jerome) should show both tables
176
StringBuffer JavaDoc result = new StringBuffer JavaDoc();
177     result.append("Exact matches:"); //$NON-NLS-1$
178
Object JavaDoc[] keyTable = this.matchingNodes.keyTable;
179     Object JavaDoc[] valueTable = this.matchingNodes.valueTable;
180     for (int i = 0, l = keyTable.length; i < l; i++) {
181         ASTNode node = (ASTNode) keyTable[i];
182         if (node == null) continue;
183         result.append("\n\t"); //$NON-NLS-1$
184
switch (((Integer JavaDoc)valueTable[i]).intValue()) {
185             case SearchMatch.A_ACCURATE:
186                 result.append("ACCURATE_MATCH: "); //$NON-NLS-1$
187
break;
188             case SearchMatch.A_INACCURATE:
189                 result.append("INACCURATE_MATCH: "); //$NON-NLS-1$
190
break;
191             case SearchPattern.R_ERASURE_MATCH:
192                 result.append("ERASURE_MATCH: "); //$NON-NLS-1$
193
break;
194         }
195         node.print(0, result);
196     }
197
198     result.append("\nPossible matches:"); //$NON-NLS-1$
199
Object JavaDoc[] nodes = this.possibleMatchingNodesSet.values;
200     for (int i = 0, l = nodes.length; i < l; i++) {
201         ASTNode node = (ASTNode) nodes[i];
202         if (node == null) continue;
203         result.append("\nPOSSIBLE_MATCH: "); //$NON-NLS-1$
204
node.print(0, result);
205     }
206     return result.toString();
207 }
208 }
209
Popular Tags