src/share/classes/com/sun/tools/javac/util/Name.java

changeset 1
9a66ca7c79fa
child 113
eff38cc97183
equal deleted inserted replaced
-1:000000000000 1:9a66ca7c79fa
1 /*
2 * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package com.sun.tools.javac.util;
27
28 import java.lang.ref.SoftReference;
29
30
31 /** An abstraction for internal compiler strings. For efficiency reasons,
32 * GJC uses hashed strings that are stored in a common large buffer.
33 *
34 * <p>Names represent unique hashable strings. Two names are equal
35 * if their indices are equal. Utf8 representation is used
36 * for storing names internally.
37 *
38 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
39 * you write code that depends on this, you do so at your own risk.
40 * This code and its internal interfaces are subject to change or
41 * deletion without notice.</b>
42 */
43 public class Name implements javax.lang.model.element.Name {
44
45 /** The table structure where the name is stored
46 */
47 public Table table;
48
49 /** The index where the bytes of this name are stored in the global name
50 * buffer `names'.
51 */
52 public int index;
53
54 /** The number of bytes in this name.
55 */
56 public int len;
57
58 /** The next name occupying the same hash bucket.
59 */
60 Name next;
61
62 /** The hashcode of a name.
63 */
64 private static int hashValue(byte cs[], int start, int len) {
65 int h = 0;
66 int off = start;
67
68 for (int i = 0; i < len; i++) {
69 h = (h << 5) - h + cs[off++];
70 }
71 return h;
72 }
73
74 /** Is (the utf8 representation of) name equal to
75 * cs[start..start+len-1]?
76 */
77 private static boolean equals(byte[] names, int index,
78 byte cs[], int start, int len) {
79 int i = 0;
80 while (i < len && names[index + i] == cs[start + i]) i++;
81 return i == len;
82 }
83
84 /** Create a name from the bytes in cs[start..start+len-1].
85 * Assume that bytes are in utf8 format.
86 */
87 public static Name fromUtf(Table table, byte cs[], int start, int len) {
88 int h = hashValue(cs, start, len) & table.hashMask;
89 Name n = table.hashes[h];
90 byte[] names = table.names;
91 while (n != null &&
92 (n.len != len || !equals(names, n.index, cs, start, len)))
93 n = n.next;
94 if (n == null) {
95 int nc = table.nc;
96 while (nc + len > names.length) {
97 // System.err.println("doubling name buffer of length + " + names.length + " to fit " + len + " bytes");//DEBUG
98 byte[] newnames = new byte[names.length * 2];
99 System.arraycopy(names, 0, newnames, 0, names.length);
100 names = table.names = newnames;
101 }
102 System.arraycopy(cs, start, names, nc, len);
103 n = new Name();
104 n.table = table;
105 n.index = nc;
106 n.len = len;
107 n.next = table.hashes[h];
108 table.hashes[h] = n;
109 table.nc = nc + len;
110 if (len == 0) table.nc++;
111 }
112 return n;
113 }
114
115 /** Create a name from the bytes in array cs.
116 * Assume that bytes are in utf8 format.
117 */
118 public static Name fromUtf(Table table, byte cs[]) {
119 return fromUtf(table, cs, 0, cs.length);
120 }
121
122 /** Create a name from the characters in cs[start..start+len-1].
123 */
124 public static Name fromChars(Table table, char[] cs, int start, int len) {
125 int nc = table.nc;
126 byte[] names = table.names;
127 while (nc + len * 3 >= names.length) {
128 // System.err.println("doubling name buffer of length " + names.length + " to fit " + len + " chars");//DEBUG
129 byte[] newnames = new byte[names.length * 2];
130 System.arraycopy(names, 0, newnames, 0, names.length);
131 names = table.names = newnames;
132 }
133 int nbytes =
134 Convert.chars2utf(cs, start, names, nc, len) - nc;
135 int h = hashValue(names, nc, nbytes) & table.hashMask;
136 Name n = table.hashes[h];
137 while (n != null &&
138 (n.len != nbytes ||
139 !equals(names, n.index, names, nc, nbytes)))
140 n = n.next;
141 if (n == null) {
142 n = new Name();
143 n.table = table;
144 n.index = nc;
145 n.len = nbytes;
146 n.next = table.hashes[h];
147 table.hashes[h] = n;
148 table.nc = nc + nbytes;
149 if (nbytes == 0) table.nc++;
150 }
151 return n;
152 }
153
154 /** Create a name from the characters in string s.
155 */
156 public static Name fromString(Table table, String s) {
157 char[] cs = s.toCharArray();
158 return fromChars(table, cs, 0, cs.length);
159 }
160
161 /** Create a name from the characters in char sequence s.
162 */
163 public static Name fromString(Table table, CharSequence s) {
164 return fromString(table, s.toString());
165 }
166
167 /** Return the Utf8 representation of this name.
168 */
169 public byte[] toUtf() {
170 byte[] bs = new byte[len];
171 System.arraycopy(table.names, index, bs, 0, len);
172 return bs;
173 }
174
175 /** Return the string representation of this name.
176 */
177 public String toString() {
178 return Convert.utf2string(table.names, index, len);
179 }
180
181 /** Copy all bytes of this name to buffer cs, starting at start.
182 */
183 public void getBytes(byte cs[], int start) {
184 System.arraycopy(table.names, index, cs, start, len);
185 }
186
187 /** Return the hash value of this name.
188 */
189 public int hashCode() {
190 return index;
191 }
192
193 /** Is this name equal to other?
194 */
195 public boolean equals(Object other) {
196 if (other instanceof Name)
197 return
198 table == ((Name)other).table && index == ((Name)other).index;
199 else return false;
200 }
201
202 /** Compare this name to other name, yielding -1 if smaller, 0 if equal,
203 * 1 if greater.
204 */
205 public boolean less(Name that) {
206 int i = 0;
207 while (i < this.len && i < that.len) {
208 byte thisb = this.table.names[this.index + i];
209 byte thatb = that.table.names[that.index + i];
210 if (thisb < thatb) return true;
211 else if (thisb > thatb) return false;
212 else i++;
213 }
214 return this.len < that.len;
215 }
216
217 /** Returns the length of this name.
218 */
219 public int length() {
220 return toString().length();
221 }
222
223 /** Returns i'th byte of this name.
224 */
225 public byte byteAt(int i) {
226 return table.names[index + i];
227 }
228
229 /** Returns first occurrence of byte b in this name, len if not found.
230 */
231 public int indexOf(byte b) {
232 byte[] names = table.names;
233 int i = 0;
234 while (i < len && names[index + i] != b) i++;
235 return i;
236 }
237
238 /** Returns last occurrence of byte b in this name, -1 if not found.
239 */
240 public int lastIndexOf(byte b) {
241 byte[] names = table.names;
242 int i = len - 1;
243 while (i >= 0 && names[index + i] != b) i--;
244 return i;
245 }
246
247 /** Does this name start with prefix?
248 */
249 public boolean startsWith(Name prefix) {
250 int i = 0;
251 while (i < prefix.len &&
252 i < len &&
253 table.names[index + i] == prefix.table.names[prefix.index + i])
254 i++;
255 return i == prefix.len;
256 }
257
258 /** Does this name end with suffix?
259 */
260 public boolean endsWith(Name suffix) {
261 int i = len - 1;
262 int j = suffix.len - 1;
263 while (j >= 0 && i >= 0 &&
264 table.names[index + i] == suffix.table.names[suffix.index + j]) {
265 i--; j--;
266 }
267 return j < 0;
268 }
269
270 /** Returns the sub-name starting at position start, up to and
271 * excluding position end.
272 */
273 public Name subName(int start, int end) {
274 if (end < start) end = start;
275 return fromUtf(table, table.names, index + start, end - start);
276 }
277
278 /** Replace all `from' bytes in this name with `to' bytes.
279 */
280 public Name replace(byte from, byte to) {
281 byte[] names = table.names;
282 int i = 0;
283 while (i < len) {
284 if (names[index + i] == from) {
285 byte[] bs = new byte[len];
286 System.arraycopy(names, index, bs, 0, i);
287 bs[i] = to;
288 i++;
289 while (i < len) {
290 byte b = names[index + i];
291 bs[i] = b == from ? to : b;
292 i++;
293 }
294 return fromUtf(table, bs, 0, len);
295 }
296 i++;
297 }
298 return this;
299 }
300
301 /** Return the concatenation of this name and name `n'.
302 */
303 public Name append(Name n) {
304 byte[] bs = new byte[len + n.len];
305 getBytes(bs, 0);
306 n.getBytes(bs, len);
307 return fromUtf(table, bs, 0, bs.length);
308 }
309
310 /** Return the concatenation of this name, the given ASCII
311 * character, and name `n'.
312 */
313 public Name append(char c, Name n) {
314 byte[] bs = new byte[len + n.len + 1];
315 getBytes(bs, 0);
316 bs[len] = (byte)c;
317 n.getBytes(bs, len+1);
318 return fromUtf(table, bs, 0, bs.length);
319 }
320
321 /** An arbitrary but consistent complete order among all Names.
322 */
323 public int compareTo(Name other) {
324 return other.index - this.index;
325 }
326
327 /** Return the concatenation of all names in the array `ns'.
328 */
329 public static Name concat(Table table, Name ns[]) {
330 int len = 0;
331 for (int i = 0; i < ns.length; i++)
332 len = len + ns[i].len;
333 byte[] bs = new byte[len];
334 len = 0;
335 for (int i = 0; i < ns.length; i++) {
336 ns[i].getBytes(bs, len);
337 len = len + ns[i].len;
338 }
339 return fromUtf(table, bs, 0, len);
340 }
341
342 public char charAt(int index) {
343 return toString().charAt(index);
344 }
345
346 public CharSequence subSequence(int start, int end) {
347 return toString().subSequence(start, end);
348 }
349
350 public boolean contentEquals(CharSequence cs) {
351 return this.toString().equals(cs.toString());
352 }
353
354 public static class Table {
355 // maintain a freelist of recently used name tables for reuse.
356 private static List<SoftReference<Table>> freelist = List.nil();
357
358 static private synchronized Table make() {
359 while (freelist.nonEmpty()) {
360 Table t = freelist.head.get();
361 freelist = freelist.tail;
362 if (t != null) return t;
363 }
364 return new Table();
365 }
366
367 static private synchronized void dispose(Table t) {
368 freelist = freelist.prepend(new SoftReference<Table>(t));
369 }
370
371 public void dispose() {
372 dispose(this);
373 }
374
375 public static final Context.Key<Table> namesKey =
376 new Context.Key<Table>();
377
378 public static Table instance(Context context) {
379 Table instance = context.get(namesKey);
380 if (instance == null) {
381 instance = make();
382 context.put(namesKey, instance);
383 }
384 return instance;
385 }
386
387 /** The hash table for names.
388 */
389 private Name[] hashes;
390
391 /** The array holding all encountered names.
392 */
393 public byte[] names;
394
395 /** The mask to be used for hashing
396 */
397 private int hashMask;
398
399 /** The number of filled bytes in `names'.
400 */
401 private int nc = 0;
402
403 /** Allocator
404 * @param hashSize the (constant) size to be used for the hash table
405 * needs to be a power of two.
406 * @param nameSize the initial size of the name table.
407 */
408 public Table(int hashSize, int nameSize) {
409 hashMask = hashSize - 1;
410 hashes = new Name[hashSize];
411 names = new byte[nameSize];
412
413 slash = fromString("/");
414 hyphen = fromString("-");
415 T = fromString("T");
416 slashequals = fromString("/=");
417 deprecated = fromString("deprecated");
418
419 init = fromString("<init>");
420 clinit = fromString("<clinit>");
421 error = fromString("<error>");
422 any = fromString("<any>");
423 empty = fromString("");
424 one = fromString("1");
425 period = fromString(".");
426 comma = fromString(",");
427 semicolon = fromString(";");
428 asterisk = fromString("*");
429 _this = fromString("this");
430 _super = fromString("super");
431 _default = fromString("default");
432
433 _class = fromString("class");
434 java_lang = fromString("java.lang");
435 java_lang_Object = fromString("java.lang.Object");
436 java_lang_Class = fromString("java.lang.Class");
437 java_lang_Cloneable = fromString("java.lang.Cloneable");
438 java_io_Serializable = fromString("java.io.Serializable");
439 java_lang_Enum = fromString("java.lang.Enum");
440 package_info = fromString("package-info");
441 serialVersionUID = fromString("serialVersionUID");
442 ConstantValue = fromString("ConstantValue");
443 LineNumberTable = fromString("LineNumberTable");
444 LocalVariableTable = fromString("LocalVariableTable");
445 LocalVariableTypeTable = fromString("LocalVariableTypeTable");
446 CharacterRangeTable = fromString("CharacterRangeTable");
447 StackMap = fromString("StackMap");
448 StackMapTable = fromString("StackMapTable");
449 SourceID = fromString("SourceID");
450 CompilationID = fromString("CompilationID");
451 Code = fromString("Code");
452 Exceptions = fromString("Exceptions");
453 SourceFile = fromString("SourceFile");
454 InnerClasses = fromString("InnerClasses");
455 Synthetic = fromString("Synthetic");
456 Bridge= fromString("Bridge");
457 Deprecated = fromString("Deprecated");
458 Enum = fromString("Enum");
459 _name = fromString("name");
460 Signature = fromString("Signature");
461 Varargs = fromString("Varargs");
462 Annotation = fromString("Annotation");
463 RuntimeVisibleAnnotations = fromString("RuntimeVisibleAnnotations");
464 RuntimeInvisibleAnnotations = fromString("RuntimeInvisibleAnnotations");
465 RuntimeVisibleParameterAnnotations = fromString("RuntimeVisibleParameterAnnotations");
466 RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
467 Value = fromString("Value");
468 EnclosingMethod = fromString("EnclosingMethod");
469
470 desiredAssertionStatus = fromString("desiredAssertionStatus");
471
472 append = fromString("append");
473 family = fromString("family");
474 forName = fromString("forName");
475 toString = fromString("toString");
476 length = fromString("length");
477 valueOf = fromString("valueOf");
478 value = fromString("value");
479 getMessage = fromString("getMessage");
480 getClass = fromString("getClass");
481
482 TYPE = fromString("TYPE");
483 FIELD = fromString("FIELD");
484 METHOD = fromString("METHOD");
485 PARAMETER = fromString("PARAMETER");
486 CONSTRUCTOR = fromString("CONSTRUCTOR");
487 LOCAL_VARIABLE = fromString("LOCAL_VARIABLE");
488 ANNOTATION_TYPE = fromString("ANNOTATION_TYPE");
489 PACKAGE = fromString("PACKAGE");
490
491 SOURCE = fromString("SOURCE");
492 CLASS = fromString("CLASS");
493 RUNTIME = fromString("RUNTIME");
494
495 Array = fromString("Array");
496 Method = fromString("Method");
497 Bound = fromString("Bound");
498 clone = fromString("clone");
499 getComponentType = fromString("getComponentType");
500 getClassLoader = fromString("getClassLoader");
501 initCause = fromString("initCause");
502 values = fromString("values");
503 iterator = fromString("iterator");
504 hasNext = fromString("hasNext");
505 next = fromString("next");
506 AnnotationDefault = fromString("AnnotationDefault");
507 ordinal = fromString("ordinal");
508 equals = fromString("equals");
509 hashCode = fromString("hashCode");
510 compareTo = fromString("compareTo");
511 getDeclaringClass = fromString("getDeclaringClass");
512 ex = fromString("ex");
513 finalize = fromString("finalize");
514 }
515
516 public Table() {
517 this(0x8000, 0x20000);
518 }
519
520 /** Create a name from the bytes in cs[start..start+len-1].
521 * Assume that bytes are in utf8 format.
522 */
523 public Name fromUtf(byte cs[], int start, int len) {
524 return Name.fromUtf(this, cs, start, len);
525 }
526
527 /** Create a name from the bytes in array cs.
528 * Assume that bytes are in utf8 format.
529 */
530 public Name fromUtf(byte cs[]) {
531 return Name.fromUtf(this, cs, 0, cs.length);
532 }
533
534 /** Create a name from the characters in cs[start..start+len-1].
535 */
536 public Name fromChars(char[] cs, int start, int len) {
537 return Name.fromChars(this, cs, start, len);
538 }
539
540 /** Create a name from the characters in string s.
541 */
542 public Name fromString(CharSequence s) {
543 return Name.fromString(this, s);
544 }
545
546 public final Name slash;
547 public final Name hyphen;
548 public final Name T;
549 public final Name slashequals;
550 public final Name deprecated;
551
552 public final Name init;
553 public final Name clinit;
554 public final Name error;
555 public final Name any;
556 public final Name empty;
557 public final Name one;
558 public final Name period;
559 public final Name comma;
560 public final Name semicolon;
561 public final Name asterisk;
562 public final Name _this;
563 public final Name _super;
564 public final Name _default;
565
566 public final Name _class;
567 public final Name java_lang;
568 public final Name java_lang_Object;
569 public final Name java_lang_Class;
570 public final Name java_lang_Cloneable;
571 public final Name java_io_Serializable;
572 public final Name serialVersionUID;
573 public final Name java_lang_Enum;
574 public final Name package_info;
575 public final Name ConstantValue;
576 public final Name LineNumberTable;
577 public final Name LocalVariableTable;
578 public final Name LocalVariableTypeTable;
579 public final Name CharacterRangeTable;
580 public final Name StackMap;
581 public final Name StackMapTable;
582 public final Name SourceID;
583 public final Name CompilationID;
584 public final Name Code;
585 public final Name Exceptions;
586 public final Name SourceFile;
587 public final Name InnerClasses;
588 public final Name Synthetic;
589 public final Name Bridge;
590 public final Name Deprecated;
591 public final Name Enum;
592 public final Name _name;
593 public final Name Signature;
594 public final Name Varargs;
595 public final Name Annotation;
596 public final Name RuntimeVisibleAnnotations;
597 public final Name RuntimeInvisibleAnnotations;
598 public final Name RuntimeVisibleParameterAnnotations;
599 public final Name RuntimeInvisibleParameterAnnotations;
600
601 public final Name Value;
602 public final Name EnclosingMethod;
603
604 public final Name desiredAssertionStatus;
605
606 public final Name append;
607 public final Name family;
608 public final Name forName;
609 public final Name toString;
610 public final Name length;
611 public final Name valueOf;
612 public final Name value;
613 public final Name getMessage;
614 public final Name getClass;
615
616 public final Name TYPE;
617 public final Name FIELD;
618 public final Name METHOD;
619 public final Name PARAMETER;
620 public final Name CONSTRUCTOR;
621 public final Name LOCAL_VARIABLE;
622 public final Name ANNOTATION_TYPE;
623 public final Name PACKAGE;
624
625 public final Name SOURCE;
626 public final Name CLASS;
627 public final Name RUNTIME;
628
629 public final Name Array;
630 public final Name Method;
631 public final Name Bound;
632 public final Name clone;
633 public final Name getComponentType;
634 public final Name getClassLoader;
635 public final Name initCause;
636 public final Name values;
637 public final Name iterator;
638 public final Name hasNext;
639 public final Name next;
640 public final Name AnnotationDefault;
641 public final Name ordinal;
642 public final Name equals;
643 public final Name hashCode;
644 public final Name compareTo;
645 public final Name getDeclaringClass;
646 public final Name ex;
647 public final Name finalize;
648 }
649
650 public boolean isEmpty() {
651 return len == 0;
652 }
653 }

mercurial