Source Code Cross Referenced for IClass.java in  » Scripting » jacl » org » codehaus » janino » 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 » Scripting » jacl » org.codehaus.janino 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Janino - An embedded Java[TM] compiler
003:         *
004:         * Copyright (c) 2006, Arno Unkrig
005:         * All rights reserved.
006:         *
007:         * Redistribution and use in source and binary forms, with or without
008:         * modification, are permitted provided that the following conditions
009:         * are met:
010:         *
011:         *    1. Redistributions of source code must retain the above copyright
012:         *       notice, this list of conditions and the following disclaimer.
013:         *    2. Redistributions in binary form must reproduce the above
014:         *       copyright notice, this list of conditions and the following
015:         *       disclaimer in the documentation and/or other materials
016:         *       provided with the distribution.
017:         *    3. The name of the author may not be used to endorse or promote
018:         *       products derived from this software without specific prior
019:         *       written permission.
020:         *
021:         * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
022:         * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
023:         * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
024:         * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
025:         * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
026:         * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
027:         * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
028:         * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
029:         * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
030:         * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
031:         * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
032:         */
033:
034:        package org.codehaus.janino;
035:
036:        import java.util.*;
037:
038:        /**
039:         * A simplified equivalent to "java.lang.reflect".
040:         */
041:        public abstract class IClass {
042:            private static final boolean DEBUG = false;
043:
044:            public static final IClass VOID = new PrimitiveIClass(
045:                    Descriptor.VOID);
046:            public static final IClass BYTE = new PrimitiveIClass(
047:                    Descriptor.BYTE);
048:            public static final IClass CHAR = new PrimitiveIClass(
049:                    Descriptor.CHAR);
050:            public static final IClass DOUBLE = new PrimitiveIClass(
051:                    Descriptor.DOUBLE);
052:            public static final IClass FLOAT = new PrimitiveIClass(
053:                    Descriptor.FLOAT);
054:            public static final IClass INT = new PrimitiveIClass(Descriptor.INT);
055:            public static final IClass LONG = new PrimitiveIClass(
056:                    Descriptor.LONG);
057:            public static final IClass SHORT = new PrimitiveIClass(
058:                    Descriptor.SHORT);
059:            public static final IClass BOOLEAN = new PrimitiveIClass(
060:                    Descriptor.BOOLEAN);
061:
062:            private static class PrimitiveIClass extends IClass {
063:                private final String fieldDescriptor;
064:
065:                public PrimitiveIClass(String fieldDescriptor) {
066:                    this .fieldDescriptor = fieldDescriptor;
067:                }
068:
069:                protected IClass getComponentType2() {
070:                    return null;
071:                }
072:
073:                protected IClass[] getDeclaredIClasses2() {
074:                    return new IClass[0];
075:                }
076:
077:                protected IConstructor[] getDeclaredIConstructors2() {
078:                    return new IConstructor[0];
079:                }
080:
081:                protected IField[] getDeclaredIFields2() {
082:                    return new IField[0];
083:                }
084:
085:                protected IMethod[] getDeclaredIMethods2() {
086:                    return new IMethod[0];
087:                }
088:
089:                protected IClass getDeclaringIClass2() {
090:                    return null;
091:                }
092:
093:                protected String getDescriptor2() {
094:                    return this .fieldDescriptor;
095:                }
096:
097:                protected IClass[] getInterfaces2() {
098:                    return new IClass[0];
099:                }
100:
101:                protected IClass getOuterIClass2() {
102:                    return null;
103:                }
104:
105:                protected IClass getSuperclass2() {
106:                    return null;
107:                }
108:
109:                public boolean isAbstract() {
110:                    return false;
111:                }
112:
113:                public boolean isArray() {
114:                    return false;
115:                }
116:
117:                public boolean isFinal() {
118:                    return true;
119:                }
120:
121:                public boolean isInterface() {
122:                    return false;
123:                }
124:
125:                public boolean isPrimitive() {
126:                    return true;
127:                }
128:
129:                public boolean isPrimitiveNumeric() {
130:                    return Descriptor.isPrimitiveNumeric(this .fieldDescriptor);
131:                }
132:
133:                public Access getAccess() {
134:                    return Access.PUBLIC;
135:                }
136:            }
137:
138:            /**
139:             * Returns all the constructors declared by the class represented by the
140:             * type. If the class has a default constructor, it is included.
141:             * <p>
142:             * Returns an array with zero elements for an interface, array, primitive type or
143:             * "void".
144:             */
145:            public final IConstructor[] getDeclaredIConstructors() {
146:                if (this .declaredIConstructors == null) {
147:                    this .declaredIConstructors = this 
148:                            .getDeclaredIConstructors2();
149:                }
150:                return this .declaredIConstructors;
151:            }
152:
153:            private IConstructor[] declaredIConstructors = null;
154:
155:            protected abstract IConstructor[] getDeclaredIConstructors2();
156:
157:            /**
158:             * Returns the methods of the class or interface (but not inherited
159:             * methods).<br>
160:             * Returns an empty array for an array, primitive type or "void".
161:             */
162:            public final IMethod[] getDeclaredIMethods() {
163:                if (this .declaredIMethods == null) {
164:                    this .declaredIMethods = this .getDeclaredIMethods2();
165:                }
166:                return this .declaredIMethods;
167:            }
168:
169:            protected IMethod[] declaredIMethods = null;
170:
171:            protected abstract IMethod[] getDeclaredIMethods2();
172:
173:            /**
174:             * Returns all methods with the given name declared in the class or
175:             * interface (but not inherited methods).<br>
176:             * Returns an empty array if no methods with that name are declared.
177:             * 
178:             * @return an array of {@link IMethod}s that must not be modified
179:             */
180:            public final IMethod[] getDeclaredIMethods(String methodName) {
181:                if (this .declaredIMethodCache == null) {
182:                    Map m = new HashMap();
183:
184:                    // Fill the map with "IMethod"s and "List"s.
185:                    IMethod[] dims = this .getDeclaredIMethods();
186:                    for (int i = 0; i < dims.length; i++) {
187:                        IMethod dim = dims[i];
188:                        String mn = dim.getName();
189:                        Object o = m.get(mn);
190:                        if (o == null) {
191:                            m.put(mn, dim);
192:                        } else if (o instanceof  IMethod) {
193:                            List l = new ArrayList();
194:                            l.add(o);
195:                            l.add(dim);
196:                            m.put(mn, l);
197:                        } else {
198:                            ((List) o).add(dim);
199:                        }
200:                    }
201:
202:                    // Convert "IMethod"s and "List"s to "IMethod[]"s.
203:                    for (Iterator it = m.entrySet().iterator(); it.hasNext();) {
204:                        Map.Entry me = (Map.Entry) it.next();
205:                        Object v = me.getValue();
206:                        if (v instanceof  IMethod) {
207:                            me.setValue(new IMethod[] { (IMethod) v });
208:                        } else {
209:                            List l = (List) v;
210:                            me.setValue(l.toArray(new IMethod[l.size()]));
211:                        }
212:                    }
213:                    this .declaredIMethodCache = m;
214:                }
215:
216:                IMethod[] methods = (IMethod[]) this .declaredIMethodCache
217:                        .get(methodName);
218:                return methods == null ? IClass.NO_IMETHODS : methods;
219:            }
220:
221:            /*package*/Map declaredIMethodCache = null;
222:            public static final IMethod[] NO_IMETHODS = new IMethod[0];
223:
224:            /**
225:             * Returns the fields of a class or interface (but not inherited
226:             * fields).<br>
227:             * Returns an empty array for an array, primitive type or "void".
228:             */
229:            public final IField[] getDeclaredIFields() {
230:                if (this .declaredIFields == null) {
231:                    this .declaredIFields = this .getDeclaredIFields2();
232:                }
233:                return this .declaredIFields;
234:            }
235:
236:            protected IField[] declaredIFields = null;
237:
238:            protected abstract IField[] getDeclaredIFields2();
239:
240:            /**
241:             * Returns the synthetic fields of an anonymous or local class, in
242:             * the order in which they are passed to all constructors.
243:             */
244:            public IField[] getSyntheticIFields() {
245:                return new IField[0];
246:            }
247:
248:            /**
249:             * Returns the classes and interfaces declared as members of the class
250:             * (but not inherited classes and interfaces).<br>
251:             * Returns an empty array for an array, primitive type or "void".
252:             */
253:            public final IClass[] getDeclaredIClasses() throws CompileException {
254:                if (this .declaredIClasses == null) {
255:                    this .declaredIClasses = this .getDeclaredIClasses2();
256:                }
257:                return this .declaredIClasses;
258:            }
259:
260:            private IClass[] declaredIClasses = null;
261:
262:            protected abstract IClass[] getDeclaredIClasses2()
263:                    throws CompileException;
264:
265:            /**
266:             * If this class is a member class, return the declaring class, otherwise return
267:             * <code>null</code>.
268:             */
269:            public final IClass getDeclaringIClass() throws CompileException {
270:                if (!this .declaringIClassIsCached) {
271:                    this .declaringIClass = this .getDeclaringIClass2();
272:                    this .declaringIClassIsCached = true;
273:                }
274:                return this .declaringIClass;
275:            }
276:
277:            private boolean declaringIClassIsCached = false;
278:            private IClass declaringIClass = null;
279:
280:            protected abstract IClass getDeclaringIClass2()
281:                    throws CompileException;
282:
283:            /**
284:             * The following types have an "outer class":
285:             * <ul>
286:             *   <li>Anonymous classes declared in a non-static method of a class
287:             *   <li>Local classes declared in a non-static method of a class
288:             *   <li>Non-static member classes
289:             * </ul>
290:             */
291:            public final IClass getOuterIClass() throws CompileException {
292:                if (!this .outerIClassIsCached) {
293:                    this .outerIClass = this .getOuterIClass2();
294:                    this .outerIClassIsCached = true;
295:                }
296:                return this .outerIClass;
297:            }
298:
299:            private boolean outerIClassIsCached = false;
300:            private IClass outerIClass = null;
301:
302:            protected abstract IClass getOuterIClass2() throws CompileException;
303:
304:            /**
305:             * Returns the superclass of the class.<br>
306:             * Returns "null" for class "Object", interfaces, arrays, primitive types
307:             * and "void".
308:             */
309:            public final IClass getSuperclass() throws CompileException {
310:                if (!this .super classIsCached) {
311:                    this .super class = this .getSuperclass2();
312:                    this .super classIsCached = true;
313:                    if (this .super class != null
314:                            && this .super class.isSubclassOf(this ))
315:                        throw new CompileException(
316:                                "Class circularity detected for \""
317:                                        + Descriptor.toClassName(this 
318:                                                .getDescriptor()) + "\"", null);
319:                }
320:                return this .super class;
321:            }
322:
323:            private boolean super classIsCached = false;
324:            private IClass super class = null;
325:
326:            protected abstract IClass getSuperclass2() throws CompileException;
327:
328:            public abstract Access getAccess();
329:
330:            /**
331:             * Whether subclassing is allowed (JVMS 4.1 access_flags)
332:             * @return <code>true</code> if subclassing is prohibited
333:             */
334:            public abstract boolean isFinal();
335:
336:            /**
337:             * Returns the interfaces implemented by the class.<br>
338:             * Returns the superinterfaces of the interface.<br>
339:             * Returns "Cloneable" and "Serializable" for arrays.<br>
340:             * Returns an empty array for primitive types and "void".
341:             */
342:            public final IClass[] getInterfaces() throws CompileException {
343:                if (this .interfaces == null) {
344:                    this .interfaces = this .getInterfaces2();
345:                    for (int i = 0; i < this .interfaces.length; ++i) {
346:                        if (this .interfaces[i].implements Interface(this ))
347:                            throw new CompileException(
348:                                    "Interface circularity detected for \""
349:                                            + Descriptor.toClassName(this 
350:                                                    .getDescriptor()) + "\"",
351:                                    null);
352:                    }
353:                }
354:                return this .interfaces;
355:            }
356:
357:            private IClass[] interfaces = null;
358:
359:            protected abstract IClass[] getInterfaces2()
360:                    throws CompileException;
361:
362:            /**
363:             * Whether the class may be instantiated (JVMS 4.1 access_flags)
364:             * @return <code>true</code> if instantiation is prohibited
365:             */
366:            public abstract boolean isAbstract();
367:
368:            /**
369:             * Returns the field descriptor for the type as defined by JVMS 4.3.2.
370:             */
371:            public final String getDescriptor() {
372:                if (this .descriptor == null) {
373:                    this .descriptor = this .getDescriptor2();
374:                }
375:                return this .descriptor;
376:            }
377:
378:            private String descriptor = null;
379:
380:            protected abstract String getDescriptor2();
381:
382:            /**
383:             * Convenience method that determines the field descriptors of an array of {@link IClass}es.
384:             * @see #getDescriptor()
385:             */
386:            public static String[] getDescriptors(IClass[] iClasses) {
387:                String[] descriptors = new String[iClasses.length];
388:                for (int i = 0; i < iClasses.length; ++i)
389:                    descriptors[i] = iClasses[i].getDescriptor();
390:                return descriptors;
391:            }
392:
393:            /**
394:             * Returns "true" if this type represents an interface.
395:             */
396:            public abstract boolean isInterface();
397:
398:            /**
399:             * Returns "true" if this type represents an array.
400:             */
401:            public abstract boolean isArray();
402:
403:            /**
404:             * Returns "true" if this type represents a primitive type or "void".
405:             */
406:            public abstract boolean isPrimitive();
407:
408:            /**
409:             * Returns "true" if this type represents "byte", "short", "int", "long",
410:             * "char", "float" or "double".
411:             */
412:            public abstract boolean isPrimitiveNumeric();
413:
414:            /**
415:             * Returns the component type of the array.<br>
416:             * Returns "null" for classes, interfaces, primitive types and "void".
417:             */
418:            public final IClass getComponentType() {
419:                if (!this .componentTypeIsCached) {
420:                    this .componentType = this .getComponentType2();
421:                    this .componentTypeIsCached = true;
422:                }
423:                return this .componentType;
424:            }
425:
426:            private boolean componentTypeIsCached = false;
427:            private IClass componentType = null;
428:
429:            protected abstract IClass getComponentType2();
430:
431:            /**
432:             * Returns a string representation for this object.
433:             */
434:            public String toString() {
435:                return Descriptor.toClassName(this .getDescriptor());
436:            }
437:
438:            /**
439:             * Determine if "this" is assignable from "that". This is true if "this"
440:             * is identical with "that" (JLS2 5.1.1), or if "that" is
441:             * widening-primitive-convertible to "this" (JLS2 5.1.2), or if "that" is
442:             * widening-reference-convertible to "this" (JLS2 5.1.4).
443:             */
444:            public boolean isAssignableFrom(IClass that)
445:                    throws CompileException {
446:
447:                // Identity conversion, JLS2 5.1.1
448:                if (this  == that)
449:                    return true;
450:
451:                // Widening primitive conversion, JLS2 5.1.2
452:                {
453:                    String ds = that.getDescriptor() + this .getDescriptor();
454:                    if (ds.length() == 2
455:                            && IClass.PRIMITIVE_WIDENING_CONVERSIONS
456:                                    .contains(ds))
457:                        return true;
458:                }
459:
460:                // Widening reference conversion, JLS2 5.1.4
461:                {
462:
463:                    // JLS 5.1.4.1: Target type is superclass of source class type.
464:                    if (that.isSubclassOf(this ))
465:                        return true;
466:
467:                    // JLS 5.1.4.2: Source class type implements target interface type.
468:                    // JLS 5.1.4.4: Source interface type implements target interface type.
469:                    if (that.implements Interface(this ))
470:                        return true;
471:
472:                    // JLS 5.1.4.3 Convert "null" literal to any reference type.
473:                    if (that == IClass.VOID && !this .isPrimitive())
474:                        return true;
475:
476:                    // JLS 5.1.4.5: From any interface to type "Object".
477:                    if (that.isInterface()
478:                            && this .getDescriptor().equals(Descriptor.OBJECT))
479:                        return true;
480:
481:                    if (that.isArray()) {
482:
483:                        // JLS 5.1.4.6: From any array type to type "Object".
484:                        if (this .getDescriptor().equals(Descriptor.OBJECT))
485:                            return true;
486:
487:                        // JLS 5.1.4.7: From any array type to type "Cloneable".
488:                        if (this .getDescriptor().equals(Descriptor.CLONEABLE))
489:                            return true;
490:
491:                        // JLS 5.1.4.8: From any array type to type "java.io.Serializable".
492:                        if (this .getDescriptor()
493:                                .equals(Descriptor.SERIALIZABLE))
494:                            return true;
495:
496:                        // JLS 5.1.4.9: From SC[] to TC[] while SC if widening reference convertible to TC.
497:                        if (this .isArray()) {
498:                            IClass this CT = this .getComponentType();
499:                            IClass thatCT = that.getComponentType();
500:                            if (!this CT.isPrimitive()
501:                                    && this CT.isAssignableFrom(thatCT))
502:                                return true;
503:                        }
504:                    }
505:                }
506:                return false;
507:            }
508:
509:            private static final Set PRIMITIVE_WIDENING_CONVERSIONS = new HashSet();
510:            static {
511:                String[] pwcs = new String[] {
512:                        Descriptor.BYTE + Descriptor.SHORT,
513:
514:                        Descriptor.BYTE + Descriptor.INT,
515:                        Descriptor.SHORT + Descriptor.INT,
516:                        Descriptor.CHAR + Descriptor.INT,
517:
518:                        Descriptor.BYTE + Descriptor.LONG,
519:                        Descriptor.SHORT + Descriptor.LONG,
520:                        Descriptor.CHAR + Descriptor.LONG,
521:                        Descriptor.INT + Descriptor.LONG,
522:
523:                        Descriptor.BYTE + Descriptor.FLOAT,
524:                        Descriptor.SHORT + Descriptor.FLOAT,
525:                        Descriptor.CHAR + Descriptor.FLOAT,
526:                        Descriptor.INT + Descriptor.FLOAT,
527:
528:                        Descriptor.LONG + Descriptor.FLOAT,
529:
530:                        Descriptor.BYTE + Descriptor.DOUBLE,
531:                        Descriptor.SHORT + Descriptor.DOUBLE,
532:                        Descriptor.CHAR + Descriptor.DOUBLE,
533:                        Descriptor.INT + Descriptor.DOUBLE,
534:
535:                        Descriptor.LONG + Descriptor.DOUBLE,
536:
537:                        Descriptor.FLOAT + Descriptor.DOUBLE, };
538:                for (int i = 0; i < pwcs.length; ++i)
539:                    IClass.PRIMITIVE_WIDENING_CONVERSIONS.add(pwcs[i]);
540:            }
541:
542:            /**
543:             * Returns <code>true</code> if this class is an immediate or non-immediate
544:             * subclass of <code>that</code> class.
545:             */
546:            public boolean isSubclassOf(IClass that) throws CompileException {
547:                for (IClass sc = this .getSuperclass(); sc != null; sc = sc
548:                        .getSuperclass()) {
549:                    if (sc == that)
550:                        return true;
551:                }
552:                return false;
553:            }
554:
555:            /**
556:             * If <code>this</code> represents a class: Return <code>true</code> if this class
557:             * directly or indirectly implements <code>that</code> interface.
558:             * <p>
559:             * If <code>this</code> represents an interface: Return <code>true</code> if this
560:             * interface directly or indirectly extends <code>that</code> interface.
561:             */
562:            public boolean implements Interface(IClass that)
563:                    throws CompileException {
564:                for (IClass c = this ; c != null; c = c.getSuperclass()) {
565:                    IClass[] tis = c.getInterfaces();
566:                    for (int i = 0; i < tis.length; ++i) {
567:                        IClass ti = tis[i];
568:                        if (ti == that || ti.implements Interface(that))
569:                            return true;
570:                    }
571:                }
572:                return false;
573:            }
574:
575:            /**
576:             * Get an {@link IClass} that represents an n-dimensional array of this type.
577:             *
578:             * @param n dimension count
579:             * @param objectType Required because the superclass of an array class is {@link Object} by definition
580:             */
581:            public IClass getArrayIClass(int n, IClass objectType) {
582:                IClass result = this ;
583:                for (int i = 0; i < n; ++i)
584:                    result = result.getArrayIClass(objectType);
585:                return result;
586:            }
587:
588:            /**
589:             * Get an {@link IClass} that represents an array of this type.
590:             *
591:             * @param objectType Required because the superclass of an array class is {@link Object} by definition
592:             */
593:            public IClass getArrayIClass(IClass objectType) {
594:                if (this .arrayIClass == null)
595:                    this .arrayIClass = this .getArrayIClass2(objectType);
596:                return this .arrayIClass;
597:            }
598:
599:            private IClass arrayIClass = null;
600:
601:            private IClass getArrayIClass2(final IClass objectType) {
602:                final IClass componentType = this ;
603:                return new IClass() {
604:                    public IClass.IConstructor[] getDeclaredIConstructors2() {
605:                        return new IClass.IConstructor[0];
606:                    }
607:
608:                    public IClass.IMethod[] getDeclaredIMethods2() {
609:                        return new IClass.IMethod[0];
610:                    }
611:
612:                    public IClass.IField[] getDeclaredIFields2() {
613:                        return new IClass.IField[0];
614:                    }
615:
616:                    public IClass[] getDeclaredIClasses2() {
617:                        return new IClass[0];
618:                    }
619:
620:                    public IClass getDeclaringIClass2() {
621:                        return null;
622:                    }
623:
624:                    public IClass getOuterIClass2() {
625:                        return null;
626:                    }
627:
628:                    public IClass getSuperclass2() {
629:                        return objectType;
630:                    }
631:
632:                    public IClass[] getInterfaces2() {
633:                        return new IClass[0];
634:                    }
635:
636:                    public String getDescriptor2() {
637:                        return '[' + componentType.getDescriptor();
638:                    }
639:
640:                    public Access getAccess() {
641:                        return componentType.getAccess();
642:                    }
643:
644:                    public boolean isFinal() {
645:                        return true;
646:                    }
647:
648:                    public boolean isInterface() {
649:                        return false;
650:                    }
651:
652:                    public boolean isAbstract() {
653:                        return false;
654:                    }
655:
656:                    public boolean isArray() {
657:                        return true;
658:                    }
659:
660:                    public boolean isPrimitive() {
661:                        return false;
662:                    }
663:
664:                    public boolean isPrimitiveNumeric() {
665:                        return false;
666:                    }
667:
668:                    public IClass getComponentType2() {
669:                        return componentType;
670:                    }
671:
672:                    public String toString() {
673:                        return componentType.toString() + "[]";
674:                    }
675:                };
676:            }
677:
678:            /**
679:             * If <code>optionalName</code> is <code>null</code>, find all {@link IClass}es visible in the
680:             * scope of the current class.
681:             * <p>
682:             * If <code>optionalName</code> is not <code>null</code>, find the member {@link IClass}es
683:             * that has the given name. If the name is ambiguous (i.e. if more than one superclass,
684:             * interface of enclosing type declares a type with that name), then the size of the
685:             * returned array is greater than one.
686:             * <p>
687:             * Examines superclasses, interfaces and enclosing type declarations.
688:             * @return an array of {@link IClass}es in unspecified order, possibly of length zero
689:             */
690:            IClass[] findMemberType(String optionalName)
691:                    throws CompileException {
692:                IClass[] res = (IClass[]) this .memberTypeCache
693:                        .get(optionalName);
694:                if (res == null) {
695:
696:                    // Notice: A type may be added multiply to the result set because we are in its scope
697:                    // multiply. E.g. the type is a member of a superclass AND a member of an enclosing type.
698:                    Set s = new HashSet(); // IClass
699:                    this .findMemberType(optionalName, s);
700:                    res = s.isEmpty() ? IClass.ZERO_ICLASSES : (IClass[]) s
701:                            .toArray(new IClass[s.size()]);
702:
703:                    this .memberTypeCache.put(optionalName, res);
704:                }
705:
706:                return res;
707:            }
708:
709:            private final Map memberTypeCache = new HashMap(); // String name => IClass[]
710:            private static final IClass[] ZERO_ICLASSES = new IClass[0];
711:
712:            private void findMemberType(String optionalName, Collection result)
713:                    throws CompileException {
714:
715:                // Search for a type with the given name in the current class.
716:                IClass[] memberTypes = this .getDeclaredIClasses();
717:                if (optionalName == null) {
718:                    result.addAll(Arrays.asList(memberTypes));
719:                } else {
720:                    String memberDescriptor = Descriptor
721:                            .fromClassName(Descriptor.toClassName(this 
722:                                    .getDescriptor())
723:                                    + '$' + optionalName);
724:                    for (int i = 0; i < memberTypes.length; ++i) {
725:                        final IClass mt = memberTypes[i];
726:                        if (mt.getDescriptor().equals(memberDescriptor)) {
727:                            result.add(mt);
728:                            return;
729:                        }
730:                    }
731:                }
732:
733:                // Examine superclass.
734:                {
735:                    IClass super class = this .getSuperclass();
736:                    if (super class != null)
737:                        super class.findMemberType(optionalName, result);
738:                }
739:
740:                // Examine interfaces.
741:                {
742:                    IClass[] ifs = this .getInterfaces();
743:                    for (int i = 0; i < ifs.length; ++i)
744:                        ifs[i].findMemberType(optionalName, result);
745:                }
746:
747:                // Examine enclosing type declarations.
748:                {
749:                    IClass declaringIClass = this .getDeclaringIClass();
750:                    IClass outerIClass = this .getOuterIClass();
751:                    if (declaringIClass != null) {
752:                        declaringIClass.findMemberType(optionalName, result);
753:                    }
754:                    if (outerIClass != null && outerIClass != declaringIClass) {
755:                        outerIClass.findMemberType(optionalName, result);
756:                    }
757:                }
758:            }
759:
760:            public interface IMember {
761:
762:                /**
763:                 * @return One of {@link Access#PRIVATE}, {@link Access#PROTECTED},
764:                 * {@link Access#DEFAULT} and {@link Access#PUBLIC}.
765:                 */
766:                Access getAccess();
767:
768:                /**
769:                 * Returns the {@link IClass} that declares this {@link IClass.IMember}.
770:                 */
771:                IClass getDeclaringIClass();
772:            }
773:
774:            public abstract class IInvocable implements  IMember {
775:
776:                // Implement IMember.
777:                public abstract Access getAccess();
778:
779:                public IClass getDeclaringIClass() {
780:                    return IClass.this ;
781:                }
782:
783:                public abstract IClass[] getParameterTypes()
784:                        throws CompileException;
785:
786:                public abstract String getDescriptor() throws CompileException;
787:
788:                public abstract IClass[] getThrownExceptions()
789:                        throws CompileException;
790:
791:                public boolean isMoreSpecificThan(IInvocable that)
792:                        throws CompileException {
793:                    if (IClass.DEBUG)
794:                        System.out
795:                                .print("\"" + this  + "\".isMoreSpecificThan(\""
796:                                        + that + "\") => ");
797:                    if (!that.getDeclaringIClass().isAssignableFrom(
798:                            this .getDeclaringIClass())) {
799:                        if (IClass.DEBUG)
800:                            System.out.println("falsE");
801:                        return false;
802:                    }
803:                    IClass[] this ParameterTypes = this .getParameterTypes();
804:                    IClass[] thatParameterTypes = that.getParameterTypes();
805:                    int i;
806:                    for (i = 0; i < this ParameterTypes.length; ++i) {
807:                        if (!thatParameterTypes[i]
808:                                .isAssignableFrom(this ParameterTypes[i])) {
809:                            if (IClass.DEBUG)
810:                                System.out.println("false");
811:                            return false;
812:                        }
813:                    }
814:                    if (IClass.DEBUG)
815:                        System.out.println("true");
816:                    return true;
817:                }
818:
819:                public boolean isLessSpecificThan(IInvocable that)
820:                        throws CompileException {
821:                    return that.isMoreSpecificThan(this );
822:                }
823:
824:                public abstract String toString();
825:            }
826:
827:            public abstract class IConstructor extends IInvocable {
828:
829:                /**
830:                 * Opposed to {@link java.lang.reflect.Constructor#getParameterTypes()}, the
831:                 * return value of this method does not include the optionally leading "synthetic
832:                 * parameters".
833:                 */
834:                public abstract IClass[] getParameterTypes()
835:                        throws CompileException;
836:
837:                /**
838:                 * Opposed to {@link #getParameterTypes()}, the method descriptor returned by this
839:                 * method does include the optionally leading synthetic parameters.
840:                 */
841:                public String getDescriptor() throws CompileException {
842:                    return new MethodDescriptor(IClass.getDescriptors(this 
843:                            .getParameterTypes()), Descriptor.VOID).toString();
844:                }
845:
846:                public String toString() {
847:                    StringBuffer sb = new StringBuffer(this 
848:                            .getDeclaringIClass().toString());
849:                    sb.append('(');
850:                    try {
851:                        IClass[] parameterTypes = this .getParameterTypes();
852:                        for (int i = 0; i < parameterTypes.length; ++i) {
853:                            if (i > 0)
854:                                sb.append(", ");
855:                            sb.append(parameterTypes[i].toString());
856:                        }
857:                    } catch (CompileException ex) {
858:                        sb.append("<invalid type>");
859:                    }
860:                    sb.append(')');
861:                    return sb.toString();
862:                }
863:            }
864:
865:            public abstract class IMethod extends IInvocable {
866:                public abstract boolean isStatic();
867:
868:                public abstract boolean isAbstract();
869:
870:                public abstract IClass getReturnType() throws CompileException;
871:
872:                public abstract String getName();
873:
874:                public String getDescriptor() throws CompileException {
875:                    return new MethodDescriptor(IClass.getDescriptors(this 
876:                            .getParameterTypes()), this .getReturnType()
877:                            .getDescriptor()).toString();
878:                }
879:
880:                public String toString() {
881:                    StringBuffer sb = new StringBuffer();
882:                    try {
883:                        sb.append(this .getReturnType().toString());
884:                    } catch (CompileException ex) {
885:                        sb.append("<invalid type>");
886:                    }
887:                    sb.append(' ');
888:                    sb.append(this .getDeclaringIClass().toString());
889:                    sb.append('.');
890:                    sb.append(this .getName());
891:                    sb.append('(');
892:                    try {
893:                        IClass[] parameterTypes = this .getParameterTypes();
894:                        for (int i = 0; i < parameterTypes.length; ++i) {
895:                            if (i > 0)
896:                                sb.append(", ");
897:                            sb.append(parameterTypes[i].toString());
898:                        }
899:                    } catch (CompileException ex) {
900:                        sb.append("<invalid type>");
901:                    }
902:                    sb.append(')');
903:                    try {
904:                        IClass[] tes = this .getThrownExceptions();
905:                        if (tes.length > 0) {
906:                            sb.append(" throws ").append(tes[0]);
907:                            for (int i = 1; i < tes.length; ++i)
908:                                sb.append(", ").append(tes[i]);
909:                        }
910:                    } catch (CompileException ex) {
911:                        sb.append("<invalid thrown exception type>");
912:                    }
913:                    return sb.toString();
914:                }
915:            }
916:
917:            public abstract class IField implements  IMember {
918:
919:                // Implement IMember.
920:                public abstract Access getAccess();
921:
922:                public IClass getDeclaringIClass() {
923:                    return IClass.this ;
924:                }
925:
926:                public abstract boolean isStatic();
927:
928:                public abstract IClass getType() throws CompileException;
929:
930:                public abstract String getName();
931:
932:                public String getDescriptor() throws CompileException {
933:                    return this .getType().getDescriptor();
934:                }
935:
936:                /**
937:                 * Returns the value of the field if it is a compile-time constant
938:                 * value, i.e. the field is FINAL and its initializer is a constant
939:                 * expression (JLS2 15.28, bullet 12).
940:                 */
941:                public abstract Object getConstantValue()
942:                        throws CompileException;
943:
944:                public String toString() {
945:                    return this.getName();
946:                }
947:            }
948:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.