Source Code Cross Referenced for ClassDefinition.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 java.util.*;
0029:        import java.io.OutputStream;
0030:        import java.io.PrintStream;
0031:        import sun.tools.tree.Context;
0032:        import sun.tools.tree.Vset;
0033:        import sun.tools.tree.Expression;
0034:        import sun.tools.tree.LocalMember;
0035:        import sun.tools.tree.UplevelReference;
0036:
0037:        /**
0038:         * This class is a Java class definition
0039:         *
0040:         * WARNING: The contents of this source file are not part of any
0041:         * supported API.  Code that depends on them does so at its own risk:
0042:         * they are subject to change or removal without notice.
0043:         */
0044:        public class ClassDefinition implements  Constants {
0045:
0046:            protected Object source;
0047:            protected long where;
0048:            protected int modifiers;
0049:            protected Identifier localName; // for local classes
0050:            protected ClassDeclaration declaration;
0051:            protected IdentifierToken super ClassId;
0052:            protected IdentifierToken interfaceIds[];
0053:            protected ClassDeclaration super Class;
0054:            protected ClassDeclaration interfaces[];
0055:            protected ClassDefinition outerClass;
0056:            protected MemberDefinition outerMember;
0057:            protected MemberDefinition innerClassMember; // field for me in outerClass
0058:            protected MemberDefinition firstMember;
0059:            protected MemberDefinition lastMember;
0060:            protected boolean resolved;
0061:            protected String documentation;
0062:            protected boolean error;
0063:            protected boolean nestError;
0064:            protected UplevelReference references;
0065:            protected boolean referencesFrozen;
0066:            private Hashtable fieldHash = new Hashtable(31);
0067:            private int abstr;
0068:
0069:            // Table of local and anonymous classes whose internal names are constructed
0070:            // using the current class as a prefix.  This is part of a fix for
0071:            // bugid 4054523 and 4030421.  See also 'Environment.getClassDefinition'
0072:            // and 'BatchEnvironment.makeClassDefinition'.  Allocated on demand.
0073:            private Hashtable localClasses = null;
0074:            private final int LOCAL_CLASSES_SIZE = 31;
0075:
0076:            // The immediately surrounding context in which the class appears.
0077:            // Set at the beginning of checking, upon entry to 'SourceClass.checkInternal'.
0078:            // Null for classes that are not local or inside a local class.
0079:            // At present, this field exists only for the benefit of 'resolveName' as part
0080:            // of the fix for 4095716.
0081:            protected Context classContext;
0082:
0083:            // The saved class context is now also used in 'SourceClass.getAccessMember'.
0084:            // Provide read-only access via this method.  Part of fix for 4098093.
0085:            public Context getClassContext() {
0086:                return classContext;
0087:            }
0088:
0089:            /**
0090:             * Constructor
0091:             */
0092:            protected ClassDefinition(Object source, long where,
0093:                    ClassDeclaration declaration, int modifiers,
0094:                    IdentifierToken super Class, IdentifierToken interfaces[]) {
0095:                this .source = source;
0096:                this .where = where;
0097:                this .declaration = declaration;
0098:                this .modifiers = modifiers;
0099:                this .super ClassId = super Class;
0100:                this .interfaceIds = interfaces;
0101:            }
0102:
0103:            /**
0104:             * Get the source of the class
0105:             */
0106:            public final Object getSource() {
0107:                return source;
0108:            }
0109:
0110:            /**
0111:             * Check if there were any errors in this class.
0112:             */
0113:            public final boolean getError() {
0114:                return error;
0115:            }
0116:
0117:            /**
0118:             * Mark this class to be erroneous.
0119:             */
0120:            public final void setError() {
0121:                this .error = true;
0122:                setNestError();
0123:            }
0124:
0125:            /**
0126:             * Check if there were any errors in our class nest.
0127:             */
0128:            public final boolean getNestError() {
0129:                // Check to see if our error value is set, or if any of our
0130:                // outer classes' error values are set.  This will work in
0131:                // conjunction with setError(), which sets the error value
0132:                // of its outer class, to yield true is any of our nest
0133:                // siblings has an error.  This addresses bug 4111488: either
0134:                // code should be generated for all classes in a nest, or
0135:                // none of them.
0136:                return nestError
0137:                        || ((outerClass != null) ? outerClass.getNestError()
0138:                                : false);
0139:            }
0140:
0141:            /**
0142:             * Mark this class, and all siblings in its class nest, to be
0143:             * erroneous.
0144:             */
0145:            public final void setNestError() {
0146:                this .nestError = true;
0147:                if (outerClass != null) {
0148:                    // If we have an outer class, set it to be erroneous as well.
0149:                    // This will work in conjunction with getError(), which checks
0150:                    // the error value of its outer class, to set the whole class
0151:                    // nest to be erroneous.  This address bug 4111488: either
0152:                    // code should be generated for all classes in a nest, or
0153:                    // none of them.
0154:                    outerClass.setNestError();
0155:                }
0156:            }
0157:
0158:            /**
0159:             * Get the position in the input
0160:             */
0161:            public final long getWhere() {
0162:                return where;
0163:            }
0164:
0165:            /**
0166:             * Get the class declaration
0167:             */
0168:            public final ClassDeclaration getClassDeclaration() {
0169:                return declaration;
0170:            }
0171:
0172:            /**
0173:             * Get the class' modifiers
0174:             */
0175:            public final int getModifiers() {
0176:                return modifiers;
0177:            }
0178:
0179:            public final void subModifiers(int mod) {
0180:                modifiers &= ~mod;
0181:            }
0182:
0183:            public final void addModifiers(int mod) {
0184:                modifiers |= mod;
0185:            }
0186:
0187:            // *** DEBUG ***
0188:            protected boolean super sCheckStarted = !(this  instanceof  sun.tools.javac.SourceClass);
0189:
0190:            /**
0191:             * Get the class' super class
0192:             */
0193:            public final ClassDeclaration getSuperClass() {
0194:                /*---
0195:                if (superClass == null && superClassId != null)
0196:                    throw new CompilerError("getSuperClass "+superClassId);
0197:                // There are obscure cases where null is the right answer,
0198:                // in order to enable some error reporting later on.
0199:                // For example:  class T extends T.N { class N { } }
0200:                ---*/
0201:
0202:                // *** DEBUG ***
0203:                // This method should not be called if the superclass has not been resolved.
0204:                if (!super sCheckStarted)
0205:                    throw new CompilerError("unresolved super");
0206:
0207:                return super Class;
0208:            }
0209:
0210:            /**
0211:             * Get the super class, and resolve names now if necessary.
0212:             *
0213:             * It is only possible to resolve names at this point if we are
0214:             * a source class.  The provision of this method at this level
0215:             * in the class hierarchy is dubious, but see 'getInnerClass' below.
0216:             * All other calls to 'getSuperClass(env)' appear in 'SourceClass'.
0217:             * NOTE: An older definition of this method has been moved to
0218:             * 'SourceClass', where it overrides this one.
0219:             *
0220:             * @see #resolveTypeStructure
0221:             */
0222:
0223:            public ClassDeclaration getSuperClass(Environment env) {
0224:                return getSuperClass();
0225:            }
0226:
0227:            /**
0228:             * Get the class' interfaces
0229:             */
0230:            public final ClassDeclaration getInterfaces()[] {
0231:                if (interfaces == null)
0232:                    throw new CompilerError("getInterfaces");
0233:                return interfaces;
0234:            }
0235:
0236:            /**
0237:             * Get the class' enclosing class (or null if not inner)
0238:             */
0239:            public final ClassDefinition getOuterClass() {
0240:                return outerClass;
0241:            }
0242:
0243:            /**
0244:             * Set the class' enclosing class.  Must be done at most once.
0245:             */
0246:            protected final void setOuterClass(ClassDefinition outerClass) {
0247:                if (this .outerClass != null)
0248:                    throw new CompilerError("setOuterClass");
0249:                this .outerClass = outerClass;
0250:            }
0251:
0252:            /**
0253:             * Set the class' enclosing current instance pointer.
0254:             * Must be done at most once.
0255:             */
0256:            protected final void setOuterMember(MemberDefinition outerMember) {
0257:
0258:                if (isStatic() || !isInnerClass())
0259:                    throw new CompilerError("setOuterField");
0260:                if (this .outerMember != null)
0261:                    throw new CompilerError("setOuterField");
0262:                this .outerMember = outerMember;
0263:            }
0264:
0265:            /**
0266:             * Tell if the class is inner.
0267:             * This predicate also returns true for top-level nested types.
0268:             * To test for a true inner class as seen by the programmer,
0269:             * use <tt>!isTopLevel()</tt>.
0270:             */
0271:            public final boolean isInnerClass() {
0272:                return outerClass != null;
0273:            }
0274:
0275:            /**
0276:             * Tell if the class is a member of another class.
0277:             * This is false for package members and for block-local classes.
0278:             */
0279:            public final boolean isMember() {
0280:                return outerClass != null && !isLocal();
0281:            }
0282:
0283:            /**
0284:             * Tell if the class is "top-level", which is either a package member,
0285:             * or a static member of another top-level class.
0286:             */
0287:            public final boolean isTopLevel() {
0288:                return outerClass == null || isStatic() || isInterface();
0289:            }
0290:
0291:            /**
0292:             * Tell if the class is local or inside a local class,
0293:             * which means it cannot be mentioned outside of its file.
0294:             */
0295:
0296:            // The comment above is true only because M_LOCAL is set
0297:            // whenever M_ANONYMOUS is.  I think it is risky to assume that
0298:            // isAnonymous(x) => isLocal(x).
0299:            public final boolean isInsideLocal() {
0300:                return isLocal()
0301:                        || (outerClass != null && outerClass.isInsideLocal());
0302:            }
0303:
0304:            /**
0305:             * Tell if the class is local or or anonymous class, or inside
0306:             * such a class, which means it cannot be mentioned outside of
0307:             * its file.
0308:             */
0309:            public final boolean isInsideLocalOrAnonymous() {
0310:                return isLocal()
0311:                        || isAnonymous()
0312:                        || (outerClass != null && outerClass
0313:                                .isInsideLocalOrAnonymous());
0314:            }
0315:
0316:            /**
0317:             * Return a simple identifier for this class (idNull if anonymous).
0318:             */
0319:            public Identifier getLocalName() {
0320:                if (localName != null) {
0321:                    return localName;
0322:                }
0323:                // This is also the name of the innerClassMember, if any:
0324:                return getName().getFlatName().getName();
0325:            }
0326:
0327:            /**
0328:             * Set the local name of a class.  Must be a local class.
0329:             */
0330:            public void setLocalName(Identifier name) {
0331:                if (isLocal()) {
0332:                    localName = name;
0333:                }
0334:            }
0335:
0336:            /**
0337:             * If inner, get the field for this class in the enclosing class
0338:             */
0339:            public final MemberDefinition getInnerClassMember() {
0340:                if (outerClass == null)
0341:                    return null;
0342:                if (innerClassMember == null) {
0343:                    // We must find the field in the outer class.
0344:                    Identifier nm = getName().getFlatName().getName();
0345:                    for (MemberDefinition field = outerClass.getFirstMatch(nm); field != null; field = field
0346:                            .getNextMatch()) {
0347:                        if (field.isInnerClass()) {
0348:                            innerClassMember = field;
0349:                            break;
0350:                        }
0351:                    }
0352:                    if (innerClassMember == null)
0353:                        throw new CompilerError("getInnerClassField");
0354:                }
0355:                return innerClassMember;
0356:            }
0357:
0358:            /**
0359:             * If inner, return an innermost uplevel self pointer, if any exists.
0360:             * Otherwise, return null.
0361:             */
0362:            public final MemberDefinition findOuterMember() {
0363:                return outerMember;
0364:            }
0365:
0366:            /**
0367:             * See if this is a (nested) static class.
0368:             */
0369:            public final boolean isStatic() {
0370:                return (modifiers & ACC_STATIC) != 0;
0371:            }
0372:
0373:            /**
0374:             * Get the class' top-level enclosing class
0375:             */
0376:            public final ClassDefinition getTopClass() {
0377:                ClassDefinition p, q;
0378:                for (p = this ; (q = p.outerClass) != null; p = q)
0379:                    ;
0380:                return p;
0381:            }
0382:
0383:            /**
0384:             * Get the class' first field or first match
0385:             */
0386:            public final MemberDefinition getFirstMember() {
0387:                return firstMember;
0388:            }
0389:
0390:            public final MemberDefinition getFirstMatch(Identifier name) {
0391:                return (MemberDefinition) fieldHash.get(name);
0392:            }
0393:
0394:            /**
0395:             * Get the class' name
0396:             */
0397:            public final Identifier getName() {
0398:                return declaration.getName();
0399:            }
0400:
0401:            /**
0402:             * Get the class' type
0403:             */
0404:            public final Type getType() {
0405:                return declaration.getType();
0406:            }
0407:
0408:            /**
0409:             * Get the class' documentation
0410:             */
0411:            public String getDocumentation() {
0412:                return documentation;
0413:            }
0414:
0415:            /**
0416:             * Return true if the given documentation string contains a deprecation
0417:             * paragraph.  This is true if the string contains the tag @deprecated
0418:             * is the first word in a line.
0419:             */
0420:            public static boolean containsDeprecated(String documentation) {
0421:                if (documentation == null) {
0422:                    return false;
0423:                }
0424:                doScan: for (int scan = 0; (scan = documentation.indexOf(
0425:                        paraDeprecated, scan)) >= 0; scan += paraDeprecated
0426:                        .length()) {
0427:                    // make sure there is only whitespace between this word
0428:                    // and the beginning of the line
0429:                    for (int beg = scan - 1; beg >= 0; beg--) {
0430:                        char ch = documentation.charAt(beg);
0431:                        if (ch == '\n' || ch == '\r') {
0432:                            break; // OK
0433:                        }
0434:                        if (!Character.isSpace(ch)) {
0435:                            continue doScan;
0436:                        }
0437:                    }
0438:                    // make sure the char after the word is space or end of line
0439:                    int end = scan + paraDeprecated.length();
0440:                    if (end < documentation.length()) {
0441:                        char ch = documentation.charAt(end);
0442:                        if (!(ch == '\n' || ch == '\r')
0443:                                && !Character.isSpace(ch)) {
0444:                            continue doScan;
0445:                        }
0446:                    }
0447:                    return true;
0448:                }
0449:                return false;
0450:            }
0451:
0452:            public final boolean inSamePackage(ClassDeclaration c) {
0453:                // find out if the class stored in c is defined in the same
0454:                // package as the current class.
0455:                return inSamePackage(c.getName().getQualifier());
0456:            }
0457:
0458:            public final boolean inSamePackage(ClassDefinition c) {
0459:                // find out if the class stored in c is defined in the same
0460:                // package as the current class.
0461:                return inSamePackage(c.getName().getQualifier());
0462:            }
0463:
0464:            public final boolean inSamePackage(Identifier packageName) {
0465:                return (getName().getQualifier().equals(packageName));
0466:            }
0467:
0468:            /**
0469:             * Checks
0470:             */
0471:            public final boolean isInterface() {
0472:                return (getModifiers() & M_INTERFACE) != 0;
0473:            }
0474:
0475:            public final boolean isClass() {
0476:                return (getModifiers() & M_INTERFACE) == 0;
0477:            }
0478:
0479:            public final boolean isPublic() {
0480:                return (getModifiers() & M_PUBLIC) != 0;
0481:            }
0482:
0483:            public final boolean isPrivate() {
0484:                return (getModifiers() & M_PRIVATE) != 0;
0485:            }
0486:
0487:            public final boolean isProtected() {
0488:                return (getModifiers() & M_PROTECTED) != 0;
0489:            }
0490:
0491:            public final boolean isPackagePrivate() {
0492:                return (modifiers & (M_PUBLIC | M_PRIVATE | M_PROTECTED)) == 0;
0493:            }
0494:
0495:            public final boolean isFinal() {
0496:                return (getModifiers() & M_FINAL) != 0;
0497:            }
0498:
0499:            public final boolean isAbstract() {
0500:                return (getModifiers() & M_ABSTRACT) != 0;
0501:            }
0502:
0503:            public final boolean isSynthetic() {
0504:                return (getModifiers() & M_SYNTHETIC) != 0;
0505:            }
0506:
0507:            public final boolean isDeprecated() {
0508:                return (getModifiers() & M_DEPRECATED) != 0;
0509:            }
0510:
0511:            public final boolean isAnonymous() {
0512:                return (getModifiers() & M_ANONYMOUS) != 0;
0513:            }
0514:
0515:            public final boolean isLocal() {
0516:                return (getModifiers() & M_LOCAL) != 0;
0517:            }
0518:
0519:            public final boolean hasConstructor() {
0520:                return getFirstMatch(idInit) != null;
0521:            }
0522:
0523:            /**
0524:             * Check to see if a class must be abstract.  This method replaces
0525:             * isAbstract(env)
0526:             */
0527:            public final boolean mustBeAbstract(Environment env) {
0528:                // If it is declared abstract, return true.
0529:                // (Fix for 4110534.)
0530:                if (isAbstract()) {
0531:                    return true;
0532:                }
0533:
0534:                // Check to see if the class should have been declared to be
0535:                // abstract.
0536:
0537:                // We make sure that the inherited method collection has been
0538:                // performed.
0539:                collectInheritedMethods(env);
0540:
0541:                // We check for any abstract methods inherited or declared
0542:                // by this class.
0543:                Iterator methods = getMethods();
0544:                while (methods.hasNext()) {
0545:                    MemberDefinition method = (MemberDefinition) methods.next();
0546:
0547:                    if (method.isAbstract()) {
0548:                        return true;
0549:                    }
0550:                }
0551:
0552:                // We check for hidden "permanently abstract" methods in
0553:                // our superclasses.
0554:                return getPermanentlyAbstractMethods().hasNext();
0555:            }
0556:
0557:            /**
0558:             * Check if this is a super class of another class
0559:             */
0560:            public boolean super ClassOf(Environment env,
0561:                    ClassDeclaration otherClass) throws ClassNotFound {
0562:                while (otherClass != null) {
0563:                    if (getClassDeclaration().equals(otherClass)) {
0564:                        return true;
0565:                    }
0566:                    otherClass = otherClass.getClassDefinition(env)
0567:                            .getSuperClass();
0568:                }
0569:                return false;
0570:            }
0571:
0572:            /**
0573:             * Check if this is an enclosing class of another class
0574:             */
0575:            public boolean enclosingClassOf(ClassDefinition otherClass) {
0576:                while ((otherClass = otherClass.getOuterClass()) != null) {
0577:                    if (this  == otherClass) {
0578:                        return true;
0579:                    }
0580:                }
0581:                return false;
0582:            }
0583:
0584:            /**
0585:             * Check if this is a sub class of another class
0586:             */
0587:            public boolean subClassOf(Environment env,
0588:                    ClassDeclaration otherClass) throws ClassNotFound {
0589:                ClassDeclaration c = getClassDeclaration();
0590:                while (c != null) {
0591:                    if (c.equals(otherClass)) {
0592:                        return true;
0593:                    }
0594:                    c = c.getClassDefinition(env).getSuperClass();
0595:                }
0596:                return false;
0597:            }
0598:
0599:            /**
0600:             * Check if this class is implemented by another class
0601:             */
0602:            public boolean implementedBy(Environment env, ClassDeclaration c)
0603:                    throws ClassNotFound {
0604:                for (; c != null; c = c.getClassDefinition(env).getSuperClass()) {
0605:                    if (getClassDeclaration().equals(c)) {
0606:                        return true;
0607:                    }
0608:                    ClassDeclaration intf[] = c.getClassDefinition(env)
0609:                            .getInterfaces();
0610:                    for (int i = 0; i < intf.length; i++) {
0611:                        if (implementedBy(env, intf[i])) {
0612:                            return true;
0613:                        }
0614:                    }
0615:                }
0616:                return false;
0617:            }
0618:
0619:            /**
0620:             * Check to see if a class which implements interface `this' could
0621:             * possibly implement the interface `intDef'.  Note that the only
0622:             * way that this can fail is if `this' and `intDef' have methods
0623:             * which are of the same signature and different return types.  This
0624:             * method is used by Environment.explicitCast() to determine if a
0625:             * cast between two interfaces is legal.
0626:             *
0627:             * This method should only be called on a class after it has been
0628:             * basicCheck()'ed.
0629:             */
0630:            public boolean couldImplement(ClassDefinition intDef) {
0631:                // Check to see if we could have done the necessary checks.
0632:                if (!doInheritanceChecks) {
0633:                    throw new CompilerError("couldImplement: no checks");
0634:                }
0635:
0636:                // This method should only be called for interfaces.
0637:                if (!isInterface() || !intDef.isInterface()) {
0638:                    throw new CompilerError("couldImplement: not interface");
0639:                }
0640:
0641:                // Make sure we are not called before we have collected our
0642:                // inheritance information.
0643:                if (allMethods == null) {
0644:                    throw new CompilerError("couldImplement: called early");
0645:                }
0646:
0647:                // Get the other classes' methods.  getMethods() in
0648:                // general can return methods which are not visible to the
0649:                // current package.  We need to make sure that these do not
0650:                // prevent this class from being implemented.
0651:                Iterator otherMethods = intDef.getMethods();
0652:
0653:                while (otherMethods.hasNext()) {
0654:                    // Get one of the methods from intDef...
0655:                    MemberDefinition method = (MemberDefinition) otherMethods
0656:                            .next();
0657:
0658:                    Identifier name = method.getName();
0659:                    Type type = method.getType();
0660:
0661:                    // See if we implement a method of the same signature...
0662:                    MemberDefinition myMethod = allMethods
0663:                            .lookupSig(name, type);
0664:
0665:                    //System.out.println("Comparing\n\t" + myMethod +
0666:                    //                   "\nand\n\t" + method);
0667:
0668:                    if (myMethod != null) {
0669:                        // We do.  Make sure the methods have the same return type.
0670:                        if (!myMethod.sameReturnType(method)) {
0671:                            return false;
0672:                        }
0673:                    }
0674:                }
0675:
0676:                return true;
0677:            }
0678:
0679:            /**
0680:             * Check if another class can be accessed from the 'extends' or 'implements'
0681:             * clause of this class.
0682:             */
0683:            public boolean extendsCanAccess(Environment env, ClassDeclaration c)
0684:                    throws ClassNotFound {
0685:
0686:                // Names in the 'extends' or 'implements' clause of an inner class
0687:                // are checked as if they appeared in the body of the surrounding class.
0688:                if (outerClass != null) {
0689:                    return outerClass.canAccess(env, c);
0690:                }
0691:
0692:                // We are a package member.
0693:
0694:                ClassDefinition cdef = c.getClassDefinition(env);
0695:
0696:                if (cdef.isLocal()) {
0697:                    // No locals should be in scope in the 'extends' or 
0698:                    // 'implements' clause of a package member.
0699:                    throw new CompilerError("top local");
0700:                }
0701:
0702:                if (cdef.isInnerClass()) {
0703:                    MemberDefinition f = cdef.getInnerClassMember();
0704:
0705:                    // Access to public member is always allowed.
0706:                    if (f.isPublic()) {
0707:                        return true;
0708:                    }
0709:
0710:                    // Private access is ok only from the same class nest.  This can
0711:                    // happen only if the class represented by 'this' encloses the inner
0712:                    // class represented by 'f'.
0713:                    if (f.isPrivate()) {
0714:                        return getClassDeclaration().equals(
0715:                                f.getTopClass().getClassDeclaration());
0716:                    }
0717:
0718:                    // Protected or default access -- allow access if in same package.
0719:                    return getName().getQualifier().equals(
0720:                            f.getClassDeclaration().getName().getQualifier());
0721:                }
0722:
0723:                // Access to public member is always allowed.
0724:                if (cdef.isPublic()) {
0725:                    return true;
0726:                }
0727:
0728:                // Default access -- allow access if in same package.
0729:                return getName().getQualifier().equals(
0730:                        c.getName().getQualifier());
0731:            }
0732:
0733:            /**
0734:             * Check if another class can be accessed from within the body of this class.
0735:             */
0736:            public boolean canAccess(Environment env, ClassDeclaration c)
0737:                    throws ClassNotFound {
0738:                ClassDefinition cdef = c.getClassDefinition(env);
0739:
0740:                if (cdef.isLocal()) {
0741:                    // if it's in scope, it's accessible
0742:                    return true;
0743:                }
0744:
0745:                if (cdef.isInnerClass()) {
0746:                    return canAccess(env, cdef.getInnerClassMember());
0747:                }
0748:
0749:                // Public access is always ok
0750:                if (cdef.isPublic()) {
0751:                    return true;
0752:                }
0753:
0754:                // It must be in the same package
0755:                return getName().getQualifier().equals(
0756:                        c.getName().getQualifier());
0757:            }
0758:
0759:            /**
0760:             * Check if a field can be accessed from a class
0761:             */
0762:
0763:            public boolean canAccess(Environment env, MemberDefinition f)
0764:                    throws ClassNotFound {
0765:
0766:                // Public access is always ok
0767:                if (f.isPublic()) {
0768:                    return true;
0769:                }
0770:                // Protected access is ok from a subclass
0771:                if (f.isProtected() && subClassOf(env, f.getClassDeclaration())) {
0772:                    return true;
0773:                }
0774:                // Private access is ok only from the same class nest
0775:                if (f.isPrivate()) {
0776:                    return getTopClass().getClassDeclaration().equals(
0777:                            f.getTopClass().getClassDeclaration());
0778:                }
0779:                // It must be in the same package
0780:                return getName().getQualifier().equals(
0781:                        f.getClassDeclaration().getName().getQualifier());
0782:            }
0783:
0784:            /**
0785:             * Check if a class is entitled to inline access to a class from 
0786:             * another class.
0787:             */
0788:            public boolean permitInlinedAccess(Environment env,
0789:                    ClassDeclaration c) throws ClassNotFound {
0790:
0791:                return (env.opt() && c.equals(declaration))
0792:                        || (env.opt_interclass() && canAccess(env, c));
0793:            }
0794:
0795:            /**
0796:             * Check if a class is entitled to inline access to a method from 
0797:             * another class.
0798:             */
0799:            public boolean permitInlinedAccess(Environment env,
0800:                    MemberDefinition f) throws ClassNotFound {
0801:                return (env.opt() && (f.clazz.getClassDeclaration()
0802:                        .equals(declaration)))
0803:                        || (env.opt_interclass() && canAccess(env, f));
0804:            }
0805:
0806:            /**
0807:             * We know the the field is marked protected (and not public) and that
0808:             * the field is visible (as per canAccess).  Can we access the field as
0809:             * <accessor>.<field>, where <accessor> has the type <accessorType>?
0810:             *
0811:             * Protected fields can only be accessed when the accessorType is a 
0812:             * subclass of the current class
0813:             */
0814:            public boolean protectedAccess(Environment env, MemberDefinition f,
0815:                    Type accessorType) throws ClassNotFound {
0816:
0817:                return
0818:                // static protected fields are accessible
0819:                f.isStatic() || // allow array.clone()
0820:                        (accessorType.isType(TC_ARRAY)
0821:                                && (f.getName() == idClone) && (f.getType()
0822:                                .getArgumentTypes().length == 0)) || // <accessorType> is a subtype of the current class
0823:                        (accessorType.isType(TC_CLASS) && env
0824:                                .getClassDefinition(accessorType.getClassName())
0825:                                .subClassOf(env, getClassDeclaration())) || // we are accessing the field from a friendly class (same package)
0826:                        (getName().getQualifier()
0827:                                .equals(f.getClassDeclaration().getName()
0828:                                        .getQualifier()));
0829:            }
0830:
0831:            /**
0832:             * Find or create an access method for a private member,
0833:             * or return null if this is not possible.
0834:             */
0835:            public MemberDefinition getAccessMember(Environment env,
0836:                    Context ctx, MemberDefinition field, boolean isSuper) {
0837:                throw new CompilerError("binary getAccessMember");
0838:            }
0839:
0840:            /**
0841:             * Find or create an update method for a private member,
0842:             * or return null if this is not possible.
0843:             */
0844:            public MemberDefinition getUpdateMember(Environment env,
0845:                    Context ctx, MemberDefinition field, boolean isSuper) {
0846:                throw new CompilerError("binary getUpdateMember");
0847:            }
0848:
0849:            /**
0850:             * Get a field from this class.  Report ambiguous fields.
0851:             * If no accessible field is found, this method may return an
0852:             * inaccessible field to allow a useful error message.
0853:             *
0854:             * getVariable now takes the source class `source' as an argument.
0855:             * This allows getVariable to check whether a field is inaccessible
0856:             * before it signals that a field is ambiguous.  The compiler used to
0857:             * signal an ambiguity even when one of the fields involved was not
0858:             * accessible.  (bug 4053724)
0859:             */
0860:            public MemberDefinition getVariable(Environment env, Identifier nm,
0861:                    ClassDefinition source) throws AmbiguousMember,
0862:                    ClassNotFound {
0863:
0864:                return getVariable0(env, nm, source, true, true);
0865:            }
0866:
0867:            /*
0868:             * private fields are never inherited.  package-private fields are
0869:             * not inherited across package boundaries.  To capture this, we
0870:             * take two booleans as parameters: showPrivate indicates whether
0871:             * we have passed a class boundary, and showPackage indicates whether
0872:             * we have crossed a package boundary.
0873:             */
0874:            private MemberDefinition getVariable0(Environment env,
0875:                    Identifier nm, ClassDefinition source, boolean showPrivate,
0876:                    boolean showPackage) throws AmbiguousMember, ClassNotFound {
0877:
0878:                // Check to see if this field is defined in the current class
0879:                for (MemberDefinition member = getFirstMatch(nm); member != null; member = member
0880:                        .getNextMatch()) {
0881:                    if (member.isVariable()) {
0882:                        if ((showPrivate || !member.isPrivate())
0883:                                && (showPackage || !member.isPackagePrivate())) {
0884:                            // It is defined in this class.
0885:                            return member;
0886:                        } else {
0887:                            // Even though this definition is not inherited,
0888:                            // it hides all definitions in supertypes.
0889:                            return null;
0890:                        }
0891:                    }
0892:                }
0893:
0894:                // Find the field in our superclass.
0895:                ClassDeclaration sup = getSuperClass();
0896:                MemberDefinition field = null;
0897:                if (sup != null) {
0898:                    field = sup.getClassDefinition(env).getVariable0(env, nm,
0899:                            source, false, showPackage && inSamePackage(sup));
0900:                }
0901:
0902:                // Find the field in our superinterfaces.
0903:                for (int i = 0; i < interfaces.length; i++) {
0904:                    // Try to look up the field in an interface.  Since interfaces
0905:                    // only have public fields, the values of the two boolean
0906:                    // arguments are not important.
0907:                    MemberDefinition field2 = interfaces[i].getClassDefinition(
0908:                            env).getVariable0(env, nm, source, true, true);
0909:
0910:                    if (field2 != null) {
0911:                        // If we have two different, accessible fields, then
0912:                        // we've found an ambiguity.
0913:                        if (field != null && source.canAccess(env, field)
0914:                                && field2 != field) {
0915:
0916:                            throw new AmbiguousMember(field2, field);
0917:                        }
0918:                        field = field2;
0919:                    }
0920:                }
0921:                return field;
0922:            }
0923:
0924:            /**
0925:             * Tells whether to report a deprecation error for this class.
0926:             */
0927:            public boolean reportDeprecated(Environment env) {
0928:                return (isDeprecated() || (outerClass != null && outerClass
0929:                        .reportDeprecated(env)));
0930:            }
0931:
0932:            /**
0933:             * Note that this class is being used somehow by <tt>ref</tt>.
0934:             * Report deprecation errors, etc.
0935:             */
0936:            public void noteUsedBy(ClassDefinition ref, long where,
0937:                    Environment env) {
0938:                // (Have this deal with canAccess() checks, too?)
0939:                if (reportDeprecated(env)) {
0940:                    env.error(where, "warn.class.is.deprecated", this );
0941:                }
0942:            }
0943:
0944:            /**
0945:             * Get an inner class.
0946:             * Look in supers but not outers.
0947:             * (This is used directly to resolve expressions like "site.K", and
0948:             * inside a loop to resolve lone names like "K" or the "K" in "K.L".)
0949:             *
0950:             * Called from 'Context' and 'FieldExpression' as well as this class.
0951:             *
0952:             * @see FieldExpression.checkCommon
0953:             * @see resolveName
0954:             */
0955:            public MemberDefinition getInnerClass(Environment env, Identifier nm)
0956:                    throws ClassNotFound {
0957:                // Note:  AmbiguousClass will not be thrown unless and until
0958:                // inner classes can be defined inside interfaces.
0959:
0960:                // Check if it is defined in the current class
0961:                for (MemberDefinition field = getFirstMatch(nm); field != null; field = field
0962:                        .getNextMatch()) {
0963:                    if (field.isInnerClass()) {
0964:                        if (field.getInnerClass().isLocal()) {
0965:                            continue; // ignore this name; it is internally generated
0966:                        }
0967:                        return field;
0968:                    }
0969:                }
0970:
0971:                // Get it from the super class
0972:                // It is likely that 'getSuperClass()' could be made to work here
0973:                // but we would have to assure somehow that 'resolveTypeStructure'
0974:                // has been called on the current class nest.  Since we can get
0975:                // here from 'resolveName', which is called from 'resolveSupers',
0976:                // it is possible that the first attempt to resolve the superclass
0977:                // will originate here, instead of in the call to 'getSuperClass'
0978:                // in 'checkSupers'.  See 'resolveTypeStructure', in which a call
0979:                // to 'resolveSupers' precedes the call to 'checkSupers'.  Why is
0980:                // name resolution done twice, first in 'resolveName'?
0981:                // NOTE: 'SourceMember.resolveTypeStructure' may initiate type
0982:                // structure resolution for an inner class.  Normally, this
0983:                // occurs during the resolution of the outer class, but fields
0984:                // added after the resolution of their containing class will
0985:                // be resolved late -- see 'addMember(env,field)' below.
0986:                // This should only happen for synthetic members, which should
0987:                // never be an inner class.
0988:                ClassDeclaration sup = getSuperClass(env);
0989:                if (sup != null)
0990:                    return sup.getClassDefinition(env).getInnerClass(env, nm);
0991:
0992:                return null;
0993:            }
0994:
0995:            /**
0996:             * Lookup a method.  This code implements the method lookup
0997:             * mechanism specified in JLS 15.11.2.
0998:             *
0999:             * This mechanism cannot be used to lookup synthetic methods.
1000:             */
1001:            private MemberDefinition matchMethod(Environment env,
1002:                    ClassDefinition accessor, Identifier methodName,
1003:                    Type[] argumentTypes, boolean isAnonConstCall,
1004:                    Identifier accessPackage) throws AmbiguousMember,
1005:                    ClassNotFound {
1006:
1007:                if (allMethods == null || !allMethods.isFrozen()) {
1008:                    // This may be too restrictive.
1009:                    throw new CompilerError("matchMethod called early");
1010:                    // collectInheritedMethods(env);
1011:                }
1012:
1013:                // A tentative maximally specific method.
1014:                MemberDefinition tentative = null;
1015:
1016:                // A list of other methods which may be maximally specific too.
1017:                List candidateList = null;
1018:
1019:                // Get all the methods inherited by this class which
1020:                // have the name `methodName'.
1021:                Iterator methods = allMethods.lookupName(methodName);
1022:
1023:                while (methods.hasNext()) {
1024:                    MemberDefinition method = (MemberDefinition) methods.next();
1025:
1026:                    // See if this method is applicable.
1027:                    if (!env.isApplicable(method, argumentTypes)) {
1028:                        continue;
1029:                    }
1030:
1031:                    // See if this method is accessible.
1032:                    if (accessor != null) {
1033:                        if (!accessor.canAccess(env, method)) {
1034:                            continue;
1035:                        }
1036:                    } else if (isAnonConstCall) {
1037:                        if (method.isPrivate()
1038:                                || (method.isPackagePrivate()
1039:                                        && accessPackage != null && !inSamePackage(accessPackage))) {
1040:                            // For anonymous constructor accesses, we
1041:                            // haven't yet built an accessing class.
1042:                            // We disallow anonymous classes from seeing
1043:                            // private/package-private inaccessible
1044:                            // constructors in their superclass.
1045:                            continue;
1046:                        }
1047:                    } else {
1048:                        // If accessor is null, we assume that the access
1049:                        // is allowed.  Query: is this option used?
1050:                    }
1051:
1052:                    if (tentative == null) {
1053:                        // `method' becomes our tentative maximally specific match.
1054:                        tentative = method;
1055:                    } else {
1056:                        if (env.isMoreSpecific(method, tentative)) {
1057:                            // We have found a method which is a strictly better
1058:                            // match than `tentative'.  Replace it.
1059:                            tentative = method;
1060:                        } else {
1061:                            // If this method could possibly be another
1062:                            // maximally specific method, add it to our
1063:                            // list of other candidates.
1064:                            if (!env.isMoreSpecific(tentative, method)) {
1065:                                if (candidateList == null) {
1066:                                    candidateList = new ArrayList();
1067:                                }
1068:                                candidateList.add(method);
1069:                            }
1070:                        }
1071:                    }
1072:                }
1073:
1074:                if (tentative != null && candidateList != null) {
1075:                    // Find out if our `tentative' match is a uniquely
1076:                    // maximally specific.
1077:                    Iterator candidates = candidateList.iterator();
1078:                    while (candidates.hasNext()) {
1079:                        MemberDefinition method = (MemberDefinition) candidates
1080:                                .next();
1081:                        if (!env.isMoreSpecific(tentative, method)) {
1082:                            throw new AmbiguousMember(tentative, method);
1083:                        }
1084:                    }
1085:                }
1086:
1087:                return tentative;
1088:            }
1089:
1090:            /**
1091:             * Lookup a method.  This code implements the method lookup
1092:             * mechanism specified in JLS 15.11.2.
1093:             *
1094:             * This mechanism cannot be used to lookup synthetic methods.
1095:             */
1096:            public MemberDefinition matchMethod(Environment env,
1097:                    ClassDefinition accessor, Identifier methodName,
1098:                    Type[] argumentTypes) throws AmbiguousMember, ClassNotFound {
1099:
1100:                return matchMethod(env, accessor, methodName, argumentTypes,
1101:                        false, null);
1102:            }
1103:
1104:            /**
1105:             * Lookup a method.  This code implements the method lookup
1106:             * mechanism specified in JLS 15.11.2.
1107:             *
1108:             * This mechanism cannot be used to lookup synthetic methods.
1109:             */
1110:            public MemberDefinition matchMethod(Environment env,
1111:                    ClassDefinition accessor, Identifier methodName)
1112:                    throws AmbiguousMember, ClassNotFound {
1113:
1114:                return matchMethod(env, accessor, methodName, Type.noArgs,
1115:                        false, null);
1116:            }
1117:
1118:            /**
1119:             * A version of matchMethod to be used only for constructors
1120:             * when we cannot pass in a sourceClass argument.  We just assert
1121:             * our package name.
1122:             *
1123:             * This is used only for anonymous classes, where we have to look up
1124:             * a (potentially) protected constructor with no valid sourceClass
1125:             * parameter available.
1126:             */
1127:            public MemberDefinition matchAnonConstructor(Environment env,
1128:                    Identifier accessPackage, Type argumentTypes[])
1129:                    throws AmbiguousMember, ClassNotFound {
1130:
1131:                return matchMethod(env, null, idInit, argumentTypes, true,
1132:                        accessPackage);
1133:            }
1134:
1135:            /**
1136:             * Find a method, ie: exact match in this class or any of the super
1137:             * classes.
1138:             *
1139:             * Only called by javadoc.  For now I am holding off rewriting this
1140:             * code to rely on collectInheritedMethods(), as that code has
1141:             * not gotten along with javadoc in the past.
1142:             */
1143:            public MemberDefinition findMethod(Environment env, Identifier nm,
1144:                    Type t) throws ClassNotFound {
1145:                // look in the current class
1146:                MemberDefinition f;
1147:                for (f = getFirstMatch(nm); f != null; f = f.getNextMatch()) {
1148:                    // Note that non-method types return false for equalArguments().
1149:                    if (f.getType().equalArguments(t)) {
1150:                        return f;
1151:                    }
1152:                }
1153:
1154:                // constructors are not inherited
1155:                if (nm.equals(idInit)) {
1156:                    return null;
1157:                }
1158:
1159:                // look in the super class
1160:                ClassDeclaration sup = getSuperClass();
1161:                if (sup == null)
1162:                    return null;
1163:
1164:                return sup.getClassDefinition(env).findMethod(env, nm, t);
1165:            }
1166:
1167:            // We create a stub for this.  Source classes do more work.
1168:            protected void basicCheck(Environment env) throws ClassNotFound {
1169:                // Do the outer class first.
1170:                if (outerClass != null)
1171:                    outerClass.basicCheck(env);
1172:            }
1173:
1174:            /**
1175:             * Check this class.
1176:             */
1177:            public void check(Environment env) throws ClassNotFound {
1178:            }
1179:
1180:            public Vset checkLocalClass(Environment env, Context ctx,
1181:                    Vset vset, ClassDefinition sup, Expression args[],
1182:                    Type argTypes[]) throws ClassNotFound {
1183:                throw new CompilerError("checkLocalClass");
1184:            }
1185:
1186:            //---------------------------------------------------------------
1187:            // The non-synthetic methods defined in this class or in any
1188:            // of its parents (class or interface).  This member is used
1189:            // to cache work done in collectInheritedMethods for use by
1190:            // getMethods() and matchMethod().  It should be accessed by
1191:            // no other method without forethought.
1192:            MethodSet allMethods = null;
1193:
1194:            // One of our superclasses may contain an abstract method which
1195:            // we are unable to ever implement.  This happens when there is
1196:            // a package-private abstract method in our parent and we are in
1197:            // a different package than our parent.  In these cases, we
1198:            // keep a list of the "permanently abstract" or "unimplementable"
1199:            // methods so that we can correctly detect that this class is
1200:            // indeed abstract and so that we can give somewhat comprehensible
1201:            // error messages.
1202:            private List permanentlyAbstractMethods = new ArrayList();
1203:
1204:            /**
1205:             * This method returns an Iterator of all abstract methods
1206:             * in our superclasses which we are unable to implement.
1207:             */
1208:            protected Iterator getPermanentlyAbstractMethods() {
1209:                // This method can only be called after collectInheritedMethods.
1210:                if (allMethods == null) {
1211:                    throw new CompilerError(
1212:                            "isPermanentlyAbstract() called early");
1213:                }
1214:
1215:                return permanentlyAbstractMethods.iterator();
1216:            }
1217:
1218:            /**
1219:             * A flag used by turnOffInheritanceChecks() to indicate if
1220:             * inheritance checks are on or off.
1221:             */
1222:            protected static boolean doInheritanceChecks = true;
1223:
1224:            /**
1225:             * This is a workaround to allow javadoc to turn off certain
1226:             * inheritance/override checks which interfere with javadoc
1227:             * badly.  In the future it might be good to eliminate the
1228:             * shared sources of javadoc and javac to avoid the need for this
1229:             * sort of workaround.
1230:             */
1231:            public static void turnOffInheritanceChecks() {
1232:                doInheritanceChecks = false;
1233:            }
1234:
1235:            /**
1236:             * Add all of the methods declared in or above `parent' to
1237:             * `allMethods', the set of methods in the current class.
1238:             * `myMethods' is the set of all methods declared in this
1239:             * class, and `mirandaMethods' is a repository for Miranda methods.
1240:             * If mirandaMethods is null, no mirandaMethods will be
1241:             * generated.
1242:             *
1243:             * For a definition of Miranda methods, see the comment above the
1244:             * method addMirandaMethods() which occurs later in this file.
1245:             */
1246:            private void collectOneClass(Environment env,
1247:                    ClassDeclaration parent, MethodSet myMethods,
1248:                    MethodSet allMethods, MethodSet mirandaMethods) {
1249:
1250:                // System.out.println("Inheriting methods from " + parent);
1251:
1252:                try {
1253:                    ClassDefinition pClass = parent.getClassDefinition(env);
1254:                    Iterator methods = pClass.getMethods(env);
1255:                    while (methods.hasNext()) {
1256:                        MemberDefinition method = (MemberDefinition) methods
1257:                                .next();
1258:
1259:                        // Private methods are not inherited.
1260:                        //
1261:                        // Constructors are not inherited.
1262:                        //
1263:                        // Any non-abstract methods in an interface come
1264:                        // from java.lang.Object.  This means that they
1265:                        // should have already been added to allMethods
1266:                        // when we walked our superclass lineage.
1267:                        if (method.isPrivate()
1268:                                || method.isConstructor()
1269:                                || (pClass.isInterface() && !method
1270:                                        .isAbstract())) {
1271:
1272:                            continue;
1273:                        }
1274:
1275:                        // Get the components of the methods' signature.
1276:                        Identifier name = method.getName();
1277:                        Type type = method.getType();
1278:
1279:                        // Check for a method of the same signature which
1280:                        // was locally declared.
1281:                        MemberDefinition override = myMethods.lookupSig(name,
1282:                                type);
1283:
1284:                        // Is this method inaccessible due to package-private
1285:                        // visibility?
1286:                        if (method.isPackagePrivate()
1287:                                && !inSamePackage(method.getClassDeclaration())) {
1288:
1289:                            if (override != null
1290:                                    && this  instanceof  sun.tools.javac.SourceClass) {
1291:                                // We give a warning when a class shadows an
1292:                                // inaccessible package-private method from
1293:                                // its superclass.  This warning is meant
1294:                                // to prevent people from relying on overriding
1295:                                // when it does not happen.  This warning should
1296:                                // probably be removed to be consistent with the
1297:                                // general "no warnings" policy of this
1298:                                // compiler.
1299:                                //
1300:                                // The `instanceof' above is a hack so that only
1301:                                // SourceClass generates this warning, not a
1302:                                // BinaryClass, for example.
1303:                                env.error(method.getWhere(),
1304:                                        "warn.no.override.access", override,
1305:                                        override.getClassDeclaration(), method
1306:                                                .getClassDeclaration());
1307:                            }
1308:
1309:                            // If our superclass has a package-private abstract
1310:                            // method that we have no access to, then we add
1311:                            // this method to our list of permanently abstract
1312:                            // methods.  The idea is, since we cannot override
1313:                            // the method, we can never make this class
1314:                            // non-abstract.
1315:                            if (method.isAbstract()) {
1316:                                permanentlyAbstractMethods.add(method);
1317:                            }
1318:
1319:                            // `method' is inaccessible.  We do not inherit it.
1320:                            continue;
1321:                        }
1322:
1323:                        if (override != null) {
1324:                            // `method' and `override' have the same signature.
1325:                            // We are required to check that `override' is a
1326:                            // legal override of `method'
1327:
1328:                            //System.out.println ("About to check override of " +
1329:                            //		    method);
1330:
1331:                            override.checkOverride(env, method);
1332:                        } else {
1333:                            // In the absence of a definition in the class
1334:                            // itself, we check to see if this definition
1335:                            // can be successfully merged with any other
1336:                            // inherited definitions.
1337:
1338:                            // Have we added a member of the same signature
1339:                            // to `allMethods' already?
1340:                            MemberDefinition formerMethod = allMethods
1341:                                    .lookupSig(name, type);
1342:
1343:                            // If the previous definition is nonexistent or
1344:                            // ignorable, replace it.
1345:                            if (formerMethod == null) {
1346:                                //System.out.println("Added " + method + " to " +
1347:                                //	       this);
1348:
1349:                                if (mirandaMethods != null
1350:                                        && pClass.isInterface()
1351:                                        && !isInterface()) {
1352:                                    // Whenever a class inherits a method
1353:                                    // from an interface, that method is
1354:                                    // one of our "miranda" methods.  Early
1355:                                    // VMs require that these methods be
1356:                                    // added as true members to the class
1357:                                    // to enable method lookup to work in the
1358:                                    // VM.
1359:                                    method = new sun.tools.javac.SourceMember(
1360:                                            method, this , env);
1361:                                    mirandaMethods.add(method);
1362:
1363:                                    //System.out.println("Added " + method +
1364:                                    // " to " + this + " as a Miranda");
1365:                                }
1366:
1367:                                // There is no previous inherited definition.
1368:                                // Add `method' to `allMethods'.
1369:                                allMethods.add(method);
1370:                            } else if (isInterface()
1371:                                    && !formerMethod.isAbstract()
1372:                                    && method.isAbstract()) {
1373:                                // If we are in an interface and we have inherited
1374:                                // both an abstract method and a non-abstract method
1375:                                // then we know that the non-abstract method is
1376:                                // a placeholder from Object put in for type checking
1377:                                // and the abstract method was already checked to
1378:                                // be proper by our superinterface.
1379:                                allMethods.replace(method);
1380:
1381:                            } else {
1382:                                // Okay, `formerMethod' and `method' both have the
1383:                                // same signature.  See if they are compatible.
1384:
1385:                                //System.out.println ("About to check meet of " +
1386:                                //		method);
1387:
1388:                                if (!formerMethod.checkMeet(env, method, this 
1389:                                        .getClassDeclaration())) {
1390:                                    // The methods are incompatible.  Skip to
1391:                                    // next method.
1392:                                    continue;
1393:                                }
1394:
1395:                                if (formerMethod.couldOverride(env, method)) {
1396:                                    // Do nothing.  The current definition
1397:                                    // is specific enough.
1398:
1399:                                    //System.out.println("trivial meet of " +
1400:                                    //		   method);
1401:                                    continue;
1402:                                }
1403:
1404:                                if (method.couldOverride(env, formerMethod)) {
1405:                                    // `method' is more specific than
1406:                                    // `formerMethod'.  replace `formerMethod'.
1407:
1408:                                    //System.out.println("new def of " + method);
1409:                                    if (mirandaMethods != null
1410:                                            && pClass.isInterface()
1411:                                            && !isInterface()) {
1412:                                        // Whenever a class inherits a method
1413:                                        // from an interface, that method is
1414:                                        // one of our "miranda" methods.  Early
1415:                                        // VMs require that these methods be
1416:                                        // added as true members to the class
1417:                                        // to enable method lookup to work in the
1418:                                        // VM.
1419:                                        method = new sun.tools.javac.SourceMember(
1420:                                                method, this , env);
1421:
1422:                                        mirandaMethods.replace(method);
1423:
1424:                                        //System.out.println("Added " + method +
1425:                                        // " to " + this + " as a Miranda");
1426:                                    }
1427:
1428:                                    allMethods.replace(method);
1429:
1430:                                    continue;
1431:                                }
1432:
1433:                                // Neither method is more specific than the other.
1434:                                // Oh well.  We need to construct a nontrivial
1435:                                // meet of the two methods.
1436:                                //
1437:                                // This is not yet implemented, so we give
1438:                                // a message with a helpful workaround.
1439:                                env.error(this .where, "nontrivial.meet",
1440:                                        method, formerMethod
1441:                                                .getClassDefinition(), method
1442:                                                .getClassDeclaration());
1443:                            }
1444:                        }
1445:                    }
1446:                } catch (ClassNotFound ee) {
1447:                    env.error(getWhere(), "class.not.found", ee.name, this );
1448:                }
1449:            }
1450:
1451:            /**
1452:             * <p>Collect all methods defined in this class or inherited from
1453:             * any of our superclasses or interfaces.  Look for any
1454:             * incompatible definitions.
1455:             *
1456:             * <p>This function is also responsible for collecting the
1457:             * <em>Miranda</em> methods for a class.  For a definition of
1458:             * Miranda methods, see the comment in addMirandaMethods()
1459:             * below.
1460:             */
1461:            protected void collectInheritedMethods(Environment env) {
1462:                // The methods defined in this class.
1463:                MethodSet myMethods;
1464:                MethodSet mirandaMethods;
1465:
1466:                //System.out.println("Called collectInheritedMethods() for " +
1467:                //		   this);
1468:
1469:                if (allMethods != null) {
1470:                    if (allMethods.isFrozen()) {
1471:                        // We have already done the collection.  No need to
1472:                        // do it again.
1473:                        return;
1474:                    } else {
1475:                        // We have run into a circular need to collect our methods.
1476:                        // This should not happen at this stage.
1477:                        throw new CompilerError("collectInheritedMethods()");
1478:                    }
1479:                }
1480:
1481:                myMethods = new MethodSet();
1482:                allMethods = new MethodSet();
1483:
1484:                // For testing, do not generate miranda methods.
1485:                if (env.version12()) {
1486:                    mirandaMethods = null;
1487:                } else {
1488:                    mirandaMethods = new MethodSet();
1489:                }
1490:
1491:                // Any methods defined in the current class get added
1492:                // to both the myMethods and the allMethods MethodSets.
1493:
1494:                for (MemberDefinition member = getFirstMember(); member != null; member = member.nextMember) {
1495:
1496:                    // We only collect methods.  Initializers are not relevant.
1497:                    if (member.isMethod() && !member.isInitializer()) {
1498:
1499:                        //System.out.println("Declared in " + this + ", " + member);
1500:
1501:                        ////////////////////////////////////////////////////////////
1502:                        // PCJ 2003-07-30 modified the following code because with
1503:                        // the covariant return type feature of the 1.5 compiler,
1504:                        // there might be multiple methods with the same signature
1505:                        // but different return types, and MethodSet doesn't
1506:                        // support that.  We use a new utility method that attempts
1507:                        // to ensure that the appropriate method winds up in the
1508:                        // MethodSet.  See 4892308.
1509:                        ////////////////////////////////////////////////////////////
1510:                        // myMethods.add(member);
1511:                        // allMethods.add(member);
1512:                        ////////////////////////////////////////////////////////////
1513:                        methodSetAdd(env, myMethods, member);
1514:                        methodSetAdd(env, allMethods, member);
1515:                        ////////////////////////////////////////////////////////////
1516:                    }
1517:                }
1518:
1519:                // We're ready to start adding inherited methods.  First add
1520:                // the methods from our superclass.
1521:
1522:                //System.out.println("About to start superclasses for " + this);
1523:
1524:                ClassDeclaration scDecl = getSuperClass(env);
1525:                if (scDecl != null) {
1526:                    collectOneClass(env, scDecl, myMethods, allMethods,
1527:                            mirandaMethods);
1528:
1529:                    // Make sure that we add all unimplementable methods from our
1530:                    // superclass to our list of unimplementable methods.
1531:                    ClassDefinition sc = scDecl.getClassDefinition();
1532:                    Iterator supIter = sc.getPermanentlyAbstractMethods();
1533:                    while (supIter.hasNext()) {
1534:                        permanentlyAbstractMethods.add(supIter.next());
1535:                    }
1536:                }
1537:
1538:                // Now we inherit all of the methods from our interfaces.
1539:
1540:                //System.out.println("About to start interfaces for " + this);
1541:
1542:                for (int i = 0; i < interfaces.length; i++) {
1543:                    collectOneClass(env, interfaces[i], myMethods, allMethods,
1544:                            mirandaMethods);
1545:                }
1546:                allMethods.freeze();
1547:
1548:                // Now we have collected all of our methods from our superclasses
1549:                // and interfaces into our `allMethods' member.  Good.  As a last
1550:                // task, we add our collected miranda methods to this class.
1551:                //
1552:                // If we do not add the mirandas to the class explicitly, there
1553:                // will be no code generated for them.
1554:                if (mirandaMethods != null && mirandaMethods.size() > 0) {
1555:                    addMirandaMethods(env, mirandaMethods.iterator());
1556:                }
1557:            }
1558:
1559:            ////////////////////////////////////////////////////////////
1560:            // PCJ 2003-07-30 added this utility method to insulate
1561:            // MethodSet additions from the covariant return type
1562:            // feature of the 1.5 compiler.  When there are multiple
1563:            // methods with the same signature and different return
1564:            // types to be added, we try to ensure that the one with
1565:            // the most specific return type winds up in the MethodSet.
1566:            // This logic was not put into MethodSet itself because it
1567:            // requires access to an Environment for type relationship
1568:            // checking.  No error checking is performed here, but that
1569:            // should be OK because this code is only still used by
1570:            // rmic.  See 4892308.
1571:            ////////////////////////////////////////////////////////////
1572:            private static void methodSetAdd(Environment env,
1573:                    MethodSet methodSet, MemberDefinition newMethod) {
1574:                MemberDefinition oldMethod = methodSet.lookupSig(newMethod
1575:                        .getName(), newMethod.getType());
1576:                if (oldMethod != null) {
1577:                    Type oldReturnType = oldMethod.getType().getReturnType();
1578:                    Type newReturnType = newMethod.getType().getReturnType();
1579:                    try {
1580:                        if (env.isMoreSpecific(newReturnType, oldReturnType)) {
1581:                            methodSet.replace(newMethod);
1582:                        }
1583:                    } catch (ClassNotFound ignore) {
1584:                    }
1585:                } else {
1586:                    methodSet.add(newMethod);
1587:                }
1588:            }
1589:
1590:            ////////////////////////////////////////////////////////////
1591:
1592:            /**
1593:             * Get an Iterator of all methods which could be accessed in an
1594:             * instance of this class.
1595:             */
1596:            public Iterator getMethods(Environment env) {
1597:                if (allMethods == null) {
1598:                    collectInheritedMethods(env);
1599:                }
1600:                return getMethods();
1601:            }
1602:
1603:            /**
1604:             * Get an Iterator of all methods which could be accessed in an
1605:             * instance of this class.  Throw a compiler error if we haven't
1606:             * generated this information yet.
1607:             */
1608:            public Iterator getMethods() {
1609:                if (allMethods == null) {
1610:                    throw new CompilerError("getMethods: too early");
1611:                }
1612:                return allMethods.iterator();
1613:            }
1614:
1615:            // In early VM's there was a bug -- the VM didn't walk the interfaces
1616:            // of a class looking for a method, they only walked the superclass
1617:            // chain.  This meant that abstract methods defined only in interfaces
1618:            // were not being found.  To fix this bug, a counter-bug was introduced
1619:            // in the compiler -- the so-called Miranda methods.  If a class
1620:            // does not provide a definition for an abstract method in one of
1621:            // its interfaces then the compiler inserts one in the class artificially.
1622:            // That way the VM didn't have to bother looking at the interfaces.
1623:            //
1624:            // This is a problem.  Miranda methods are not part of the specification.
1625:            // But they continue to be inserted so that old VM's can run new code.
1626:            // Someday, when the old VM's are gone, perhaps classes can be compiled
1627:            // without Miranda methods.  Towards this end, the compiler has a
1628:            // flag, -nomiranda, which can turn off the creation of these methods.
1629:            // Eventually that behavior should become the default.
1630:            //
1631:            // Why are they called Miranda methods?  Well the sentence "If the
1632:            // class is not able to provide a method, then one will be provided
1633:            // by the compiler" is very similar to the sentence "If you cannot
1634:            // afford an attorney, one will be provided by the court," -- one
1635:            // of the so-called "Miranda" rights in the United States.
1636:
1637:            /**
1638:             * Add a list of methods to this class as miranda methods.  This
1639:             * gets overridden with a meaningful implementation in SourceClass.
1640:             * BinaryClass should not need to do anything -- it should already
1641:             * have its miranda methods and, if it doesn't, then that doesn't
1642:             * affect our compilation.
1643:             */
1644:            protected void addMirandaMethods(Environment env, Iterator mirandas) {
1645:                // do nothing.
1646:            }
1647:
1648:            //---------------------------------------------------------------
1649:
1650:            public void inlineLocalClass(Environment env) {
1651:            }
1652:
1653:            /**
1654:             * We create a stub for this.  Source classes do more work.
1655:             * Some calls from 'SourceClass.checkSupers' execute this method.
1656:             * @see sun.tools.javac.SourceClass#resolveTypeStructure
1657:             */
1658:
1659:            public void resolveTypeStructure(Environment env) {
1660:            }
1661:
1662:            /**
1663:             * Look up an inner class name, from somewhere inside this class.
1664:             * Since supers and outers are in scope, search them too.
1665:             * <p>
1666:             * If no inner class is found, env.resolveName() is then called,
1667:             * to interpret the ambient package and import directives.
1668:             * <p>
1669:             * This routine operates on a "best-efforts" basis.  If
1670:             * at some point a class is not found, the partially-resolved
1671:             * identifier is returned.  Eventually, someone else has to
1672:             * try to get the ClassDefinition and diagnose the ClassNotFound.
1673:             * <p>
1674:             * resolveName() looks at surrounding scopes, and hence
1675:             * pulling in both inherited and uplevel types.  By contrast,
1676:             * resolveInnerClass() is intended only for interpreting
1677:             * explicitly qualified names, and so look only at inherited
1678:             * types.  Also, resolveName() looks for package prefixes,
1679:             * which appear similar to "very uplevel" outer classes.
1680:             * <p>
1681:             * A similar (but more complex) name-lookup process happens
1682:             * when field and identifier expressions denoting qualified names
1683:             * are type-checked.  The added complexity comes from the fact
1684:             * that variables may occur in such names, and take precedence
1685:             * over class and package names.
1686:             * <p>
1687:             * In the expression type-checker, resolveInnerClass() is paralleled
1688:             * by code in FieldExpression.checkAmbigName(), which also calls
1689:             * ClassDefinition.getInnerClass() to interpret names of the form
1690:             * "OuterClass.Inner" (and also outerObject.Inner).  The checking
1691:             * of an identifier expression that fails to be a variable is referred
1692:             * directly to resolveName().
1693:             */
1694:            public Identifier resolveName(Environment env, Identifier name) {
1695:                if (tracing)
1696:                    env.dtEvent("ClassDefinition.resolveName: " + name);
1697:                // This logic is pretty much exactly parallel to that of
1698:                // Environment.resolveName().
1699:                if (name.isQualified()) {
1700:                    // Try to resolve the first identifier component,
1701:                    // because inner class names take precedence over
1702:                    // package prefixes.  (Cf. Environment.resolveName.)
1703:                    Identifier rhead = resolveName(env, name.getHead());
1704:
1705:                    if (rhead.hasAmbigPrefix()) {
1706:                        // The first identifier component refers to an
1707:                        // ambiguous class.  Limp on.  We throw away the
1708:                        // rest of the classname as it is irrelevant.
1709:                        // (part of solution for 4059855).
1710:                        return rhead;
1711:                    }
1712:
1713:                    if (!env.classExists(rhead)) {
1714:                        return env.resolvePackageQualifiedName(name);
1715:                    }
1716:                    try {
1717:                        return env.getClassDefinition(rhead).resolveInnerClass(
1718:                                env, name.getTail());
1719:                    } catch (ClassNotFound ee) {
1720:                        // return partially-resolved name someone else can fail on
1721:                        return Identifier.lookupInner(rhead, name.getTail());
1722:                    }
1723:                }
1724:
1725:                // This method used to fail to look for local classes, thus a
1726:                // reference to a local class within, e.g., the type of a member
1727:                // declaration, would fail to resolve if the immediately enclosing
1728:                // context was an inner class.  The code added below is ugly, but
1729:                // it works, and is lifted from existing code in 'Context.resolveName'
1730:                // and 'Context.getClassCommon'. See the comments there about the design.
1731:                // Fixes 4095716.
1732:
1733:                int ls = -2;
1734:                LocalMember lf = null;
1735:                if (classContext != null) {
1736:                    lf = classContext.getLocalClass(name);
1737:                    if (lf != null) {
1738:                        ls = lf.getScopeNumber();
1739:                    }
1740:                }
1741:
1742:                // Look for an unqualified name in enclosing scopes.
1743:                for (ClassDefinition c = this ; c != null; c = c.outerClass) {
1744:                    try {
1745:                        MemberDefinition f = c.getInnerClass(env, name);
1746:                        if (f != null
1747:                                && (lf == null || classContext
1748:                                        .getScopeNumber(c) > ls)) {
1749:                            // An uplevel member was found, and was nested more deeply than
1750:                            // any enclosing local of the same name.
1751:                            return f.getInnerClass().getName();
1752:                        }
1753:                    } catch (ClassNotFound ee) {
1754:                        // a missing superclass, or something catastrophic
1755:                    }
1756:                }
1757:
1758:                // No uplevel member found, so use the enclosing local if one was found.
1759:                if (lf != null) {
1760:                    return lf.getInnerClass().getName();
1761:                }
1762:
1763:                // look in imports, etc.
1764:                return env.resolveName(name);
1765:            }
1766:
1767:            /**
1768:             * Interpret a qualified class name, which may have further subcomponents..
1769:             * Follow inheritance links, as in:
1770:             *	class C { class N { } }  class D extends C { }  ... new D.N() ...
1771:             * Ignore outer scopes and packages.
1772:             * @see resolveName
1773:             */
1774:            public Identifier resolveInnerClass(Environment env, Identifier nm) {
1775:                if (nm.isInner())
1776:                    throw new CompilerError("inner");
1777:                if (nm.isQualified()) {
1778:                    Identifier rhead = resolveInnerClass(env, nm.getHead());
1779:                    try {
1780:                        return env.getClassDefinition(rhead).resolveInnerClass(
1781:                                env, nm.getTail());
1782:                    } catch (ClassNotFound ee) {
1783:                        // return partially-resolved name someone else can fail on
1784:                        return Identifier.lookupInner(rhead, nm.getTail());
1785:                    }
1786:                } else {
1787:                    try {
1788:                        MemberDefinition f = getInnerClass(env, nm);
1789:                        if (f != null) {
1790:                            return f.getInnerClass().getName();
1791:                        }
1792:                    } catch (ClassNotFound ee) {
1793:                        // a missing superclass, or something catastrophic
1794:                    }
1795:                    // Fake a good name for a diagnostic.
1796:                    return Identifier.lookupInner(this .getName(), nm);
1797:                }
1798:            }
1799:
1800:            /**
1801:             * While resolving import directives, the question has arisen:
1802:             * does a given inner class exist?  If the top-level class exists,
1803:             * we ask it about an inner class via this method.
1804:             * This method looks only at the literal name of the class,
1805:             * and does not attempt to follow inheritance links.
1806:             * This is necessary, since at the time imports are being
1807:             * processed, inheritance links have not been resolved yet.
1808:             * (Thus, an import directive must always spell a class
1809:             * name exactly.)
1810:             */
1811:            public boolean innerClassExists(Identifier nm) {
1812:                for (MemberDefinition field = getFirstMatch(nm.getHead()); field != null; field = field
1813:                        .getNextMatch()) {
1814:                    if (field.isInnerClass()) {
1815:                        if (field.getInnerClass().isLocal()) {
1816:                            continue; // ignore this name; it is internally generated
1817:                        }
1818:                        return !nm.isQualified()
1819:                                || field.getInnerClass().innerClassExists(
1820:                                        nm.getTail());
1821:                    }
1822:                }
1823:                return false;
1824:            }
1825:
1826:            /**
1827:             * Find any method with a given name.
1828:             */
1829:            public MemberDefinition findAnyMethod(Environment env, Identifier nm)
1830:                    throws ClassNotFound {
1831:                MemberDefinition f;
1832:                for (f = getFirstMatch(nm); f != null; f = f.getNextMatch()) {
1833:                    if (f.isMethod()) {
1834:                        return f;
1835:                    }
1836:                }
1837:
1838:                // look in the super class
1839:                ClassDeclaration sup = getSuperClass();
1840:                if (sup == null)
1841:                    return null;
1842:                return sup.getClassDefinition(env).findAnyMethod(env, nm);
1843:            }
1844:
1845:            /**
1846:             * Given the fact that this class has no method "nm" matching "argTypes",
1847:             * find out if the mismatch can be blamed on a particular actual argument
1848:             * which disagrees with all of the overloadings.
1849:             * If so, return the code (i<<2)+(castOK<<1)+ambig, where
1850:             * "i" is the number of the offending argument, and
1851:             * "castOK" is 1 if a cast could fix the problem.
1852:             * The target type for the argument is returned in margTypeResult[0].
1853:             * If not all methods agree on this type, "ambig" is 1.
1854:             * If there is more than one method, the choice of target type is
1855:             * arbitrary.<p>
1856:             * Return -1 if every argument is acceptable to at least one method.
1857:             * Return -2 if there are no methods of the required arity.
1858:             * The value "start" gives the index of the first argument to begin
1859:             * checking.
1860:             */
1861:            public int diagnoseMismatch(Environment env, Identifier nm,
1862:                    Type argTypes[], int start, Type margTypeResult[])
1863:                    throws ClassNotFound {
1864:                int haveMatch[] = new int[argTypes.length];
1865:                Type margType[] = new Type[argTypes.length];
1866:                if (!diagnoseMismatch(env, nm, argTypes, start, haveMatch,
1867:                        margType))
1868:                    return -2;
1869:                for (int i = start; i < argTypes.length; i++) {
1870:                    if (haveMatch[i] < 4) {
1871:                        margTypeResult[0] = margType[i];
1872:                        return (i << 2) | haveMatch[i];
1873:                    }
1874:                }
1875:                return -1;
1876:            }
1877:
1878:            private boolean diagnoseMismatch(Environment env, Identifier nm,
1879:                    Type argTypes[], int start, int haveMatch[],
1880:                    Type margType[]) throws ClassNotFound {
1881:                // look in the current class
1882:                boolean haveOne = false;
1883:                MemberDefinition f;
1884:                for (f = getFirstMatch(nm); f != null; f = f.getNextMatch()) {
1885:                    if (!f.isMethod()) {
1886:                        continue;
1887:                    }
1888:                    Type fArgTypes[] = f.getType().getArgumentTypes();
1889:                    if (fArgTypes.length == argTypes.length) {
1890:                        haveOne = true;
1891:                        for (int i = start; i < argTypes.length; i++) {
1892:                            Type at = argTypes[i];
1893:                            Type ft = fArgTypes[i];
1894:                            if (env.implicitCast(at, ft)) {
1895:                                haveMatch[i] = 4;
1896:                                continue;
1897:                            } else if (haveMatch[i] <= 2
1898:                                    && env.explicitCast(at, ft)) {
1899:                                if (haveMatch[i] < 2)
1900:                                    margType[i] = null;
1901:                                haveMatch[i] = 2;
1902:                            } else if (haveMatch[i] > 0) {
1903:                                continue;
1904:                            }
1905:                            if (margType[i] == null)
1906:                                margType[i] = ft;
1907:                            else if (margType[i] != ft)
1908:                                haveMatch[i] |= 1;
1909:                        }
1910:                    }
1911:                }
1912:
1913:                // constructors are not inherited
1914:                if (nm.equals(idInit)) {
1915:                    return haveOne;
1916:                }
1917:
1918:                // look in the super class
1919:                ClassDeclaration sup = getSuperClass();
1920:                if (sup != null) {
1921:                    if (sup.getClassDefinition(env).diagnoseMismatch(env, nm,
1922:                            argTypes, start, haveMatch, margType))
1923:                        haveOne = true;
1924:                }
1925:                return haveOne;
1926:            }
1927:
1928:            /**
1929:             * Add a field (no checks)
1930:             */
1931:            public void addMember(MemberDefinition field) {
1932:                //System.out.println("ADD = " + field);
1933:                if (firstMember == null) {
1934:                    firstMember = lastMember = field;
1935:                } else if (field.isSynthetic() && field.isFinal()
1936:                        && field.isVariable()) {
1937:                    // insert this at the front, because of initialization order
1938:                    field.nextMember = firstMember;
1939:                    firstMember = field;
1940:                    field.nextMatch = (MemberDefinition) fieldHash
1941:                            .get(field.name);
1942:                } else {
1943:                    lastMember.nextMember = field;
1944:                    lastMember = field;
1945:                    field.nextMatch = (MemberDefinition) fieldHash
1946:                            .get(field.name);
1947:                }
1948:                fieldHash.put(field.name, field);
1949:            }
1950:
1951:            /**
1952:             * Add a field (subclasses make checks)
1953:             */
1954:            public void addMember(Environment env, MemberDefinition field) {
1955:                addMember(field);
1956:                if (resolved) {
1957:                    // a late addition
1958:                    field.resolveTypeStructure(env);
1959:                }
1960:            }
1961:
1962:            /**
1963:             * Find or create an uplevel reference for the given target.
1964:             */
1965:            public UplevelReference getReference(LocalMember target) {
1966:                for (UplevelReference r = references; r != null; r = r
1967:                        .getNext()) {
1968:                    if (r.getTarget() == target) {
1969:                        return r;
1970:                    }
1971:                }
1972:                return addReference(target);
1973:            }
1974:
1975:            protected UplevelReference addReference(LocalMember target) {
1976:                if (target.getClassDefinition() == this ) {
1977:                    throw new CompilerError("addReference " + target);
1978:                }
1979:                referencesMustNotBeFrozen();
1980:                UplevelReference r = new UplevelReference(this , target);
1981:                references = r.insertInto(references);
1982:                return r;
1983:            }
1984:
1985:            /**
1986:             * Return the list of all uplevel references.
1987:             */
1988:            public UplevelReference getReferences() {
1989:                return references;
1990:            }
1991:
1992:            /**
1993:             * Return the same value as getReferences.
1994:             * Also, mark the set of references frozen.
1995:             * After that, it is an error to add new references.
1996:             */
1997:            public UplevelReference getReferencesFrozen() {
1998:                referencesFrozen = true;
1999:                return references;
2000:            }
2001:
2002:            /**
2003:             * assertion check
2004:             */
2005:            public final void referencesMustNotBeFrozen() {
2006:                if (referencesFrozen) {
2007:                    throw new CompilerError("referencesMustNotBeFrozen " + this );
2008:                }
2009:            }
2010:
2011:            /**
2012:             * Get helper method for class literal lookup.
2013:             */
2014:            public MemberDefinition getClassLiteralLookup(long fwhere) {
2015:                throw new CompilerError("binary class");
2016:            }
2017:
2018:            /**
2019:             * Add a dependency
2020:             */
2021:            public void addDependency(ClassDeclaration c) {
2022:                throw new CompilerError("addDependency");
2023:            }
2024:
2025:            /**
2026:             * Maintain a hash table of local and anonymous classes
2027:             * whose internal names are prefixed by the current class.
2028:             * The key is the simple internal name, less the prefix.
2029:             */
2030:
2031:            public ClassDefinition getLocalClass(String name) {
2032:                if (localClasses == null) {
2033:                    return null;
2034:                } else {
2035:                    return (ClassDefinition) localClasses.get(name);
2036:                }
2037:            }
2038:
2039:            public void addLocalClass(ClassDefinition c, String name) {
2040:                if (localClasses == null) {
2041:                    localClasses = new Hashtable(LOCAL_CLASSES_SIZE);
2042:                }
2043:                localClasses.put(name, c);
2044:            }
2045:
2046:            /**
2047:             * Print for debugging
2048:             */
2049:            public void print(PrintStream out) {
2050:                if (isPublic()) {
2051:                    out.print("public ");
2052:                }
2053:                if (isInterface()) {
2054:                    out.print("interface ");
2055:                } else {
2056:                    out.print("class ");
2057:                }
2058:                out.print(getName() + " ");
2059:                if (getSuperClass() != null) {
2060:                    out.print("extends " + getSuperClass().getName() + " ");
2061:                }
2062:                if (interfaces.length > 0) {
2063:                    out.print("implements ");
2064:                    for (int i = 0; i < interfaces.length; i++) {
2065:                        if (i > 0) {
2066:                            out.print(", ");
2067:                        }
2068:                        out.print(interfaces[i].getName());
2069:                        out.print(" ");
2070:                    }
2071:                }
2072:                out.println("{");
2073:
2074:                for (MemberDefinition f = getFirstMember(); f != null; f = f
2075:                        .getNextMember()) {
2076:                    out.print("    ");
2077:                    f.print(out);
2078:                }
2079:
2080:                out.println("}");
2081:            }
2082:
2083:            /**
2084:             * Convert to String
2085:             */
2086:            public String toString() {
2087:                return getClassDeclaration().toString();
2088:            }
2089:
2090:            /**
2091:             * After the class has been written to disk, try to free up
2092:             * some storage.
2093:             */
2094:            public void cleanup(Environment env) {
2095:                if (env.dump()) {
2096:                    env.output("[cleanup " + getName() + "]");
2097:                }
2098:                for (MemberDefinition f = getFirstMember(); f != null; f = f
2099:                        .getNextMember()) {
2100:                    f.cleanup(env);
2101:                }
2102:                // keep "references" around, for the sake of local subclasses
2103:                documentation = null;
2104:            }
2105:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.