KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > builder > ReferenceCollection


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  * Tim Hanson <thanson@bea.com> - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=137634
11  *******************************************************************************/

12 package org.eclipse.jdt.internal.core.builder;
13
14 import org.eclipse.jdt.core.compiler.CharOperation;
15 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
16
17 public class ReferenceCollection {
18
19 char[][][] qualifiedNameReferences; // contains no simple names as in just 'a' which is kept in simpleNameReferences instead
20
char[][] simpleNameReferences;
21
22 protected ReferenceCollection(char[][][] qualifiedNameReferences, char[][] simpleNameReferences) {
23     this.qualifiedNameReferences = internQualifiedNames(qualifiedNameReferences);
24     this.simpleNameReferences = internSimpleNames(simpleNameReferences, true);
25 }
26
27 void addDependencies(String JavaDoc[] typeNameDependencies) {
28     // if each qualified type name is already known then all of its subNames can be skipped
29
// and its expected that very few qualified names in typeNameDependencies need to be added
30
// but could always take 'p1.p2.p3.X' and make all qualified names 'p1' 'p1.p2' 'p1.p2.p3' 'p1.p2.p3.X', then intern
31
char[][][] qNames = new char[typeNameDependencies.length][][];
32     for (int i = typeNameDependencies.length; --i >= 0;)
33         qNames[i] = CharOperation.splitOn('.', typeNameDependencies[i].toCharArray());
34     qNames = internQualifiedNames(qNames);
35
36     next : for (int i = qNames.length; --i >= 0;) {
37         char[][] qualifiedTypeName = qNames[i];
38         while (!includes(qualifiedTypeName)) {
39             if (!includes(qualifiedTypeName[qualifiedTypeName.length - 1])) {
40                 int length = this.simpleNameReferences.length;
41                 System.arraycopy(this.simpleNameReferences, 0, this.simpleNameReferences = new char[length + 1][], 0, length);
42                 this.simpleNameReferences[length] = qualifiedTypeName[qualifiedTypeName.length - 1];
43             }
44             int length = this.qualifiedNameReferences.length;
45             System.arraycopy(this.qualifiedNameReferences, 0, this.qualifiedNameReferences = new char[length + 1][][], 0, length);
46             this.qualifiedNameReferences[length] = qualifiedTypeName;
47
48             qualifiedTypeName = CharOperation.subarray(qualifiedTypeName, 0, qualifiedTypeName.length - 1);
49             char[][][] temp = internQualifiedNames(new char[][][] {qualifiedTypeName});
50             if (temp == EmptyQualifiedNames)
51                 continue next; // qualifiedTypeName is a well known name
52
qualifiedTypeName = temp[0];
53         }
54     }
55 }
56
57 boolean includes(char[] simpleName) {
58     for (int i = 0, l = simpleNameReferences.length; i < l; i++)
59         if (simpleName == simpleNameReferences[i]) return true;
60     return false;
61 }
62
63 boolean includes(char[][] qualifiedName) {
64     for (int i = 0, l = qualifiedNameReferences.length; i < l; i++)
65         if (qualifiedName == qualifiedNameReferences[i]) return true;
66     return false;
67 }
68
69 boolean includes(char[][][] qualifiedNames, char[][] simpleNames) {
70     // if either collection of names is null, it means it contained a well known name so we know it already has a match
71
if (simpleNames == null || qualifiedNames == null) {
72         if (simpleNames == null && qualifiedNames == null) {
73             if (JavaBuilder.DEBUG)
74                 System.out.println("Found well known match"); //$NON-NLS-1$
75
return true;
76         } else if (qualifiedNames == null) {
77             for (int i = 0, l = simpleNames.length; i < l; i++) {
78                 if (includes(simpleNames[i])) {
79                     if (JavaBuilder.DEBUG)
80                         System.out.println("Found match in well known package to " + new String JavaDoc(simpleNames[i])); //$NON-NLS-1$
81
return true;
82                 }
83             }
84         } else {
85             for (int i = 0, l = qualifiedNames.length; i < l; i++) {
86                 char[][] qualifiedName = qualifiedNames[i];
87                 if (qualifiedName.length == 1 ? includes(qualifiedName[0]) : includes(qualifiedName)) {
88                     if (JavaBuilder.DEBUG)
89                         System.out.println("Found well known match in " + CharOperation.toString(qualifiedName)); //$NON-NLS-1$
90
return true;
91                 }
92             }
93         }
94     } else {
95         for (int i = 0, l = simpleNames.length; i < l; i++) {
96             if (includes(simpleNames[i])) {
97                 for (int j = 0, m = qualifiedNames.length; j < m; j++) {
98                     char[][] qualifiedName = qualifiedNames[j];
99                     if (qualifiedName.length == 1 ? includes(qualifiedName[0]) : includes(qualifiedName)) {
100                         if (JavaBuilder.DEBUG)
101                             System.out.println("Found match in " + CharOperation.toString(qualifiedName) //$NON-NLS-1$
102
+ " to " + new String JavaDoc(simpleNames[i])); //$NON-NLS-1$
103
return true;
104                     }
105                 }
106                 return false;
107             }
108         }
109     }
110     return false;
111 }
112
113
114 // When any type is compiled, its methods are verified for certain problems
115
// the MethodVerifier requests 3 well known types which end up in the reference collection
116
// having WellKnownQualifiedNames & WellKnownSimpleNames, saves every type 40 bytes
117
// NOTE: These collections are sorted by length
118
static final char[][][] WellKnownQualifiedNames = new char[][][] {
119     TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION,
120     TypeConstants.JAVA_LANG_THROWABLE,
121     TypeConstants.JAVA_LANG_OBJECT,
122     TypeConstants.JAVA_LANG,
123     new char[][] {TypeConstants.JAVA},
124     new char[][] {new char[] {'o', 'r', 'g'}},
125     new char[][] {new char[] {'c', 'o', 'm'}},
126     CharOperation.NO_CHAR_CHAR}; // default package
127
static final char[][] WellKnownSimpleNames = new char[][] {
128     TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION[2],
129     TypeConstants.JAVA_LANG_THROWABLE[2],
130     TypeConstants.JAVA_LANG_OBJECT[2],
131     TypeConstants.JAVA,
132     TypeConstants.LANG,
133     new char[] {'o', 'r', 'g'},
134     new char[] {'c', 'o', 'm'}};
135
136 static final char[][][] EmptyQualifiedNames = new char[0][][];
137 static final char[][] EmptySimpleNames = CharOperation.NO_CHAR_CHAR;
138
139 // each array contains qualified char[][], one for size 2, 3, 4, 5, 6, 7 & the rest
140
static final int MaxQualifiedNames = 7;
141 static QualifiedNameSet[] InternedQualifiedNames = new QualifiedNameSet[MaxQualifiedNames];
142 // each array contains simple char[], one for size 1 to 29 & the rest
143
static final int MaxSimpleNames = 30;
144 static NameSet[] InternedSimpleNames = new NameSet[MaxSimpleNames];
145 static {
146     for (int i = 0; i < MaxQualifiedNames; i++)
147         InternedQualifiedNames[i] = new QualifiedNameSet(37);
148     for (int i = 0; i < MaxSimpleNames; i++)
149         InternedSimpleNames[i] = new NameSet(37);
150 }
151
152 static char[][][] internQualifiedNames(StringSet qualifiedStrings) {
153     if (qualifiedStrings == null) return EmptyQualifiedNames;
154     int length = qualifiedStrings.elementSize;
155     if (length == 0) return EmptyQualifiedNames;
156
157     char[][][] result = new char[length][][];
158     String JavaDoc[] strings = qualifiedStrings.values;
159     for (int i = 0, l = strings.length; i < l; i++)
160         if (strings[i] != null)
161             result[--length] = CharOperation.splitOn('/', strings[i].toCharArray());
162     return internQualifiedNames(result);
163 }
164
165 static char[][][] internQualifiedNames(char[][][] qualifiedNames) {
166     if (qualifiedNames == null) return EmptyQualifiedNames;
167     int length = qualifiedNames.length;
168     if (length == 0) return EmptyQualifiedNames;
169
170     char[][][] keepers = new char[length][][];
171     int index = 0;
172     next : for (int i = 0; i < length; i++) {
173         char[][] qualifiedName = qualifiedNames[i];
174         int qLength = qualifiedName.length;
175         for (int j = 0, m = WellKnownQualifiedNames.length; j < m; j++) {
176             char[][] wellKnownName = WellKnownQualifiedNames[j];
177             if (qLength > wellKnownName.length)
178                 break; // all remaining well known names are shorter
179
if (CharOperation.equals(qualifiedName, wellKnownName))
180                 continue next;
181         }
182
183         // InternedQualifiedNames[0] is for the rest (> 7 & 1)
184
// InternedQualifiedNames[1] is for size 2...
185
// InternedQualifiedNames[6] is for size 7
186
QualifiedNameSet internedNames = InternedQualifiedNames[qLength <= MaxQualifiedNames ? qLength - 1 : 0];
187         qualifiedName = internSimpleNames(qualifiedName, false);
188         keepers[index++] = internedNames.add(qualifiedName);
189     }
190     if (length > index) {
191         if (index == 0) return EmptyQualifiedNames;
192         System.arraycopy(keepers, 0, keepers = new char[index][][], 0, index);
193     }
194     return keepers;
195 }
196
197 static char[][] internSimpleNames(StringSet simpleStrings) {
198     if (simpleStrings == null) return EmptySimpleNames;
199     int length = simpleStrings.elementSize;
200     if (length == 0) return EmptySimpleNames;
201
202     char[][] result = new char[length][];
203     String JavaDoc[] strings = simpleStrings.values;
204     for (int i = 0, l = strings.length; i < l; i++)
205         if (strings[i] != null)
206             result[--length] = strings[i].toCharArray();
207     return internSimpleNames(result, true);
208 }
209
210 static char[][] internSimpleNames(char[][] simpleNames, boolean removeWellKnown) {
211     if (simpleNames == null) return EmptySimpleNames;
212     int length = simpleNames.length;
213     if (length == 0) return EmptySimpleNames;
214
215     char[][] keepers = new char[length][];
216     int index = 0;
217     next : for (int i = 0; i < length; i++) {
218         char[] name = simpleNames[i];
219         int sLength = name.length;
220         for (int j = 0, m = WellKnownSimpleNames.length; j < m; j++) {
221             char[] wellKnownName = WellKnownSimpleNames[j];
222             if (sLength > wellKnownName.length)
223                 break; // all remaining well known names are shorter
224
if (CharOperation.equals(name, wellKnownName)) {
225                 if (!removeWellKnown)
226                     keepers[index++] = WellKnownSimpleNames[j];
227                 continue next;
228             }
229         }
230
231         // InternedSimpleNames[0] is for the rest (> 29)
232
// InternedSimpleNames[1] is for size 1...
233
// InternedSimpleNames[29] is for size 29
234
NameSet internedNames = InternedSimpleNames[sLength < MaxSimpleNames ? sLength : 0];
235         keepers[index++] = internedNames.add(name);
236     }
237     if (length > index) {
238         if (index == 0) return EmptySimpleNames;
239         System.arraycopy(keepers, 0, keepers = new char[index][], 0, index);
240     }
241     return keepers;
242 }
243 }
244
Popular Tags