Source Code Cross Referenced for Type.java in  » Development » jode » jode » type » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Development » jode » jode.type 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Type Copyright (C) 1998-2002 Jochen Hoenicke.
002:         *
003:         * This program is free software; you can redistribute it and/or modify
004:         * it under the terms of the GNU General Public License as published by
005:         * the Free Software Foundation; either version 2, or (at your option)
006:         * any later version.
007:         *
008:         * This program is distributed in the hope that it will be useful,
009:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
010:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011:         * GNU General Public License for more details.
012:         *
013:         * You should have received a copy of the GNU General Public License
014:         * along with this program; see the file COPYING.  If not, write to
015:         * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
016:         *
017:         * $Id: Type.java.in,v 4.1.2.1 2002/05/28 17:34:22 hoenicke Exp $
018:         */
019:
020:        package jode.type;
021:
022:        import jode.AssertError;
023:        import jode.GlobalOptions;
024:        import jode.bytecode.ClassInfo;
025:        import jode.util.UnifyHash;
026:
027:        import java.util.Iterator;
028:
029:        /**
030:         * This is my type class.  It differs from java.lang.class, in that it
031:         * represents a set of types.  Since most times this set is infinite, it
032:         * needs a special representation. <br>
033:         *
034:         * The main operation on a type sets are tSuperType, tSubType and
035:         * intersection.
036:         *
037:         * @author Jochen Hoenicke */
038:        public class Type {
039:            public static final int TC_BOOLEAN = 0;
040:            public static final int TC_BYTE = 1;
041:            public static final int TC_CHAR = 2;
042:            public static final int TC_SHORT = 3;
043:            public static final int TC_INT = 4;
044:            public static final int TC_LONG = 5;
045:            public static final int TC_FLOAT = 6;
046:            public static final int TC_DOUBLE = 7;
047:            public static final int TC_NULL = 8;
048:            public static final int TC_ARRAY = 9;
049:            public static final int TC_CLASS = 10;
050:            public static final int TC_VOID = 11;
051:            public static final int TC_METHOD = 12;
052:            public static final int TC_ERROR = 13;
053:            public static final int TC_UNKNOWN = 101;
054:            public static final int TC_RANGE = 103;
055:            public static final int TC_INTEGER = 107;
056:
057:            private static final UnifyHash classHash = new UnifyHash();
058:            private static final UnifyHash arrayHash = new UnifyHash();
059:            private static final UnifyHash methodHash = new UnifyHash();
060:
061:            /**
062:             * This type represents the singleton set containing the boolean type.
063:             */
064:            public static final Type tBoolean = new IntegerType(
065:                    IntegerType.IT_Z);
066:            /**
067:             * This type represents the singleton set containing the byte type.
068:             */
069:            public static final Type tByte = new IntegerType(IntegerType.IT_B);
070:            /**
071:             * This type represents the singleton set containing the char type.
072:             */
073:            public static final Type tChar = new IntegerType(IntegerType.IT_C);
074:            /**
075:             * This type represents the singleton set containing the short type.
076:             */
077:            public static final Type tShort = new IntegerType(IntegerType.IT_S);
078:            /**
079:             * This type represents the singleton set containing the int type.
080:             */
081:            public static final Type tInt = new IntegerType(IntegerType.IT_I);
082:            /**
083:             * This type represents the singleton set containing the long type.
084:             */
085:            public static final Type tLong = new Type(TC_LONG);
086:            /**
087:             * This type represents the singleton set containing the float type.
088:             */
089:            public static final Type tFloat = new Type(TC_FLOAT);
090:            /**
091:             * This type represents the singleton set containing the double type.
092:             */
093:            public static final Type tDouble = new Type(TC_DOUBLE);
094:            /**
095:             * This type represents the void type.  It is really not a type at
096:             * all.  
097:             */
098:            public static final Type tVoid = new Type(TC_VOID);
099:            /**
100:             * This type represents the empty set, and probably means, that something
101:             * has gone wrong.
102:             */
103:            public static final Type tError = new Type(TC_ERROR);
104:            /**
105:             * This type represents the set of all possible types.
106:             */
107:            public static final Type tUnknown = new Type(TC_UNKNOWN);
108:            /**
109:             * This type represents the set of all integer types, up to 32 bit.
110:             */
111:            public static final Type tUInt = new IntegerType(IntegerType.IT_I
112:                    | IntegerType.IT_B | IntegerType.IT_C | IntegerType.IT_S);
113:            /**
114:             * This type represents the set of the boolean and int type.
115:             */
116:            public static final Type tBoolInt = new IntegerType(
117:                    IntegerType.IT_I | IntegerType.IT_Z);
118:            /**
119:             * This type represents the set of boolean and all integer types,
120:             * up to 32 bit.  
121:             */
122:            public static final Type tBoolUInt = new IntegerType(
123:                    IntegerType.IT_I | IntegerType.IT_B | IntegerType.IT_C
124:                            | IntegerType.IT_S | IntegerType.IT_Z);
125:            /**
126:             * This type represents the set of the boolean and byte type.
127:             */
128:            public static final Type tBoolByte = new IntegerType(
129:                    IntegerType.IT_B | IntegerType.IT_Z);
130:            /**
131:             * This type represents the singleton set containing 
132:             * <code>java.lang.Object</code>.
133:             */
134:            public static final ClassInterfacesType tObject = tClass("java.lang.Object");
135:            /**
136:             * This type represents the singleton set containing the special 
137:             * null type (the type of null).
138:             */
139:            public static final ReferenceType tNull = new NullType();
140:            /**
141:             * This type represents the set of all reference types, including
142:             * class types, array types, interface types and the null type.  
143:             */
144:            public static final Type tUObject = tRange(tObject, tNull);
145:            /**
146:             * This type represents the singleton set containing 
147:             * <code>java.lang.String</code>.
148:             */
149:            public static final Type tString = tClass("java.lang.String");
150:            /**
151:             * This type represents the singleton set containing 
152:             * <code>java.lang.StringBuffer</code>.
153:             */
154:            public static final Type tStringBuffer = tClass("java.lang.StringBuffer");
155:            /**
156:             * This type represents the singleton set containing 
157:             * <code>java.lang.Class</code>.
158:             */
159:            public static final Type tJavaLangClass = tClass("java.lang.Class");
160:
161:            /**
162:             * Generate the singleton set of the type represented by the given
163:             * string.
164:             * @param type the type signature (or method signature).  
165:             * @return a singleton set containing the given type.
166:             */
167:            public static final Type tType(String type) {
168:                if (type == null || type.length() == 0)
169:                    return tError;
170:                switch (type.charAt(0)) {
171:                case 'Z':
172:                    return tBoolean;
173:                case 'B':
174:                    return tByte;
175:                case 'C':
176:                    return tChar;
177:                case 'S':
178:                    return tShort;
179:                case 'I':
180:                    return tInt;
181:                case 'F':
182:                    return tFloat;
183:                case 'J':
184:                    return tLong;
185:                case 'D':
186:                    return tDouble;
187:                case 'V':
188:                    return tVoid;
189:                case '[':
190:                    return tArray(tType(type.substring(1)));
191:                case 'L':
192:                    int index = type.indexOf(';');
193:                    if (index != type.length() - 1)
194:                        return tError;
195:                    return tClass(type.substring(1, index));
196:                case '(':
197:                    return tMethod(type);
198:                }
199:                throw new AssertError("Unknown type signature: " + type);
200:            }
201:
202:            /**
203:             * Generate the singleton set of the type represented by the given
204:             * class name.
205:             * @param clazzname the full qualified name of the class. 
206:             * The packages may be separated by `.' or `/'.
207:             * @return a singleton set containing the given type.
208:             */
209:            public static final ClassInterfacesType tClass(String clazzname) {
210:                return tClass(ClassInfo.forName(clazzname.replace('/', '.')));
211:            }
212:
213:            /**
214:             * Generate the singleton set of the type represented by the given
215:             * class info.
216:             * @param clazzinfo the jode.bytecode.ClassInfo.
217:             * @return a singleton set containing the given type.
218:             */
219:            public static final ClassInterfacesType tClass(ClassInfo clazzinfo) {
220:                int hash = clazzinfo.hashCode();
221:                Iterator iter = classHash.iterateHashCode(hash);
222:                while (iter.hasNext()) {
223:                    ClassInterfacesType type = (ClassInterfacesType) iter
224:                            .next();
225:                    if (type.getClassInfo() == clazzinfo)
226:                        return type;
227:                }
228:                ClassInterfacesType type = new ClassInterfacesType(clazzinfo);
229:                classHash.put(hash, type);
230:                return type;
231:            }
232:
233:            /**
234:             * Generate/look up the set of the array type whose element types
235:             * are in the given type set.
236:             * @param type the element types (which may be the empty set tError).
237:             * @return the set of array types (which may be the empty set tError).
238:             */
239:            public static final Type tArray(Type type) {
240:                if (type == tError)
241:                    return type;
242:
243:                int hash = type.hashCode();
244:                Iterator iter = arrayHash.iterateHashCode(hash);
245:                while (iter.hasNext()) {
246:                    ArrayType arrType = (ArrayType) iter.next();
247:                    if (arrType.getElementType().equals(type))
248:                        return arrType;
249:                }
250:                ArrayType arrType = new ArrayType(type);
251:                arrayHash.put(hash, arrType);
252:                return arrType;
253:            }
254:
255:            /**
256:             * Generate/look up the method type for the given signature 
257:             * @param signature the method decriptor.
258:             * @return a method type (a singleton set).
259:             */
260:            public static MethodType tMethod(String signature) {
261:                int hash = signature.hashCode();
262:                Iterator iter = methodHash.iterateHashCode(hash);
263:                while (iter.hasNext()) {
264:                    MethodType methodType = (MethodType) iter.next();
265:                    if (methodType.getTypeSignature().equals(signature))
266:                        return methodType;
267:                }
268:                MethodType methodType = new MethodType(signature);
269:                methodHash.put(hash, methodType);
270:                return methodType;
271:            }
272:
273:            /**
274:             * Generate the range type from bottom to top.  This should
275:             * represent all reference types, that can be casted to bottom by
276:             * a widening cast and where top can be casted to.  You should not
277:             * use this method directly; use tSubType, tSuperType and
278:             * intersection instead, which is more general.
279:             * @param bottom the bottom type.
280:             * @param top the top type.  
281:             * @return the range type.
282:             */
283:            public static final Type tRange(ReferenceType bottom,
284:                    ReferenceType top) {
285:                return new RangeType(bottom, top);
286:            }
287:
288:            /**
289:             * Generate the set of types, to which one of the types in type can
290:             * be casted to by a widening cast.  The following holds:
291:             * <ul><li>tSuperType(tObject) = tObject </li>
292:             * <li>tSuperType(tError) = tError </li>
293:             * <li>type.intersection(tSuperType(type)).equals(type)
294:             *  (this means type is a subset of tSuperType(type).</li>
295:             * <li>tSuperType(tNull) = tUObject</li>
296:             * <li>tSuperType(tChar) = {tChar, tInt } </li></ul>
297:             * @param type a set of types.
298:             * @return the super types of type.
299:             */
300:            public static Type tSuperType(Type type) {
301:                return type.getSuperType();
302:            }
303:
304:            /**
305:             * Generate the set of types, which can be casted to one of the
306:             * types in type by a widening cast.  The following holds:
307:             * <ul><li>tSubType(tObject) = tUObject </li>
308:             * <li>tSubType(tError) = tError </li>
309:             * <li>type.intersection(tSubType(type)).equals(type)
310:             *  (this means type is a subset of tSubType(type).</li>
311:             * <li>tSuperType(tSubType(type)) is a subset of type </li>
312:             * <li>tSubType(tSuperType(type)) is a subset of type </li>
313:             * <li>tSubType(tNull) = tNull</li>
314:             * <li>tSubType(tBoolean, tShort) = { tBoolean, tByte, tShort }</li></ul>
315:             * @param type a set of types.
316:             * @return the sub types of type.  
317:             */
318:            public static Type tSubType(Type type) {
319:                return type.getSubType();
320:            }
321:
322:            /**
323:             * The typecode of this type. This should be one of the TC_ constants.
324:             */
325:            final int typecode;
326:
327:            /**
328:             * Create a new type with the given type code.
329:             */
330:            protected Type(int tc) {
331:                typecode = tc;
332:            }
333:
334:            /**
335:             * The sub types of this type.
336:             * @return tSubType(this).
337:             */
338:            public Type getSubType() {
339:                return this ;
340:            }
341:
342:            /**
343:             * The super types of this type.
344:             * @return tSuperType(this).
345:             */
346:            public Type getSuperType() {
347:                return this ;
348:            }
349:
350:            /**
351:             * Returns the hint type of this type set.  This returns the singleton
352:             * set containing only the `most likely' type in this set.  This doesn't
353:             * work for <code>tError</code> or <code>tUnknown</code>, and may lead
354:             * to errors for certain range types.
355:             * @return the hint type.
356:             */
357:            public Type getHint() {
358:                return getCanonic();
359:            }
360:
361:            /**
362:             * Returns the canonic type of this type set.  The intention is, to 
363:             * return for each expression the type, that the java compiler would
364:             * assign to this expression.
365:             * @return the canonic type.
366:             */
367:            public Type getCanonic() {
368:                return this ;
369:            }
370:
371:            /**
372:             * Returns the type code of this type.  Don't use this; it is
373:             * merily needed by the sub types (and the bytecode verifier, which
374:             * has its own type merging methods).
375:             * @return the type code of the type.  
376:             */
377:            public final int getTypeCode() {
378:                return typecode;
379:            }
380:
381:            /**
382:             * Returns the number of stack/local entries an object of this type
383:             * occupies.
384:             * @return 0 for tVoid, 2 for tDouble and tLong and 
385:             * 1 for every other type.
386:             */
387:            public int stackSize() {
388:                switch (typecode) {
389:                case TC_VOID:
390:                    return 0;
391:                case TC_ERROR:
392:                default:
393:                    return 1;
394:                case TC_DOUBLE:
395:                case TC_LONG:
396:                    return 2;
397:                }
398:            }
399:
400:            /**
401:             * Intersect this set of types with another type set and return the
402:             * intersection.
403:             * @param type the other type set.
404:             * @return the intersection, tError, if the intersection is empty.
405:             */
406:            public Type intersection(Type type) {
407:                if (this  == tError || type == tError)
408:                    return tError;
409:                if (this  == tUnknown)
410:                    return type;
411:                if (type == tUnknown || this  == type)
412:                    return this ;
413:                /* We have two different singleton sets now.
414:                 */
415:                if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_TYPES) != 0)
416:                    GlobalOptions.err.println("intersecting " + this  + " and "
417:                            + type + " to <error>");
418:                return tError;
419:            }
420:
421:            /**
422:             * Checks if we need to cast to a middle type, before we can cast from
423:             * fromType to this type.  For example it is impossible to cast a 
424:             * String to a StringBuffer, but if we cast to Object in between this
425:             * is allowed (it doesn't make much sense though).
426:             * @return the middle type, or null if it is not necessary.
427:             */
428:            public Type getCastHelper(Type fromType) {
429:                return null;
430:            }
431:
432:            /**
433:             * Checks if this type represents a valid singleton type.
434:             */
435:            public boolean isValidType() {
436:                return typecode <= TC_DOUBLE;
437:            }
438:
439:            /**
440:             * Checks if this is a class or array type (but not a null type).
441:             * @XXX remove this?
442:             * @return true if this is a class or array type.
443:             */
444:            public boolean isClassType() {
445:                return false;
446:            }
447:
448:            /**
449:             * Check if this type set and the other type set are not disjunct.
450:             * @param type the other type set.
451:             * @return true if this they aren't disjunct.
452:             */
453:            public boolean isOfType(Type type) {
454:                return this .intersection(type) != Type.tError;
455:            }
456:
457:            /**
458:             * Generates the default name, that is the `natural' choice for
459:             * local of this type.
460:             * @return the default name of a local of this type.  
461:             */
462:            public String getDefaultName() {
463:                switch (typecode) {
464:                case TC_LONG:
465:                    return "l";
466:                case TC_FLOAT:
467:                    return "f";
468:                case TC_DOUBLE:
469:                    return "d";
470:                default:
471:                    return "local";
472:                }
473:            }
474:
475:            /**
476:             * Generates the default value, that is the initial value of a field
477:             * of this type.
478:             * @return the default value of a field of this type.  
479:             */
480:            public Object getDefaultValue() {
481:                switch (typecode) {
482:                case TC_LONG:
483:                    return new Long(0);
484:                case TC_FLOAT:
485:                    return new Float(0);
486:                case TC_DOUBLE:
487:                    return new Double(0);
488:                default:
489:                    return null;
490:                }
491:            }
492:
493:            /**
494:             * Returns the type signature of this type.  You should only call
495:             * this on singleton types.
496:             * @return the type (or method) signature of this type.
497:             */
498:            public String getTypeSignature() {
499:                switch (typecode) {
500:                case TC_LONG:
501:                    return "J";
502:                case TC_FLOAT:
503:                    return "F";
504:                case TC_DOUBLE:
505:                    return "D";
506:                default:
507:                    return "?";
508:                }
509:            }
510:
511:            /**
512:             * Returns the java.lang.Class representing this type.  You should
513:             * only call this on singleton types.  
514:             * @return the Class object representing this type.
515:             */
516:            public Class getTypeClass() throws ClassNotFoundException {
517:                switch (typecode) {
518:                case TC_LONG:
519:                    return Long.TYPE;
520:                case TC_FLOAT:
521:                    return Float.TYPE;
522:                case TC_DOUBLE:
523:                    return Double.TYPE;
524:                default:
525:                    throw new AssertError(
526:                            "getTypeClass() called on illegal type");
527:                }
528:            }
529:
530:            /**
531:             * Returns a string representation describing this type set.
532:             * @return a string representation describing this type set.
533:             */
534:            public String toString() {
535:                switch (typecode) {
536:                case TC_LONG:
537:                    return "long";
538:                case TC_FLOAT:
539:                    return "float";
540:                case TC_DOUBLE:
541:                    return "double";
542:                case TC_NULL:
543:                    return "null";
544:                case TC_VOID:
545:                    return "void";
546:                case TC_UNKNOWN:
547:                    return "<unknown>";
548:                case TC_ERROR:
549:                default:
550:                    return "<error>";
551:                }
552:            }
553:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.