Source Code Cross Referenced for ClassType.java in  » Scripting » Kawa » gnu » bytecode » 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 » Kawa » gnu.bytecode 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        // Copyright (c) 1997, 1998, 1999, 2001, 2002, 2004, 2005  Per M.A. Bothner.
0002:        // This is free software;  for terms and warranty disclaimer see ./COPYING.
0003:
0004:        package gnu.bytecode;
0005:
0006:        import java.io.*;
0007:        import java.util.Vector;
0008:
0009:        public class ClassType extends ObjectType implements  AttrContainer,
0010:                Externalizable {
0011:            // An old but generally valid default value.
0012:            int classfileFormatVersion = 45 * 0x10000 + 3;
0013:
0014:            public short getClassfileMajorVersion() {
0015:                return (short) (classfileFormatVersion >> 16);
0016:            }
0017:
0018:            public short getClassfileMinorVersion() {
0019:                return (short) (classfileFormatVersion & 0xFFFF);
0020:            }
0021:
0022:            public void setClassfileVersion(int major, int minor) {
0023:                classfileFormatVersion = (major & 0xFFFF) * 0x10000
0024:                        + (minor * 0xFFFF);
0025:            }
0026:
0027:            public void setClassfileVersionJava5() {
0028:                setClassfileVersion(49, 0);
0029:            }
0030:
0031:            /** Find a ClassType with the given name, or create a new one.
0032:             * Use this for "library classes", where you need the field/method types,
0033:             * but not one where you are about to generate code for.
0034:             * @param name the name of the class (e..g. "java.lang.String").
0035:             */
0036:            public static ClassType make(String name) {
0037:                return (ClassType) Type.getType(name);
0038:            }
0039:
0040:            public static ClassType make(String name, ClassType super Class) {
0041:                ClassType type = make(name);
0042:                if (type.super Class == null)
0043:                    type.setSuper(super Class);
0044:                return type;
0045:            }
0046:
0047:            int this ClassIndex;
0048:
0049:            /** The super (base) class of the current class.
0050:             * X.superClass == null means the superClass has not been specified,
0051:             * and defaults to java.lang.Object. */
0052:            ClassType super Class;
0053:            /** The constant pool index of the superClass, or -1 if unassigned. */
0054:            int super ClassIndex = -1;
0055:
0056:            ClassType[] interfaces;
0057:            int[] interfaceIndexes;
0058:            public int access_flags;
0059:
0060:            Attribute attributes;
0061:
0062:            public final Attribute getAttributes() {
0063:                return attributes;
0064:            }
0065:
0066:            public final void setAttributes(Attribute attributes) {
0067:                this .attributes = attributes;
0068:            }
0069:
0070:            public static final ClassType[] noClasses = {};
0071:
0072:            boolean emitDebugInfo = true;
0073:
0074:            ConstantPool constants;
0075:
0076:            public final ConstantPool getConstants() {
0077:                return constants;
0078:            }
0079:
0080:            public final CpoolEntry getConstant(int i) {
0081:                if (constants == null || constants.pool == null
0082:                        || i > constants.count)
0083:                    return null;
0084:                return constants.pool[i];
0085:            }
0086:
0087:            /** Return the modifiers (access flags) for this class. */
0088:            public final int getModifiers() {
0089:                if (access_flags == 0 && (flags & EXISTING_CLASS) != 0
0090:                        && getReflectClass() != null)
0091:                    access_flags = reflectClass.getModifiers();
0092:                return access_flags;
0093:            }
0094:
0095:            /** Set the modifiers (access flags) for this class. */
0096:            public final void setModifiers(int flags) {
0097:                access_flags = flags;
0098:            }
0099:
0100:            public final boolean hasOuterLink() {
0101:                getFields();
0102:                return (flags & HAS_OUTER_LINK) != 0;
0103:            }
0104:
0105:            public ClassType getOuterLinkType() {
0106:                return !hasOuterLink() ? null : (ClassType) getDeclaredField(
0107:                        "this$0").getType();
0108:            }
0109:
0110:            /** Note that this class needs an other link ("this$0") field.
0111:             * This is only allowed if !isExisting().
0112:             * Adjust any existing "<init>" methods to take the extra
0113:             * implicit parameter.
0114:             * @param outer the outer class
0115:             */
0116:            public final Field setOuterLink(ClassType outer) {
0117:                if ((flags & EXISTING_CLASS) != 0)
0118:                    throw new Error("setOuterLink called for existing class "
0119:                            + getName());
0120:                Field field = getDeclaredField("this$0");
0121:                if (field == null) {
0122:                    field = addField("this$0", outer);
0123:                    flags |= HAS_OUTER_LINK;
0124:                    for (Method meth = methods; meth != null; meth = meth
0125:                            .getNext()) {
0126:                        if ("<init>".equals(meth.getName())) {
0127:                            if (meth.code != null)
0128:                                throw new Error("setOuterLink called when "
0129:                                        + meth + " has code");
0130:                            Type[] arg_types = meth.arg_types;
0131:                            Type[] new_types = new Type[arg_types.length + 1];
0132:                            System.arraycopy(arg_types, 0, new_types, 1,
0133:                                    arg_types.length);
0134:                            new_types[0] = outer;
0135:                            meth.arg_types = new_types;
0136:                            meth.signature = null;
0137:                        }
0138:                    }
0139:                } else if (!outer.equals(field.getType()))
0140:                    throw new Error("inconsistent setOuterLink call for "
0141:                            + getName());
0142:                return field;
0143:            }
0144:
0145:            /** Check if a component is accessible from this class.
0146:             * @param declaring the class containing the component (a field, method,
0147:             *   or inner class)
0148:             * @param modifiers the access flags of the component
0149:             * @return true if the specified component can be accessed from this class.
0150:             */
0151:            public boolean isAccessible(ClassType declaring, int modifiers) {
0152:                int cmods = declaring.getModifiers();
0153:                if ((modifiers & Access.PUBLIC) != 0
0154:                        && (cmods & Access.PUBLIC) != 0)
0155:                    return true;
0156:                String callerName = getName();
0157:                String className = declaring.getName();
0158:                if (callerName.equals(className))
0159:                    return true;
0160:                if ((modifiers & Access.PRIVATE) != 0)
0161:                    return false;
0162:                int dot = callerName.lastIndexOf('.');
0163:                String callerPackage = dot >= 0 ? callerName.substring(0, dot)
0164:                        : "";
0165:                dot = className.lastIndexOf('.');
0166:                String classPackage = dot >= 0 ? className.substring(0, dot)
0167:                        : "";
0168:                if (callerPackage.equals(classPackage))
0169:                    return true;
0170:                if ((modifiers & Access.PROTECTED) != 0
0171:                        && this .isSubclass(declaring))
0172:                    return true;
0173:                return false;
0174:            }
0175:
0176:            /** Sets the name of the class being defined in this classfile.
0177:             * @param name the name to give to the class
0178:             */
0179:            public void setName(String name) {
0180:                this _name = name;
0181:                setSignature("L" + name.replace('.', '/') + ";");
0182:            }
0183:
0184:            SourceDebugExtAttr sourceDbgExt;
0185:
0186:            /** Create a <code>SourceDebugExtAttr</code>, if needed, and
0187:             * set the "stratum".  The stratum is typically a programming language
0188:             * such as "JSP", "Scheme", or "Java" (the default). */
0189:            public void setStratum(String stratum) {
0190:                if (sourceDbgExt == null)
0191:                    sourceDbgExt = new SourceDebugExtAttr(this );
0192:                sourceDbgExt.addStratum(stratum);
0193:            }
0194:
0195:            /** Set the name of the SourceFile associated with this class. */
0196:            public void setSourceFile(String name) {
0197:                if (sourceDbgExt != null) {
0198:                    sourceDbgExt.addFile(name);
0199:                    if (sourceDbgExt.fileCount > 1)
0200:                        return;
0201:                }
0202:
0203:                name = SourceFileAttr.fixSourceFile(name);
0204:                int slash = name.lastIndexOf('/');
0205:                if (slash >= 0)
0206:                    name = name.substring(slash + 1);
0207:                SourceFileAttr.setSourceFile(this , name);
0208:            }
0209:
0210:            /**
0211:             * Set the superclass of the is class.
0212:             * @param name name of super class, or null if this is "Object".
0213:             */
0214:            public void setSuper(String name) {
0215:                setSuper(name == null ? Type.pointer_type : ClassType
0216:                        .make(name));
0217:            }
0218:
0219:            public void setSuper(ClassType super Class) {
0220:                this .super Class = super Class;
0221:            }
0222:
0223:            public ClassType getSuperclass() {
0224:                if (super Class == null && !isInterface()
0225:                        && !("java.lang.Object".equals(getName()))
0226:                        && (flags & EXISTING_CLASS) != 0
0227:                        && getReflectClass() != null) {
0228:                    super Class = (ClassType) make(reflectClass.getSuperclass());
0229:                }
0230:                return super Class;
0231:            }
0232:
0233:            public String getPackageName() {
0234:                String name = getName();
0235:                int index = name.lastIndexOf('.');
0236:                return index < 0 ? "" : name.substring(0, index);
0237:            }
0238:
0239:            /**
0240:             * @return the interfaces this class is declared to implement
0241:             * (not those inherited from its superclass/superinterfaces).
0242:             */
0243:            public synchronized ClassType[] getInterfaces() {
0244:                if (interfaces == null && (flags & EXISTING_CLASS) != 0
0245:                        && getReflectClass() != null) {
0246:                    Class[] reflectInterfaces = reflectClass.getInterfaces();
0247:                    int numInterfaces = reflectInterfaces.length;
0248:                    interfaces = numInterfaces == 0 ? noClasses
0249:                            : new ClassType[numInterfaces];
0250:
0251:                    for (int i = 0; i < numInterfaces; i++)
0252:                        interfaces[i] = (ClassType) Type
0253:                                .make(reflectInterfaces[i]);
0254:                }
0255:                return interfaces;
0256:            }
0257:
0258:            public void setInterfaces(ClassType[] interfaces) {
0259:                this .interfaces = interfaces;
0260:            }
0261:
0262:            /** Add an interface to the list of implemented interfaces. */
0263:            public void addInterface(ClassType newInterface) {
0264:                int oldCount;
0265:                if (interfaces == null || interfaces.length == 0) {
0266:                    oldCount = 0;
0267:                    interfaces = new ClassType[1];
0268:                } else {
0269:                    oldCount = interfaces.length;
0270:                    for (int i = oldCount; --i >= 0;)
0271:                        if (interfaces[i] == newInterface)
0272:                            return;
0273:                    ClassType[] newInterfaces = new ClassType[oldCount + 1];
0274:                    System.arraycopy(interfaces, 0, newInterfaces, 0, oldCount);
0275:                    interfaces = newInterfaces;
0276:                }
0277:                interfaces[oldCount] = newInterface;
0278:            }
0279:
0280:            public final boolean isInterface() {
0281:                return (getModifiers() & Access.INTERFACE) != 0;
0282:            }
0283:
0284:            public final void setInterface(boolean val) {
0285:                if (val)
0286:                    access_flags |= Access.INTERFACE | Access.ABSTRACT;
0287:                else
0288:                    access_flags &= ~Access.INTERFACE | Access.ABSTRACT;
0289:            }
0290:
0291:            public ClassType() {
0292:            }
0293:
0294:            public ClassType(String class_name) {
0295:                super ();
0296:                setName(class_name);
0297:            }
0298:
0299:            Field fields;
0300:            int fields_count;
0301:            Field last_field;
0302:            /**  Constant pool index of "ConstantValue". */
0303:            int ConstantValue_name_index;
0304:
0305:            /** Constant pool index of "Code". */
0306:            int Code_name_index;
0307:
0308:            /** Constant pool index of "LocalVariableTable". */
0309:            int LocalVariableTable_name_index;
0310:
0311:            /** Constant pool index of "LineNumberTable". */
0312:            int LineNumberTable_name_index;
0313:
0314:            /** Get the fields of this class. */
0315:            public final synchronized Field getFields() {
0316:                if ((flags & (ADD_FIELDS_DONE | EXISTING_CLASS)) == EXISTING_CLASS)
0317:                    addFields();
0318:                return fields;
0319:            }
0320:
0321:            public final int getFieldCount() {
0322:                return fields_count;
0323:            }
0324:
0325:            /** Find a field with the given name declared in this class.
0326:             * @return the matching field, or null if there is no such field.
0327:             */
0328:            public Field getDeclaredField(String name) {
0329:                for (Field field = getFields(); field != null; field = field.next) {
0330:                    if (name.equals(field.name))
0331:                        return field;
0332:                }
0333:                return null;
0334:            }
0335:
0336:            /** Find a field with the given name declared in this class or its ancestors.
0337:             * @param name the name of the field.
0338:             * @param mask of match a field whose modifiers has one of these bits set.
0339:             *   Howeve, if mask is -1, ignore the access flags.
0340:             * @return the matching field, or null if there is no such field.
0341:             */
0342:            public Field getField(String name, int mask) {
0343:                ClassType cl = this ;
0344:                for (;;) {
0345:                    Field field = cl.getDeclaredField(name);
0346:                    if (field != null
0347:                            && (mask == -1 || (field.getModifiers() & mask) != 0))
0348:                        return field;
0349:                    ClassType[] interfaces = cl.getInterfaces();
0350:                    if (interfaces != null) {
0351:                        for (int i = 0; i < interfaces.length; i++) {
0352:                            field = interfaces[i].getField(name, mask);
0353:                            if (field != null)
0354:                                return field;
0355:                        }
0356:                    }
0357:                    cl = cl.getSuperclass();
0358:                    if (cl == null)
0359:                        return null;
0360:                }
0361:            }
0362:
0363:            /** Find a field with the given name declared in this class or its ancestors.
0364:             * @return the matching field, or null if there is no such field.
0365:             */
0366:            public Field getField(String name) {
0367:                return getField(name, Access.PUBLIC);
0368:            }
0369:
0370:            /**
0371:             * Add a new field to this class.
0372:             */
0373:            public Field addField() {
0374:                return new Field(this );
0375:            }
0376:
0377:            /**
0378:             * Add a new field to this class, and name the field.
0379:             * @param name the name of the new field
0380:             */
0381:            public Field addField(String name) {
0382:                Field field = new Field(this );
0383:                field.setName(name);
0384:                return field;
0385:            }
0386:
0387:            public final Field addField(String name, Type type) {
0388:                Field field = new Field(this );
0389:                field.setName(name);
0390:                field.setType(type);
0391:                return field;
0392:            }
0393:
0394:            public final Field addField(String name, Type type, int flags) {
0395:                Field field = addField(name, type);
0396:                field.flags = flags;
0397:                return field;
0398:            }
0399:
0400:            /** Use reflection to add all the declared fields of this class.
0401:             * Does not add private or package-private fields.
0402:             * Does not check for duplicate (already-known) fields.
0403:             * Is not thread-safe if another thread may access this ClassType. */
0404:            public void addFields() {
0405:                Class clas = getReflectClass();
0406:                java.lang.reflect.Field[] fields;
0407:                try {
0408:                    fields = clas.getDeclaredFields();
0409:                } catch (SecurityException ex) {
0410:                    fields = clas.getFields();
0411:                }
0412:                int count = fields.length;
0413:                for (int i = 0; i < count; i++) {
0414:                    java.lang.reflect.Field field = fields[i];
0415:                    if ("this$0".equals(field.getName()))
0416:                        flags |= HAS_OUTER_LINK;
0417:                    addField(field.getName(), Type.make(field.getType()), field
0418:                            .getModifiers());
0419:                }
0420:                flags |= ADD_FIELDS_DONE;
0421:            }
0422:
0423:            Method methods;
0424:            int methods_count;
0425:            Method last_method;
0426:            public Method constructor;
0427:
0428:            /** Get the methods of this class. */
0429:            public final Method getMethods() {
0430:                return methods;
0431:            }
0432:
0433:            public final int getMethodCount() {
0434:                return methods_count;
0435:            }
0436:
0437:            Method addMethod() {
0438:                return new Method(this , 0);
0439:            }
0440:
0441:            public Method addMethod(String name) {
0442:                return addMethod(name, 0);
0443:            }
0444:
0445:            public Method addMethod(String name, int flags) {
0446:                Method method = new Method(this , flags);
0447:                method.setName(name);
0448:                return method;
0449:            }
0450:
0451:            // deprecated:
0452:            public Method addMethod(String name, Type[] arg_types,
0453:                    Type return_type, int flags) {
0454:                return addMethod(name, flags, arg_types, return_type);
0455:            }
0456:
0457:            /** Add a method to this ClassType.
0458:             * If an existing method matches, return that.  Otherwise, create
0459:             * a new one.
0460:             * In contrast, the other addMethod methods always create new Methods. */
0461:            public Method addMethod(String name, int flags, Type[] arg_types,
0462:                    Type return_type) {
0463:                Method method = getDeclaredMethod(name, arg_types);
0464:                if (method != null
0465:                        && return_type.equals(method.getReturnType())
0466:                        && (flags & method.access_flags) == flags)
0467:                    return method;
0468:                method = addMethod(name, flags);
0469:                method.arg_types = arg_types;
0470:                method.return_type = return_type;
0471:                return method;
0472:            }
0473:
0474:            public Method addMethod(String name, String signature, int flags) {
0475:                Method meth = addMethod(name, flags);
0476:                meth.setSignature(signature);
0477:                return meth;
0478:            }
0479:
0480:            /** Add a method to this ClassType.
0481:             * If an existing method matches, return that.  Otherwise, create
0482:             * a new one. */
0483:            public Method getMethod(java.lang.reflect.Method method) {
0484:                String name = method.getName();
0485:                Class[] parameterClasses = method.getParameterTypes();
0486:                Type[] parameterTypes = new Type[parameterClasses.length];
0487:                for (int i = parameterClasses.length; --i >= 0;)
0488:                    parameterTypes[i] = Type.make(parameterClasses[i]);
0489:                return addMethod(name, method.getModifiers(), parameterTypes,
0490:                        Type.make(method.getReturnType()));
0491:            }
0492:
0493:            public final synchronized Method getDeclaredMethods() {
0494:                if ((flags & (ADD_METHODS_DONE | EXISTING_CLASS)) == EXISTING_CLASS)
0495:                    addMethods(getReflectClass());
0496:                return methods;
0497:            }
0498:
0499:            /** Count methods matching a given filter.
0500:             * @param filter to select methods to return
0501:             * @param searchSupers 0 if only current class should be searched,
0502:             *   1 if superclasses should also be searched,
0503:             *   2 if super-interfaces should also be search
0504:             * @return number of methods that match
0505:             */
0506:            public final int countMethods(Filter filter, int searchSupers) {
0507:                return getMethods(filter, searchSupers, null, 0);
0508:            }
0509:
0510:            public Method[] getMethods(Filter filter, boolean searchSupers) {
0511:                return getMethods(filter, searchSupers ? 1 : 0);
0512:            }
0513:
0514:            /** Get methods matching a given filter.
0515:             * @param filter to select methods to return
0516:             * @param searchSupers 0 if only current class should be searched,
0517:             *   1 if superclasses should also be searched,
0518:             *   2 if super-interfaces should also be searched
0519:             * @return a fresh array containing the methods satisfying the filter
0520:             */
0521:            public Method[] getMethods(Filter filter, int searchSupers) {
0522:                int count = getMethods(filter, searchSupers, null, 0);
0523:                Method[] result = new Method[count];
0524:                getMethods(filter, searchSupers, result, 0);
0525:                return result;
0526:            }
0527:
0528:            /** Helper to get methods satisfying a filtering predicate.
0529:             * @param filter to select methods to return
0530:             * @param searchSupers 0 if only current class should be searched,
0531:             *   1 if superclasses should also be searched,
0532:             *   2 if super-interfaces should also be searched
0533:             * @param result array to place selected methods in
0534:             * @param offset start of where in result to place result
0535:             * @return number of methods placed in result array
0536:             * @deprecated
0537:             */
0538:            public int getMethods(Filter filter, int searchSupers,
0539:                    Method[] result, int offset) {
0540:                int count = 0;
0541:                for (ClassType ctype = this ; ctype != null; ctype = ctype
0542:                        .getSuperclass()) {
0543:                    for (Method meth = ctype.getDeclaredMethods(); meth != null; meth = meth
0544:                            .getNext())
0545:                        if (filter.select(meth)) {
0546:                            if (result != null)
0547:                                result[offset + count] = meth;
0548:                            count++;
0549:                        }
0550:                    if (searchSupers == 0)
0551:                        break;
0552:
0553:                    if (searchSupers > 1) {
0554:                        ClassType[] interfaces = ctype.getInterfaces();
0555:                        if (interfaces != null) {
0556:                            for (int i = 0; i < interfaces.length; i++)
0557:                                count += interfaces[i].getMethods(filter,
0558:                                        searchSupers, result, offset + count);
0559:                        }
0560:                    }
0561:                }
0562:                return count;
0563:            }
0564:
0565:            /** Helper to get methods satisfying a filtering predicate.
0566:             * @param filter to select methods to return
0567:             * @param searchSupers 0 if only current class should be searched,
0568:             *   1 if superclasses should also be searched,
0569:             *   2 if super-interfaces should also be searched
0570:             * @param result Vector to add selected methods in
0571:             * @param context If non-null, skip if class not visible in named package.
0572:             * @return number of methods placed in result array
0573:             */
0574:            public int getMethods(Filter filter, int searchSupers,
0575:                    Vector result, String context) {
0576:                int count = 0;
0577:                for (ClassType ctype = this ; ctype != null; ctype = ctype
0578:                        .getSuperclass()) {
0579:                    if (context == null
0580:                            || (ctype.getModifiers() & Access.PUBLIC) != 0
0581:                            || context.equals(ctype.getPackageName())) {
0582:                        for (Method meth = ctype.getDeclaredMethods(); meth != null; meth = meth
0583:                                .getNext())
0584:                            if (filter.select(meth)) {
0585:                                if (result != null)
0586:                                    result.addElement(meth);
0587:                                count++;
0588:                            }
0589:                    }
0590:                    if (searchSupers == 0)
0591:                        break;
0592:
0593:                    if (searchSupers > 1) {
0594:                        ClassType[] interfaces = ctype.getInterfaces();
0595:                        if (interfaces != null) {
0596:                            for (int i = 0; i < interfaces.length; i++)
0597:                                count += interfaces[i].getMethods(filter,
0598:                                        searchSupers, result, context);
0599:                        }
0600:                    }
0601:                }
0602:                return count;
0603:            }
0604:
0605:            /** Look for a matching method.
0606:             * @param name method name
0607:             * @param arg_types parameter types that must match.
0608:             *  Can also be null, to match any parameter type list.
0609:             *  Otherwise, an element of arg_types must be the same type (equals),
0610:             *  though a null element of arg_types is a wildcard that matches any type.
0611:             */
0612:            public Method getDeclaredMethod(String name, Type[] arg_types) {
0613:                int needOuterLinkArg = "<init>".equals(name) && hasOuterLink() ? 1
0614:                        : 0;
0615:                for (Method method = getDeclaredMethods(); method != null; method = method.next) {
0616:                    if (!name.equals(method.getName()))
0617:                        continue;
0618:                    Type[] method_args = method.getParameterTypes();
0619:                    if (arg_types == null
0620:                            || (arg_types == method_args && needOuterLinkArg == 0))
0621:                        return method;
0622:                    int i = arg_types.length;
0623:                    if (i != method_args.length - needOuterLinkArg)
0624:                        continue;
0625:                    while (--i >= 0) {
0626:                        Type meth_type = method_args[i + needOuterLinkArg];
0627:                        Type need_type = arg_types[i];
0628:                        if (meth_type == need_type || need_type == null)
0629:                            continue;
0630:                        String meth_sig = meth_type.getSignature();
0631:                        String need_sig = need_type.getSignature();
0632:                        if (!meth_sig.equals(need_sig))
0633:                            break;
0634:                    }
0635:                    if (i < 0)
0636:                        return method;
0637:                }
0638:                return null;
0639:            }
0640:
0641:            /** Get a method with matching name and number of arguments. */
0642:            public Method getDeclaredMethod(String name, int argCount) {
0643:                Method result = null;
0644:                int needOuterLinkArg = "<init>".equals(name) && hasOuterLink() ? 1
0645:                        : 0;
0646:                for (Method method = getDeclaredMethods(); method != null; method = method.next) {
0647:                    if (name.equals(method.getName())
0648:                            && argCount + needOuterLinkArg == method
0649:                                    .getParameterTypes().length) {
0650:                        if (result != null)
0651:                            throw new Error(
0652:                                    "ambiguous call to getDeclaredMethod(\""
0653:                                            + name + "\", " + argCount
0654:                                            + ")\n - " + result + "\n - "
0655:                                            + method);
0656:                        result = method;
0657:                    }
0658:                }
0659:                return result;
0660:            }
0661:
0662:            public Method getMethod(String name, Type[] arg_types) {
0663:                ClassType cl = this ;
0664:                for (;;) {
0665:                    Method method = cl.getDeclaredMethod(name, arg_types);
0666:                    if (method != null)
0667:                        return method;
0668:                    cl = cl.getSuperclass();
0669:                    if (cl == null)
0670:                        break;
0671:                }
0672:                cl = this ;
0673:                for (;;) {
0674:                    ClassType[] interfaces = cl.getInterfaces();
0675:                    if (interfaces != null) {
0676:                        for (int i = 0; i < interfaces.length; i++) {
0677:                            Method method = interfaces[i].getDeclaredMethod(
0678:                                    name, arg_types);
0679:                            if (method != null)
0680:                                return method;
0681:                        }
0682:                    }
0683:                    cl = cl.getSuperclass();
0684:                    if (cl == null)
0685:                        break;
0686:                }
0687:                return null;
0688:            }
0689:
0690:            /** Use reflection to add all the declared methods of this class.
0691:             * Does not add constructors nor private or package-private methods.
0692:             * Does not check for duplicate (already-known) methods.
0693:             * @param clas should be the same as getReflectClass(). */
0694:            public void addMethods(Class clas) {
0695:                // Set this flag BEFORE the actual addition.
0696:                // This prevents this method to be called indirectly for the same class
0697:                // while it is executed, which would result in methods being listed
0698:                // twice in this class.
0699:                flags |= ADD_METHODS_DONE;
0700:
0701:                java.lang.reflect.Method[] methods;
0702:                try {
0703:                    methods = clas.getDeclaredMethods();
0704:                } catch (SecurityException ex) {
0705:                    methods = clas.getMethods();
0706:                }
0707:                int count = methods.length;
0708:                for (int i = 0; i < count; i++) {
0709:                    java.lang.reflect.Method method = methods[i];
0710:                    if (!method.getDeclaringClass().equals(clas))
0711:                        continue;
0712:                    int modifiers = method.getModifiers();
0713:                    Class[] paramTypes = method.getParameterTypes();
0714:                    int j = paramTypes.length;
0715:                    Type[] args = new Type[j];
0716:                    while (--j >= 0)
0717:                        args[j] = Type.make(paramTypes[j]);
0718:                    Method meth = addMethod(method.getName(), modifiers);
0719:                    meth.arg_types = args;
0720:                    meth.return_type = Type.make(method.getReturnType());
0721:                }
0722:
0723:                java.lang.reflect.Constructor[] cmethods;
0724:                try {
0725:                    cmethods = clas.getDeclaredConstructors();
0726:                } catch (SecurityException ex) {
0727:                    cmethods = clas.getConstructors();
0728:                }
0729:                count = cmethods.length;
0730:                for (int i = 0; i < count; i++) {
0731:                    java.lang.reflect.Constructor method = cmethods[i];
0732:                    if (!method.getDeclaringClass().equals(clas))
0733:                        continue;
0734:                    int modifiers = method.getModifiers();
0735:                    if ((modifiers & (Access.PUBLIC | Access.PROTECTED)) == 0)
0736:                        continue;
0737:                    Class[] paramTypes = method.getParameterTypes();
0738:                    int j = paramTypes.length;
0739:                    Type[] args = new Type[j];
0740:                    while (--j >= 0)
0741:                        args[j] = Type.make(paramTypes[j]);
0742:                    Method meth = addMethod("<init>", modifiers);
0743:                    meth.arg_types = args;
0744:                    meth.return_type = Type.void_type;
0745:                }
0746:            }
0747:
0748:            public Method[] getMatchingMethods(String name, Type[] paramTypes,
0749:                    int flags) {
0750:                int nMatches = 0;
0751:                java.util.Vector matches = new java.util.Vector(10);
0752:                for (Method method = methods; method != null; method = method
0753:                        .getNext()) {
0754:                    if (!name.equals(method.getName()))
0755:                        continue;
0756:                    if ((flags & Access.STATIC) != (method.access_flags & Access.STATIC))
0757:                        continue;
0758:                    if ((flags & Access.PUBLIC) > (method.access_flags & Access.PUBLIC))
0759:                        continue;
0760:                    Type[] mtypes = method.arg_types;
0761:                    if (mtypes.length != paramTypes.length)
0762:                        continue;
0763:                    nMatches++;
0764:                    matches.addElement(method);
0765:                }
0766:                Method[] result = new Method[nMatches];
0767:                matches.copyInto(result);
0768:                return result;
0769:            }
0770:
0771:            /** Do various fixups after generating code but before we can write it out.
0772:             * This includes assigning constant pool indexes where needed,
0773:             * finalizing labels, etc. */
0774:            public void doFixups() {
0775:                if (constants == null)
0776:                    constants = new ConstantPool();
0777:                if (this ClassIndex == 0)
0778:                    this ClassIndex = constants.addClass(this ).index;
0779:                if (super Class == this )
0780:                    setSuper((ClassType) null);
0781:                if (super ClassIndex < 0)
0782:                    super ClassIndex = super Class == null ? 0 : constants
0783:                            .addClass(super Class).index;
0784:                if (interfaces != null && interfaceIndexes == null) {
0785:                    int n = interfaces.length;
0786:                    interfaceIndexes = new int[n];
0787:                    for (int i = 0; i < n; i++)
0788:                        interfaceIndexes[i] = constants.addClass(interfaces[i]).index;
0789:                }
0790:                for (Field field = fields; field != null; field = field.next) {
0791:                    field.assign_constants(this );
0792:                }
0793:                for (Method method = methods; method != null; method = method.next)
0794:                    method.assignConstants();
0795:                Attribute.assignConstants(this , this );
0796:            }
0797:
0798:            public void writeToStream(OutputStream stream)
0799:                    throws java.io.IOException {
0800:                java.io.DataOutputStream dstr = new java.io.DataOutputStream(
0801:                        stream);
0802:                int i;
0803:
0804:                doFixups();
0805:
0806:                dstr.writeInt(0xcafebabe); // magic
0807:                dstr.writeShort(getClassfileMinorVersion());
0808:                dstr.writeShort(getClassfileMajorVersion());
0809:
0810:                // Write out the constant pool.
0811:                if (constants == null)
0812:                    dstr.writeShort(1);
0813:                else
0814:                    constants.write(dstr);
0815:
0816:                dstr.writeShort(access_flags);
0817:                dstr.writeShort(this ClassIndex);
0818:                dstr.writeShort(super ClassIndex);
0819:                if (interfaceIndexes == null)
0820:                    dstr.writeShort(0); // interfaces_count
0821:                else {
0822:                    int interfaces_count = interfaceIndexes.length;
0823:                    dstr.writeShort(interfaces_count);
0824:                    for (i = 0; i < interfaces_count; i++)
0825:                        dstr.writeShort(interfaceIndexes[i]);
0826:                }
0827:
0828:                dstr.writeShort(fields_count);
0829:                for (Field field = fields; field != null; field = field.next)
0830:                    field.write(dstr, this );
0831:
0832:                dstr.writeShort(methods_count);
0833:                for (Method method = methods; method != null; method = method.next)
0834:                    method.write(dstr, this );
0835:
0836:                Attribute.writeAll(this , dstr);
0837:
0838:                flags |= ADD_FIELDS_DONE | ADD_METHODS_DONE;
0839:            }
0840:
0841:            public void writeToFile(String filename) throws java.io.IOException {
0842:                OutputStream stream = new BufferedOutputStream(
0843:                        new FileOutputStream(filename));
0844:                writeToStream(stream);
0845:                stream.close();
0846:            }
0847:
0848:            public void writeToFile() throws java.io.IOException {
0849:                writeToFile(this _name.replace('.', File.separatorChar)
0850:                        + ".class");
0851:            }
0852:
0853:            public byte[] writeToArray() {
0854:                ByteArrayOutputStream stream = new ByteArrayOutputStream(500);
0855:                try {
0856:                    writeToStream(stream);
0857:                } catch (java.io.IOException ex) {
0858:                    throw new InternalError(ex.toString());
0859:                }
0860:                return stream.toByteArray();
0861:            }
0862:
0863:            /**
0864:             * Convert a String to a Utf8 byte array.
0865:             * @param str the input String.
0866:             * @return the input encoded as a utf8 byte array.
0867:             */
0868:            public static byte[] to_utf8(String str) {
0869:                if (str == null)
0870:                    return null;
0871:                int str_len = str.length();
0872:                int utf_len = 0;
0873:                for (int i = 0; i < str_len; i++) {
0874:                    int c = str.charAt(i);
0875:                    if ((c > 0) && (c <= 0x7F))
0876:                        utf_len++;
0877:                    else if (c <= 0x7FF)
0878:                        utf_len += 2;
0879:                    else
0880:                        utf_len += 3;
0881:                }
0882:                byte[] buffer = new byte[utf_len];
0883:                int j = 0;
0884:                for (int i = 0; i < str_len; i++) {
0885:                    int c = str.charAt(i);
0886:                    if ((c > 0) && (c <= 0x7F))
0887:                        buffer[j++] = (byte) c;
0888:                    else if (c <= 0x7FF) {
0889:                        buffer[j++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
0890:                        buffer[j++] = (byte) (0x80 | ((c >> 0) & 0x3F));
0891:                    } else {
0892:                        buffer[j++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
0893:                        buffer[j++] = (byte) (0x80 | ((c >> 6) & 0x3F));
0894:                        buffer[j++] = (byte) (0x80 | ((c >> 0) & 0x3F));
0895:                    }
0896:                }
0897:                return buffer;
0898:            }
0899:
0900:            /** True if this class/interface implements the interface iface. */
0901:            public final boolean implements Interface(ClassType iface) {
0902:                if (this  == iface)
0903:                    return true;
0904:                ClassType baseClass = this .getSuperclass();
0905:                if (baseClass != null && baseClass.implements Interface(iface))
0906:                    return true;
0907:                ClassType[] interfaces = getInterfaces();
0908:                if (interfaces != null) {
0909:                    for (int i = interfaces.length; --i >= 0;) {
0910:                        if (interfaces[i].implements Interface(iface))
0911:                            return true;
0912:                    }
0913:                }
0914:                return false;
0915:            }
0916:
0917:            /** A more efficient version of isSubclass(ClassType.make(cname)).
0918:             * Does not cause the named class be loaded if it hasn't been.
0919:             * @param cname a class name - cannot be an interface name
0920:             */
0921:            public final boolean isSubclass(String cname) {
0922:                ClassType ctype = this ;
0923:                for (;;) {
0924:                    if (cname.equals(ctype.getName()))
0925:                        return true;
0926:                    ctype = ctype.getSuperclass();
0927:                    if (ctype == null)
0928:                        return false;
0929:                }
0930:            }
0931:
0932:            public final boolean isSubclass(ClassType other) {
0933:                if (other.isInterface())
0934:                    return implements Interface(other);
0935:                if ((this  == tostring_type && other == string_type)
0936:                        || (this  == string_type && other == tostring_type))
0937:                    return true;
0938:                ClassType baseClass = this ;
0939:                while (baseClass != null) {
0940:                    if (baseClass == other)
0941:                        return true;
0942:                    baseClass = baseClass.getSuperclass();
0943:                }
0944:                return false;
0945:            }
0946:
0947:            public int compare(Type other) {
0948:                if (other == nullType)
0949:                    return 1;
0950:                if (!(other instanceof  ClassType))
0951:                    return swappedCompareResult(other.compare(this ));
0952:                String name = getName();
0953:                if (name != null && name.equals(other.getName()))
0954:                    return 0;
0955:                ClassType cother = (ClassType) other;
0956:                if (isSubclass(cother))
0957:                    return -1;
0958:                if (cother.isSubclass(this ))
0959:                    return 1;
0960:                if (this  == tostring_type)
0961:                    return cother == Type.pointer_type ? -1 : 1;
0962:                if (cother == tostring_type)
0963:                    return this  == Type.pointer_type ? 1 : -1;
0964:                if (this .isInterface() || cother.isInterface())
0965:                    return -2;
0966:                return -3;
0967:            }
0968:
0969:            public String toString() {
0970:                return "ClassType " + getName();
0971:            }
0972:
0973:            /**
0974:             * @serialData Write the class name (as given by getName()) using writeUTF.
0975:             */
0976:            public void writeExternal(ObjectOutput out) throws IOException {
0977:                out.writeUTF(getName());
0978:            }
0979:
0980:            public void readExternal(ObjectInput in) throws IOException,
0981:                    ClassNotFoundException {
0982:                setName(in.readUTF());
0983:                flags |= ClassType.EXISTING_CLASS;
0984:            }
0985:
0986:            public Object readResolve() throws ObjectStreamException {
0987:                String name = getName();
0988:                /* #ifdef JAVA5 */
0989:                // java.util.HashMap<String,Type> map = mapNameToType;
0990:                /* #else */
0991:                java.util.Hashtable map = mapNameToType;
0992:                /* #endif */
0993:                synchronized (map) {
0994:                    Type found = (Type) map.get(name);
0995:                    if (found != null)
0996:                        return found;
0997:                    map.put(name, this );
0998:                }
0999:                return this ;
1000:            }
1001:
1002:            /** Clear various object references, to help garbage collection. */
1003:            public void cleanupAfterCompilation() {
1004:                for (Method meth = methods; meth != null; meth = meth.getNext())
1005:                    meth.cleanupAfterCompilation();
1006:
1007:                constants = null;
1008:                attributes = null;
1009:                sourceDbgExt = null;
1010:            }
1011:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.