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


0001:        /*
0002:         * Copyright 1994-2004 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.javac;
0027:
0028:        import sun.tools.java.*;
0029:        import sun.tools.tree.*;
0030:        import sun.tools.tree.CompoundStatement;
0031:        import sun.tools.asm.Assembler;
0032:        import sun.tools.asm.ConstantPool;
0033:        import java.util.Vector;
0034:        import java.util.Enumeration;
0035:        import java.util.Hashtable;
0036:        import java.util.Iterator;
0037:        import java.io.IOException;
0038:        import java.io.OutputStream;
0039:        import java.io.DataOutputStream;
0040:        import java.io.ByteArrayOutputStream;
0041:        import java.io.File;
0042:
0043:        /**
0044:         * This class represents an Java class as it is read from
0045:         * an Java source file.
0046:         *
0047:         * WARNING: The contents of this source file are not part of any
0048:         * supported API.  Code that depends on them does so at its own risk:
0049:         * they are subject to change or removal without notice.
0050:         */
0051:        @Deprecated
0052:        public class SourceClass extends ClassDefinition {
0053:
0054:            /**
0055:             * The toplevel environment, shared with the parser
0056:             */
0057:            Environment toplevelEnv;
0058:
0059:            /**
0060:             * The default constructor
0061:             */
0062:            SourceMember defConstructor;
0063:
0064:            /**
0065:             * The constant pool
0066:             */
0067:            ConstantPool tab = new ConstantPool();
0068:
0069:            /**
0070:             * The list of class dependencies
0071:             */
0072:            Hashtable deps = new Hashtable(11);
0073:
0074:            /**
0075:             * The field used to represent "this" in all of my code.
0076:             */
0077:            LocalMember this Arg;
0078:
0079:            /**
0080:             * Last token of class, as reported by parser.
0081:             */
0082:            long endPosition;
0083:
0084:            /**
0085:             * Access methods for constructors are distinguished from
0086:             * the constructors themselves by a dummy first argument.
0087:             * A unique type used for this purpose and shared by all
0088:             * constructor access methods within a package-member class is
0089:             * maintained here.
0090:             * <p>
0091:             * This field is null except in an outermost class containing
0092:             * one or more classes needing such an access method.
0093:             */
0094:            private Type dummyArgumentType = null;
0095:
0096:            /**
0097:             * Constructor
0098:             */
0099:            public SourceClass(Environment env, long where,
0100:                    ClassDeclaration declaration, String documentation,
0101:                    int modifiers, IdentifierToken super Class,
0102:                    IdentifierToken interfaces[], SourceClass outerClass,
0103:                    Identifier localName) {
0104:                super (env.getSource(), where, declaration, modifiers,
0105:                        super Class, interfaces);
0106:                setOuterClass(outerClass);
0107:
0108:                this .toplevelEnv = env;
0109:                this .documentation = documentation;
0110:
0111:                if (ClassDefinition.containsDeprecated(documentation)) {
0112:                    this .modifiers |= M_DEPRECATED;
0113:                }
0114:
0115:                // Check for a package level class which is declared static.
0116:                if (isStatic() && outerClass == null) {
0117:                    env.error(where, "static.class", this );
0118:                    this .modifiers &= ~M_STATIC;
0119:                }
0120:
0121:                // Inner classes cannot be static, nor can they be interfaces
0122:                // (which are implicitly static).  Static classes and interfaces
0123:                // can only occur as top-level entities.
0124:                // 
0125:                // Note that we do not have to check for local classes declared
0126:                // to be static (this is currently caught by the parser) but
0127:                // we check anyway in case the parser is modified to allow this.
0128:                if (isLocal()
0129:                        || (outerClass != null && !outerClass.isTopLevel())) {
0130:                    if (isInterface()) {
0131:                        env.error(where, "inner.interface");
0132:                    } else if (isStatic()) {
0133:                        env.error(where, "static.inner.class", this );
0134:                        this .modifiers &= ~M_STATIC;
0135:                        if (innerClassMember != null) {
0136:                            innerClassMember.subModifiers(M_STATIC);
0137:                        }
0138:                    }
0139:                }
0140:
0141:                if (isPrivate() && outerClass == null) {
0142:                    env.error(where, "private.class", this );
0143:                    this .modifiers &= ~M_PRIVATE;
0144:                }
0145:                if (isProtected() && outerClass == null) {
0146:                    env.error(where, "protected.class", this );
0147:                    this .modifiers &= ~M_PROTECTED;
0148:                }
0149:                /*----*
0150:                if ((isPublic() || isProtected()) && isInsideLocal()) {
0151:                    env.error(where, "warn.public.local.class", this);
0152:                }
0153:                 *----*/
0154:
0155:                // maybe define an uplevel "A.this" current instance field
0156:                if (!isTopLevel() && !isLocal()) {
0157:                    LocalMember outerArg = ((SourceClass) outerClass)
0158:                            .getThisArgument();
0159:                    UplevelReference r = getReference(outerArg);
0160:                    setOuterMember(r.getLocalField(env));
0161:                }
0162:
0163:                // Set simple, unmangled local name for a local or anonymous class.
0164:                // NOTE: It would be OK to do this unconditionally, as null is the
0165:                // correct value for a member (non-local) class.
0166:                if (localName != null)
0167:                    setLocalName(localName);
0168:
0169:                // Check for inner class with same simple name as one of
0170:                // its enclosing classes.  Note that 'getLocalName' returns
0171:                // the simple, unmangled source-level name of any class.
0172:                // The previous version of this code was not careful to avoid
0173:                // mangled local class names.  This version fixes 4047746.
0174:                Identifier this Name = getLocalName();
0175:                if (this Name != idNull) {
0176:                    // Test above suppresses error for nested anonymous classes,
0177:                    // which have an internal "name", but are not named in source code.
0178:                    for (ClassDefinition scope = outerClass; scope != null; scope = scope
0179:                            .getOuterClass()) {
0180:                        Identifier outerName = scope.getLocalName();
0181:                        if (this Name.equals(outerName))
0182:                            env.error(where, "inner.redefined", this Name);
0183:                    }
0184:                }
0185:            }
0186:
0187:            /**
0188:             * Return last position in this class.
0189:             * @see #getWhere
0190:             */
0191:            public long getEndPosition() {
0192:                return endPosition;
0193:            }
0194:
0195:            public void setEndPosition(long endPosition) {
0196:                this .endPosition = endPosition;
0197:            }
0198:
0199:            // JCOV
0200:            /** 
0201:             * Return absolute name of source file
0202:             */
0203:            public String getAbsoluteName() {
0204:                String AbsName = ((ClassFile) getSource()).getAbsoluteName();
0205:
0206:                return AbsName;
0207:            }
0208:
0209:            //end JCOV
0210:
0211:            /**
0212:             * Return imports
0213:             */
0214:            public Imports getImports() {
0215:                return toplevelEnv.getImports();
0216:            }
0217:
0218:            /**
0219:             * Find or create my "this" argument, which is used for all methods.
0220:             */
0221:            public LocalMember getThisArgument() {
0222:                if (this Arg == null) {
0223:                    this Arg = new LocalMember(where, this , 0, getType(), idThis);
0224:                }
0225:                return this Arg;
0226:            }
0227:
0228:            /**
0229:             * Add a dependency
0230:             */
0231:            public void addDependency(ClassDeclaration c) {
0232:                if (tab != null) {
0233:                    tab.put(c);
0234:                }
0235:                // If doing -xdepend option, save away list of class dependencies
0236:                //   making sure to NOT include duplicates or the class we are in
0237:                //   (Hashtable's put() makes sure we don't have duplicates)
0238:                if (toplevelEnv.print_dependencies()
0239:                        && c != getClassDeclaration()) {
0240:                    deps.put(c, c);
0241:                }
0242:            }
0243:
0244:            /**
0245:             * Add a field (check it first)
0246:             */
0247:            public void addMember(Environment env, MemberDefinition f) {
0248:                // Make sure the access permissions are self-consistent:
0249:                switch (f.getModifiers() & (M_PUBLIC | M_PRIVATE | M_PROTECTED)) {
0250:                case M_PUBLIC:
0251:                case M_PRIVATE:
0252:                case M_PROTECTED:
0253:                case 0:
0254:                    break;
0255:                default:
0256:                    env.error(f.getWhere(), "inconsistent.modifier", f);
0257:                    // Cut out the more restrictive modifier(s):
0258:                    if (f.isPublic()) {
0259:                        f.subModifiers(M_PRIVATE | M_PROTECTED);
0260:                    } else {
0261:                        f.subModifiers(M_PRIVATE);
0262:                    }
0263:                    break;
0264:                }
0265:
0266:                // Note exemption for synthetic members below.
0267:                if (f.isStatic() && !isTopLevel() && !f.isSynthetic()) {
0268:                    if (f.isMethod()) {
0269:                        env.error(f.getWhere(), "static.inner.method", f, this );
0270:                        f.subModifiers(M_STATIC);
0271:                    } else if (f.isVariable()) {
0272:                        if (!f.isFinal() || f.isBlankFinal()) {
0273:                            env.error(f.getWhere(), "static.inner.field", f
0274:                                    .getName(), this );
0275:                            f.subModifiers(M_STATIC);
0276:                        }
0277:                        // Even if a static passes this test, there is still another
0278:                        // check in 'SourceMember.check'.  The check is delayed so
0279:                        // that the initializer may be inspected more closely, using
0280:                        // 'isConstant()'.  Part of fix for 4095568.
0281:                    } else {
0282:                        // Static inner classes are diagnosed in 'SourceClass.<init>'.
0283:                        f.subModifiers(M_STATIC);
0284:                    }
0285:                }
0286:
0287:                if (f.isMethod()) {
0288:                    if (f.isConstructor()) {
0289:                        if (f.getClassDefinition().isInterface()) {
0290:                            env.error(f.getWhere(), "intf.constructor");
0291:                            return;
0292:                        }
0293:                        if (f.isNative() || f.isAbstract() || f.isStatic()
0294:                                || f.isSynchronized() || f.isFinal()) {
0295:                            env.error(f.getWhere(), "constr.modifier", f);
0296:                            f.subModifiers(M_NATIVE | M_ABSTRACT | M_STATIC
0297:                                    | M_SYNCHRONIZED | M_FINAL);
0298:                        }
0299:                    } else if (f.isInitializer()) {
0300:                        if (f.getClassDefinition().isInterface()) {
0301:                            env.error(f.getWhere(), "intf.initializer");
0302:                            return;
0303:                        }
0304:                    }
0305:
0306:                    // f is not allowed to return an array of void
0307:                    if ((f.getType().getReturnType()).isVoidArray()) {
0308:                        env.error(f.getWhere(), "void.array");
0309:                    }
0310:
0311:                    if (f.getClassDefinition().isInterface()
0312:                            && (f.isStatic() || f.isSynchronized()
0313:                                    || f.isNative() || f.isFinal()
0314:                                    || f.isPrivate() || f.isProtected())) {
0315:                        env.error(f.getWhere(), "intf.modifier.method", f);
0316:                        f.subModifiers(M_STATIC | M_SYNCHRONIZED | M_NATIVE
0317:                                | M_FINAL | M_PRIVATE);
0318:                    }
0319:                    if (f.isTransient()) {
0320:                        env.error(f.getWhere(), "transient.meth", f);
0321:                        f.subModifiers(M_TRANSIENT);
0322:                    }
0323:                    if (f.isVolatile()) {
0324:                        env.error(f.getWhere(), "volatile.meth", f);
0325:                        f.subModifiers(M_VOLATILE);
0326:                    }
0327:                    if (f.isAbstract()) {
0328:                        if (f.isPrivate()) {
0329:                            env.error(f.getWhere(),
0330:                                    "abstract.private.modifier", f);
0331:                            f.subModifiers(M_PRIVATE);
0332:                        }
0333:                        if (f.isStatic()) {
0334:                            env.error(f.getWhere(), "abstract.static.modifier",
0335:                                    f);
0336:                            f.subModifiers(M_STATIC);
0337:                        }
0338:                        if (f.isFinal()) {
0339:                            env.error(f.getWhere(), "abstract.final.modifier",
0340:                                    f);
0341:                            f.subModifiers(M_FINAL);
0342:                        }
0343:                        if (f.isNative()) {
0344:                            env.error(f.getWhere(), "abstract.native.modifier",
0345:                                    f);
0346:                            f.subModifiers(M_NATIVE);
0347:                        }
0348:                        if (f.isSynchronized()) {
0349:                            env.error(f.getWhere(),
0350:                                    "abstract.synchronized.modifier", f);
0351:                            f.subModifiers(M_SYNCHRONIZED);
0352:                        }
0353:                    }
0354:                    if (f.isAbstract() || f.isNative()) {
0355:                        if (f.getValue() != null) {
0356:                            env.error(f.getWhere(), "invalid.meth.body", f);
0357:                            f.setValue(null);
0358:                        }
0359:                    } else {
0360:                        if (f.getValue() == null) {
0361:                            if (f.isConstructor()) {
0362:                                env.error(f.getWhere(), "no.constructor.body",
0363:                                        f);
0364:                            } else {
0365:                                env.error(f.getWhere(), "no.meth.body", f);
0366:                            }
0367:                            f.addModifiers(M_ABSTRACT);
0368:                        }
0369:                    }
0370:                    Vector arguments = f.getArguments();
0371:                    if (arguments != null) {
0372:                        // arguments can be null if this is an implicit abstract method
0373:                        int argumentLength = arguments.size();
0374:                        Type argTypes[] = f.getType().getArgumentTypes();
0375:                        for (int i = 0; i < argTypes.length; i++) {
0376:                            Object arg = arguments.elementAt(i);
0377:                            long where = f.getWhere();
0378:                            if (arg instanceof  MemberDefinition) {
0379:                                where = ((MemberDefinition) arg).getWhere();
0380:                                arg = ((MemberDefinition) arg).getName();
0381:                            }
0382:                            // (arg should be an Identifier now)
0383:                            if (argTypes[i].isType(TC_VOID)
0384:                                    || argTypes[i].isVoidArray()) {
0385:                                env.error(where, "void.argument", arg);
0386:                            }
0387:                        }
0388:                    }
0389:                } else if (f.isInnerClass()) {
0390:                    if (f.isVolatile() || f.isTransient() || f.isNative()
0391:                            || f.isSynchronized()) {
0392:                        env.error(f.getWhere(), "inner.modifier", f);
0393:                        f.subModifiers(M_VOLATILE | M_TRANSIENT | M_NATIVE
0394:                                | M_SYNCHRONIZED);
0395:                    }
0396:                    // same check as for fields, below:
0397:                    if (f.getClassDefinition().isInterface()
0398:                            && (f.isPrivate() || f.isProtected())) {
0399:                        env.error(f.getWhere(), "intf.modifier.field", f);
0400:                        f.subModifiers(M_PRIVATE | M_PROTECTED);
0401:                        f.addModifiers(M_PUBLIC);
0402:                        // Fix up the class itself to agree with
0403:                        // the inner-class member.
0404:                        ClassDefinition c = f.getInnerClass();
0405:                        c.subModifiers(M_PRIVATE | M_PROTECTED);
0406:                        c.addModifiers(M_PUBLIC);
0407:                    }
0408:                } else {
0409:                    if (f.getType().isType(TC_VOID)
0410:                            || f.getType().isVoidArray()) {
0411:                        env.error(f.getWhere(), "void.inst.var", f.getName());
0412:                        // REMIND: set type to error
0413:                        return;
0414:                    }
0415:
0416:                    if (f.isSynchronized() || f.isAbstract() || f.isNative()) {
0417:                        env.error(f.getWhere(), "var.modifier", f);
0418:                        f.subModifiers(M_SYNCHRONIZED | M_ABSTRACT | M_NATIVE);
0419:                    }
0420:                    if (f.isStrict()) {
0421:                        env.error(f.getWhere(), "var.floatmodifier", f);
0422:                        f.subModifiers(M_STRICTFP);
0423:                    }
0424:                    if (f.isTransient() && isInterface()) {
0425:                        env.error(f.getWhere(), "transient.modifier", f);
0426:                        f.subModifiers(M_TRANSIENT);
0427:                    }
0428:                    if (f.isVolatile() && (isInterface() || f.isFinal())) {
0429:                        env.error(f.getWhere(), "volatile.modifier", f);
0430:                        f.subModifiers(M_VOLATILE);
0431:                    }
0432:                    if (f.isFinal() && (f.getValue() == null) && isInterface()) {
0433:                        env.error(f.getWhere(), "initializer.needed", f);
0434:                        f.subModifiers(M_FINAL);
0435:                    }
0436:
0437:                    if (f.getClassDefinition().isInterface()
0438:                            && (f.isPrivate() || f.isProtected())) {
0439:                        env.error(f.getWhere(), "intf.modifier.field", f);
0440:                        f.subModifiers(M_PRIVATE | M_PROTECTED);
0441:                        f.addModifiers(M_PUBLIC);
0442:                    }
0443:                }
0444:                // Do not check for repeated methods here:  Types are not yet resolved.
0445:                if (!f.isInitializer()) {
0446:                    for (MemberDefinition f2 = getFirstMatch(f.getName()); f2 != null; f2 = f2
0447:                            .getNextMatch()) {
0448:                        if (f.isVariable() && f2.isVariable()) {
0449:                            env.error(f.getWhere(), "var.multidef", f, f2);
0450:                            return;
0451:                        } else if (f.isInnerClass() && f2.isInnerClass()
0452:                                && !f.getInnerClass().isLocal()
0453:                                && !f2.getInnerClass().isLocal()) {
0454:                            // Found a duplicate inner-class member.
0455:                            // Duplicate local classes are detected in
0456:                            // 'VarDeclarationStatement.checkDeclaration'.
0457:                            env.error(f.getWhere(), "inner.class.multidef", f);
0458:                            return;
0459:                        }
0460:                    }
0461:                }
0462:
0463:                super .addMember(env, f);
0464:            }
0465:
0466:            /**
0467:             * Create an environment suitable for checking this class.
0468:             * Make sure the source and imports are set right.
0469:             * Make sure the environment contains no context information.
0470:             * (Actually, throw away env altogether and use toplevelEnv instead.)
0471:             */
0472:            public Environment setupEnv(Environment env) {
0473:                // In some cases, we go to some trouble to create the 'env' argument
0474:                // that is discarded.  We should remove the 'env' argument entirely
0475:                // as well as the vestigial code that supports it.  See comments on
0476:                // 'newEnvironment' in 'checkInternal' below.
0477:                return new Environment(toplevelEnv, this );
0478:            }
0479:
0480:            /**
0481:             * A source class never reports deprecation, since the compiler
0482:             * allows access to deprecated features that are being compiled
0483:             * in the same job.
0484:             */
0485:            public boolean reportDeprecated(Environment env) {
0486:                return false;
0487:            }
0488:
0489:            /**
0490:             * See if the source file of this class is right.
0491:             * @see ClassDefinition#noteUsedBy
0492:             */
0493:            public void noteUsedBy(ClassDefinition ref, long where,
0494:                    Environment env) {
0495:                // If this class is not public, watch for cross-file references.
0496:                super .noteUsedBy(ref, where, env);
0497:                ClassDefinition def = this ;
0498:                while (def.isInnerClass()) {
0499:                    def = def.getOuterClass();
0500:                }
0501:                if (def.isPublic()) {
0502:                    return; // already checked
0503:                }
0504:                while (ref.isInnerClass()) {
0505:                    ref = ref.getOuterClass();
0506:                }
0507:                if (def.getSource().equals(ref.getSource())) {
0508:                    return; // intra-file reference
0509:                }
0510:                ((SourceClass) def).checkSourceFile(env, where);
0511:            }
0512:
0513:            /**
0514:             * Check this class and all its fields.
0515:             */
0516:            public void check(Environment env) throws ClassNotFound {
0517:                if (tracing)
0518:                    env.dtEnter("SourceClass.check: " + getName());
0519:                if (isInsideLocal()) {
0520:                    // An inaccessible class gets checked when the surrounding
0521:                    // block is checked.
0522:                    // QUERY: Should this case ever occur?
0523:                    // What would invoke checking of a local class aside from
0524:                    // checking the surrounding method body?
0525:                    if (tracing)
0526:                        env.dtEvent("SourceClass.check: INSIDE LOCAL "
0527:                                + getOuterClass().getName());
0528:                    getOuterClass().check(env);
0529:                } else {
0530:                    if (isInnerClass()) {
0531:                        if (tracing)
0532:                            env.dtEvent("SourceClass.check: INNER CLASS "
0533:                                    + getOuterClass().getName());
0534:                        // Make sure the outer is checked first.
0535:                        ((SourceClass) getOuterClass()).maybeCheck(env);
0536:                    }
0537:                    Vset vset = new Vset();
0538:                    Context ctx = null;
0539:                    if (tracing)
0540:                        env.dtEvent("SourceClass.check: CHECK INTERNAL "
0541:                                + getName());
0542:                    vset = checkInternal(setupEnv(env), ctx, vset);
0543:                    // drop vset here
0544:                }
0545:                if (tracing)
0546:                    env.dtExit("SourceClass.check: " + getName());
0547:            }
0548:
0549:            private void maybeCheck(Environment env) throws ClassNotFound {
0550:                if (tracing)
0551:                    env.dtEvent("SourceClass.maybeCheck: " + getName());
0552:                // Check this class now, if it has not yet been checked.
0553:                // Cf. Main.compile().  Perhaps this code belongs there somehow.
0554:                ClassDeclaration c = getClassDeclaration();
0555:                if (c.getStatus() == CS_PARSED) {
0556:                    // Set it first to avoid vicious circularity:
0557:                    c.setDefinition(this , CS_CHECKED);
0558:                    check(env);
0559:                }
0560:            }
0561:
0562:            private Vset checkInternal(Environment env, Context ctx, Vset vset)
0563:                    throws ClassNotFound {
0564:                Identifier nm = getClassDeclaration().getName();
0565:                if (env.verbose()) {
0566:                    env.output("[checking class " + nm + "]");
0567:                }
0568:
0569:                // Save context enclosing class for later access
0570:                // by 'ClassDefinition.resolveName.'
0571:                classContext = ctx;
0572:
0573:                // At present, the call to 'newEnvironment' is not needed.
0574:                // The incoming environment to 'basicCheck' is always passed to
0575:                // 'setupEnv', which discards it completely.  This is also the
0576:                // only call to 'newEnvironment', which is now apparently dead code.
0577:                basicCheck(Context.newEnvironment(env, ctx));
0578:
0579:                // Validate access for all inner-class components
0580:                // of a qualified name, not just the last one, which
0581:                // is checked below.  Yes, this is a dirty hack...
0582:                // Much of this code was cribbed from 'checkSupers'.
0583:                // Part of fix for 4094658.
0584:                ClassDeclaration sup = getSuperClass();
0585:                if (sup != null) {
0586:                    long where = getWhere();
0587:                    where = IdentifierToken.getWhere(super ClassId, where);
0588:                    env.resolveExtendsByName(where, this , sup.getName());
0589:                }
0590:                for (int i = 0; i < interfaces.length; i++) {
0591:                    ClassDeclaration intf = interfaces[i];
0592:                    long where = getWhere();
0593:                    // Error localization fails here if interfaces were
0594:                    // elided during error recovery from an invalid one.
0595:                    if (interfaceIds != null
0596:                            && interfaceIds.length == interfaces.length) {
0597:                        where = IdentifierToken
0598:                                .getWhere(interfaceIds[i], where);
0599:                    }
0600:                    env.resolveExtendsByName(where, this , intf.getName());
0601:                }
0602:
0603:                // Does the name already exist in an imported package?
0604:                // See JLS 8.1 for the precise rules.
0605:                if (!isInnerClass() && !isInsideLocal()) {
0606:                    // Discard package qualification for the import checks.
0607:                    Identifier simpleName = nm.getName();
0608:                    try {
0609:                        // We want this to throw a ClassNotFound exception
0610:                        Imports imports = toplevelEnv.getImports();
0611:                        Identifier ID = imports.resolve(env, simpleName);
0612:                        if (ID != getName())
0613:                            env.error(where, "class.multidef.import",
0614:                                    simpleName, ID);
0615:                    } catch (AmbiguousClass e) {
0616:                        // At least one of e.name1 and e.name2 must be different
0617:                        Identifier ID = (e.name1 != getName()) ? e.name1
0618:                                : e.name2;
0619:                        env.error(where, "class.multidef.import", simpleName,
0620:                                ID);
0621:                    } catch (ClassNotFound e) {
0622:                        // we want this to happen
0623:                    }
0624:
0625:                    // Make sure that no package with the same fully qualified
0626:                    // name exists.  This is required by JLS 7.1.  We only need
0627:                    // to perform this check for top level classes -- it isn't
0628:                    // necessary for inner classes.  (bug 4101529)
0629:                    //
0630:                    // This change has been backed out because, on WIN32, it
0631:                    // failed to distinguish between java.awt.event and
0632:                    // java.awt.Event when looking for a directory.  We will
0633:                    // add this back in later.
0634:                    //
0635:                    // try {
0636:                    //	if (env.getPackage(nm).exists()) {
0637:                    //	    env.error(where, "class.package.conflict", nm);
0638:                    //	}
0639:                    // } catch (java.io.IOException ee) {
0640:                    //	env.error(where, "io.exception.package", nm);
0641:                    // }
0642:
0643:                    // Make sure it was defined in the right file
0644:                    if (isPublic()) {
0645:                        checkSourceFile(env, getWhere());
0646:                    }
0647:                }
0648:
0649:                vset = checkMembers(env, ctx, vset);
0650:                return vset;
0651:            }
0652:
0653:            private boolean sourceFileChecked = false;
0654:
0655:            /**
0656:             * See if the source file of this class is of the right name.
0657:             */
0658:            public void checkSourceFile(Environment env, long where) {
0659:                // one error per offending class is sufficient
0660:                if (sourceFileChecked)
0661:                    return;
0662:                sourceFileChecked = true;
0663:
0664:                String fname = getName().getName() + ".java";
0665:                String src = ((ClassFile) getSource()).getName();
0666:                if (!src.equals(fname)) {
0667:                    if (isPublic()) {
0668:                        env.error(where, "public.class.file", this , fname);
0669:                    } else {
0670:                        env.error(where, "warn.package.class.file", this , src,
0671:                                fname);
0672:                    }
0673:                }
0674:            }
0675:
0676:            // Set true if superclass (but not necessarily superinterfaces) have
0677:            // been checked.  If the superclass is still unresolved, then an error
0678:            // message should have been issued, and we assume that no further
0679:            // resolution is possible.
0680:            private boolean super sChecked = false;
0681:
0682:            /**
0683:             * Overrides 'ClassDefinition.getSuperClass'.
0684:             */
0685:
0686:            public ClassDeclaration getSuperClass(Environment env) {
0687:                if (tracing)
0688:                    env.dtEnter("SourceClass.getSuperClass: " + this );
0689:                // Superclass may fail to be set because of error recovery,
0690:                // so resolve types here only if 'checkSupers' has not yet
0691:                // completed its checks on the superclass.
0692:                // QUERY: Can we eliminate the need to resolve superclasses on demand?
0693:                // See comments in 'checkSupers' and in 'ClassDefinition.getInnerClass'.
0694:                if (super Class == null && super ClassId != null
0695:                        && !super sChecked) {
0696:                    resolveTypeStructure(env);
0697:                    // We used to report an error here if the superclass was not
0698:                    // resolved.  Having moved the call to 'checkSupers' from 'basicCheck'
0699:                    // into 'resolveTypeStructure', the errors reported here should have
0700:                    // already been reported.  Furthermore, error recovery can null out
0701:                    // the superclass, which would cause a spurious error from the test here.
0702:                }
0703:                if (tracing)
0704:                    env.dtExit("SourceClass.getSuperClass: " + this );
0705:                return super Class;
0706:            }
0707:
0708:            /**
0709:             * Check that all superclasses and superinterfaces are defined and
0710:             * well formed.  Among other checks, verify that the inheritance
0711:             * graph is acyclic.  Called from 'resolveTypeStructure'.
0712:             */
0713:
0714:            private void checkSupers(Environment env) throws ClassNotFound {
0715:
0716:                // *** DEBUG ***
0717:                super sCheckStarted = true;
0718:
0719:                if (tracing)
0720:                    env.dtEnter("SourceClass.checkSupers: " + this );
0721:
0722:                if (isInterface()) {
0723:                    if (isFinal()) {
0724:                        Identifier nm = getClassDeclaration().getName();
0725:                        env.error(getWhere(), "final.intf", nm);
0726:                        // Interfaces have no superclass.  Superinterfaces
0727:                        // are checked below, in code shared with the class case.
0728:                    }
0729:                } else {
0730:                    // Check superclass.
0731:                    // Call to 'getSuperClass(env)' (note argument) attempts
0732:                    // 'resolveTypeStructure' if superclass has not successfully
0733:                    // been resolved.  Since we have just now called 'resolveSupers'
0734:                    // (see our call in 'resolveTypeStructure'), it is not clear
0735:                    // that this can do any good.  Why not 'getSuperClass()' here?
0736:                    if (getSuperClass(env) != null) {
0737:                        long where = getWhere();
0738:                        where = IdentifierToken.getWhere(super ClassId, where);
0739:                        try {
0740:                            ClassDefinition def = getSuperClass()
0741:                                    .getClassDefinition(env);
0742:                            // Resolve superclass and its ancestors.
0743:                            def.resolveTypeStructure(env);
0744:                            // Access to the superclass should be checked relative
0745:                            // to the surrounding context, not as if the reference
0746:                            // appeared within the class body. Changed 'canAccess'
0747:                            // to 'extendsCanAccess' to fix 4087314.
0748:                            if (!extendsCanAccess(env, getSuperClass())) {
0749:                                env.error(where, "cant.access.class",
0750:                                        getSuperClass());
0751:                                // Might it be a better recovery to let the access go through?
0752:                                super Class = null;
0753:                            } else if (def.isFinal()) {
0754:                                env.error(where, "super.is.final",
0755:                                        getSuperClass());
0756:                                // Might it be a better recovery to let the access go through?
0757:                                super Class = null;
0758:                            } else if (def.isInterface()) {
0759:                                env.error(where, "super.is.intf",
0760:                                        getSuperClass());
0761:                                super Class = null;
0762:                            } else if (super ClassOf(env, getSuperClass())) {
0763:                                env.error(where, "cyclic.super");
0764:                                super Class = null;
0765:                            } else {
0766:                                def.noteUsedBy(this , where, env);
0767:                            }
0768:                            if (super Class == null) {
0769:                                def = null;
0770:                            } else {
0771:                                // If we have a valid superclass, check its
0772:                                // supers as well, and so on up to root class.
0773:                                // Call to 'enclosingClassOf' will raise
0774:                                // 'NullPointerException' if 'def' is null,
0775:                                // so omit this check as error recovery.
0776:                                ClassDefinition sup = def;
0777:                                for (;;) {
0778:                                    if (enclosingClassOf(sup)) {
0779:                                        // Do we need a similar test for
0780:                                        // interfaces?  See bugid 4038529.
0781:                                        env.error(where, "super.is.inner");
0782:                                        super Class = null;
0783:                                        break;
0784:                                    }
0785:                                    // Since we resolved the superclass and its
0786:                                    // ancestors above, we should not discover
0787:                                    // any unresolved classes on the superclass
0788:                                    // chain.  It should thus be sufficient to
0789:                                    // call 'getSuperClass()' (no argument) here.
0790:                                    ClassDeclaration s = sup.getSuperClass(env);
0791:                                    if (s == null) {
0792:                                        // Superclass not resolved due to error.
0793:                                        break;
0794:                                    }
0795:                                    sup = s.getClassDefinition(env);
0796:                                }
0797:                            }
0798:                        } catch (ClassNotFound e) {
0799:                            // Error is detected in call to 'getClassDefinition'.
0800:                            // The class may actually exist but be ambiguous.
0801:                            // Call env.resolve(e.name) to see if it is.
0802:                            // env.resolve(name) will definitely tell us if the
0803:                            // class is ambiguous, but may not necessarily tell
0804:                            // us if the class is not found.
0805:                            // (part of solution for 4059855)
0806:                            reportError: {
0807:                                try {
0808:                                    env.resolve(e.name);
0809:                                } catch (AmbiguousClass ee) {
0810:                                    env.error(where, "ambig.class", ee.name1,
0811:                                            ee.name2);
0812:                                    super Class = null;
0813:                                    break reportError;
0814:                                } catch (ClassNotFound ee) {
0815:                                    // fall through
0816:                                }
0817:                                env.error(where, "super.not.found", e.name,
0818:                                        this );
0819:                                super Class = null;
0820:                            } // The break exits this block
0821:                        }
0822:
0823:                    } else {
0824:                        // Superclass was null on entry, after call to
0825:                        // 'resolveSupers'.  This should normally not happen,
0826:                        // as 'resolveSupers' sets 'superClass' to a non-null
0827:                        // value for all named classes, except for one special
0828:                        // case: 'java.lang.Object', which has no superclass.
0829:                        if (isAnonymous()) {
0830:                            // checker should have filled it in first
0831:                            throw new CompilerError("anonymous super");
0832:                        } else if (!getName().equals(idJavaLangObject)) {
0833:                            throw new CompilerError("unresolved super");
0834:                        }
0835:                    }
0836:                }
0837:
0838:                // At this point, if 'superClass' is null due to an error
0839:                // in the user program, a message should have been issued.
0840:                super sChecked = true;
0841:
0842:                // Check interfaces
0843:                for (int i = 0; i < interfaces.length; i++) {
0844:                    ClassDeclaration intf = interfaces[i];
0845:                    long where = getWhere();
0846:                    if (interfaceIds != null
0847:                            && interfaceIds.length == interfaces.length) {
0848:                        where = IdentifierToken
0849:                                .getWhere(interfaceIds[i], where);
0850:                    }
0851:                    try {
0852:                        ClassDefinition def = intf.getClassDefinition(env);
0853:                        // Resolve superinterface and its ancestors.
0854:                        def.resolveTypeStructure(env);
0855:                        // Check superinterface access in the correct context.
0856:                        // Changed 'canAccess' to 'extendsCanAccess' to fix 4087314.
0857:                        if (!extendsCanAccess(env, intf)) {
0858:                            env.error(where, "cant.access.class", intf);
0859:                        } else if (!intf.getClassDefinition(env).isInterface()) {
0860:                            env.error(where, "not.intf", intf);
0861:                        } else if (isInterface() && implementedBy(env, intf)) {
0862:                            env.error(where, "cyclic.intf", intf);
0863:                        } else {
0864:                            def.noteUsedBy(this , where, env);
0865:                            // Interface is OK, leave it in the interface list.
0866:                            continue;
0867:                        }
0868:                    } catch (ClassNotFound e) {
0869:                        // The interface may actually exist but be ambiguous.
0870:                        // Call env.resolve(e.name) to see if it is.
0871:                        // env.resolve(name) will definitely tell us if the
0872:                        // interface is ambiguous, but may not necessarily tell
0873:                        // us if the interface is not found.
0874:                        // (part of solution for 4059855)
0875:                        reportError2: {
0876:                            try {
0877:                                env.resolve(e.name);
0878:                            } catch (AmbiguousClass ee) {
0879:                                env.error(where, "ambig.class", ee.name1,
0880:                                        ee.name2);
0881:                                super Class = null;
0882:                                break reportError2;
0883:                            } catch (ClassNotFound ee) {
0884:                                // fall through
0885:                            }
0886:                            env.error(where, "intf.not.found", e.name, this );
0887:                            super Class = null;
0888:                        } // The break exits this block
0889:                    }
0890:                    // Remove this interface from the list of interfaces
0891:                    // as recovery from an error.
0892:                    ClassDeclaration newInterfaces[] = new ClassDeclaration[interfaces.length - 1];
0893:                    System.arraycopy(interfaces, 0, newInterfaces, 0, i);
0894:                    System.arraycopy(interfaces, i + 1, newInterfaces, i,
0895:                            newInterfaces.length - i);
0896:                    interfaces = newInterfaces;
0897:                    --i;
0898:                }
0899:                if (tracing)
0900:                    env.dtExit("SourceClass.checkSupers: " + this );
0901:            }
0902:
0903:            /**
0904:             * Check all of the members of this class.
0905:             * <p>
0906:             * Inner classes are checked in the following way.  Any class which
0907:             * is immediately contained in a block (anonymous and local classes)
0908:             * is checked along with its containing method; see the
0909:             * SourceMember.check() method for more information.  Member classes
0910:             * of this class are checked immediately after this class, unless this
0911:             * class is insideLocal(), in which case, they are checked with the
0912:             * rest of the members.
0913:             */
0914:            private Vset checkMembers(Environment env, Context ctx, Vset vset)
0915:                    throws ClassNotFound {
0916:
0917:                // bail out if there were any errors
0918:                if (getError()) {
0919:                    return vset;
0920:                }
0921:
0922:                // Make sure that all of our member classes have been
0923:                // basicCheck'ed before we check the rest of our members.
0924:                // If our member classes haven't been basicCheck'ed, then they
0925:                // may not have <init> methods.  It is important that they
0926:                // have <init> methods so we can process NewInstanceExpressions
0927:                // correctly.  This problem didn't occur before 1.2beta1.
0928:                // This is a fix for bug 4082816.
0929:                for (MemberDefinition f = getFirstMember(); f != null; f = f
0930:                        .getNextMember()) {
0931:                    if (f.isInnerClass()) {
0932:                        // System.out.println("Considering " + f + " in " + this);
0933:                        SourceClass cdef = (SourceClass) f.getInnerClass();
0934:                        if (cdef.isMember()) {
0935:                            cdef.basicCheck(env);
0936:                        }
0937:                    }
0938:                }
0939:
0940:                if (isFinal() && isAbstract()) {
0941:                    env
0942:                            .error(where, "final.abstract", this .getName()
0943:                                    .getName());
0944:                }
0945:
0946:                // This class should be abstract if there are any abstract methods
0947:                // in our parent classes and interfaces which we do not override.
0948:                // There are odd cases when, even though we cannot access some
0949:                // abstract method from our superclass, that abstract method can
0950:                // still force this class to be abstract.  See the discussion in
0951:                // bug id 1240831.
0952:                if (!isInterface() && !isAbstract() && mustBeAbstract(env)) {
0953:                    // Set the class abstract.
0954:                    modifiers |= M_ABSTRACT;
0955:
0956:                    // Tell the user which methods force this class to be abstract.
0957:
0958:                    // First list all of the "unimplementable" abstract methods.
0959:                    Iterator iter = getPermanentlyAbstractMethods();
0960:                    while (iter.hasNext()) {
0961:                        MemberDefinition method = (MemberDefinition) iter
0962:                                .next();
0963:                        // We couldn't override this method even if we
0964:                        // wanted to.  Try to make the error message
0965:                        // as non-confusing as possible.
0966:                        env.error(where, "abstract.class.cannot.override",
0967:                                getClassDeclaration(), method, method
0968:                                        .getDefiningClassDeclaration());
0969:                    }
0970:
0971:                    // Now list all of the traditional abstract methods.
0972:                    iter = getMethods(env);
0973:                    while (iter.hasNext()) {
0974:                        // For each method, check if it is abstract.  If it is,
0975:                        // output an appropriate error message.
0976:                        MemberDefinition method = (MemberDefinition) iter
0977:                                .next();
0978:                        if (method.isAbstract()) {
0979:                            env.error(where, "abstract.class",
0980:                                    getClassDeclaration(), method, method
0981:                                            .getDefiningClassDeclaration());
0982:                        }
0983:                    }
0984:                }
0985:
0986:                // Check the instance variables in a pre-pass before any constructors.
0987:                // This lets constructors "in-line" any initializers directly.
0988:                // It also lets us do some definite assignment checks on variables.
0989:                Context ctxInit = new Context(ctx);
0990:                Vset vsInst = vset.copy();
0991:                Vset vsClass = vset.copy();
0992:
0993:                // Do definite assignment checking on blank finals.
0994:                // Other variables do not need such checks.  The simple textual
0995:                // ordering constraints implemented by MemberDefinition.canReach()
0996:                // are necessary and sufficient for the other variables.
0997:                // Note that within non-static code, all statics are always
0998:                // definitely assigned, and vice-versa.
0999:                for (MemberDefinition f = getFirstMember(); f != null; f = f
1000:                        .getNextMember()) {
1001:                    if (f.isVariable() && f.isBlankFinal()) {
1002:                        // The following allocates a LocalMember object as a proxy
1003:                        // to represent the field.
1004:                        int number = ctxInit.declareFieldNumber(f);
1005:                        if (f.isStatic()) {
1006:                            vsClass = vsClass.addVarUnassigned(number);
1007:                            vsInst = vsInst.addVar(number);
1008:                        } else {
1009:                            vsInst = vsInst.addVarUnassigned(number);
1010:                            vsClass = vsClass.addVar(number);
1011:                        }
1012:                    }
1013:                }
1014:
1015:                // For instance variable checks, use a context with a "this" parameter.
1016:                Context ctxInst = new Context(ctxInit, this );
1017:                LocalMember this Arg = getThisArgument();
1018:                int this Number = ctxInst.declare(env, this Arg);
1019:                vsInst = vsInst.addVar(this Number);
1020:
1021:                // Do all the initializers in order, checking the definite
1022:                // assignment of blank finals.  Separate static from non-static.
1023:                for (MemberDefinition f = getFirstMember(); f != null; f = f
1024:                        .getNextMember()) {
1025:                    try {
1026:                        if (f.isVariable() || f.isInitializer()) {
1027:                            if (f.isStatic()) {
1028:                                vsClass = f.check(env, ctxInit, vsClass);
1029:                            } else {
1030:                                vsInst = f.check(env, ctxInst, vsInst);
1031:                            }
1032:                        }
1033:                    } catch (ClassNotFound ee) {
1034:                        env.error(f.getWhere(), "class.not.found", ee.name,
1035:                                this );
1036:                    }
1037:                }
1038:
1039:                checkBlankFinals(env, ctxInit, vsClass, true);
1040:
1041:                // Check the rest of the field definitions.
1042:                // (Note:  Re-checking a field is a no-op.)
1043:                for (MemberDefinition f = getFirstMember(); f != null; f = f
1044:                        .getNextMember()) {
1045:                    try {
1046:                        if (f.isConstructor()) {
1047:                            // When checking a constructor, an explicit call to
1048:                            // 'this(...)' makes all blank finals definitely assigned.
1049:                            // See 'MethodExpression.checkValue'.
1050:                            Vset vsCon = f.check(env, ctxInit, vsInst.copy());
1051:                            // May issue multiple messages for the same variable!!
1052:                            checkBlankFinals(env, ctxInit, vsCon, false);
1053:                            // (drop vsCon here)
1054:                        } else {
1055:                            Vset vsFld = f.check(env, ctx, vset.copy());
1056:                            // (drop vsFld here)
1057:                        }
1058:                    } catch (ClassNotFound ee) {
1059:                        env.error(f.getWhere(), "class.not.found", ee.name,
1060:                                this );
1061:                    }
1062:                }
1063:
1064:                // Must mark class as checked before visiting inner classes,
1065:                // as they may in turn request checking of the current class
1066:                // as an outer class.  Fix for bug id 4056774.
1067:                getClassDeclaration().setDefinition(this , CS_CHECKED);
1068:
1069:                // Also check other classes in the same nest.
1070:                // All checking of this nest must be finished before any
1071:                // of its classes emit bytecode.
1072:                // Otherwise, the inner classes might not have a chance to
1073:                // add access or class literal fields to the outer class.
1074:                for (MemberDefinition f = getFirstMember(); f != null; f = f
1075:                        .getNextMember()) {
1076:                    if (f.isInnerClass()) {
1077:                        SourceClass cdef = (SourceClass) f.getInnerClass();
1078:                        if (!cdef.isInsideLocal()) {
1079:                            cdef.maybeCheck(env);
1080:                        }
1081:                    }
1082:                }
1083:
1084:                // Note:  Since inner classes cannot set up-level variables,
1085:                // the returned vset is always equal to the passed-in vset.
1086:                // Still, we'll return it for the sake of regularity.
1087:                return vset;
1088:            }
1089:
1090:            /** Make sure all my blank finals exist now. */
1091:
1092:            private void checkBlankFinals(Environment env, Context ctxInit,
1093:                    Vset vset, boolean isStatic) {
1094:                for (int i = 0; i < ctxInit.getVarNumber(); i++) {
1095:                    if (!vset.testVar(i)) {
1096:                        MemberDefinition ff = ctxInit.getElement(i);
1097:                        if (ff != null && ff.isBlankFinal()
1098:                                && ff.isStatic() == isStatic
1099:                                && ff.getClassDefinition() == this ) {
1100:                            env.error(ff.getWhere(),
1101:                                    "final.var.not.initialized", ff.getName());
1102:                        }
1103:                    }
1104:                }
1105:            }
1106:
1107:            /**
1108:             * Check this class has its superclass and its interfaces.  Also
1109:             * force it to have an <init> method (if it doesn't already have one)
1110:             * and to have all the abstract methods of its parents.
1111:             */
1112:            private boolean basicChecking = false;
1113:            private boolean basicCheckDone = false;
1114:
1115:            protected void basicCheck(Environment env) throws ClassNotFound {
1116:
1117:                if (tracing)
1118:                    env.dtEnter("SourceClass.basicCheck: " + getName());
1119:
1120:                super .basicCheck(env);
1121:
1122:                if (basicChecking || basicCheckDone) {
1123:                    if (tracing)
1124:                        env.dtExit("SourceClass.basicCheck: OK " + getName());
1125:                    return;
1126:                }
1127:
1128:                if (tracing)
1129:                    env
1130:                            .dtEvent("SourceClass.basicCheck: CHECKING "
1131:                                    + getName());
1132:
1133:                basicChecking = true;
1134:
1135:                env = setupEnv(env);
1136:
1137:                Imports imports = env.getImports();
1138:                if (imports != null) {
1139:                    imports.resolve(env);
1140:                }
1141:
1142:                resolveTypeStructure(env);
1143:
1144:                // Check the existence of the superclass and all interfaces.
1145:                // Also responsible for breaking inheritance cycles.  This call
1146:                // has been moved to 'resolveTypeStructure', just after the call
1147:                // to 'resolveSupers', as inheritance cycles must be broken before
1148:                // resolving types within the members.  Fixes 4073739.
1149:                //   checkSupers(env);
1150:
1151:                if (!isInterface()) {
1152:
1153:                    // Add implicit <init> method, if necessary.
1154:                    // QUERY:  What keeps us from adding an implicit constructor
1155:                    // when the user explicitly declares one?  Is it truly guaranteed
1156:                    // that the declaration for such an explicit constructor will have
1157:                    // been processed by the time we arrive here?  In general, 'basicCheck'
1158:                    // is called very early, prior to the normal member checking phase.
1159:                    if (!hasConstructor()) {
1160:                        Node code = new CompoundStatement(getWhere(),
1161:                                new Statement[0]);
1162:                        Type t = Type.tMethod(Type.tVoid);
1163:
1164:                        // Default constructors inherit the access modifiers of their
1165:                        // class.  For non-inner classes, this follows from JLS 8.6.7,
1166:                        // as the only possible modifier is 'public'.  For the sake of
1167:                        // robustness in the presence of errors, we ignore any other
1168:                        // modifiers.  For inner classes, the rule needs to be extended 
1169:                        // in some way to account for the possibility of private and
1170:                        // protected classes.  We make the 'obvious' extension, however,
1171:                        // the inner classes spec is silent on this issue, and a definitive
1172:                        // resolution is needed.  See bugid 4087421.
1173:                        // WORKAROUND: A private constructor might need an access method,
1174:                        // but it is not possible to create one due to a restriction in
1175:                        // the verifier.  (This is a known problem -- see 4015397.)
1176:                        // We therefore do not inherit the 'private' modifier from the class,
1177:                        // allowing the default constructor to be package private.  This
1178:                        // workaround can be observed via reflection, but is otherwise
1179:                        // undetectable, as the constructor is always accessible within
1180:                        // the class in which its containing (private) class appears.
1181:                        int accessModifiers = getModifiers()
1182:                                & (isInnerClass() ? (M_PUBLIC | M_PROTECTED)
1183:                                        : M_PUBLIC);
1184:                        env.makeMemberDefinition(env, getWhere(), this , null,
1185:                                accessModifiers, t, idInit, null, null, code);
1186:                    }
1187:                }
1188:
1189:                // Only do the inheritance/override checks if they are turned on.
1190:                // The idea here is that they will be done in javac, but not
1191:                // in javadoc.  See the comment for turnOffChecks(), above.
1192:                if (doInheritanceChecks) {
1193:
1194:                    // Verify the compatibility of all inherited method definitions
1195:                    // by collecting all of our inheritable methods.
1196:                    collectInheritedMethods(env);
1197:                }
1198:
1199:                basicChecking = false;
1200:                basicCheckDone = true;
1201:                if (tracing)
1202:                    env.dtExit("SourceClass.basicCheck: " + getName());
1203:            }
1204:
1205:            /**
1206:             * Add a group of methods to this class as miranda methods.
1207:             *
1208:             * For a definition of Miranda methods, see the comment above the
1209:             * method addMirandaMethods() in the file
1210:             * sun/tools/java/ClassDeclaration.java
1211:             */
1212:            protected void addMirandaMethods(Environment env, Iterator mirandas) {
1213:
1214:                while (mirandas.hasNext()) {
1215:                    MemberDefinition method = (MemberDefinition) mirandas
1216:                            .next();
1217:
1218:                    addMember(method);
1219:
1220:                    //System.out.println("adding miranda method " + newMethod + 
1221:                    //                   " to " + this);
1222:                }
1223:            }
1224:
1225:            /**
1226:             * <em>After parsing is complete</em>, resolve all names
1227:             * except those inside method bodies or initializers.
1228:             * In particular, this is the point at which we find out what
1229:             * kinds of variables and methods there are in the classes,
1230:             * and therefore what is each class's interface to the world.
1231:             * <p>
1232:             * Also perform certain other transformations, such as inserting
1233:             * "this$C" arguments into constructors, and reorganizing structure
1234:             * to flatten qualified member names.
1235:             * <p>
1236:             * Do not perform type-based or name-based consistency checks
1237:             * or normalizations (such as default nullary constructors),
1238:             * and do not attempt to compile code against this class,
1239:             * until after this phase.
1240:             */
1241:
1242:            private boolean resolving = false;
1243:
1244:            public void resolveTypeStructure(Environment env) {
1245:
1246:                if (tracing)
1247:                    env.dtEnter("SourceClass.resolveTypeStructure: "
1248:                            + getName());
1249:
1250:                // Resolve immediately enclosing type, which in turn
1251:                // forces resolution of all enclosing type declarations.
1252:                ClassDefinition oc = getOuterClass();
1253:                if (oc != null && oc instanceof  SourceClass
1254:                        && !((SourceClass) oc).resolved) {
1255:                    // Do the outer class first, always.
1256:                    ((SourceClass) oc).resolveTypeStructure(env);
1257:                    // (Note:  this.resolved is probably true at this point.)
1258:                }
1259:
1260:                // Punt if we've already resolved this class, or are currently
1261:                // in the process of doing so.
1262:                if (resolved || resolving) {
1263:                    if (tracing)
1264:                        env.dtExit("SourceClass.resolveTypeStructure: OK "
1265:                                + getName());
1266:                    return;
1267:                }
1268:
1269:                // Previously, 'resolved' was set here, and served to prevent
1270:                // duplicate resolutions here as well as its function in 
1271:                // 'ClassDefinition.addMember'.  Now, 'resolving' serves the
1272:                // former purpose, distinct from that of 'resolved'.
1273:                resolving = true;
1274:
1275:                if (tracing)
1276:                    env.dtEvent("SourceClass.resolveTypeStructure: RESOLVING "
1277:                            + getName());
1278:
1279:                env = setupEnv(env);
1280:
1281:                // Resolve superclass names to class declarations
1282:                // for the immediate superclass and superinterfaces.
1283:                resolveSupers(env);
1284:
1285:                // Check all ancestor superclasses for various
1286:                // errors, verifying definition of all superclasses
1287:                // and superinterfaces.  Also breaks inheritance cycles.
1288:                // Calls 'resolveTypeStructure' recursively for ancestors
1289:                // This call used to appear in 'basicCheck', but was not
1290:                // performed early enough.  Most of the compiler will barf
1291:                // on inheritance cycles!
1292:                try {
1293:                    checkSupers(env);
1294:                } catch (ClassNotFound ee) {
1295:                    // Undefined classes should be reported by 'checkSupers'.
1296:                    env.error(where, "class.not.found", ee.name, this );
1297:                }
1298:
1299:                for (MemberDefinition f = getFirstMember(); f != null; f = f
1300:                        .getNextMember()) {
1301:                    if (f instanceof  SourceMember)
1302:                        ((SourceMember) f).resolveTypeStructure(env);
1303:                }
1304:
1305:                resolving = false;
1306:
1307:                // Mark class as resolved.  If new members are subsequently
1308:                // added to the class, they will be resolved at that time.
1309:                // See 'ClassDefinition.addMember'.  Previously, this variable was
1310:                // set prior to the calls to 'checkSupers' and 'resolveTypeStructure'
1311:                // (which may engender further calls to 'checkSupers').  This could
1312:                // lead to duplicate resolution of implicit constructors, as the call to
1313:                // 'basicCheck' from 'checkSupers' could add the constructor while
1314:                // its class is marked resolved, and thus would resolve the constructor,
1315:                // believing it to be a "late addition".  It would then be resolved
1316:                // redundantly during the normal traversal of the members, which
1317:                // immediately follows in the code above.
1318:                resolved = true;
1319:
1320:                // Now we have enough information to detect method repeats.
1321:                for (MemberDefinition f = getFirstMember(); f != null; f = f
1322:                        .getNextMember()) {
1323:                    if (f.isInitializer())
1324:                        continue;
1325:                    if (!f.isMethod())
1326:                        continue;
1327:                    for (MemberDefinition f2 = f; (f2 = f2.getNextMatch()) != null;) {
1328:                        if (!f2.isMethod())
1329:                            continue;
1330:                        if (f.getType().equals(f2.getType())) {
1331:                            env.error(f.getWhere(), "meth.multidef", f);
1332:                            continue;
1333:                        }
1334:                        if (f.getType().equalArguments(f2.getType())) {
1335:                            env
1336:                                    .error(f.getWhere(), "meth.redef.rettype",
1337:                                            f, f2);
1338:                            continue;
1339:                        }
1340:                    }
1341:                }
1342:                if (tracing)
1343:                    env
1344:                            .dtExit("SourceClass.resolveTypeStructure: "
1345:                                    + getName());
1346:            }
1347:
1348:            protected void resolveSupers(Environment env) {
1349:                if (tracing)
1350:                    env.dtEnter("SourceClass.resolveSupers: " + this );
1351:                // Find the super class
1352:                if (super ClassId != null && super Class == null) {
1353:                    super Class = resolveSuper(env, super ClassId);
1354:                    // Special-case java.lang.Object here (not in the parser).
1355:                    // In all other cases, if we have a valid 'superClassId',
1356:                    // we return with a valid and non-null 'superClass' value.
1357:                    if (super Class == getClassDeclaration()
1358:                            && getName().equals(idJavaLangObject)) {
1359:                        super Class = null;
1360:                        super ClassId = null;
1361:                    }
1362:                }
1363:                // Find interfaces
1364:                if (interfaceIds != null && interfaces == null) {
1365:                    interfaces = new ClassDeclaration[interfaceIds.length];
1366:                    for (int i = 0; i < interfaces.length; i++) {
1367:                        interfaces[i] = resolveSuper(env, interfaceIds[i]);
1368:                        for (int j = 0; j < i; j++) {
1369:                            if (interfaces[i] == interfaces[j]) {
1370:                                Identifier id = interfaceIds[i].getName();
1371:                                long where = interfaceIds[j].getWhere();
1372:                                env.error(where, "intf.repeated", id);
1373:                            }
1374:                        }
1375:                    }
1376:                }
1377:                if (tracing)
1378:                    env.dtExit("SourceClass.resolveSupers: " + this );
1379:            }
1380:
1381:            private ClassDeclaration resolveSuper(Environment env,
1382:                    IdentifierToken t) {
1383:                Identifier name = t.getName();
1384:                if (tracing)
1385:                    env.dtEnter("SourceClass.resolveSuper: " + name);
1386:                if (isInnerClass())
1387:                    name = outerClass.resolveName(env, name);
1388:                else
1389:                    name = env.resolveName(name);
1390:                ClassDeclaration result = env.getClassDeclaration(name);
1391:                // Result is never null, as a new 'ClassDeclaration' is
1392:                // created if one with the given name does not exist.
1393:                if (tracing)
1394:                    env.dtExit("SourceClass.resolveSuper: " + name);
1395:                return result;
1396:            }
1397:
1398:            /**
1399:             * During the type-checking of an outer method body or initializer,
1400:             * this routine is called to check a local class body
1401:             * in the proper context.
1402:             * @param	sup	the named super class or interface (if anonymous)
1403:             * @param	args	the actual arguments (if anonymous)
1404:             */
1405:            public Vset checkLocalClass(Environment env, Context ctx,
1406:                    Vset vset, ClassDefinition sup, Expression args[],
1407:                    Type argTypes[]) throws ClassNotFound {
1408:                env = setupEnv(env);
1409:
1410:                if ((sup != null) != isAnonymous()) {
1411:                    throw new CompilerError("resolveAnonymousStructure");
1412:                }
1413:                if (isAnonymous()) {
1414:                    resolveAnonymousStructure(env, sup, args, argTypes);
1415:                }
1416:
1417:                // Run the checks in the lexical context from the outer class.
1418:                vset = checkInternal(env, ctx, vset);
1419:
1420:                // This is now done by 'checkInternal' via its call to 'checkMembers'.
1421:                // getClassDeclaration().setDefinition(this, CS_CHECKED);
1422:
1423:                return vset;
1424:            }
1425:
1426:            /**
1427:             * As with checkLocalClass, run the inline phase for a local class.
1428:             */
1429:            public void inlineLocalClass(Environment env) {
1430:                for (MemberDefinition f = getFirstMember(); f != null; f = f
1431:                        .getNextMember()) {
1432:                    if ((f.isVariable() || f.isInitializer()) && !f.isStatic()) {
1433:                        continue; // inlined inside of constructors only
1434:                    }
1435:                    try {
1436:                        ((SourceMember) f).inline(env);
1437:                    } catch (ClassNotFound ee) {
1438:                        env.error(f.getWhere(), "class.not.found", ee.name,
1439:                                this );
1440:                    }
1441:                }
1442:                if (getReferencesFrozen() != null && !inlinedLocalClass) {
1443:                    inlinedLocalClass = true;
1444:                    // add more constructor arguments for uplevel references
1445:                    for (MemberDefinition f = getFirstMember(); f != null; f = f
1446:                            .getNextMember()) {
1447:                        if (f.isConstructor()) {
1448:                            //((SourceMember)f).addUplevelArguments(false);
1449:                            ((SourceMember) f).addUplevelArguments();
1450:                        }
1451:                    }
1452:                }
1453:            }
1454:
1455:            private boolean inlinedLocalClass = false;
1456:
1457:            /**
1458:             * Check a class which is inside a local class, but is not itself local.
1459:             */
1460:            public Vset checkInsideClass(Environment env, Context ctx, Vset vset)
1461:                    throws ClassNotFound {
1462:                if (!isInsideLocal() || isLocal()) {
1463:                    throw new CompilerError("checkInsideClass");
1464:                }
1465:                return checkInternal(env, ctx, vset);
1466:            }
1467:
1468:            /**
1469:             * Just before checking an anonymous class, decide its true
1470:             * inheritance, and build its (sole, implicit) constructor.
1471:             */
1472:            private void resolveAnonymousStructure(Environment env,
1473:                    ClassDefinition sup, Expression args[], Type argTypes[])
1474:                    throws ClassNotFound {
1475:
1476:                if (tracing)
1477:                    env.dtEvent("SourceClass.resolveAnonymousStructure: "
1478:                            + this  + ", super " + sup);
1479:
1480:                // Decide now on the superclass.
1481:
1482:                // This check has been removed as part of the fix for 4055017.
1483:                // In the anonymous class created to hold the 'class$' method
1484:                // of an interface, 'superClassId' refers to 'java.lang.Object'.
1485:                /*---------------------*
1486:                if (!(superClass == null && superClassId.getName() == idNull)) {
1487:                    throw new CompilerError("superclass "+superClass);
1488:                }
1489:                 *---------------------*/
1490:
1491:                if (sup.isInterface()) {
1492:                    // allow an interface in the "super class" position
1493:                    int ni = (interfaces == null) ? 0 : interfaces.length;
1494:                    ClassDeclaration i1[] = new ClassDeclaration[1 + ni];
1495:                    if (ni > 0) {
1496:                        System.arraycopy(interfaces, 0, i1, 1, ni);
1497:                        if (interfaceIds != null && interfaceIds.length == ni) {
1498:                            IdentifierToken id1[] = new IdentifierToken[1 + ni];
1499:                            System.arraycopy(interfaceIds, 0, id1, 1, ni);
1500:                            id1[0] = new IdentifierToken(sup.getName());
1501:                        }
1502:                    }
1503:                    i1[0] = sup.getClassDeclaration();
1504:                    interfaces = i1;
1505:
1506:                    sup = toplevelEnv.getClassDefinition(idJavaLangObject);
1507:                }
1508:                super Class = sup.getClassDeclaration();
1509:
1510:                if (hasConstructor()) {
1511:                    throw new CompilerError("anonymous constructor");
1512:                }
1513:
1514:                // Synthesize an appropriate constructor.
1515:                Type t = Type.tMethod(Type.tVoid, argTypes);
1516:                IdentifierToken names[] = new IdentifierToken[argTypes.length];
1517:                for (int i = 0; i < names.length; i++) {
1518:                    names[i] = new IdentifierToken(args[i].getWhere(),
1519:                            Identifier.lookup("$" + i));
1520:                }
1521:                int outerArg = (sup.isTopLevel() || sup.isLocal()) ? 0 : 1;
1522:                Expression super Args[] = new Expression[-outerArg + args.length];
1523:                for (int i = outerArg; i < args.length; i++) {
1524:                    super Args[-outerArg + i] = new IdentifierExpression(
1525:                            names[i]);
1526:                }
1527:                long where = getWhere();
1528:                Expression super Exp;
1529:                if (outerArg == 0) {
1530:                    super Exp = new SuperExpression(where);
1531:                } else {
1532:                    super Exp = new SuperExpression(where,
1533:                            new IdentifierExpression(names[0]));
1534:                }
1535:                Expression super Call = new MethodExpression(where, super Exp,
1536:                        idInit, super Args);
1537:                Statement body[] = { new ExpressionStatement(where, super Call) };
1538:                Node code = new CompoundStatement(where, body);
1539:                int mod = M_SYNTHETIC; // ISSUE: make M_PRIVATE, with wrapper?
1540:                env.makeMemberDefinition(env, where, this , null, mod, t,
1541:                        idInit, names, null, code);
1542:            }
1543:
1544:            /**
1545:             * Convert class modifiers to a string for diagnostic purposes.
1546:             * Accepts modifiers applicable to inner classes and that appear
1547:             * in the InnerClasses attribute only, as well as those that may
1548:             * appear in the class modifier proper.
1549:             */
1550:
1551:            private static int classModifierBits[] = { ACC_PUBLIC, ACC_PRIVATE,
1552:                    ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_INTERFACE,
1553:                    ACC_ABSTRACT, ACC_SUPER, M_ANONYMOUS, M_LOCAL, M_STRICTFP,
1554:                    ACC_STRICT };
1555:
1556:            private static String classModifierNames[] = { "PUBLIC", "PRIVATE",
1557:                    "PROTECTED", "STATIC", "FINAL", "INTERFACE", "ABSTRACT",
1558:                    "SUPER", "ANONYMOUS", "LOCAL", "STRICTFP", "STRICT" };
1559:
1560:            static String classModifierString(int mods) {
1561:                String s = "";
1562:                for (int i = 0; i < classModifierBits.length; i++) {
1563:                    if ((mods & classModifierBits[i]) != 0) {
1564:                        s = s + " " + classModifierNames[i];
1565:                        mods &= ~classModifierBits[i];
1566:                    }
1567:                }
1568:                if (mods != 0) {
1569:                    s = s + " ILLEGAL:" + Integer.toHexString(mods);
1570:                }
1571:                return s;
1572:            }
1573:
1574:            /**
1575:             * Find or create an access method for a private member,
1576:             * or return null if this is not possible.
1577:             */
1578:            public MemberDefinition getAccessMember(Environment env,
1579:                    Context ctx, MemberDefinition field, boolean isSuper) {
1580:                return getAccessMember(env, ctx, field, false, isSuper);
1581:            }
1582:
1583:            public MemberDefinition getUpdateMember(Environment env,
1584:                    Context ctx, MemberDefinition field, boolean isSuper) {
1585:                if (!field.isVariable()) {
1586:                    throw new CompilerError("method");
1587:                }
1588:                return getAccessMember(env, ctx, field, true, isSuper);
1589:            }
1590:
1591:            private MemberDefinition getAccessMember(Environment env,
1592:                    Context ctx, MemberDefinition field, boolean isUpdate,
1593:                    boolean isSuper) {
1594:
1595:                // The 'isSuper' argument is really only meaningful when the
1596:                // target member is a method, in which case an 'invokespecial'
1597:                // is needed.  For fields, 'getfield' and 'putfield' instructions
1598:                // are generated in either case, and 'isSuper' currently plays
1599:                // no essential role.  Nonetheless, we maintain the distinction
1600:                // consistently for the time being.
1601:
1602:                boolean isStatic = field.isStatic();
1603:                boolean isMethod = field.isMethod();
1604:
1605:                // Find pre-existing access method.
1606:                // In the case of a field access method, we only look for the getter.
1607:                // A getter is always created whenever a setter is.
1608:                // QUERY: Why doesn't the 'MemberDefinition' object for the field
1609:                // itself just have fields for its getter and setter?
1610:                MemberDefinition af;
1611:                for (af = getFirstMember(); af != null; af = af.getNextMember()) {
1612:                    if (af.getAccessMethodTarget() == field) {
1613:                        if (isMethod && af.isSuperAccessMethod() == isSuper) {
1614:                            break;
1615:                        }
1616:                        // Distinguish the getter and the setter by the number of
1617:                        // arguments.
1618:                        int nargs = af.getType().getArgumentTypes().length;
1619:                        // This was (nargs == (isStatic ? 0 : 1) + (isUpdate ? 1 : 0))
1620:                        // in order to find a setter as well as a getter.  This caused
1621:                        // allocation of multiple getters.
1622:                        if (nargs == (isStatic ? 0 : 1)) {
1623:                            break;
1624:                        }
1625:                    }
1626:                }
1627:
1628:                if (af != null) {
1629:                    if (!isUpdate) {
1630:                        return af;
1631:                    } else {
1632:                        MemberDefinition uf = af.getAccessUpdateMember();
1633:                        if (uf != null) {
1634:                            return uf;
1635:                        }
1636:                    }
1637:                } else if (isUpdate) {
1638:                    // must find or create the getter before creating the setter
1639:                    af = getAccessMember(env, ctx, field, false, isSuper);
1640:                }
1641:
1642:                // If we arrive here, we are creating a new access member.
1643:
1644:                Identifier anm;
1645:                Type dummyType = null;
1646:
1647:                if (field.isConstructor()) {
1648:                    // For a constructor, we use the same name as for all
1649:                    // constructors ("<init>"), but add a distinguishing
1650:                    // argument of an otherwise unused "dummy" type.
1651:                    anm = idInit;
1652:                    // Get the dummy class, creating it if necessary.
1653:                    SourceClass outerMostClass = (SourceClass) getTopClass();
1654:                    dummyType = outerMostClass.dummyArgumentType;
1655:                    if (dummyType == null) {
1656:                        // Create dummy class.
1657:                        IdentifierToken sup = new IdentifierToken(0,
1658:                                idJavaLangObject);
1659:                        IdentifierToken interfaces[] = {};
1660:                        IdentifierToken t = new IdentifierToken(0, idNull);
1661:                        int mod = M_ANONYMOUS | M_STATIC | M_SYNTHETIC;
1662:                        // If an interface has a public inner class, the dummy class for 
1663:                        // the constructor must always be accessible. Fix for 4221648.
1664:                        if (outerMostClass.isInterface()) {
1665:                            mod |= M_PUBLIC;
1666:                        }
1667:                        ClassDefinition dummyClass = toplevelEnv
1668:                                .makeClassDefinition(toplevelEnv, 0, t, null,
1669:                                        mod, sup, interfaces, outerMostClass);
1670:                        // Check the class.
1671:                        // It is likely that a full check is not really necessary,
1672:                        // but it is essential that the class be marked as parsed.
1673:                        dummyClass.getClassDeclaration().setDefinition(
1674:                                dummyClass, CS_PARSED);
1675:                        Expression argsX[] = {};
1676:                        Type argTypesX[] = {};
1677:                        try {
1678:                            ClassDefinition supcls = toplevelEnv
1679:                                    .getClassDefinition(idJavaLangObject);
1680:                            dummyClass.checkLocalClass(toplevelEnv, null,
1681:                                    new Vset(), supcls, argsX, argTypesX);
1682:                        } catch (ClassNotFound ee) {
1683:                        }
1684:                        ;
1685:                        // Get class type.
1686:                        dummyType = dummyClass.getType();
1687:                        outerMostClass.dummyArgumentType = dummyType;
1688:                    }
1689:                } else {
1690:                    // Otherwise, we use the name "access$N", for the
1691:                    // smallest value of N >= 0 yielding an unused name.
1692:                    for (int i = 0;; i++) {
1693:                        anm = Identifier.lookup(prefixAccess + i);
1694:                        if (getFirstMatch(anm) == null) {
1695:                            break;
1696:                        }
1697:                    }
1698:                }
1699:
1700:                Type argTypes[];
1701:                Type t = field.getType();
1702:
1703:                if (isStatic) {
1704:                    if (!isMethod) {
1705:                        if (!isUpdate) {
1706:                            Type at[] = {};
1707:                            argTypes = at;
1708:                            t = Type.tMethod(t); // nullary getter
1709:                        } else {
1710:                            Type at[] = { t };
1711:                            argTypes = at;
1712:                            t = Type.tMethod(Type.tVoid, argTypes); // unary setter
1713:                        }
1714:                    } else {
1715:                        // Since constructors are never static, we don't 
1716:                        // have to worry about a dummy argument here.
1717:                        argTypes = t.getArgumentTypes();
1718:                    }
1719:                } else {
1720:                    // All access methods for non-static members get an explicit
1721:                    // 'this' pointer as an extra argument, as the access methods
1722:                    // themselves must be static. EXCEPTION: Access methods for
1723:                    // constructors are non-static.
1724:                    Type classType = this .getType();
1725:                    if (!isMethod) {
1726:                        if (!isUpdate) {
1727:                            Type at[] = { classType };
1728:                            argTypes = at;
1729:                            t = Type.tMethod(t, argTypes); // nullary getter
1730:                        } else {
1731:                            Type at[] = { classType, t };
1732:                            argTypes = at;
1733:                            t = Type.tMethod(Type.tVoid, argTypes); // unary setter
1734:                        }
1735:                    } else {
1736:                        // Target is a method, possibly a constructor.
1737:                        Type at[] = t.getArgumentTypes();
1738:                        int nargs = at.length;
1739:                        if (field.isConstructor()) {
1740:                            // Access method is a constructor.
1741:                            // Requires a dummy argument.
1742:                            MemberDefinition outerThisArg = ((SourceMember) field)
1743:                                    .getOuterThisArg();
1744:                            if (outerThisArg != null) {
1745:                                // Outer instance link must be the first argument.
1746:                                // The following is a sanity check that will catch
1747:                                // most cases in which in this requirement is violated.
1748:                                if (at[0] != outerThisArg.getType()) {
1749:                                    throw new CompilerError(
1750:                                            "misplaced outer this");
1751:                                }
1752:                                // Strip outer 'this' argument.
1753:                                // It will be added back when the access method is checked.
1754:                                argTypes = new Type[nargs];
1755:                                argTypes[0] = dummyType;
1756:                                for (int i = 1; i < nargs; i++) {
1757:                                    argTypes[i] = at[i];
1758:                                }
1759:                            } else {
1760:                                // There is no outer instance.
1761:                                argTypes = new Type[nargs + 1];
1762:                                argTypes[0] = dummyType;
1763:                                for (int i = 0; i < nargs; i++) {
1764:                                    argTypes[i + 1] = at[i];
1765:                                }
1766:                            }
1767:                        } else {
1768:                            // Access method is static.
1769:                            // Requires an explicit 'this' argument.
1770:                            argTypes = new Type[nargs + 1];
1771:                            argTypes[0] = classType;
1772:                            for (int i = 0; i < nargs; i++) {
1773:                                argTypes[i + 1] = at[i];
1774:                            }
1775:                        }
1776:                        t = Type.tMethod(t.getReturnType(), argTypes);
1777:                    }
1778:                }
1779:
1780:                int nlen = argTypes.length;
1781:                long where = field.getWhere();
1782:                IdentifierToken names[] = new IdentifierToken[nlen];
1783:                for (int i = 0; i < nlen; i++) {
1784:                    names[i] = new IdentifierToken(where, Identifier.lookup("$"
1785:                            + i));
1786:                }
1787:
1788:                Expression access = null;
1789:                Expression this Arg = null;
1790:                Expression args[] = null;
1791:
1792:                if (isStatic) {
1793:                    args = new Expression[nlen];
1794:                    for (int i = 0; i < nlen; i++) {
1795:                        args[i] = new IdentifierExpression(names[i]);
1796:                    }
1797:                } else {
1798:                    if (field.isConstructor()) {
1799:                        // Constructor access method is non-static, so
1800:                        // 'this' works normally.
1801:                        this Arg = new ThisExpression(where);
1802:                        // Remove dummy argument, as it is not
1803:                        // passed to the target method.
1804:                        args = new Expression[nlen - 1];
1805:                        for (int i = 1; i < nlen; i++) {
1806:                            args[i - 1] = new IdentifierExpression(names[i]);
1807:                        }
1808:                    } else {
1809:                        // Non-constructor access method is static, so
1810:                        // we use the first argument as 'this'.
1811:                        this Arg = new IdentifierExpression(names[0]);
1812:                        // Remove first argument.
1813:                        args = new Expression[nlen - 1];
1814:                        for (int i = 1; i < nlen; i++) {
1815:                            args[i - 1] = new IdentifierExpression(names[i]);
1816:                        }
1817:                    }
1818:                    access = this Arg;
1819:                }
1820:
1821:                if (!isMethod) {
1822:                    access = new FieldExpression(where, access, field);
1823:                    if (isUpdate) {
1824:                        access = new AssignExpression(where, access, args[0]);
1825:                    }
1826:                } else {
1827:                    // If true, 'isSuper' forces a non-virtual call.
1828:                    access = new MethodExpression(where, access, field, args,
1829:                            isSuper);
1830:                }
1831:
1832:                Statement code;
1833:                if (t.getReturnType().isType(TC_VOID)) {
1834:                    code = new ExpressionStatement(where, access);
1835:                } else {
1836:                    code = new ReturnStatement(where, access);
1837:                }
1838:                Statement body[] = { code };
1839:                code = new CompoundStatement(where, body);
1840:
1841:                // Access methods are now static (constructors excepted), and no longer final.
1842:                // This change was mandated by the interaction of the access method
1843:                // naming conventions and the restriction against overriding final
1844:                // methods.
1845:                int mod = M_SYNTHETIC;
1846:                if (!field.isConstructor()) {
1847:                    mod |= M_STATIC;
1848:                }
1849:
1850:                // Create the synthetic method within the class in which the referenced
1851:                // private member appears.  The 'env' argument to 'makeMemberDefinition'
1852:                // is suspect because it represents the environment at the point at
1853:                // which a reference takes place, while it should represent the
1854:                // environment in which the definition of the synthetic method appears.
1855:                // We get away with this because 'env' is used only to access globals
1856:                // such as 'Environment.error', and also as an argument to
1857:                // 'resolveTypeStructure', which immediately discards it using
1858:                // 'setupEnv'. Apparently, the current definition of 'setupEnv'
1859:                // represents a design change that has not been thoroughly propagated.
1860:                // An access method is declared with same list of exceptions as its
1861:                // target. As the exceptions are simply listed by name, the correctness
1862:                // of this approach requires that the access method be checked
1863:                // (name-resolved) in the same context as its target method  This
1864:                // should always be the case.
1865:                SourceMember newf = (SourceMember) env.makeMemberDefinition(
1866:                        env, where, this , null, mod, t, anm, names, field
1867:                                .getExceptionIds(), code);
1868:                // Just to be safe, copy over the name-resolved exceptions from the
1869:                // target so that the context in which the access method is checked
1870:                // doesn't matter.
1871:                newf.setExceptions(field.getExceptions(env));
1872:
1873:                newf.setAccessMethodTarget(field);
1874:                if (isUpdate) {
1875:                    af.setAccessUpdateMember(newf);
1876:                }
1877:                newf.setIsSuperAccessMethod(isSuper);
1878:
1879:                // The call to 'check' is not needed, as the access method will be
1880:                // checked by the containing class after it is added.  This is the
1881:                // idiom followed in the implementation of class literals. (See
1882:                // 'FieldExpression.java'.) In any case, the context is wrong in the
1883:                // call below.  The access method must be checked in the context in
1884:                // which it is declared, i.e., the class containing the referenced
1885:                // private member, not the (inner) class in which the original member
1886:                // reference occurs.
1887:                //
1888:                // try {
1889:                //     newf.check(env, ctx, new Vset());
1890:                // } catch (ClassNotFound ee) {
1891:                //     env.error(where, "class.not.found", ee.name, this);
1892:                // }
1893:
1894:                // The comment above is inaccurate.  While it is often the case
1895:                // that the containing class will check the access method, this is
1896:                // by no means guaranteed.  In fact, an access method may be added
1897:                // after the checking of its class is complete.  In this case, however,
1898:                // the context in which the class was checked will have been saved in
1899:                // the class definition object (by the fix for 4095716), allowing us
1900:                // to check the field now, and in the correct context.
1901:                // This fixes bug 4098093.
1902:
1903:                Context checkContext = newf.getClassDefinition()
1904:                        .getClassContext();
1905:                if (checkContext != null) {
1906:                    //System.out.println("checking late addition: " + this);
1907:                    try {
1908:                        newf.check(env, checkContext, new Vset());
1909:                    } catch (ClassNotFound ee) {
1910:                        env.error(where, "class.not.found", ee.name, this );
1911:                    }
1912:                }
1913:
1914:                //System.out.println("[Access member '" +
1915:                //			newf + "' created for field '" +
1916:                //			field +"' in class '" + this + "']");
1917:
1918:                return newf;
1919:            }
1920:
1921:            /**
1922:             * Find an inner class of 'this', chosen arbitrarily.
1923:             * Result is always an actual class, never an interface.
1924:             * Returns null if none found.
1925:             */
1926:            SourceClass findLookupContext() {
1927:                // Look for an immediate inner class.
1928:                for (MemberDefinition f = getFirstMember(); f != null; f = f
1929:                        .getNextMember()) {
1930:                    if (f.isInnerClass()) {
1931:                        SourceClass ic = (SourceClass) f.getInnerClass();
1932:                        if (!ic.isInterface()) {
1933:                            return ic;
1934:                        }
1935:                    }
1936:                }
1937:                // Look for a class nested within an immediate inner interface.
1938:                // At this point, we have given up on finding a minimally-nested
1939:                // class (which would require a breadth-first traversal).  It doesn't
1940:                // really matter which inner class we find.
1941:                for (MemberDefinition f = getFirstMember(); f != null; f = f
1942:                        .getNextMember()) {
1943:                    if (f.isInnerClass()) {
1944:                        SourceClass lc = ((SourceClass) f.getInnerClass())
1945:                                .findLookupContext();
1946:                        if (lc != null) {
1947:                            return lc;
1948:                        }
1949:                    }
1950:                }
1951:                // No inner classes.
1952:                return null;
1953:            }
1954:
1955:            private MemberDefinition lookup = null;
1956:
1957:            /**
1958:             * Get helper method for class literal lookup.
1959:             */
1960:            public MemberDefinition getClassLiteralLookup(long fwhere) {
1961:
1962:                // If we have already created a lookup method, reuse it.
1963:                if (lookup != null) {
1964:                    return lookup;
1965:                }
1966:
1967:                // If the current class is a nested class, make sure we put the
1968:                // lookup method in the outermost class.  Set 'lookup' for the
1969:                // intervening inner classes so we won't have to do the search
1970:                // again.
1971:                if (outerClass != null) {
1972:                    lookup = outerClass.getClassLiteralLookup(fwhere);
1973:                    return lookup;
1974:                }
1975:
1976:                // If we arrive here, there was no existing 'class$' method.
1977:
1978:                ClassDefinition c = this ;
1979:                boolean needNewClass = false;
1980:
1981:                if (isInterface()) {
1982:                    // The top-level type is an interface.  Try to find an existing
1983:                    // inner class in which to create the helper method.  Any will do.
1984:                    c = findLookupContext();
1985:                    if (c == null) {
1986:                        // The interface has no inner classes.  Create an anonymous
1987:                        // inner class to hold the helper method, as an interface must
1988:                        // not have any methods.  The tests above for prior creation
1989:                        // of a 'class$' method assure that only one such class is
1990:                        // allocated for each outermost class containing a class
1991:                        // literal embedded somewhere within.  Part of fix for 4055017.
1992:                        needNewClass = true;
1993:                        IdentifierToken sup = new IdentifierToken(fwhere,
1994:                                idJavaLangObject);
1995:                        IdentifierToken interfaces[] = {};
1996:                        IdentifierToken t = new IdentifierToken(fwhere, idNull);
1997:                        int mod = M_PUBLIC | M_ANONYMOUS | M_STATIC
1998:                                | M_SYNTHETIC;
1999:                        c = (SourceClass) toplevelEnv.makeClassDefinition(
2000:                                toplevelEnv, fwhere, t, null, mod, sup,
2001:                                interfaces, this );
2002:                    }
2003:                }
2004:
2005:                // The name of the class-getter stub is "class$"
2006:                Identifier idDClass = Identifier.lookup(prefixClass);
2007:                Type strarg[] = { Type.tString };
2008:
2009:                // Some sanity checks of questionable value.
2010:                //
2011:                // This check became useless after matchMethod() was modified
2012:                // to not return synthetic methods.
2013:                //
2014:                //try {
2015:                //    lookup = c.matchMethod(toplevelEnv, c, idDClass, strarg);
2016:                //} catch (ClassNotFound ee) {
2017:                //    throw new CompilerError("unexpected missing class");
2018:                //} catch (AmbiguousMember ee) {
2019:                //    throw new CompilerError("synthetic name clash");
2020:                //}
2021:                //if (lookup != null && lookup.getClassDefinition() == c) {
2022:                //    // Error if method found was not inherited.
2023:                //    throw new CompilerError("unexpected duplicate");
2024:                //}
2025:                // Some sanity checks of questionable value.
2026:
2027:                /*  // The helper function looks like this.
2028:                 *  // It simply maps a checked exception to an unchecked one.
2029:                 *  static Class class$(String class$) {
2030:                 *    try { return Class.forName(class$); }
2031:                 *    catch (ClassNotFoundException forName) {
2032:                 *      throw new NoClassDefFoundError(forName.getMessage());
2033:                 *    }
2034:                 *  }
2035:                 */
2036:                long w = c.getWhere();
2037:                IdentifierToken arg = new IdentifierToken(w, idDClass);
2038:                Expression e = new IdentifierExpression(arg);
2039:                Expression a1[] = { e };
2040:                Identifier idForName = Identifier.lookup("forName");
2041:                e = new MethodExpression(w, new TypeExpression(w,
2042:                        Type.tClassDesc), idForName, a1);
2043:                Statement body = new ReturnStatement(w, e);
2044:                // map the exceptions
2045:                Identifier idClassNotFound = Identifier
2046:                        .lookup("java.lang.ClassNotFoundException");
2047:                Identifier idNoClassDefFound = Identifier
2048:                        .lookup("java.lang.NoClassDefFoundError");
2049:                Type ctyp = Type.tClass(idClassNotFound);
2050:                Type exptyp = Type.tClass(idNoClassDefFound);
2051:                Identifier idGetMessage = Identifier.lookup("getMessage");
2052:                e = new IdentifierExpression(w, idForName);
2053:                e = new MethodExpression(w, e, idGetMessage, new Expression[0]);
2054:                Expression a2[] = { e };
2055:                e = new NewInstanceExpression(w, new TypeExpression(w, exptyp),
2056:                        a2);
2057:                Statement handler = new CatchStatement(w, new TypeExpression(w,
2058:                        ctyp), new IdentifierToken(idForName),
2059:                        new ThrowStatement(w, e));
2060:                Statement handlers[] = { handler };
2061:                body = new TryStatement(w, body, handlers);
2062:
2063:                Type mtype = Type.tMethod(Type.tClassDesc, strarg);
2064:                IdentifierToken args[] = { arg };
2065:
2066:                // Use default (package) access.  If private, an access method would
2067:                // be needed in the event that the class literal belonged to an interface.
2068:                // Also, making it private tickles bug 4098316.
2069:                lookup = toplevelEnv.makeMemberDefinition(toplevelEnv, w, c,
2070:                        null, M_STATIC | M_SYNTHETIC, mtype, idDClass, args,
2071:                        null, body);
2072:
2073:                // If a new class was created to contain the helper method,
2074:                // check it now.
2075:                if (needNewClass) {
2076:                    if (c.getClassDeclaration().getStatus() == CS_CHECKED) {
2077:                        throw new CompilerError("duplicate check");
2078:                    }
2079:                    c.getClassDeclaration().setDefinition(c, CS_PARSED);
2080:                    Expression argsX[] = {};
2081:                    Type argTypesX[] = {};
2082:                    try {
2083:                        ClassDefinition sup = toplevelEnv
2084:                                .getClassDefinition(idJavaLangObject);
2085:                        c.checkLocalClass(toplevelEnv, null, new Vset(), sup,
2086:                                argsX, argTypesX);
2087:                    } catch (ClassNotFound ee) {
2088:                    }
2089:                    ;
2090:                }
2091:
2092:                return lookup;
2093:            }
2094:
2095:            /**
2096:             * A list of active ongoing compilations. This list
2097:             * is used to stop two compilations from saving the
2098:             * same class.
2099:             */
2100:            private static Vector active = new Vector();
2101:
2102:            /**
2103:             * Compile this class
2104:             */
2105:            public void compile(OutputStream out) throws InterruptedException,
2106:                    IOException {
2107:                Environment env = toplevelEnv;
2108:                synchronized (active) {
2109:                    while (active.contains(getName())) {
2110:                        active.wait();
2111:                    }
2112:                    active.addElement(getName());
2113:                }
2114:
2115:                try {
2116:                    compileClass(env, out);
2117:                } catch (ClassNotFound e) {
2118:                    throw new CompilerError(e);
2119:                } finally {
2120:                    synchronized (active) {
2121:                        active.removeElement(getName());
2122:                        active.notifyAll();
2123:                    }
2124:                }
2125:            }
2126:
2127:            /**
2128:             * Verify that the modifier bits included in 'required' are
2129:             * all present in 'mods', otherwise signal an internal error.
2130:             * Note that errors in the source program may corrupt the modifiers,
2131:             * thus we rely on the fact that 'CompilerError' exceptions are 
2132:             * silently ignored after an error message has been issued.
2133:             */
2134:            private static void assertModifiers(int mods, int required) {
2135:                if ((mods & required) != required) {
2136:                    throw new CompilerError("illegal class modifiers");
2137:                }
2138:            }
2139:
2140:            protected void compileClass(Environment env, OutputStream out)
2141:                    throws IOException, ClassNotFound {
2142:                Vector variables = new Vector();
2143:                Vector methods = new Vector();
2144:                Vector innerClasses = new Vector();
2145:                CompilerMember init = new CompilerMember(new MemberDefinition(
2146:                        getWhere(), this , M_STATIC, Type.tMethod(Type.tVoid),
2147:                        idClassInit, null, null), new Assembler());
2148:                Context ctx = new Context((Context) null, init.field);
2149:
2150:                for (ClassDefinition def = this ; def.isInnerClass(); def = def
2151:                        .getOuterClass()) {
2152:                    innerClasses.addElement(def);
2153:                }
2154:                // Reverse the order, so that outer levels come first:
2155:                int ncsize = innerClasses.size();
2156:                for (int i = ncsize; --i >= 0;)
2157:                    innerClasses.addElement(innerClasses.elementAt(i));
2158:                for (int i = ncsize; --i >= 0;)
2159:                    innerClasses.removeElementAt(i);
2160:
2161:                // System.out.println("compile class " + getName());
2162:
2163:                boolean haveDeprecated = this .isDeprecated();
2164:                boolean haveSynthetic = this .isSynthetic();
2165:                boolean haveConstantValue = false;
2166:                boolean haveExceptions = false;
2167:
2168:                // Generate code for all fields
2169:                for (SourceMember field = (SourceMember) getFirstMember(); field != null; field = (SourceMember) field
2170:                        .getNextMember()) {
2171:
2172:                    //System.out.println("compile field " + field.getName());
2173:
2174:                    haveDeprecated |= field.isDeprecated();
2175:                    haveSynthetic |= field.isSynthetic();
2176:
2177:                    try {
2178:                        if (field.isMethod()) {
2179:                            haveExceptions |= (field.getExceptions(env).length > 0);
2180:
2181:                            if (field.isInitializer()) {
2182:                                if (field.isStatic()) {
2183:                                    field.code(env, init.asm);
2184:                                }
2185:                            } else {
2186:                                CompilerMember f = new CompilerMember(field,
2187:                                        new Assembler());
2188:                                field.code(env, f.asm);
2189:                                methods.addElement(f);
2190:                            }
2191:                        } else if (field.isInnerClass()) {
2192:                            innerClasses.addElement(field.getInnerClass());
2193:                        } else if (field.isVariable()) {
2194:                            field.inline(env);
2195:                            CompilerMember f = new CompilerMember(field, null);
2196:                            variables.addElement(f);
2197:                            if (field.isStatic()) {
2198:                                field.codeInit(env, ctx, init.asm);
2199:
2200:                            }
2201:                            haveConstantValue |= (field.getInitialValue() != null);
2202:                        }
2203:                    } catch (CompilerError ee) {
2204:                        ee.printStackTrace();
2205:                        env
2206:                                .error(field, 0, "generic", field
2207:                                        .getClassDeclaration()
2208:                                        + ":" + field + "@" + ee.toString(),
2209:                                        null, null);
2210:                    }
2211:                }
2212:                if (!init.asm.empty()) {
2213:                    init.asm.add(getWhere(), opc_return, true);
2214:                    methods.addElement(init);
2215:                }
2216:
2217:                // bail out if there were any errors
2218:                if (getNestError()) {
2219:                    return;
2220:                }
2221:
2222:                int nClassAttrs = 0;
2223:
2224:                // Insert constants
2225:                if (methods.size() > 0) {
2226:                    tab.put("Code");
2227:                }
2228:                if (haveConstantValue) {
2229:                    tab.put("ConstantValue");
2230:                }
2231:
2232:                String sourceFile = null;
2233:                if (env.debug_source()) {
2234:                    sourceFile = ((ClassFile) getSource()).getName();
2235:                    tab.put("SourceFile");
2236:                    tab.put(sourceFile);
2237:                    nClassAttrs += 1;
2238:                }
2239:
2240:                if (haveExceptions) {
2241:                    tab.put("Exceptions");
2242:                }
2243:
2244:                if (env.debug_lines()) {
2245:                    tab.put("LineNumberTable");
2246:                }
2247:                if (haveDeprecated) {
2248:                    tab.put("Deprecated");
2249:                    if (this .isDeprecated()) {
2250:                        nClassAttrs += 1;
2251:                    }
2252:                }
2253:                if (haveSynthetic) {
2254:                    tab.put("Synthetic");
2255:                    if (this .isSynthetic()) {
2256:                        nClassAttrs += 1;
2257:                    }
2258:                }
2259:                // JCOV
2260:                if (env.coverage()) {
2261:                    nClassAttrs += 2; // AbsoluteSourcePath, TimeStamp
2262:                    tab.put("AbsoluteSourcePath");
2263:                    tab.put("TimeStamp");
2264:                    tab.put("CoverageTable");
2265:                }
2266:                // end JCOV
2267:                if (env.debug_vars()) {
2268:                    tab.put("LocalVariableTable");
2269:                }
2270:                if (innerClasses.size() > 0) {
2271:                    tab.put("InnerClasses");
2272:                    nClassAttrs += 1; // InnerClasses
2273:                }
2274:
2275:                // JCOV
2276:                String absoluteSourcePath = "";
2277:                long timeStamp = 0;
2278:
2279:                if (env.coverage()) {
2280:                    absoluteSourcePath = getAbsoluteName();
2281:                    timeStamp = System.currentTimeMillis();
2282:                    tab.put(absoluteSourcePath);
2283:                }
2284:                // end JCOV
2285:                tab.put(getClassDeclaration());
2286:                if (getSuperClass() != null) {
2287:                    tab.put(getSuperClass());
2288:                }
2289:                for (int i = 0; i < interfaces.length; i++) {
2290:                    tab.put(interfaces[i]);
2291:                }
2292:
2293:                // Sort the methods in order to make sure both constant pool
2294:                // entries and methods are in a deterministic order from run
2295:                // to run (this allows comparing class files for a fixed point
2296:                // to validate the compiler)
2297:                CompilerMember[] ordered_methods = new CompilerMember[methods
2298:                        .size()];
2299:                methods.copyInto(ordered_methods);
2300:                java.util.Arrays.sort(ordered_methods);
2301:                for (int i = 0; i < methods.size(); i++)
2302:                    methods.setElementAt(ordered_methods[i], i);
2303:
2304:                // Optimize Code and Collect method constants
2305:                for (Enumeration e = methods.elements(); e.hasMoreElements();) {
2306:                    CompilerMember f = (CompilerMember) e.nextElement();
2307:                    try {
2308:                        f.asm.optimize(env);
2309:                        f.asm.collect(env, f.field, tab);
2310:                        tab.put(f.name);
2311:                        tab.put(f.sig);
2312:                        ClassDeclaration exp[] = f.field.getExceptions(env);
2313:                        for (int i = 0; i < exp.length; i++) {
2314:                            tab.put(exp[i]);
2315:                        }
2316:                    } catch (Exception ee) {
2317:                        ee.printStackTrace();
2318:                        env.error(f.field, -1, "generic", f.field.getName()
2319:                                + "@" + ee.toString(), null, null);
2320:                        f.asm.listing(System.out);
2321:                    }
2322:                }
2323:
2324:                // Collect field constants
2325:                for (Enumeration e = variables.elements(); e.hasMoreElements();) {
2326:                    CompilerMember f = (CompilerMember) e.nextElement();
2327:                    tab.put(f.name);
2328:                    tab.put(f.sig);
2329:
2330:                    Object val = f.field.getInitialValue();
2331:                    if (val != null) {
2332:                        tab.put((val instanceof  String) ? new StringExpression(
2333:                                f.field.getWhere(), (String) val) : val);
2334:                    }
2335:                }
2336:
2337:                // Collect inner class constants
2338:                for (Enumeration e = innerClasses.elements(); e
2339:                        .hasMoreElements();) {
2340:                    ClassDefinition inner = (ClassDefinition) e.nextElement();
2341:                    tab.put(inner.getClassDeclaration());
2342:
2343:                    // If the inner class is local, we do not need to add its
2344:                    // outer class here -- the outer_class_info_index is zero.
2345:                    if (!inner.isLocal()) {
2346:                        ClassDefinition outer = inner.getOuterClass();
2347:                        tab.put(outer.getClassDeclaration());
2348:                    }
2349:
2350:                    // If the local name of the class is idNull, don't bother to
2351:                    // add it to the constant pool.  We won't need it.
2352:                    Identifier inner_local_name = inner.getLocalName();
2353:                    if (inner_local_name != idNull) {
2354:                        tab.put(inner_local_name.toString());
2355:                    }
2356:                }
2357:
2358:                // Write header
2359:                DataOutputStream data = new DataOutputStream(out);
2360:                data.writeInt(JAVA_MAGIC);
2361:                data.writeShort(toplevelEnv.getMinorVersion());
2362:                data.writeShort(toplevelEnv.getMajorVersion());
2363:                tab.write(env, data);
2364:
2365:                // Write class information
2366:                int cmods = getModifiers() & MM_CLASS;
2367:
2368:                // Certain modifiers are implied:
2369:                // 1.  Any interface (nested or not) is implicitly deemed to be abstract,
2370:                //     whether it is explicitly marked so or not.  (Java 1.0.)
2371:                // 2.  A interface which is a member of a type is implicitly deemed to
2372:                //     be static, whether it is explicitly marked so or not.
2373:                // 3a. A type which is a member of an interface is implicitly deemed
2374:                //     to be public, whether it is explicitly marked so or not.
2375:                // 3b. A type which is a member of an interface is implicitly deemed
2376:                //     to be static, whether it is explicitly marked so or not.
2377:                // All of these rules are implemented in 'BatchParser.beginClass',
2378:                // but the results are verified here.
2379:
2380:                if (isInterface()) {
2381:                    // Rule 1.
2382:                    // The VM spec states that ACC_ABSTRACT must be set when
2383:                    // ACC_INTERFACE is; this was not done by javac prior to 1.2,
2384:                    // and the runtime compensates by setting it.  Making sure
2385:                    // it is set here will allow the runtime hack to eventually
2386:                    // be removed. Rule 2 doesn't apply to transformed modifiers.
2387:                    assertModifiers(cmods, ACC_ABSTRACT);
2388:                } else {
2389:                    // Contrary to the JVM spec, we only set ACC_SUPER for classes,
2390:                    // not interfaces.  This is a workaround for a bug in IE3.0,
2391:                    // which refuses interfaces with ACC_SUPER on.
2392:                    cmods |= ACC_SUPER;
2393:                }
2394:
2395:                // If this is a nested class, transform access modifiers.
2396:                if (outerClass != null) {
2397:                    // If private, transform to default (package) access.
2398:                    // If protected, transform to public.
2399:                    // M_PRIVATE and M_PROTECTED are already masked off by MM_CLASS above.
2400:                    // cmods &= ~(M_PRIVATE | M_PROTECTED);
2401:                    if (isProtected())
2402:                        cmods |= M_PUBLIC;
2403:                    // Rule 3a.  Note that Rule 3b doesn't apply to transformed modifiers.
2404:                    if (outerClass.isInterface()) {
2405:                        assertModifiers(cmods, M_PUBLIC);
2406:                    }
2407:                }
2408:
2409:                data.writeShort(cmods);
2410:
2411:                if (env.dumpModifiers()) {
2412:                    Identifier cn = getName();
2413:                    Identifier nm = Identifier.lookup(cn.getQualifier(), cn
2414:                            .getFlatName());
2415:                    System.out.println();
2416:                    System.out.println("CLASSFILE  " + nm);
2417:                    System.out.println("---" + classModifierString(cmods));
2418:                }
2419:
2420:                data.writeShort(tab.index(getClassDeclaration()));
2421:                data.writeShort((getSuperClass() != null) ? tab
2422:                        .index(getSuperClass()) : 0);
2423:                data.writeShort(interfaces.length);
2424:                for (int i = 0; i < interfaces.length; i++) {
2425:                    data.writeShort(tab.index(interfaces[i]));
2426:                }
2427:
2428:                // write variables
2429:                ByteArrayOutputStream buf = new ByteArrayOutputStream(256);
2430:                ByteArrayOutputStream attbuf = new ByteArrayOutputStream(256);
2431:                DataOutputStream databuf = new DataOutputStream(buf);
2432:
2433:                data.writeShort(variables.size());
2434:                for (Enumeration e = variables.elements(); e.hasMoreElements();) {
2435:                    CompilerMember f = (CompilerMember) e.nextElement();
2436:                    Object val = f.field.getInitialValue();
2437:
2438:                    data.writeShort(f.field.getModifiers() & MM_FIELD);
2439:                    data.writeShort(tab.index(f.name));
2440:                    data.writeShort(tab.index(f.sig));
2441:
2442:                    int fieldAtts = (val != null ? 1 : 0);
2443:                    boolean dep = f.field.isDeprecated();
2444:                    boolean syn = f.field.isSynthetic();
2445:                    fieldAtts += (dep ? 1 : 0) + (syn ? 1 : 0);
2446:
2447:                    data.writeShort(fieldAtts);
2448:                    if (val != null) {
2449:                        data.writeShort(tab.index("ConstantValue"));
2450:                        data.writeInt(2);
2451:                        data
2452:                                .writeShort(tab
2453:                                        .index((val instanceof  String) ? new StringExpression(
2454:                                                f.field.getWhere(),
2455:                                                (String) val)
2456:                                                : val));
2457:                    }
2458:                    if (dep) {
2459:                        data.writeShort(tab.index("Deprecated"));
2460:                        data.writeInt(0);
2461:                    }
2462:                    if (syn) {
2463:                        data.writeShort(tab.index("Synthetic"));
2464:                        data.writeInt(0);
2465:                    }
2466:                }
2467:
2468:                // write methods
2469:
2470:                data.writeShort(methods.size());
2471:                for (Enumeration e = methods.elements(); e.hasMoreElements();) {
2472:                    CompilerMember f = (CompilerMember) e.nextElement();
2473:
2474:                    int xmods = f.field.getModifiers() & MM_METHOD;
2475:                    // Transform floating point modifiers.  M_STRICTFP 
2476:                    // of member + status of enclosing class turn into
2477:                    // ACC_STRICT bit.
2478:                    if (((xmods & M_STRICTFP) != 0)
2479:                            || ((cmods & M_STRICTFP) != 0)) {
2480:                        xmods |= ACC_STRICT;
2481:                    } else {
2482:                        // Use the default
2483:                        if (env.strictdefault()) {
2484:                            xmods |= ACC_STRICT;
2485:                        }
2486:                    }
2487:                    data.writeShort(xmods);
2488:
2489:                    data.writeShort(tab.index(f.name));
2490:                    data.writeShort(tab.index(f.sig));
2491:                    ClassDeclaration exp[] = f.field.getExceptions(env);
2492:                    int methodAtts = ((exp.length > 0) ? 1 : 0);
2493:                    boolean dep = f.field.isDeprecated();
2494:                    boolean syn = f.field.isSynthetic();
2495:                    methodAtts += (dep ? 1 : 0) + (syn ? 1 : 0);
2496:
2497:                    if (!f.asm.empty()) {
2498:                        data.writeShort(methodAtts + 1);
2499:                        f.asm.write(env, databuf, f.field, tab);
2500:                        int natts = 0;
2501:                        if (env.debug_lines()) {
2502:                            natts++;
2503:                        }
2504:                        // JCOV
2505:                        if (env.coverage()) {
2506:                            natts++;
2507:                        }
2508:                        // end JCOV
2509:                        if (env.debug_vars()) {
2510:                            natts++;
2511:                        }
2512:                        databuf.writeShort(natts);
2513:
2514:                        if (env.debug_lines()) {
2515:                            f.asm.writeLineNumberTable(env,
2516:                                    new DataOutputStream(attbuf), tab);
2517:                            databuf.writeShort(tab.index("LineNumberTable"));
2518:                            databuf.writeInt(attbuf.size());
2519:                            attbuf.writeTo(buf);
2520:                            attbuf.reset();
2521:                        }
2522:
2523:                        //JCOV
2524:                        if (env.coverage()) {
2525:                            f.asm.writeCoverageTable(env,
2526:                                    (ClassDefinition) this ,
2527:                                    new DataOutputStream(attbuf), tab, f.field
2528:                                            .getWhere());
2529:                            databuf.writeShort(tab.index("CoverageTable"));
2530:                            databuf.writeInt(attbuf.size());
2531:                            attbuf.writeTo(buf);
2532:                            attbuf.reset();
2533:                        }
2534:                        // end JCOV
2535:                        if (env.debug_vars()) {
2536:                            f.asm.writeLocalVariableTable(env, f.field,
2537:                                    new DataOutputStream(attbuf), tab);
2538:                            databuf.writeShort(tab.index("LocalVariableTable"));
2539:                            databuf.writeInt(attbuf.size());
2540:                            attbuf.writeTo(buf);
2541:                            attbuf.reset();
2542:                        }
2543:
2544:                        data.writeShort(tab.index("Code"));
2545:                        data.writeInt(buf.size());
2546:                        buf.writeTo(data);
2547:                        buf.reset();
2548:                    } else {
2549:                        //JCOV
2550:                        if ((env.coverage())
2551:                                && ((f.field.getModifiers() & M_NATIVE) > 0))
2552:                            f.asm.addNativeToJcovTab(env,
2553:                                    (ClassDefinition) this );
2554:                        // end JCOV
2555:                        data.writeShort(methodAtts);
2556:                    }
2557:
2558:                    if (exp.length > 0) {
2559:                        data.writeShort(tab.index("Exceptions"));
2560:                        data.writeInt(2 + exp.length * 2);
2561:                        data.writeShort(exp.length);
2562:                        for (int i = 0; i < exp.length; i++) {
2563:                            data.writeShort(tab.index(exp[i]));
2564:                        }
2565:                    }
2566:                    if (dep) {
2567:                        data.writeShort(tab.index("Deprecated"));
2568:                        data.writeInt(0);
2569:                    }
2570:                    if (syn) {
2571:                        data.writeShort(tab.index("Synthetic"));
2572:                        data.writeInt(0);
2573:                    }
2574:                }
2575:
2576:                // class attributes
2577:                data.writeShort(nClassAttrs);
2578:
2579:                if (env.debug_source()) {
2580:                    data.writeShort(tab.index("SourceFile"));
2581:                    data.writeInt(2);
2582:                    data.writeShort(tab.index(sourceFile));
2583:                }
2584:
2585:                if (this .isDeprecated()) {
2586:                    data.writeShort(tab.index("Deprecated"));
2587:                    data.writeInt(0);
2588:                }
2589:                if (this .isSynthetic()) {
2590:                    data.writeShort(tab.index("Synthetic"));
2591:                    data.writeInt(0);
2592:                }
2593:
2594:                // JCOV 
2595:                if (env.coverage()) {
2596:                    data.writeShort(tab.index("AbsoluteSourcePath"));
2597:                    data.writeInt(2);
2598:                    data.writeShort(tab.index(absoluteSourcePath));
2599:                    data.writeShort(tab.index("TimeStamp"));
2600:                    data.writeInt(8);
2601:                    data.writeLong(timeStamp);
2602:                }
2603:                // end JCOV
2604:
2605:                if (innerClasses.size() > 0) {
2606:                    data.writeShort(tab.index("InnerClasses"));
2607:                    data.writeInt(2 + 2 * 4 * innerClasses.size());
2608:                    data.writeShort(innerClasses.size());
2609:                    for (Enumeration e = innerClasses.elements(); e
2610:                            .hasMoreElements();) {
2611:                        // For each inner class name transformation, we have a record
2612:                        // with the following fields:
2613:                        //
2614:                        //    u2 inner_class_info_index;   // CONSTANT_Class_info index
2615:                        //    u2 outer_class_info_index;   // CONSTANT_Class_info index
2616:                        //    u2 inner_name_index;         // CONSTANT_Utf8_info index
2617:                        //    u2 inner_class_access_flags; // access_flags bitmask
2618:                        //
2619:                        // The spec states that outer_class_info_index is 0 iff
2620:                        // the inner class is not a member of its enclosing class (i.e.
2621:                        // it is a local or anonymous class).  The spec also states
2622:                        // that if a class is anonymous then inner_name_index should
2623:                        // be 0.
2624:                        //
2625:                        // See also the initInnerClasses() method in BinaryClass.java.
2626:
2627:                        // Generate inner_class_info_index.
2628:                        ClassDefinition inner = (ClassDefinition) e
2629:                                .nextElement();
2630:                        data.writeShort(tab.index(inner.getClassDeclaration()));
2631:
2632:                        // Generate outer_class_info_index.
2633:                        //
2634:                        // Checking isLocal() should probably be enough here,
2635:                        // but the check for isAnonymous is added for good
2636:                        // measure.
2637:                        if (inner.isLocal() || inner.isAnonymous()) {
2638:                            data.writeShort(0);
2639:                        } else {
2640:                            // Query: what about if inner.isInsideLocal()?
2641:                            // For now we continue to generate a nonzero
2642:                            // outer_class_info_index.
2643:                            ClassDefinition outer = inner.getOuterClass();
2644:                            data.writeShort(tab.index(outer
2645:                                    .getClassDeclaration()));
2646:                        }
2647:
2648:                        // Generate inner_name_index.
2649:                        Identifier inner_name = inner.getLocalName();
2650:                        if (inner_name == idNull) {
2651:                            if (!inner.isAnonymous()) {
2652:                                throw new CompilerError(
2653:                                        "compileClass(), anonymous");
2654:                            }
2655:                            data.writeShort(0);
2656:                        } else {
2657:                            data.writeShort(tab.index(inner_name.toString()));
2658:                        }
2659:
2660:                        // Generate inner_class_access_flags.
2661:                        int imods = inner.getInnerClassMember().getModifiers()
2662:                                & ACCM_INNERCLASS;
2663:
2664:                        // Certain modifiers are implied for nested types.
2665:                        // See rules 1, 2, 3a, and 3b enumerated above.
2666:                        // All of these rules are implemented in 'BatchParser.beginClass',
2667:                        // but are verified here.
2668:
2669:                        if (inner.isInterface()) {
2670:                            // Rules 1 and 2.
2671:                            assertModifiers(imods, M_ABSTRACT | M_STATIC);
2672:                        }
2673:                        if (inner.getOuterClass().isInterface()) {
2674:                            // Rules 3a and 3b.
2675:                            imods &= ~(M_PRIVATE | M_PROTECTED); // error recovery
2676:                            assertModifiers(imods, M_PUBLIC | M_STATIC);
2677:                        }
2678:
2679:                        data.writeShort(imods);
2680:
2681:                        if (env.dumpModifiers()) {
2682:                            Identifier fn = inner.getInnerClassMember()
2683:                                    .getName();
2684:                            Identifier nm = Identifier.lookup(
2685:                                    fn.getQualifier(), fn.getFlatName());
2686:                            System.out.println("INNERCLASS " + nm);
2687:                            System.out.println("---"
2688:                                    + classModifierString(imods));
2689:                        }
2690:
2691:                    }
2692:                }
2693:
2694:                // Cleanup
2695:                data.flush();
2696:                tab = null;
2697:
2698:                // JCOV 
2699:                // generate coverage data
2700:                if (env.covdata()) {
2701:                    Assembler CovAsm = new Assembler();
2702:                    CovAsm.GenVecJCov(env, (ClassDefinition) this , timeStamp);
2703:                }
2704:                // end JCOV
2705:            }
2706:
2707:            /**
2708:             * Print out the dependencies for this class (-xdepend) option
2709:             */
2710:
2711:            public void printClassDependencies(Environment env) {
2712:
2713:                // Only do this if the -xdepend flag is on
2714:                if (toplevelEnv.print_dependencies()) {
2715:
2716:                    // Name of java source file this class was in (full path)
2717:                    //    e.g. /home/ohair/Test.java
2718:                    String src = ((ClassFile) getSource()).getAbsoluteName();
2719:
2720:                    // Class name, fully qualified
2721:                    //   e.g. "java.lang.Object" or "FooBar" or "sun.tools.javac.Main"
2722:                    // Inner class names must be mangled, as ordinary '.' qualification
2723:                    // is used internally where the spec requires '$' separators.
2724:                    //   String className = getName().toString();
2725:                    String className = Type.mangleInnerType(getName())
2726:                            .toString();
2727:
2728:                    // Line number where class starts in the src file
2729:                    long startLine = getWhere() >> WHEREOFFSETBITS;
2730:
2731:                    // Line number where class ends in the src file (not used yet)
2732:                    long endLine = getEndPosition() >> WHEREOFFSETBITS;
2733:
2734:                    // First line looks like:
2735:                    //    CLASS:src,startLine,endLine,className
2736:                    System.out.println("CLASS:" + src + "," + startLine + ","
2737:                            + endLine + "," + className);
2738:
2739:                    // For each class this class is dependent on:
2740:                    //    CLDEP:className1,className2
2741:                    //	where className1 is the name of the class we are in, and
2742:                    //	      classname2 is the name of the class className1
2743:                    //		is dependent on.
2744:                    for (Enumeration e = deps.elements(); e.hasMoreElements();) {
2745:                        ClassDeclaration data = (ClassDeclaration) e
2746:                                .nextElement();
2747:                        // Mangle name of class dependend on.
2748:                        String depName = Type.mangleInnerType(data.getName())
2749:                                .toString();
2750:                        env.output("CLDEP:" + className + "," + depName);
2751:                    }
2752:                }
2753:            }
2754:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.