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


0001:        /*
0002:         * Janino - An embedded Java[TM] compiler
0003:         *
0004:         * Copyright (c) 2001-2007, Arno Unkrig
0005:         * All rights reserved.
0006:         *
0007:         * Redistribution and use in source and binary forms, with or without
0008:         * modification, are permitted provided that the following conditions
0009:         * are met:
0010:         *
0011:         *    1. Redistributions of source code must retain the above copyright
0012:         *       notice, this list of conditions and the following disclaimer.
0013:         *    2. Redistributions in binary form must reproduce the above
0014:         *       copyright notice, this list of conditions and the following
0015:         *       disclaimer in the documentation and/or other materials
0016:         *       provided with the distribution.
0017:         *    3. The name of the author may not be used to endorse or promote
0018:         *       products derived from this software without specific prior
0019:         *       written permission.
0020:         *
0021:         * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0022:         * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
0023:         * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024:         * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
0025:         * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0026:         * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
0027:         * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028:         * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
0029:         * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
0030:         * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
0031:         * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0032:         */
0033:
0034:        package org.codehaus.janino;
0035:
0036:        import java.util.*;
0037:
0038:        /**
0039:         * A simplified equivalent to "java.lang.reflect".
0040:         */
0041:        public abstract class IClass {
0042:            private static final boolean DEBUG = false;
0043:
0044:            public static final IClass VOID = new PrimitiveIClass(
0045:                    Descriptor.VOID_);
0046:            public static final IClass BYTE = new PrimitiveIClass(
0047:                    Descriptor.BYTE_);
0048:            public static final IClass CHAR = new PrimitiveIClass(
0049:                    Descriptor.CHAR_);
0050:            public static final IClass DOUBLE = new PrimitiveIClass(
0051:                    Descriptor.DOUBLE_);
0052:            public static final IClass FLOAT = new PrimitiveIClass(
0053:                    Descriptor.FLOAT_);
0054:            public static final IClass INT = new PrimitiveIClass(
0055:                    Descriptor.INT_);
0056:            public static final IClass LONG = new PrimitiveIClass(
0057:                    Descriptor.LONG_);
0058:            public static final IClass SHORT = new PrimitiveIClass(
0059:                    Descriptor.SHORT_);
0060:            public static final IClass BOOLEAN = new PrimitiveIClass(
0061:                    Descriptor.BOOLEAN_);
0062:
0063:            private static class PrimitiveIClass extends IClass {
0064:                private final String fieldDescriptor;
0065:
0066:                public PrimitiveIClass(String fieldDescriptor) {
0067:                    this .fieldDescriptor = fieldDescriptor;
0068:                }
0069:
0070:                protected IClass getComponentType2() {
0071:                    return null;
0072:                }
0073:
0074:                protected IClass[] getDeclaredIClasses2() {
0075:                    return new IClass[0];
0076:                }
0077:
0078:                protected IConstructor[] getDeclaredIConstructors2() {
0079:                    return new IConstructor[0];
0080:                }
0081:
0082:                protected IField[] getDeclaredIFields2() {
0083:                    return new IField[0];
0084:                }
0085:
0086:                protected IMethod[] getDeclaredIMethods2() {
0087:                    return new IMethod[0];
0088:                }
0089:
0090:                protected IClass getDeclaringIClass2() {
0091:                    return null;
0092:                }
0093:
0094:                protected String getDescriptor2() {
0095:                    return this .fieldDescriptor;
0096:                }
0097:
0098:                protected IClass[] getInterfaces2() {
0099:                    return new IClass[0];
0100:                }
0101:
0102:                protected IClass getOuterIClass2() {
0103:                    return null;
0104:                }
0105:
0106:                protected IClass getSuperclass2() {
0107:                    return null;
0108:                }
0109:
0110:                public boolean isAbstract() {
0111:                    return false;
0112:                }
0113:
0114:                public boolean isArray() {
0115:                    return false;
0116:                }
0117:
0118:                public boolean isFinal() {
0119:                    return true;
0120:                }
0121:
0122:                public boolean isInterface() {
0123:                    return false;
0124:                }
0125:
0126:                public boolean isPrimitive() {
0127:                    return true;
0128:                }
0129:
0130:                public boolean isPrimitiveNumeric() {
0131:                    return Descriptor.isPrimitiveNumeric(this .fieldDescriptor);
0132:                }
0133:
0134:                public Access getAccess() {
0135:                    return Access.PUBLIC;
0136:                }
0137:            }
0138:
0139:            /**
0140:             * Returns all the constructors declared by the class represented by the
0141:             * type. If the class has a default constructor, it is included.
0142:             * <p>
0143:             * Returns an array with zero elements for an interface, array, primitive type or
0144:             * "void".
0145:             */
0146:            public final IConstructor[] getDeclaredIConstructors() {
0147:                if (this .declaredIConstructors == null) {
0148:                    this .declaredIConstructors = this 
0149:                            .getDeclaredIConstructors2();
0150:                }
0151:                return this .declaredIConstructors;
0152:            }
0153:
0154:            private IConstructor[] declaredIConstructors = null;
0155:
0156:            protected abstract IConstructor[] getDeclaredIConstructors2();
0157:
0158:            /**
0159:             * Returns the methods of the class or interface (but not inherited
0160:             * methods).<br>
0161:             * Returns an empty array for an array, primitive type or "void".
0162:             */
0163:            public final IMethod[] getDeclaredIMethods() {
0164:                if (this .declaredIMethods == null) {
0165:                    this .declaredIMethods = this .getDeclaredIMethods2();
0166:                }
0167:                return this .declaredIMethods;
0168:            }
0169:
0170:            protected IMethod[] declaredIMethods = null;
0171:
0172:            protected abstract IMethod[] getDeclaredIMethods2();
0173:
0174:            /**
0175:             * Returns all methods with the given name declared in the class or
0176:             * interface (but not inherited methods).<br>
0177:             * Returns an empty array if no methods with that name are declared.
0178:             * 
0179:             * @return an array of {@link IMethod}s that must not be modified
0180:             */
0181:            public final IMethod[] getDeclaredIMethods(String methodName) {
0182:                if (this .declaredIMethodCache == null) {
0183:                    Map m = new HashMap();
0184:
0185:                    // Fill the map with "IMethod"s and "List"s.
0186:                    IMethod[] dims = this .getDeclaredIMethods();
0187:                    for (int i = 0; i < dims.length; i++) {
0188:                        IMethod dim = dims[i];
0189:                        String mn = dim.getName();
0190:                        Object o = m.get(mn);
0191:                        if (o == null) {
0192:                            m.put(mn, dim);
0193:                        } else if (o instanceof  IMethod) {
0194:                            List l = new ArrayList();
0195:                            l.add(o);
0196:                            l.add(dim);
0197:                            m.put(mn, l);
0198:                        } else {
0199:                            ((List) o).add(dim);
0200:                        }
0201:                    }
0202:
0203:                    // Convert "IMethod"s and "List"s to "IMethod[]"s.
0204:                    for (Iterator it = m.entrySet().iterator(); it.hasNext();) {
0205:                        Map.Entry me = (Map.Entry) it.next();
0206:                        Object v = me.getValue();
0207:                        if (v instanceof  IMethod) {
0208:                            me.setValue(new IMethod[] { (IMethod) v });
0209:                        } else {
0210:                            List l = (List) v;
0211:                            me.setValue(l.toArray(new IMethod[l.size()]));
0212:                        }
0213:                    }
0214:                    this .declaredIMethodCache = m;
0215:                }
0216:
0217:                IMethod[] methods = (IMethod[]) this .declaredIMethodCache
0218:                        .get(methodName);
0219:                return methods == null ? IClass.NO_IMETHODS : methods;
0220:            }
0221:
0222:            /*package*/Map declaredIMethodCache = null; // String methodName => IMethod[]
0223:
0224:            /**
0225:             * Returns all methods declared in the class or interface, its superclasses and its
0226:             * superinterfaces.<br>
0227:             * For overridden methods, only the last non-abstract implementation is returned.
0228:             * 
0229:             * @return an array of {@link IMethod}s that must not be modified
0230:             */
0231:            public final IMethod[] getIMethods() throws CompileException {
0232:                if (this .iMethodCache == null) {
0233:                    Map m = new HashMap();
0234:                    this .getIMethods(m);
0235:                    Collection iMethods = m.values();
0236:                    this .iMethodCache = (IMethod[]) iMethods
0237:                            .toArray(new IMethod[iMethods.size()]);
0238:                }
0239:                return this .iMethodCache;
0240:            }
0241:
0242:            /*package*/IMethod[] iMethodCache = null;
0243:
0244:            private void getIMethods(Map result) throws CompileException {
0245:                IMethod[] ms = this .getDeclaredIMethods();
0246:                for (int i = 0; i < ms.length; ++i) {
0247:                    IMethod m = ms[i];
0248:                    String key = m.getName() + m.getDescriptor();
0249:                    IMethod m2 = (IMethod) result.get(key);
0250:                    if (m2 == null || m2.isAbstract())
0251:                        result.put(key, m);
0252:                }
0253:                {
0254:                    IClass sc = this .getSuperclass();
0255:                    if (sc != null)
0256:                        sc.getIMethods(result);
0257:                }
0258:                {
0259:                    IClass[] iis = this .getInterfaces();
0260:                    for (int i = 0; i < iis.length; ++i)
0261:                        iis[i].getIMethods(result);
0262:                }
0263:            }
0264:
0265:            public static final IMethod[] NO_IMETHODS = new IMethod[0];
0266:
0267:            public final boolean hasIMethod(String methodName,
0268:                    IClass[] parameterTypes) throws CompileException {
0269:                IMethod[] ims = this .getDeclaredIMethods(methodName);
0270:                for (int i = 0; i < ims.length; ++i) {
0271:                    IClass[] pts = ims[i].getParameterTypes();
0272:                    if (Arrays.equals(pts, parameterTypes))
0273:                        return true;
0274:                }
0275:                return false;
0276:            }
0277:
0278:            /**
0279:             * Returns the fields of a class or interface (but not inherited
0280:             * fields).<br>
0281:             * Returns an empty array for an array, primitive type or "void".
0282:             */
0283:            public final IField[] getDeclaredIFields() {
0284:                if (this .declaredIFields == null) {
0285:                    this .declaredIFields = this .getDeclaredIFields2();
0286:                }
0287:                return this .declaredIFields;
0288:            }
0289:
0290:            protected IField[] declaredIFields = null;
0291:
0292:            protected abstract IField[] getDeclaredIFields2();
0293:
0294:            /**
0295:             * Returns the synthetic fields of an anonymous or local class, in
0296:             * the order in which they are passed to all constructors.
0297:             */
0298:            public IField[] getSyntheticIFields() {
0299:                return new IField[0];
0300:            }
0301:
0302:            /**
0303:             * Returns the classes and interfaces declared as members of the class
0304:             * (but not inherited classes and interfaces).<br>
0305:             * Returns an empty array for an array, primitive type or "void".
0306:             */
0307:            public final IClass[] getDeclaredIClasses() throws CompileException {
0308:                if (this .declaredIClasses == null) {
0309:                    this .declaredIClasses = this .getDeclaredIClasses2();
0310:                }
0311:                return this .declaredIClasses;
0312:            }
0313:
0314:            private IClass[] declaredIClasses = null;
0315:
0316:            protected abstract IClass[] getDeclaredIClasses2()
0317:                    throws CompileException;
0318:
0319:            /**
0320:             * If this class is a member class, return the declaring class, otherwise return
0321:             * <code>null</code>.
0322:             */
0323:            public final IClass getDeclaringIClass() throws CompileException {
0324:                if (!this .declaringIClassIsCached) {
0325:                    this .declaringIClass = this .getDeclaringIClass2();
0326:                    this .declaringIClassIsCached = true;
0327:                }
0328:                return this .declaringIClass;
0329:            }
0330:
0331:            private boolean declaringIClassIsCached = false;
0332:            private IClass declaringIClass = null;
0333:
0334:            protected abstract IClass getDeclaringIClass2()
0335:                    throws CompileException;
0336:
0337:            /**
0338:             * The following types have an "outer class":
0339:             * <ul>
0340:             *   <li>Anonymous classes declared in a non-static method of a class
0341:             *   <li>Local classes declared in a non-static method of a class
0342:             *   <li>Non-static member classes
0343:             * </ul>
0344:             */
0345:            public final IClass getOuterIClass() throws CompileException {
0346:                if (!this .outerIClassIsCached) {
0347:                    this .outerIClass = this .getOuterIClass2();
0348:                    this .outerIClassIsCached = true;
0349:                }
0350:                return this .outerIClass;
0351:            }
0352:
0353:            private boolean outerIClassIsCached = false;
0354:            private IClass outerIClass = null;
0355:
0356:            protected abstract IClass getOuterIClass2() throws CompileException;
0357:
0358:            /**
0359:             * Returns the superclass of the class.<br>
0360:             * Returns "null" for class "Object", interfaces, arrays, primitive types
0361:             * and "void".
0362:             */
0363:            public final IClass getSuperclass() throws CompileException {
0364:                if (!this .super classIsCached) {
0365:                    this .super class = this .getSuperclass2();
0366:                    this .super classIsCached = true;
0367:                    if (this .super class != null
0368:                            && this .super class.isSubclassOf(this ))
0369:                        throw new CompileException(
0370:                                "Class circularity detected for \""
0371:                                        + Descriptor.toClassName(this 
0372:                                                .getDescriptor()) + "\"", null);
0373:                }
0374:                return this .super class;
0375:            }
0376:
0377:            private boolean super classIsCached = false;
0378:            private IClass super class = null;
0379:
0380:            protected abstract IClass getSuperclass2() throws CompileException;
0381:
0382:            public abstract Access getAccess();
0383:
0384:            /**
0385:             * Whether subclassing is allowed (JVMS 4.1 access_flags)
0386:             * @return <code>true</code> if subclassing is prohibited
0387:             */
0388:            public abstract boolean isFinal();
0389:
0390:            /**
0391:             * Returns the interfaces implemented by the class.<br>
0392:             * Returns the superinterfaces of the interface.<br>
0393:             * Returns "Cloneable" and "Serializable" for arrays.<br>
0394:             * Returns an empty array for primitive types and "void".
0395:             */
0396:            public final IClass[] getInterfaces() throws CompileException {
0397:                if (this .interfaces == null) {
0398:                    this .interfaces = this .getInterfaces2();
0399:                    for (int i = 0; i < this .interfaces.length; ++i) {
0400:                        if (this .interfaces[i].implements Interface(this ))
0401:                            throw new CompileException(
0402:                                    "Interface circularity detected for \""
0403:                                            + Descriptor.toClassName(this 
0404:                                                    .getDescriptor()) + "\"",
0405:                                    null);
0406:                    }
0407:                }
0408:                return this .interfaces;
0409:            }
0410:
0411:            private IClass[] interfaces = null;
0412:
0413:            protected abstract IClass[] getInterfaces2()
0414:                    throws CompileException;
0415:
0416:            /**
0417:             * Whether the class may be instantiated (JVMS 4.1 access_flags)
0418:             * @return <code>true</code> if instantiation is prohibited
0419:             */
0420:            public abstract boolean isAbstract();
0421:
0422:            /**
0423:             * Returns the field descriptor for the type as defined by JVMS 4.3.2.
0424:             */
0425:            public final String getDescriptor() {
0426:                if (this .descriptor == null) {
0427:                    this .descriptor = this .getDescriptor2();
0428:                }
0429:                return this .descriptor;
0430:            }
0431:
0432:            private String descriptor = null;
0433:
0434:            protected abstract String getDescriptor2();
0435:
0436:            /**
0437:             * Convenience method that determines the field descriptors of an array of {@link IClass}es.
0438:             * @see #getDescriptor()
0439:             */
0440:            public static String[] getDescriptors(IClass[] iClasses) {
0441:                String[] descriptors = new String[iClasses.length];
0442:                for (int i = 0; i < iClasses.length; ++i)
0443:                    descriptors[i] = iClasses[i].getDescriptor();
0444:                return descriptors;
0445:            }
0446:
0447:            /**
0448:             * Returns "true" if this type represents an interface.
0449:             */
0450:            public abstract boolean isInterface();
0451:
0452:            /**
0453:             * Returns "true" if this type represents an array.
0454:             */
0455:            public abstract boolean isArray();
0456:
0457:            /**
0458:             * Returns "true" if this type represents a primitive type or "void".
0459:             */
0460:            public abstract boolean isPrimitive();
0461:
0462:            /**
0463:             * Returns "true" if this type represents "byte", "short", "int", "long",
0464:             * "char", "float" or "double".
0465:             */
0466:            public abstract boolean isPrimitiveNumeric();
0467:
0468:            /**
0469:             * Returns the component type of the array.<br>
0470:             * Returns "null" for classes, interfaces, primitive types and "void".
0471:             */
0472:            public final IClass getComponentType() {
0473:                if (!this .componentTypeIsCached) {
0474:                    this .componentType = this .getComponentType2();
0475:                    this .componentTypeIsCached = true;
0476:                }
0477:                return this .componentType;
0478:            }
0479:
0480:            private boolean componentTypeIsCached = false;
0481:            private IClass componentType = null;
0482:
0483:            protected abstract IClass getComponentType2();
0484:
0485:            /**
0486:             * Returns a string representation for this object.
0487:             */
0488:            public String toString() {
0489:                return Descriptor.toClassName(this .getDescriptor());
0490:            }
0491:
0492:            /**
0493:             * Determine if "this" is assignable from "that". This is true if "this"
0494:             * is identical with "that" (JLS2 5.1.1), or if "that" is
0495:             * widening-primitive-convertible to "this" (JLS2 5.1.2), or if "that" is
0496:             * widening-reference-convertible to "this" (JLS2 5.1.4).
0497:             */
0498:            public boolean isAssignableFrom(IClass that)
0499:                    throws CompileException {
0500:
0501:                // Identity conversion, JLS2 5.1.1
0502:                if (this  == that)
0503:                    return true;
0504:
0505:                // Widening primitive conversion, JLS2 5.1.2
0506:                {
0507:                    String ds = that.getDescriptor() + this .getDescriptor();
0508:                    if (ds.length() == 2
0509:                            && IClass.PRIMITIVE_WIDENING_CONVERSIONS
0510:                                    .contains(ds))
0511:                        return true;
0512:                }
0513:
0514:                // Widening reference conversion, JLS2 5.1.4
0515:                {
0516:
0517:                    // JLS 5.1.4.1: Target type is superclass of source class type.
0518:                    if (that.isSubclassOf(this ))
0519:                        return true;
0520:
0521:                    // JLS 5.1.4.2: Source class type implements target interface type.
0522:                    // JLS 5.1.4.4: Source interface type implements target interface type.
0523:                    if (that.implements Interface(this ))
0524:                        return true;
0525:
0526:                    // JLS 5.1.4.3 Convert "null" literal to any reference type.
0527:                    if (that == IClass.VOID && !this .isPrimitive())
0528:                        return true;
0529:
0530:                    // JLS 5.1.4.5: From any interface to type "Object".
0531:                    if (that.isInterface()
0532:                            && this .getDescriptor().equals(Descriptor.OBJECT))
0533:                        return true;
0534:
0535:                    if (that.isArray()) {
0536:
0537:                        // JLS 5.1.4.6: From any array type to type "Object".
0538:                        if (this .getDescriptor().equals(Descriptor.OBJECT))
0539:                            return true;
0540:
0541:                        // JLS 5.1.4.7: From any array type to type "Cloneable".
0542:                        if (this .getDescriptor().equals(Descriptor.CLONEABLE))
0543:                            return true;
0544:
0545:                        // JLS 5.1.4.8: From any array type to type "java.io.Serializable".
0546:                        if (this .getDescriptor()
0547:                                .equals(Descriptor.SERIALIZABLE))
0548:                            return true;
0549:
0550:                        // JLS 5.1.4.9: From SC[] to TC[] while SC if widening reference convertible to TC.
0551:                        if (this .isArray()) {
0552:                            IClass this CT = this .getComponentType();
0553:                            IClass thatCT = that.getComponentType();
0554:                            if (!this CT.isPrimitive()
0555:                                    && this CT.isAssignableFrom(thatCT))
0556:                                return true;
0557:                        }
0558:                    }
0559:                }
0560:                return false;
0561:            }
0562:
0563:            private static final Set PRIMITIVE_WIDENING_CONVERSIONS = new HashSet();
0564:            static {
0565:                String[] pwcs = new String[] {
0566:                        Descriptor.BYTE_ + Descriptor.SHORT_,
0567:
0568:                        Descriptor.BYTE_ + Descriptor.INT_,
0569:                        Descriptor.SHORT_ + Descriptor.INT_,
0570:                        Descriptor.CHAR_ + Descriptor.INT_,
0571:
0572:                        Descriptor.BYTE_ + Descriptor.LONG_,
0573:                        Descriptor.SHORT_ + Descriptor.LONG_,
0574:                        Descriptor.CHAR_ + Descriptor.LONG_,
0575:                        Descriptor.INT_ + Descriptor.LONG_,
0576:
0577:                        Descriptor.BYTE_ + Descriptor.FLOAT_,
0578:                        Descriptor.SHORT_ + Descriptor.FLOAT_,
0579:                        Descriptor.CHAR_ + Descriptor.FLOAT_,
0580:                        Descriptor.INT_ + Descriptor.FLOAT_,
0581:
0582:                        Descriptor.LONG_ + Descriptor.FLOAT_,
0583:
0584:                        Descriptor.BYTE_ + Descriptor.DOUBLE_,
0585:                        Descriptor.SHORT_ + Descriptor.DOUBLE_,
0586:                        Descriptor.CHAR_ + Descriptor.DOUBLE_,
0587:                        Descriptor.INT_ + Descriptor.DOUBLE_,
0588:
0589:                        Descriptor.LONG_ + Descriptor.DOUBLE_,
0590:
0591:                        Descriptor.FLOAT_ + Descriptor.DOUBLE_, };
0592:                for (int i = 0; i < pwcs.length; ++i)
0593:                    IClass.PRIMITIVE_WIDENING_CONVERSIONS.add(pwcs[i]);
0594:            }
0595:
0596:            /**
0597:             * Returns <code>true</code> if this class is an immediate or non-immediate
0598:             * subclass of <code>that</code> class.
0599:             */
0600:            public boolean isSubclassOf(IClass that) throws CompileException {
0601:                for (IClass sc = this .getSuperclass(); sc != null; sc = sc
0602:                        .getSuperclass()) {
0603:                    if (sc == that)
0604:                        return true;
0605:                }
0606:                return false;
0607:            }
0608:
0609:            /**
0610:             * If <code>this</code> represents a class: Return <code>true</code> if this class
0611:             * directly or indirectly implements <code>that</code> interface.
0612:             * <p>
0613:             * If <code>this</code> represents an interface: Return <code>true</code> if this
0614:             * interface directly or indirectly extends <code>that</code> interface.
0615:             */
0616:            public boolean implements Interface(IClass that)
0617:                    throws CompileException {
0618:                for (IClass c = this ; c != null; c = c.getSuperclass()) {
0619:                    IClass[] tis = c.getInterfaces();
0620:                    for (int i = 0; i < tis.length; ++i) {
0621:                        IClass ti = tis[i];
0622:                        if (ti == that || ti.implements Interface(that))
0623:                            return true;
0624:                    }
0625:                }
0626:                return false;
0627:            }
0628:
0629:            /**
0630:             * Get an {@link IClass} that represents an n-dimensional array of this type.
0631:             *
0632:             * @param n dimension count
0633:             * @param objectType Required because the superclass of an array class is {@link Object} by definition
0634:             */
0635:            public IClass getArrayIClass(int n, IClass objectType) {
0636:                IClass result = this ;
0637:                for (int i = 0; i < n; ++i)
0638:                    result = result.getArrayIClass(objectType);
0639:                return result;
0640:            }
0641:
0642:            /**
0643:             * Get an {@link IClass} that represents an array of this type.
0644:             *
0645:             * @param objectType Required because the superclass of an array class is {@link Object} by definition
0646:             */
0647:            public IClass getArrayIClass(IClass objectType) {
0648:                if (this .arrayIClass == null)
0649:                    this .arrayIClass = this .getArrayIClass2(objectType);
0650:                return this .arrayIClass;
0651:            }
0652:
0653:            private IClass arrayIClass = null;
0654:
0655:            private IClass getArrayIClass2(final IClass objectType) {
0656:                final IClass componentType = this ;
0657:                return new IClass() {
0658:                    public IClass.IConstructor[] getDeclaredIConstructors2() {
0659:                        return new IClass.IConstructor[0];
0660:                    }
0661:
0662:                    // Special trickery #17: Arrays override "Object.clone()", but without "throws
0663:                    // CloneNotSupportedException"!
0664:                    public IClass.IMethod[] getDeclaredIMethods2() {
0665:                        return new IClass.IMethod[] { new IMethod() {
0666:                            public String getName() {
0667:                                return "clone";
0668:                            }
0669:
0670:                            public IClass getReturnType() {
0671:                                return objectType /*ot*/;
0672:                            }
0673:
0674:                            public boolean isAbstract() {
0675:                                return false;
0676:                            }
0677:
0678:                            public boolean isStatic() {
0679:                                return false;
0680:                            }
0681:
0682:                            public Access getAccess() {
0683:                                return Access.PUBLIC;
0684:                            }
0685:
0686:                            public IClass[] getParameterTypes() {
0687:                                return new IClass[0];
0688:                            }
0689:
0690:                            public IClass[] getThrownExceptions() {
0691:                                return new IClass[0];
0692:                            }
0693:                        } };
0694:                    }
0695:
0696:                    public IClass.IField[] getDeclaredIFields2() {
0697:                        return new IClass.IField[0];
0698:                    }
0699:
0700:                    public IClass[] getDeclaredIClasses2() {
0701:                        return new IClass[0];
0702:                    }
0703:
0704:                    public IClass getDeclaringIClass2() {
0705:                        return null;
0706:                    }
0707:
0708:                    public IClass getOuterIClass2() {
0709:                        return null;
0710:                    }
0711:
0712:                    public IClass getSuperclass2() {
0713:                        return objectType;
0714:                    }
0715:
0716:                    public IClass[] getInterfaces2() {
0717:                        return new IClass[0];
0718:                    }
0719:
0720:                    public String getDescriptor2() {
0721:                        return '[' + componentType.getDescriptor();
0722:                    }
0723:
0724:                    public Access getAccess() {
0725:                        return componentType.getAccess();
0726:                    }
0727:
0728:                    public boolean isFinal() {
0729:                        return true;
0730:                    }
0731:
0732:                    public boolean isInterface() {
0733:                        return false;
0734:                    }
0735:
0736:                    public boolean isAbstract() {
0737:                        return false;
0738:                    }
0739:
0740:                    public boolean isArray() {
0741:                        return true;
0742:                    }
0743:
0744:                    public boolean isPrimitive() {
0745:                        return false;
0746:                    }
0747:
0748:                    public boolean isPrimitiveNumeric() {
0749:                        return false;
0750:                    }
0751:
0752:                    public IClass getComponentType2() {
0753:                        return componentType;
0754:                    }
0755:
0756:                    public String toString() {
0757:                        return componentType.toString() + "[]";
0758:                    }
0759:                };
0760:            }
0761:
0762:            /**
0763:             * If <code>optionalName</code> is <code>null</code>, find all {@link IClass}es visible in the
0764:             * scope of the current class.
0765:             * <p>
0766:             * If <code>optionalName</code> is not <code>null</code>, find the member {@link IClass}es
0767:             * that has the given name. If the name is ambiguous (i.e. if more than one superclass,
0768:             * interface of enclosing type declares a type with that name), then the size of the
0769:             * returned array is greater than one.
0770:             * <p>
0771:             * Examines superclasses, interfaces and enclosing type declarations.
0772:             * @return an array of {@link IClass}es in unspecified order, possibly of length zero
0773:             */
0774:            IClass[] findMemberType(String optionalName)
0775:                    throws CompileException {
0776:                IClass[] res = (IClass[]) this .memberTypeCache
0777:                        .get(optionalName);
0778:                if (res == null) {
0779:
0780:                    // Notice: A type may be added multiply to the result set because we are in its scope
0781:                    // multiply. E.g. the type is a member of a superclass AND a member of an enclosing type.
0782:                    Set s = new HashSet(); // IClass
0783:                    this .findMemberType(optionalName, s);
0784:                    res = s.isEmpty() ? IClass.ZERO_ICLASSES : (IClass[]) s
0785:                            .toArray(new IClass[s.size()]);
0786:
0787:                    this .memberTypeCache.put(optionalName, res);
0788:                }
0789:
0790:                return res;
0791:            }
0792:
0793:            private final Map memberTypeCache = new HashMap(); // String name => IClass[]
0794:            private static final IClass[] ZERO_ICLASSES = new IClass[0];
0795:
0796:            private void findMemberType(String optionalName, Collection result)
0797:                    throws CompileException {
0798:
0799:                // Search for a type with the given name in the current class.
0800:                IClass[] memberTypes = this .getDeclaredIClasses();
0801:                if (optionalName == null) {
0802:                    result.addAll(Arrays.asList(memberTypes));
0803:                } else {
0804:                    String memberDescriptor = Descriptor
0805:                            .fromClassName(Descriptor.toClassName(this 
0806:                                    .getDescriptor())
0807:                                    + '$' + optionalName);
0808:                    for (int i = 0; i < memberTypes.length; ++i) {
0809:                        final IClass mt = memberTypes[i];
0810:                        if (mt.getDescriptor().equals(memberDescriptor)) {
0811:                            result.add(mt);
0812:                            return;
0813:                        }
0814:                    }
0815:                }
0816:
0817:                // Examine superclass.
0818:                {
0819:                    IClass super class = this .getSuperclass();
0820:                    if (super class != null)
0821:                        super class.findMemberType(optionalName, result);
0822:                }
0823:
0824:                // Examine interfaces.
0825:                {
0826:                    IClass[] ifs = this .getInterfaces();
0827:                    for (int i = 0; i < ifs.length; ++i)
0828:                        ifs[i].findMemberType(optionalName, result);
0829:                }
0830:
0831:                // Examine enclosing type declarations.
0832:                {
0833:                    IClass declaringIClass = this .getDeclaringIClass();
0834:                    IClass outerIClass = this .getOuterIClass();
0835:                    if (declaringIClass != null) {
0836:                        declaringIClass.findMemberType(optionalName, result);
0837:                    }
0838:                    if (outerIClass != null && outerIClass != declaringIClass) {
0839:                        outerIClass.findMemberType(optionalName, result);
0840:                    }
0841:                }
0842:            }
0843:
0844:            public interface IMember {
0845:
0846:                /**
0847:                 * @return One of {@link Access#PRIVATE}, {@link Access#PROTECTED},
0848:                 * {@link Access#DEFAULT} and {@link Access#PUBLIC}.
0849:                 */
0850:                Access getAccess();
0851:
0852:                /**
0853:                 * Returns the {@link IClass} that declares this {@link IClass.IMember}.
0854:                 */
0855:                IClass getDeclaringIClass();
0856:            }
0857:
0858:            public abstract class IInvocable implements  IMember {
0859:
0860:                // Implement IMember.
0861:                public abstract Access getAccess();
0862:
0863:                public IClass getDeclaringIClass() {
0864:                    return IClass.this ;
0865:                }
0866:
0867:                public abstract IClass[] getParameterTypes()
0868:                        throws CompileException;
0869:
0870:                public abstract String getDescriptor() throws CompileException;
0871:
0872:                public abstract IClass[] getThrownExceptions()
0873:                        throws CompileException;
0874:
0875:                public boolean isMoreSpecificThan(IInvocable that)
0876:                        throws CompileException {
0877:                    if (IClass.DEBUG)
0878:                        System.out
0879:                                .print("\"" + this  + "\".isMoreSpecificThan(\""
0880:                                        + that + "\") => ");
0881:
0882:                    // The following case is tricky: JLS2 says that the invocation is AMBIGUOUS, but only
0883:                    // JAVAC 1.2 issues an error; JAVAC 1.4.1, 1.5.0 and 1.6.0 obviously ignore the declaring
0884:                    // type and invoke "A.meth(String)".
0885:                    // JLS3 is not clear about this. For compatibility with JAVA 1.4.1, 1.5.0 and 1.6.0,
0886:                    // JANINO also ignores the declaring type.
0887:                    //
0888:                    // See also JANINO-79 and JLS2Tests / 15.12.2.2
0889:                    if (false) {
0890:                        if (!that.getDeclaringIClass().isAssignableFrom(
0891:                                this .getDeclaringIClass())) {
0892:                            if (IClass.DEBUG)
0893:                                System.out.println("falsE");
0894:                            return false;
0895:                        }
0896:                    }
0897:
0898:                    IClass[] this ParameterTypes = this .getParameterTypes();
0899:                    IClass[] thatParameterTypes = that.getParameterTypes();
0900:                    int i;
0901:                    for (i = 0; i < this ParameterTypes.length; ++i) {
0902:                        if (!thatParameterTypes[i]
0903:                                .isAssignableFrom(this ParameterTypes[i])) {
0904:                            if (IClass.DEBUG)
0905:                                System.out.println("false");
0906:                            return false;
0907:                        }
0908:                    }
0909:                    if (IClass.DEBUG)
0910:                        System.out.println("true");
0911:                    return !Arrays.equals(this ParameterTypes,
0912:                            thatParameterTypes);
0913:                }
0914:
0915:                public boolean isLessSpecificThan(IInvocable that)
0916:                        throws CompileException {
0917:                    return that.isMoreSpecificThan(this );
0918:                }
0919:
0920:                public abstract String toString();
0921:            }
0922:
0923:            public abstract class IConstructor extends IInvocable {
0924:
0925:                /**
0926:                 * Opposed to {@link java.lang.reflect.Constructor#getParameterTypes()}, the
0927:                 * return value of this method does not include the optionally leading "synthetic
0928:                 * parameters".
0929:                 */
0930:                public abstract IClass[] getParameterTypes()
0931:                        throws CompileException;
0932:
0933:                /**
0934:                 * Opposed to {@link #getParameterTypes()}, the method descriptor returned by this
0935:                 * method does include the optionally leading synthetic parameters.
0936:                 */
0937:                public String getDescriptor() throws CompileException {
0938:                    IClass[] parameterTypes = this .getParameterTypes();
0939:
0940:                    IClass outerIClass = IClass.this .getOuterIClass();
0941:                    if (outerIClass != null) {
0942:                        IClass[] tmp = new IClass[parameterTypes.length + 1];
0943:                        tmp[0] = outerIClass;
0944:                        System.arraycopy(parameterTypes, 0, tmp, 1,
0945:                                parameterTypes.length);
0946:                        parameterTypes = tmp;
0947:                    }
0948:
0949:                    return new MethodDescriptor(IClass
0950:                            .getDescriptors(parameterTypes), Descriptor.VOID_)
0951:                            .toString();
0952:                }
0953:
0954:                public String toString() {
0955:                    StringBuffer sb = new StringBuffer(this 
0956:                            .getDeclaringIClass().toString());
0957:                    sb.append('(');
0958:                    try {
0959:                        IClass[] parameterTypes = this .getParameterTypes();
0960:                        for (int i = 0; i < parameterTypes.length; ++i) {
0961:                            if (i > 0)
0962:                                sb.append(", ");
0963:                            sb.append(parameterTypes[i].toString());
0964:                        }
0965:                    } catch (CompileException ex) {
0966:                        sb.append("<invalid type>");
0967:                    }
0968:                    sb.append(')');
0969:                    return sb.toString();
0970:                }
0971:            }
0972:
0973:            public abstract class IMethod extends IInvocable {
0974:                public abstract boolean isStatic();
0975:
0976:                public abstract boolean isAbstract();
0977:
0978:                public abstract IClass getReturnType() throws CompileException;
0979:
0980:                public abstract String getName();
0981:
0982:                public String getDescriptor() throws CompileException {
0983:                    return new MethodDescriptor(IClass.getDescriptors(this 
0984:                            .getParameterTypes()), this .getReturnType()
0985:                            .getDescriptor()).toString();
0986:                }
0987:
0988:                public String toString() {
0989:                    StringBuffer sb = new StringBuffer();
0990:                    try {
0991:                        sb.append(this .getReturnType().toString());
0992:                    } catch (CompileException ex) {
0993:                        sb.append("<invalid type>");
0994:                    }
0995:                    sb.append(' ');
0996:                    sb.append(this .getDeclaringIClass().toString());
0997:                    sb.append('.');
0998:                    sb.append(this .getName());
0999:                    sb.append('(');
1000:                    try {
1001:                        IClass[] parameterTypes = this .getParameterTypes();
1002:                        for (int i = 0; i < parameterTypes.length; ++i) {
1003:                            if (i > 0)
1004:                                sb.append(", ");
1005:                            sb.append(parameterTypes[i].toString());
1006:                        }
1007:                    } catch (CompileException ex) {
1008:                        sb.append("<invalid type>");
1009:                    }
1010:                    sb.append(')');
1011:                    try {
1012:                        IClass[] tes = this .getThrownExceptions();
1013:                        if (tes.length > 0) {
1014:                            sb.append(" throws ").append(tes[0]);
1015:                            for (int i = 1; i < tes.length; ++i)
1016:                                sb.append(", ").append(tes[i]);
1017:                        }
1018:                    } catch (CompileException ex) {
1019:                        sb.append("<invalid thrown exception type>");
1020:                    }
1021:                    return sb.toString();
1022:                }
1023:            }
1024:
1025:            public abstract class IField implements  IMember {
1026:
1027:                // Implement IMember.
1028:                public abstract Access getAccess();
1029:
1030:                public IClass getDeclaringIClass() {
1031:                    return IClass.this ;
1032:                }
1033:
1034:                public abstract boolean isStatic();
1035:
1036:                public abstract IClass getType() throws CompileException;
1037:
1038:                public abstract String getName();
1039:
1040:                public String getDescriptor() throws CompileException {
1041:                    return this .getType().getDescriptor();
1042:                }
1043:
1044:                /**
1045:                 * Returns the value of the field if it is a compile-time constant
1046:                 * value, i.e. the field is FINAL and its initializer is a constant
1047:                 * expression (JLS2 15.28, bullet 12).
1048:                 */
1049:                public abstract Object getConstantValue()
1050:                        throws CompileException;
1051:
1052:                public String toString() {
1053:                    return this.getName();
1054:                }
1055:            }
1056:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.