Source Code Cross Referenced for MemberDefinition.java in  » 6.0-JDK-Modules-sun » tools » sun » tools » java » 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 » 6.0 JDK Modules sun » tools » sun.tools.java 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 1994-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        package sun.tools.java;
0027:
0028:        import sun.tools.tree.Node;
0029:        import sun.tools.tree.Vset;
0030:        import sun.tools.tree.Expression;
0031:        import sun.tools.tree.Statement;
0032:        import sun.tools.tree.Context;
0033:        import sun.tools.asm.Assembler;
0034:        import java.io.PrintStream;
0035:        import java.util.Vector;
0036:        import java.util.Map;
0037:        import java.util.HashMap;
0038:
0039:        /**
0040:         * This class defines a member of a Java class:
0041:         * a variable, a method, or an inner class.
0042:         *
0043:         * WARNING: The contents of this source file are not part of any
0044:         * supported API.  Code that depends on them does so at its own risk:
0045:         * they are subject to change or removal without notice.
0046:         */
0047:        public class MemberDefinition implements  Constants {
0048:            protected long where;
0049:            protected int modifiers;
0050:            protected Type type;
0051:            protected String documentation;
0052:            protected IdentifierToken expIds[];
0053:            protected ClassDeclaration exp[];
0054:            protected Node value;
0055:            protected ClassDefinition clazz;
0056:            protected Identifier name;
0057:            protected ClassDefinition innerClass;
0058:            protected MemberDefinition nextMember;
0059:            protected MemberDefinition nextMatch;
0060:            protected MemberDefinition accessPeer;
0061:            protected boolean super AccessMethod;
0062:
0063:            /**
0064:             * Constructor
0065:             */
0066:            public MemberDefinition(long where, ClassDefinition clazz,
0067:                    int modifiers, Type type, Identifier name,
0068:                    IdentifierToken expIds[], Node value) {
0069:                if (expIds == null) {
0070:                    expIds = new IdentifierToken[0];
0071:                }
0072:                this .where = where;
0073:                this .clazz = clazz;
0074:                this .modifiers = modifiers;
0075:                this .type = type;
0076:                this .name = name;
0077:                this .expIds = expIds;
0078:                this .value = value;
0079:            }
0080:
0081:            /**
0082:             * Constructor for an inner class.
0083:             * Inner classes are represented as fields right along with
0084:             * variables and methods for simplicity of data structure,
0085:             * and to reflect properly the textual declaration order.
0086:             * <p>
0087:             * This constructor calls the generic constructor for this
0088:             * class, extracting all necessary values from the innerClass.
0089:             */
0090:            public MemberDefinition(ClassDefinition innerClass) {
0091:                this (innerClass.getWhere(), innerClass.getOuterClass(),
0092:                        innerClass.getModifiers(), innerClass.getType(),
0093:                        innerClass.getName().getFlatName().getName(), null,
0094:                        null);
0095:                this .innerClass = innerClass;
0096:            }
0097:
0098:            /**
0099:             * A cache of previously created proxy members.  Used to ensure
0100:             * uniqueness of proxy objects.  See the makeProxyMember method
0101:             * defined below.
0102:             */
0103:            static private Map proxyCache;
0104:
0105:            /**
0106:             * Create a member which is externally the same as `field' but
0107:             * is defined in class `classDef'.  This is used by code
0108:             * in sun.tools.tree.(MethodExpression,FieldExpression) as
0109:             * part of the fix for bug 4135692.
0110:             *
0111:             * Proxy members should not be added, ala addMember(), to classes.
0112:             * They are merely "stand-ins" to produce modified MethodRef
0113:             * constant pool entries during code generation.
0114:             *
0115:             * We keep a cache of previously created proxy members not to
0116:             * save time or space, but to ensure uniqueness of the proxy
0117:             * member for any (field,classDef) pair.  If these are not made
0118:             * unique then we can end up generating duplicate MethodRef
0119:             * constant pool entries during code generation.
0120:             */
0121:            public static MemberDefinition makeProxyMember(
0122:                    MemberDefinition field, ClassDefinition classDef,
0123:                    Environment env) {
0124:
0125:                if (proxyCache == null) {
0126:                    proxyCache = new HashMap();
0127:                }
0128:
0129:                String key = field.toString() + "@" + classDef.toString();
0130:                // System.out.println("Key is : " + key);
0131:                MemberDefinition proxy = (MemberDefinition) proxyCache.get(key);
0132:
0133:                if (proxy != null)
0134:                    return proxy;
0135:
0136:                proxy = new MemberDefinition(field.getWhere(), classDef, field
0137:                        .getModifiers(), field.getType(), field.getName(),
0138:                        field.getExceptionIds(), null);
0139:                proxy.exp = field.getExceptions(env);
0140:                proxyCache.put(key, proxy);
0141:
0142:                return proxy;
0143:            }
0144:
0145:            /**
0146:             * Get the position in the input
0147:             */
0148:            public final long getWhere() {
0149:                return where;
0150:            }
0151:
0152:            /**
0153:             * Get the class declaration
0154:             */
0155:            public final ClassDeclaration getClassDeclaration() {
0156:                return clazz.getClassDeclaration();
0157:            }
0158:
0159:            /**
0160:             * A stub.  Subclasses can do more checking.
0161:             */
0162:            public void resolveTypeStructure(Environment env) {
0163:            }
0164:
0165:            /**
0166:             * Get the class declaration in which the field is actually defined
0167:             */
0168:            public ClassDeclaration getDefiningClassDeclaration() {
0169:                return getClassDeclaration();
0170:            }
0171:
0172:            /**
0173:             * Get the class definition
0174:             */
0175:            public final ClassDefinition getClassDefinition() {
0176:                return clazz;
0177:            }
0178:
0179:            /**
0180:             * Get the field's top-level enclosing class
0181:             */
0182:            public final ClassDefinition getTopClass() {
0183:                return clazz.getTopClass();
0184:            }
0185:
0186:            /**
0187:             * Get the field's modifiers
0188:             */
0189:            public final int getModifiers() {
0190:                return modifiers;
0191:            }
0192:
0193:            public final void subModifiers(int mod) {
0194:                modifiers &= ~mod;
0195:            }
0196:
0197:            public final void addModifiers(int mod) {
0198:                modifiers |= mod;
0199:            }
0200:
0201:            /**
0202:             * Get the field's type
0203:             */
0204:            public final Type getType() {
0205:                return type;
0206:            }
0207:
0208:            /**
0209:             * Get the field's name
0210:             */
0211:            public final Identifier getName() {
0212:                return name;
0213:            }
0214:
0215:            /**
0216:             * Get arguments (a vector of LocalMember)
0217:             */
0218:            public Vector getArguments() {
0219:                return isMethod() ? new Vector() : null;
0220:            }
0221:
0222:            /**
0223:             * Get the exceptions that are thrown by this method.
0224:             */
0225:            public ClassDeclaration[] getExceptions(Environment env) {
0226:                if (expIds != null && exp == null) {
0227:                    if (expIds.length == 0)
0228:                        exp = new ClassDeclaration[0];
0229:                    else
0230:                        // we should have translated this already!
0231:                        throw new CompilerError("getExceptions " + this );
0232:                }
0233:                return exp;
0234:            }
0235:
0236:            public final IdentifierToken[] getExceptionIds() {
0237:                return expIds;
0238:            }
0239:
0240:            /**
0241:             * Get an inner class.
0242:             */
0243:            public ClassDefinition getInnerClass() {
0244:                return innerClass;
0245:            }
0246:
0247:            /**
0248:             * Is this a synthetic field which holds a copy of,
0249:             * or reference to, a local variable or enclosing instance?
0250:             */
0251:            public boolean isUplevelValue() {
0252:                if (!isSynthetic() || !isVariable() || isStatic()) {
0253:                    return false;
0254:                }
0255:                String name = this .name.toString();
0256:                return name.startsWith(prefixVal)
0257:                        || name.toString().startsWith(prefixLoc)
0258:                        || name.toString().startsWith(prefixThis);
0259:            }
0260:
0261:            public boolean isAccessMethod() {
0262:                // This no longer works, because access methods
0263:                // for constructors do not use the standard naming
0264:                // scheme.
0265:                //    return isSynthetic() && isMethod()
0266:                //        && name.toString().startsWith(prefixAccess);
0267:                // Assume that a method is an access method if it has
0268:                // an access peer.  NOTE: An access method will not be
0269:                // recognized as such until 'setAccessMethodTarget' has
0270:                // been called on it.
0271:                return isSynthetic() && isMethod() && (accessPeer != null);
0272:            }
0273:
0274:            /**
0275:             * Is this a synthetic method which provides access to a
0276:             * visible private member?
0277:             */
0278:            public MemberDefinition getAccessMethodTarget() {
0279:                if (isAccessMethod()) {
0280:                    for (MemberDefinition f = accessPeer; f != null; f = f.accessPeer) {
0281:                        // perhaps skip over another access for the same field
0282:                        if (!f.isAccessMethod()) {
0283:                            return f;
0284:                        }
0285:                    }
0286:                }
0287:                return null;
0288:            }
0289:
0290:            public void setAccessMethodTarget(MemberDefinition target) {
0291:                if (getAccessMethodTarget() != target) {
0292:                    /*-------------------*
0293:                    if (!isAccessMethod() || accessPeer != null ||
0294:                        target.accessPeer != null) {
0295:                    throw new CompilerError("accessPeer");
0296:                    }
0297:                     *-------------------*/
0298:                    if (accessPeer != null || target.accessPeer != null) {
0299:                        throw new CompilerError("accessPeer");
0300:                    }
0301:                    accessPeer = target;
0302:                }
0303:            }
0304:
0305:            /**
0306:             * If this method is a getter for a private field, return the setter.
0307:             */
0308:            public MemberDefinition getAccessUpdateMember() {
0309:                if (isAccessMethod()) {
0310:                    for (MemberDefinition f = accessPeer; f != null; f = f.accessPeer) {
0311:                        if (f.isAccessMethod()) {
0312:                            return f;
0313:                        }
0314:                    }
0315:                }
0316:                return null;
0317:            }
0318:
0319:            public void setAccessUpdateMember(MemberDefinition updater) {
0320:                if (getAccessUpdateMember() != updater) {
0321:                    if (!isAccessMethod()
0322:                            || updater.getAccessMethodTarget() != getAccessMethodTarget()) {
0323:                        throw new CompilerError("accessPeer");
0324:                    }
0325:                    updater.accessPeer = accessPeer;
0326:                    accessPeer = updater;
0327:                }
0328:            }
0329:
0330:            /**
0331:             * Is this an access method for a field selection or method call
0332:             * of the form '...super.foo' or '...super.foo()'?
0333:             */
0334:            public final boolean isSuperAccessMethod() {
0335:                return super AccessMethod;
0336:            }
0337:
0338:            /**
0339:             * Mark this member as an access method for a field selection
0340:             * or method call via the 'super' keyword.
0341:             */
0342:            public final void setIsSuperAccessMethod(boolean b) {
0343:                super AccessMethod = b;
0344:            }
0345:
0346:            /**
0347:             * Tell if this is a final variable without an initializer.
0348:             * Such variables are subject to definite single assignment.
0349:             */
0350:            public final boolean isBlankFinal() {
0351:                return isFinal() && !isSynthetic() && getValue() == null;
0352:            }
0353:
0354:            public boolean isNeverNull() {
0355:                if (isUplevelValue()) {
0356:                    // loc$x and this$C are never null
0357:                    return !name.toString().startsWith(prefixVal);
0358:                }
0359:                return false;
0360:            }
0361:
0362:            /**
0363:             * Get the field's final value (may return null)
0364:             */
0365:            public Node getValue(Environment env) throws ClassNotFound {
0366:                return value;
0367:            }
0368:
0369:            public final Node getValue() {
0370:                return value;
0371:            }
0372:
0373:            public final void setValue(Node value) {
0374:                this .value = value;
0375:            }
0376:
0377:            public Object getInitialValue() {
0378:                return null;
0379:            }
0380:
0381:            /**
0382:             * Get the next field or the next match
0383:             */
0384:            public final MemberDefinition getNextMember() {
0385:                return nextMember;
0386:            }
0387:
0388:            public final MemberDefinition getNextMatch() {
0389:                return nextMatch;
0390:            }
0391:
0392:            /**
0393:             * Get the field's documentation
0394:             */
0395:            public String getDocumentation() {
0396:                return documentation;
0397:            }
0398:
0399:            /**
0400:             * Request a check of the field definition.
0401:             */
0402:            public void check(Environment env) throws ClassNotFound {
0403:            }
0404:
0405:            /**
0406:             * Really check the field definition.
0407:             */
0408:            public Vset check(Environment env, Context ctx, Vset vset)
0409:                    throws ClassNotFound {
0410:                return vset;
0411:            }
0412:
0413:            /**
0414:             * Generate code
0415:             */
0416:            public void code(Environment env, Assembler asm)
0417:                    throws ClassNotFound {
0418:                throw new CompilerError("code");
0419:            }
0420:
0421:            public void codeInit(Environment env, Context ctx, Assembler asm)
0422:                    throws ClassNotFound {
0423:                throw new CompilerError("codeInit");
0424:            }
0425:
0426:            /**
0427:             * Tells whether to report a deprecation error for this field.
0428:             */
0429:            public boolean reportDeprecated(Environment env) {
0430:                return (isDeprecated() || clazz.reportDeprecated(env));
0431:            }
0432:
0433:            /**
0434:             * Check if a field can reach another field (only considers
0435:             * forward references, not the access modifiers).
0436:             */
0437:            public final boolean canReach(Environment env, MemberDefinition f) {
0438:                if (f.isLocal() || !f.isVariable()
0439:                        || !(isVariable() || isInitializer()))
0440:                    return true;
0441:                if ((getClassDeclaration().equals(f.getClassDeclaration()))
0442:                        && (isStatic() == f.isStatic())) {
0443:                    // They are located in the same class, and are either both
0444:                    // static or both non-static.  Check the initialization order.
0445:                    while (((f = f.getNextMember()) != null) && (f != this ))
0446:                        ;
0447:                    return f != null;
0448:                }
0449:                return true;
0450:            }
0451:
0452:            //-----------------------------------------------------------------
0453:            // The code in this section is intended to test certain kinds of
0454:            // compatibility between methods.  There are two kinds of compatibility
0455:            // that the compiler may need to test.  The first is whether one
0456:            // method can legally override another.  The second is whether two
0457:            // method definitions can legally coexist.  We use the word `meet'
0458:            // to mean the intersection of two legally coexisting methods.
0459:            // For more information on these kinds of compatibility, see the
0460:            // comments/code for checkOverride() and checkMeet() below.
0461:
0462:            /**
0463:             * Constants used by getAccessLevel() to represent the access
0464:             * modifiers as numbers.
0465:             */
0466:            static final int PUBLIC_ACCESS = 1;
0467:            static final int PROTECTED_ACCESS = 2;
0468:            static final int PACKAGE_ACCESS = 3;
0469:            static final int PRIVATE_ACCESS = 4;
0470:
0471:            /**
0472:             * Return the access modifier of this member as a number.  The idea
0473:             * is that this number may be used to check properties like "the
0474:             * access modifier of x is more restrictive than the access
0475:             * modifier of y" with a simple inequality test:
0476:             * "x.getAccessLevel() > y.getAccessLevel.
0477:             *
0478:             * This is an internal utility method.
0479:             */
0480:            private int getAccessLevel() {
0481:                // Could just compute this once instead of recomputing.
0482:                // Check to see if this is worth it.
0483:                if (isPublic()) {
0484:                    return PUBLIC_ACCESS;
0485:                } else if (isProtected()) {
0486:                    return PROTECTED_ACCESS;
0487:                } else if (isPackagePrivate()) {
0488:                    return PACKAGE_ACCESS;
0489:                } else if (isPrivate()) {
0490:                    return PRIVATE_ACCESS;
0491:                } else {
0492:                    throw new CompilerError("getAccessLevel()");
0493:                }
0494:            }
0495:
0496:            /**
0497:             * Munge our error message to report whether the override conflict
0498:             * came from an inherited method or a declared method.
0499:             */
0500:            private void reportError(Environment env, String errorString,
0501:                    ClassDeclaration clazz, MemberDefinition method) {
0502:
0503:                if (clazz == null) {
0504:                    // For example:
0505:                    // "Instance method BLAH inherited from CLASSBLAH1 cannot be
0506:                    //  overridden by the static method declared in CLASSBLAH2."
0507:                    env
0508:                            .error(getWhere(), errorString, this ,
0509:                                    getClassDeclaration(), method
0510:                                            .getClassDeclaration());
0511:                } else {
0512:                    // For example:
0513:                    // "In CLASSBLAH1, instance method BLAH inherited from CLASSBLAH2
0514:                    //  cannot be overridden by the static method inherited from
0515:                    //  CLASSBLAH3."
0516:                    env.error(clazz.getClassDefinition().getWhere(),
0517:                    //"inherit." + errorString,
0518:                            errorString,
0519:                            //clazz,
0520:                            this , getClassDeclaration(), method
0521:                                    .getClassDeclaration());
0522:                }
0523:            }
0524:
0525:            /**
0526:             * Convenience method to see if two methods return the same type
0527:             */
0528:            public boolean sameReturnType(MemberDefinition method) {
0529:                // Make sure both are methods.
0530:                if (!isMethod() || !method.isMethod()) {
0531:                    throw new CompilerError("sameReturnType: not method");
0532:                }
0533:
0534:                Type myReturnType = getType().getReturnType();
0535:                Type yourReturnType = method.getType().getReturnType();
0536:
0537:                return (myReturnType == yourReturnType);
0538:            }
0539:
0540:            /**
0541:             * Check to see if `this' can override/hide `method'.  Caller is
0542:             * responsible for verifying that `method' has the same signature
0543:             * as `this'.  Caller is also responsible for verifying that
0544:             * `method' is visible to the class where this override is occurring.
0545:             * This method is called for the case when class B extends A and both
0546:             * A and B define some method.
0547:             * <pre>
0548:             *       A - void foo() throws e1
0549:             *       |
0550:             *       |
0551:             *       B - void foo() throws e2
0552:             * </pre>
0553:             */
0554:            public boolean checkOverride(Environment env,
0555:                    MemberDefinition method) {
0556:                return checkOverride(env, method, null);
0557:            }
0558:
0559:            /**
0560:             * Checks whether `this' can override `method'.  It `clazz' is
0561:             * null, it reports the errors in the class where `this' is
0562:             * declared.  If `clazz' is not null, it reports the error in `clazz'.
0563:             */
0564:            private boolean checkOverride(Environment env,
0565:                    MemberDefinition method, ClassDeclaration clazz) {
0566:                // This section of code is largely based on section 8.4.6.3
0567:                // of the JLS.
0568:
0569:                boolean success = true;
0570:
0571:                // Sanity
0572:                if (!isMethod()) {
0573:                    throw new CompilerError("checkOverride(), expected method");
0574:                }
0575:
0576:                // Suppress checks for synthetic methods, as the compiler presumably
0577:                // knows what it is doing, e.g., access methods.
0578:                if (isSynthetic()) {
0579:                    // Sanity check: We generally do not intend for one synthetic
0580:                    // method to override another, though hiding of static members
0581:                    // is expected.  This check may need to be changed if new uses
0582:                    // of synthetic methods are devised.
0583:                    //
0584:                    // Query: this code was copied from elsewhere.  What
0585:                    // exactly is the role of the !isStatic() in the test?
0586:                    if (method.isFinal()
0587:                            || (!method.isConstructor() && !method.isStatic() && !isStatic())) {
0588:                        ////////////////////////////////////////////////////////////
0589:                        // NMG 2003-01-28 removed the following test because it is
0590:                        // invalidated by bridge methods inserted by the "generic"
0591:                        // (1.5) Java compiler.  In 1.5, this code is used,
0592:                        // indirectly, by rmic
0593:                        ////////////////////////////////////////////////////////////
0594:                        // throw new CompilerError("checkOverride() synthetic");
0595:                        ////////////////////////////////////////////////////////////
0596:                    }
0597:
0598:                    // We trust the compiler.  (Ha!)  We're done checking.
0599:                    return true;
0600:                }
0601:
0602:                // Our caller should have verified that the method had the
0603:                // same signature.
0604:                if (getName() != method.getName()
0605:                        || !getType().equalArguments(method.getType())) {
0606:
0607:                    throw new CompilerError(
0608:                            "checkOverride(), signature mismatch");
0609:                }
0610:
0611:                // It is forbidden to `override' a static method with an instance
0612:                // method.
0613:                if (method.isStatic() && !isStatic()) {
0614:                    reportError(env, "override.static.with.instance", clazz,
0615:                            method);
0616:                    success = false;
0617:                }
0618:
0619:                // It is forbidden to `hide' an instance method with a static
0620:                // method.
0621:                if (!method.isStatic() && isStatic()) {
0622:                    reportError(env, "hide.instance.with.static", clazz, method);
0623:                    success = false;
0624:                }
0625:
0626:                // We cannot override a final method.
0627:                if (method.isFinal()) {
0628:                    reportError(env, "override.final.method", clazz, method);
0629:                    success = false;
0630:                }
0631:
0632:                // Give a warning when we override a deprecated method with
0633:                // a non-deprecated one.
0634:                //
0635:                // We bend over backwards to suppress this warning if
0636:                // the `method' has not been already compiled or
0637:                // `this' has been already compiled.
0638:                if (method.reportDeprecated(env) && !isDeprecated()
0639:                        && this  instanceof  sun.tools.javac.SourceMember) {
0640:                    reportError(env, "warn.override.is.deprecated", clazz,
0641:                            method);
0642:                }
0643:
0644:                // Visibility may not be more restrictive
0645:                if (getAccessLevel() > method.getAccessLevel()) {
0646:                    reportError(env, "override.more.restrictive", clazz, method);
0647:                    success = false;
0648:                }
0649:
0650:                // Return type equality
0651:                if (!sameReturnType(method)) {
0652:                    ////////////////////////////////////////////////////////////
0653:                    // PCJ 2003-07-30 removed the following error because it is
0654:                    // invalidated by the covariant return type feature of the
0655:                    // 1.5 compiler.  The resulting check is now much looser
0656:                    // than the actual 1.5 language spec, but that should be OK
0657:                    // because this code is only still used by rmic.  See 4892308.
0658:                    ////////////////////////////////////////////////////////////
0659:                    // reportError(env, "override.different.return", clazz, method);
0660:                    // success = false;
0661:                    ////////////////////////////////////////////////////////////
0662:                }
0663:
0664:                // Exception agreeement
0665:                if (!exceptionsFit(env, method)) {
0666:                    reportError(env, "override.incompatible.exceptions", clazz,
0667:                            method);
0668:                    success = false;
0669:                }
0670:
0671:                return success;
0672:            }
0673:
0674:            /**
0675:             * Check to see if two method definitions are compatible, that is
0676:             * do they have a `meet'.  The meet of two methods is essentially
0677:             * and `intersection' of
0678:             * two methods.  This method is called when some class C inherits
0679:             * declarations for some method foo from two parents (superclass,
0680:             * interfaces) but it does not, itself, have a declaration of foo.
0681:             * Caller is responsible for making sure that both methods are
0682:             * indeed visible in clazz.
0683:             * <pre>
0684:             *     A - void foo() throws e1
0685:             *      \
0686:             *       \     B void foo() throws e2
0687:             *        \   /
0688:             *         \ /
0689:             *          C
0690:             * </pre>
0691:             */
0692:            public boolean checkMeet(Environment env, MemberDefinition method,
0693:                    ClassDeclaration clazz) {
0694:                // This section of code is largely based on Section 8.4.6
0695:                // and 9.4.1 of the JLS.
0696:
0697:                // Sanity
0698:                if (!isMethod()) {
0699:                    throw new CompilerError("checkMeet(), expected method");
0700:                }
0701:
0702:                // Check for both non-abstract.
0703:                if (!isAbstract() && !method.isAbstract()) {
0704:                    throw new CompilerError("checkMeet(), no abstract method");
0705:                }
0706:
0707:                // If either method is non-abstract, then we need to check that
0708:                // the abstract method can be properly overridden.  We call
0709:                // the checkOverride method to check this and generate any errors.
0710:                // This test must follow the previous test.
0711:                else if (!isAbstract()) {
0712:                    return checkOverride(env, method, clazz);
0713:                } else if (!method.isAbstract()) {
0714:                    return method.checkOverride(env, this , clazz);
0715:                }
0716:
0717:                // Both methods are abstract.
0718:
0719:                // Our caller should have verified that the method has the
0720:                // same signature.
0721:                if (getName() != method.getName()
0722:                        || !getType().equalArguments(method.getType())) {
0723:
0724:                    throw new CompilerError("checkMeet(), signature mismatch");
0725:                }
0726:
0727:                // Check for return type equality
0728:                if (!sameReturnType(method)) {
0729:                    // More args?
0730:                    env.error(clazz.getClassDefinition().getWhere(),
0731:                            "meet.different.return", this , this 
0732:                                    .getClassDeclaration(), method
0733:                                    .getClassDeclaration());
0734:                    return false;
0735:                }
0736:
0737:                // We don't have to check visibility -- there always
0738:                // potentially exists a meet.  Similarly with exceptions.
0739:
0740:                // There does exist a meet.
0741:                return true;
0742:            }
0743:
0744:            /**
0745:             * This method is meant to be used to determine if one of two inherited
0746:             * methods could override the other.  Unlike checkOverride(), failure
0747:             * is not an error.  This method is only meant to be called after
0748:             * checkMeet() has succeeded on the two methods.
0749:             *
0750:             * If you call couldOverride() without doing a checkMeet() first, then
0751:             * you are on your own.
0752:             */
0753:            public boolean couldOverride(Environment env,
0754:                    MemberDefinition method) {
0755:
0756:                // Sanity
0757:                if (!isMethod()) {
0758:                    throw new CompilerError("coulcOverride(), expected method");
0759:                }
0760:
0761:                // couldOverride() is only called with `this' and `method' both
0762:                // being inherited methods.  Neither of them is defined in the
0763:                // class which we are currently working on.  Even though an
0764:                // abstract method defined *in* a class can override a non-abstract
0765:                // method defined in a superclass, an abstract method inherited
0766:                // from an interface *never* can override a non-abstract method.
0767:                // This comment may sound odd, but that's the way inheritance is.
0768:                // The following check makes sure we aren't trying to override
0769:                // an inherited non-abstract definition with an abstract definition
0770:                // from an interface.
0771:                if (!method.isAbstract()) {
0772:                    return false;
0773:                }
0774:
0775:                // Visibility should be less restrictive
0776:                if (getAccessLevel() > method.getAccessLevel()) {
0777:                    return false;
0778:                }
0779:
0780:                // Exceptions
0781:                if (!exceptionsFit(env, method)) {
0782:                    return false;
0783:                }
0784:
0785:                // Potentially some deprecation warnings could be given here
0786:                // when we merge two abstract methods, one of which is deprecated.
0787:                // This is not currently reported.
0788:
0789:                return true;
0790:            }
0791:
0792:            /**
0793:             * Check to see if the exceptions of `this' fit within the
0794:             * exceptions of `method'.
0795:             */
0796:            private boolean exceptionsFit(Environment env,
0797:                    MemberDefinition method) {
0798:                ClassDeclaration e1[] = getExceptions(env); // my exceptions
0799:                ClassDeclaration e2[] = method.getExceptions(env); // parent's
0800:
0801:                // This code is taken nearly verbatim from the old implementation
0802:                // of checkOverride() in SourceClass.
0803:                outer: for (int i = 0; i < e1.length; i++) {
0804:                    try {
0805:                        ClassDefinition c1 = e1[i].getClassDefinition(env);
0806:                        for (int j = 0; j < e2.length; j++) {
0807:                            if (c1.subClassOf(env, e2[j])) {
0808:                                continue outer;
0809:                            }
0810:                        }
0811:                        if (c1.subClassOf(env, env
0812:                                .getClassDeclaration(idJavaLangError)))
0813:                            continue outer;
0814:                        if (c1
0815:                                .subClassOf(
0816:                                        env,
0817:                                        env
0818:                                                .getClassDeclaration(idJavaLangRuntimeException)))
0819:                            continue outer;
0820:
0821:                        // the throws was neither something declared by a parent,
0822:                        // nor one of the ignorables.
0823:                        return false;
0824:
0825:                    } catch (ClassNotFound ee) {
0826:                        // We were unable to find one of the exceptions.
0827:                        env.error(getWhere(), "class.not.found", ee.name,
0828:                                method.getClassDeclaration());
0829:                    }
0830:                }
0831:
0832:                // All of the exceptions `fit'.
0833:                return true;
0834:            }
0835:
0836:            //-----------------------------------------------------------------
0837:
0838:            /**
0839:             * Checks
0840:             */
0841:            public final boolean isPublic() {
0842:                return (modifiers & M_PUBLIC) != 0;
0843:            }
0844:
0845:            public final boolean isPrivate() {
0846:                return (modifiers & M_PRIVATE) != 0;
0847:            }
0848:
0849:            public final boolean isProtected() {
0850:                return (modifiers & M_PROTECTED) != 0;
0851:            }
0852:
0853:            public final boolean isPackagePrivate() {
0854:                return (modifiers & (M_PUBLIC | M_PRIVATE | M_PROTECTED)) == 0;
0855:            }
0856:
0857:            public final boolean isFinal() {
0858:                return (modifiers & M_FINAL) != 0;
0859:            }
0860:
0861:            public final boolean isStatic() {
0862:                return (modifiers & M_STATIC) != 0;
0863:            }
0864:
0865:            public final boolean isSynchronized() {
0866:                return (modifiers & M_SYNCHRONIZED) != 0;
0867:            }
0868:
0869:            public final boolean isAbstract() {
0870:                return (modifiers & M_ABSTRACT) != 0;
0871:            }
0872:
0873:            public final boolean isNative() {
0874:                return (modifiers & M_NATIVE) != 0;
0875:            }
0876:
0877:            public final boolean isVolatile() {
0878:                return (modifiers & M_VOLATILE) != 0;
0879:            }
0880:
0881:            public final boolean isTransient() {
0882:                return (modifiers & M_TRANSIENT) != 0;
0883:            }
0884:
0885:            public final boolean isMethod() {
0886:                return type.isType(TC_METHOD);
0887:            }
0888:
0889:            public final boolean isVariable() {
0890:                return !type.isType(TC_METHOD) && innerClass == null;
0891:            }
0892:
0893:            public final boolean isSynthetic() {
0894:                return (modifiers & M_SYNTHETIC) != 0;
0895:            }
0896:
0897:            public final boolean isDeprecated() {
0898:                return (modifiers & M_DEPRECATED) != 0;
0899:            }
0900:
0901:            public final boolean isStrict() {
0902:                return (modifiers & M_STRICTFP) != 0;
0903:            }
0904:
0905:            public final boolean isInnerClass() {
0906:                return innerClass != null;
0907:            }
0908:
0909:            public final boolean isInitializer() {
0910:                return getName().equals(idClassInit);
0911:            }
0912:
0913:            public final boolean isConstructor() {
0914:                return getName().equals(idInit);
0915:            }
0916:
0917:            public boolean isLocal() {
0918:                return false;
0919:            }
0920:
0921:            public boolean isInlineable(Environment env, boolean fromFinal)
0922:                    throws ClassNotFound {
0923:                return (isStatic() || isPrivate() || isFinal()
0924:                        || isConstructor() || fromFinal)
0925:                        && !(isSynchronized() || isNative());
0926:            }
0927:
0928:            /**
0929:             * Check if constant:  Will it inline away to a constant?
0930:             */
0931:            public boolean isConstant() {
0932:                if (isFinal() && isVariable() && value != null) {
0933:                    try {
0934:                        // If an infinite regress requeries this name,
0935:                        // deny that it is a constant.
0936:                        modifiers &= ~M_FINAL;
0937:                        return ((Expression) value).isConstant();
0938:                    } finally {
0939:                        modifiers |= M_FINAL;
0940:                    }
0941:                }
0942:                return false;
0943:            }
0944:
0945:            /**
0946:             * toString
0947:             */
0948:            public String toString() {
0949:                Identifier name = getClassDefinition().getName();
0950:                if (isInitializer()) {
0951:                    return isStatic() ? "static {}" : "instance {}";
0952:                } else if (isConstructor()) {
0953:                    StringBuffer buf = new StringBuffer();
0954:                    buf.append(name);
0955:                    buf.append('(');
0956:                    Type argTypes[] = getType().getArgumentTypes();
0957:                    for (int i = 0; i < argTypes.length; i++) {
0958:                        if (i > 0) {
0959:                            buf.append(',');
0960:                        }
0961:                        buf.append(argTypes[i].toString());
0962:                    }
0963:                    buf.append(')');
0964:                    return buf.toString();
0965:                } else if (isInnerClass()) {
0966:                    return getInnerClass().toString();
0967:                }
0968:                return type.typeString(getName().toString());
0969:            }
0970:
0971:            /**
0972:             * Print for debugging
0973:             */
0974:            public void print(PrintStream out) {
0975:                if (isPublic()) {
0976:                    out.print("public ");
0977:                }
0978:                if (isPrivate()) {
0979:                    out.print("private ");
0980:                }
0981:                if (isProtected()) {
0982:                    out.print("protected ");
0983:                }
0984:                if (isFinal()) {
0985:                    out.print("final ");
0986:                }
0987:                if (isStatic()) {
0988:                    out.print("static ");
0989:                }
0990:                if (isSynchronized()) {
0991:                    out.print("synchronized ");
0992:                }
0993:                if (isAbstract()) {
0994:                    out.print("abstract ");
0995:                }
0996:                if (isNative()) {
0997:                    out.print("native ");
0998:                }
0999:                if (isVolatile()) {
1000:                    out.print("volatile ");
1001:                }
1002:                if (isTransient()) {
1003:                    out.print("transient ");
1004:                }
1005:                out.println(toString() + ";");
1006:            }
1007:
1008:            public void cleanup(Environment env) {
1009:                documentation = null;
1010:                if (isMethod() && value != null) {
1011:                    int cost = 0;
1012:                    if (isPrivate() || isInitializer()) {
1013:                        value = Statement.empty;
1014:                    } else if ((cost = ((Statement) value).costInline(
1015:                            Statement.MAXINLINECOST, null, null)) >= Statement.MAXINLINECOST) {
1016:                        // will never be inlined
1017:                        value = Statement.empty;
1018:                    } else {
1019:                        try {
1020:                            if (!isInlineable(null, true)) {
1021:                                value = Statement.empty;
1022:                            }
1023:                        } catch (ClassNotFound ee) {
1024:                        }
1025:                    }
1026:                    if (value != Statement.empty && env.dump()) {
1027:                        env.output("[after cleanup of " + getName() + ", "
1028:                                + cost + " expression cost units remain]");
1029:                    }
1030:                } else if (isVariable()) {
1031:                    if (isPrivate() || !isFinal() || type.isType(TC_ARRAY)) {
1032:                        value = null;
1033:                    }
1034:                }
1035:            }
1036:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.