Source Code Cross Referenced for SourceMember.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) 


001:        /*
002:         * Copyright 1994-2004 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        package sun.tools.javac;
027:
028:        import sun.tools.java.*;
029:        import sun.tools.tree.*;
030:        import sun.tools.asm.*;
031:        import java.util.Vector;
032:        import java.util.Enumeration;
033:        import java.util.Hashtable;
034:        import java.io.PrintStream;
035:
036:        /**
037:         * A Source Member
038:         *
039:         * WARNING: The contents of this source file are not part of any
040:         * supported API.  Code that depends on them does so at its own risk:
041:         * they are subject to change or removal without notice.
042:         */
043:        @Deprecated
044:        public class SourceMember extends MemberDefinition implements  Constants {
045:            /**
046:             * The argument names (if it is a method)
047:             */
048:            Vector args;
049:
050:            // set to the MemberDefinition in the interface if we have this field because
051:            // it has been forced on us 
052:            MemberDefinition abstractSource;
053:
054:            /**
055:             * The status of the field
056:             */
057:            int status;
058:
059:            static final int PARSED = 0;
060:            static final int CHECKING = 1;
061:            static final int CHECKED = 2;
062:            static final int INLINING = 3;
063:            static final int INLINED = 4;
064:            static final int ERROR = 5;
065:
066:            public Vector getArguments() {
067:                return args;
068:            }
069:
070:            /**
071:             * Constructor
072:             * @param argNames a vector of IdentifierToken
073:             */
074:            public SourceMember(long where, ClassDefinition clazz, String doc,
075:                    int modifiers, Type type, Identifier name, Vector argNames,
076:                    IdentifierToken exp[], Node value) {
077:                super (where, clazz, modifiers, type, name, exp, value);
078:                this .documentation = doc;
079:                this .args = argNames; // for the moment
080:                // not until type names are resolved: createArgumentFields(argNames);
081:
082:                if (ClassDefinition.containsDeprecated(documentation)) {
083:                    this .modifiers |= M_DEPRECATED;
084:                }
085:            }
086:
087:            void createArgumentFields(Vector argNames) {
088:                // Create a list of arguments
089:                if (isMethod()) {
090:                    args = new Vector();
091:
092:                    if (isConstructor() || !(isStatic() || isInitializer())) {
093:                        args
094:                                .addElement(((SourceClass) clazz)
095:                                        .getThisArgument());
096:                    }
097:
098:                    if (argNames != null) {
099:                        Enumeration e = argNames.elements();
100:                        Type argTypes[] = getType().getArgumentTypes();
101:                        for (int i = 0; i < argTypes.length; i++) {
102:                            Object x = e.nextElement();
103:                            if (x instanceof  LocalMember) {
104:                                // This should not happen, but it does
105:                                // in cases of vicious cyclic inheritance.
106:                                args = argNames;
107:                                return;
108:                            }
109:                            Identifier id;
110:                            int mod;
111:                            long where;
112:                            if (x instanceof  Identifier) {
113:                                // allow argNames to be simple Identifiers (deprecated!)
114:                                id = (Identifier) x;
115:                                mod = 0;
116:                                where = getWhere();
117:                            } else {
118:                                IdentifierToken token = (IdentifierToken) x;
119:                                id = token.getName();
120:                                mod = token.getModifiers();
121:                                where = token.getWhere();
122:                            }
123:                            args.addElement(new LocalMember(where, clazz, mod,
124:                                    argTypes[i], id));
125:                        }
126:                    }
127:                }
128:            }
129:
130:            // The methods addOuterThis() and addUplevelArguments() were
131:            // both originally part of a single method called addUplevelArguments()
132:            // which took a single boolean parameter describing which of the
133:            // two behaviors it wanted.
134:            //
135:            // The original addUplevelArguments() claimed to keep the arguments in
136:            // the following order:
137:            //
138:            // (1) <this> <early outer this> <uplevel arguments...> <true arguments...>
139:            //
140:            // (By <early outer this> I am referring to the clientOuterField added
141:            // to some constructors when they are created.  If an outer this is
142:            // added later, on demand, then this is mixed in with the rest of the
143:            // uplevel arguments and is added by addUplevelArguments.)
144:            //
145:            // In reality, the `args' Vector was generated in this order, but the
146:            // Type array `argTypes' was generated as:
147:            //
148:            // (2) <this> <uplevel arguments...> <early outer this> <true arguments...>
149:            //
150:            // This didn't make a difference in the common case -- that is, when
151:            // a class had an <outer.this> or <uplevel arguments...> but not both.
152:            // Both can happen in the case that a member class is declared inside
153:            // of a local class.  It seems that the calling sequences, generated
154:            // in places like NewInstanceExpression.codeCommon(), use order (2),
155:            // so I have changed the code below to stick with that order.  Since
156:            // the only time this happens is in classes which are insideLocal, no
157:            // one should be able to tell the difference between these orders.
158:            // (bug number 4085633)
159:
160:            LocalMember outerThisArg = null;
161:
162:            /**
163:             * Get outer instance link, or null if none.
164:             */
165:
166:            public LocalMember getOuterThisArg() {
167:                return outerThisArg;
168:            }
169:
170:            /**
171:             * Add the outer.this argument to the list of arguments for this
172:             * constructor.  This is called from resolveTypeStructure.  Any
173:             * additional uplevel arguments get added later by addUplevelArguments().
174:             */
175:
176:            void addOuterThis() {
177:                UplevelReference refs = clazz.getReferences();
178:
179:                // See if we have a client outer field.
180:                while (refs != null && !refs.isClientOuterField()) {
181:                    refs = refs.getNext();
182:                }
183:
184:                // There is no outer this argument.  Quit.
185:                if (refs == null) {
186:                    return;
187:                }
188:
189:                // Get the old arg types.
190:                Type oldArgTypes[] = type.getArgumentTypes();
191:
192:                // And make an array for the new ones with space for one more.
193:                Type argTypes[] = new Type[oldArgTypes.length + 1];
194:
195:                LocalMember arg = refs.getLocalArgument();
196:                outerThisArg = arg;
197:
198:                // args is our list of arguments.  It contains a `this', so
199:                // we insert at position 1.  The list of types does not have a
200:                // this, so we insert at position 0.
201:                args.insertElementAt(arg, 1);
202:                argTypes[0] = arg.getType();
203:
204:                // Add on the rest of the constructor arguments.
205:                for (int i = 0; i < oldArgTypes.length; i++) {
206:                    argTypes[i + 1] = oldArgTypes[i];
207:                }
208:
209:                type = Type.tMethod(type.getReturnType(), argTypes);
210:            }
211:
212:            /**
213:             * Prepend argument names and argument types for local variable references.
214:             * This information is never seen by the type-check phase,
215:             * but it affects code generation, which is the earliest moment
216:             * we have comprehensive information on uplevel references.
217:             * The code() methods tweaks the constructor calls, prepending
218:             * the proper values to the argument list.
219:             */
220:            void addUplevelArguments() {
221:                UplevelReference refs = clazz.getReferences();
222:                clazz.getReferencesFrozen();
223:
224:                // Count how many uplevels we have to add.
225:                int count = 0;
226:                for (UplevelReference r = refs; r != null; r = r.getNext()) {
227:                    if (!r.isClientOuterField()) {
228:                        count += 1;
229:                    }
230:                }
231:
232:                if (count == 0) {
233:                    // None to add, quit.
234:                    return;
235:                }
236:
237:                // Get the old argument types.
238:                Type oldArgTypes[] = type.getArgumentTypes();
239:
240:                // Make an array with enough room for the new.
241:                Type argTypes[] = new Type[oldArgTypes.length + count];
242:
243:                // Add all of the late uplevel references to args and argTypes.
244:                // Note that they are `off-by-one' because of the `this'.
245:                int ins = 0;
246:                for (UplevelReference r = refs; r != null; r = r.getNext()) {
247:                    if (!r.isClientOuterField()) {
248:                        LocalMember arg = r.getLocalArgument();
249:
250:                        args.insertElementAt(arg, 1 + ins);
251:                        argTypes[ins] = arg.getType();
252:
253:                        ins++;
254:                    }
255:                }
256:
257:                // Add the rest of the old arguments.
258:                for (int i = 0; i < oldArgTypes.length; i++) {
259:                    argTypes[ins + i] = oldArgTypes[i];
260:                }
261:
262:                type = Type.tMethod(type.getReturnType(), argTypes);
263:            }
264:
265:            /**
266:             * Constructor for an inner class.
267:             */
268:            public SourceMember(ClassDefinition innerClass) {
269:                super (innerClass);
270:            }
271:
272:            /**
273:             * Constructor.
274:             * Used only to generate an abstract copy of a method that a class
275:             * inherits from an interface 
276:             */
277:            public SourceMember(MemberDefinition f, ClassDefinition c,
278:                    Environment env) {
279:                this (f.getWhere(), c, f.getDocumentation(), f.getModifiers()
280:                        | M_ABSTRACT, f.getType(), f.getName(), null, f
281:                        .getExceptionIds(), null);
282:                this .args = f.getArguments();
283:                this .abstractSource = f;
284:                this .exp = f.getExceptions(env);
285:            }
286:
287:            /**
288:             * Get exceptions
289:             */
290:            public ClassDeclaration[] getExceptions(Environment env) {
291:                if ((!isMethod()) || (exp != null)) {
292:                    return exp;
293:                }
294:                if (expIds == null) {
295:                    // (should not happen)
296:                    exp = new ClassDeclaration[0];
297:                    return exp;
298:                }
299:                // be sure to get the imports right:
300:                env = ((SourceClass) getClassDefinition()).setupEnv(env);
301:                exp = new ClassDeclaration[expIds.length];
302:                for (int i = 0; i < exp.length; i++) {
303:                    Identifier e = expIds[i].getName();
304:                    Identifier rexp = getClassDefinition().resolveName(env, e);
305:                    exp[i] = env.getClassDeclaration(rexp);
306:                }
307:                return exp;
308:            }
309:
310:            /**
311:             * Set array of name-resolved exceptions directly, e.g., for access methods.
312:             */
313:            public void setExceptions(ClassDeclaration[] exp) {
314:                this .exp = exp;
315:            }
316:
317:            /**
318:             * Resolve types in a field, after parsing.
319:             * @see ClassDefinition.resolveTypeStructure
320:             */
321:
322:            public boolean resolved = false;
323:
324:            public void resolveTypeStructure(Environment env) {
325:                if (tracing)
326:                    env.dtEnter("SourceMember.resolveTypeStructure: " + this );
327:
328:                // A member should only be resolved once.  For a constructor, it is imperative
329:                // that 'addOuterThis' be called only once, else the outer instance argument may
330:                // be inserted into the argument list multiple times.
331:
332:                if (resolved) {
333:                    if (tracing)
334:                        env.dtEvent("SourceMember.resolveTypeStructure: OK "
335:                                + this );
336:                    // This case shouldn't be happening.  It is the responsibility
337:                    // of our callers to avoid attempting multiple resolutions of a member.
338:                    // *** REMOVE FOR SHIPMENT? ***
339:                    throw new CompilerError("multiple member type resolution");
340:                    //return;
341:                } else {
342:                    if (tracing)
343:                        env
344:                                .dtEvent("SourceMember.resolveTypeStructure: RESOLVING "
345:                                        + this );
346:                    resolved = true;
347:                }
348:
349:                super .resolveTypeStructure(env);
350:                if (isInnerClass()) {
351:                    ClassDefinition nc = getInnerClass();
352:                    if (nc instanceof  SourceClass && !nc.isLocal()) {
353:                        ((SourceClass) nc).resolveTypeStructure(env);
354:                    }
355:                    type = innerClass.getType();
356:                } else {
357:                    // Expand all class names in 'type', including those that are not
358:                    // fully-qualified or refer to inner classes, into fully-qualified
359:                    // names.  Local and anonymous classes get synthesized names here,
360:                    // corresponding to the class files that will be generated.  This is
361:                    // currently the only place where 'resolveNames' is used.
362:                    type = env.resolveNames(getClassDefinition(), type,
363:                            isSynthetic());
364:
365:                    // do the throws also:
366:                    getExceptions(env);
367:
368:                    if (isMethod()) {
369:                        Vector argNames = args;
370:                        args = null;
371:                        createArgumentFields(argNames);
372:                        // Add outer instance argument for constructors.
373:                        if (isConstructor()) {
374:                            addOuterThis();
375:                        }
376:                    }
377:                }
378:                if (tracing)
379:                    env.dtExit("SourceMember.resolveTypeStructure: " + this );
380:            }
381:
382:            /**
383:             * Get the class declaration in which the field is actually defined
384:             */
385:            public ClassDeclaration getDefiningClassDeclaration() {
386:                if (abstractSource == null)
387:                    return super .getDefiningClassDeclaration();
388:                else
389:                    return abstractSource.getDefiningClassDeclaration();
390:            }
391:
392:            /**
393:             * A source field never reports deprecation, since the compiler
394:             * allows access to deprecated features that are being compiled
395:             * in the same job.
396:             */
397:            public boolean reportDeprecated(Environment env) {
398:                return false;
399:            }
400:
401:            /**
402:             * Check this field.
403:             * <p>
404:             * This is the method which requests checking.
405:             * The real work is done by
406:             * <tt>Vset check(Environment, Context, Vset)</tt>.
407:             */
408:            public void check(Environment env) throws ClassNotFound {
409:                if (tracing)
410:                    env.dtEnter("SourceMember.check: " + getName()
411:                            + ", status = " + status);
412:                // rely on the class to check all fields in the proper order
413:                if (status == PARSED) {
414:                    if (isSynthetic() && getValue() == null) {
415:                        // break a big cycle for small synthetic variables
416:                        status = CHECKED;
417:                        if (tracing)
418:                            env.dtExit("SourceMember.check: BREAKING CYCLE");
419:                        return;
420:                    }
421:                    if (tracing)
422:                        env.dtEvent("SourceMember.check: CHECKING CLASS");
423:                    clazz.check(env);
424:                    if (status == PARSED) {
425:                        if (getClassDefinition().getError()) {
426:                            status = ERROR;
427:                        } else {
428:                            if (tracing)
429:                                env.dtExit("SourceMember.check: CHECK FAILED");
430:                            throw new CompilerError("check failed");
431:                        }
432:                    }
433:                }
434:                if (tracing)
435:                    env.dtExit("SourceMember.check: DONE " + getName()
436:                            + ", status = " + status);
437:            }
438:
439:            /**
440:             * Check a field.
441:             * @param vset tells which uplevel variables are definitely assigned
442:             * The vset is also used to track the initialization of blank finals
443:             * by whichever fields which are relevant to them.
444:             */
445:            public Vset check(Environment env, Context ctx, Vset vset)
446:                    throws ClassNotFound {
447:                if (tracing)
448:                    env.dtEvent("SourceMember.check: MEMBER " + getName()
449:                            + ", status = " + status);
450:                if (status == PARSED) {
451:                    if (isInnerClass()) {
452:                        // some classes are checked separately
453:                        ClassDefinition nc = getInnerClass();
454:                        if (nc instanceof  SourceClass && !nc.isLocal()
455:                                && nc.isInsideLocal()) {
456:                            status = CHECKING;
457:                            vset = ((SourceClass) nc).checkInsideClass(env,
458:                                    ctx, vset);
459:                        }
460:                        status = CHECKED;
461:                        return vset;
462:                    }
463:                    if (env.dump()) {
464:                        System.out.println("[check field "
465:                                + getClassDeclaration().getName() + "."
466:                                + getName() + "]");
467:                        if (getValue() != null) {
468:                            getValue().print(System.out);
469:                            System.out.println();
470:                        }
471:                    }
472:                    env = new Environment(env, this );
473:
474:                    // This is where all checking of names appearing within the type
475:                    // of the member is done.  Includes return type and argument types.
476:                    // Since only one location ('where') for error messages is provided,
477:                    // localization of errors is poor.  Throws clauses are handled below.
478:                    env.resolve(where, getClassDefinition(), getType());
479:
480:                    // Make sure that all the classes that we claim to throw really
481:                    // are subclasses of Throwable, and are classes that we can reach
482:                    if (isMethod()) {
483:                        ClassDeclaration throwable = env
484:                                .getClassDeclaration(idJavaLangThrowable);
485:                        ClassDeclaration exp[] = getExceptions(env);
486:                        for (int i = 0; i < exp.length; i++) {
487:                            ClassDefinition def;
488:                            long where = getWhere();
489:                            if (expIds != null && i < expIds.length) {
490:                                where = IdentifierToken.getWhere(expIds[i],
491:                                        where);
492:                            }
493:                            try {
494:                                def = exp[i].getClassDefinition(env);
495:
496:                                // Validate access for all inner-class components
497:                                // of a qualified name, not just the last one, which
498:                                // is checked below.  Yes, this is a dirty hack...
499:                                // Part of fix for 4094658.
500:                                env.resolveByName(where, getClassDefinition(),
501:                                        def.getName());
502:
503:                            } catch (ClassNotFound e) {
504:                                env.error(where, "class.not.found", e.name,
505:                                        "throws");
506:                                break;
507:                            }
508:                            def.noteUsedBy(getClassDefinition(), where, env);
509:                            if (!getClassDefinition().canAccess(env,
510:                                    def.getClassDeclaration())) {
511:                                env.error(where, "cant.access.class", def);
512:                            } else if (!def.subClassOf(env, throwable)) {
513:                                env.error(where, "throws.not.throwable", def);
514:                            }
515:                        }
516:                    }
517:
518:                    status = CHECKING;
519:
520:                    if (isMethod() && args != null) {
521:                        int length = args.size();
522:                        outer_loop: for (int i = 0; i < length; i++) {
523:                            LocalMember lf = (LocalMember) (args.elementAt(i));
524:                            Identifier name_i = lf.getName();
525:                            for (int j = i + 1; j < length; j++) {
526:                                LocalMember lf2 = (LocalMember) (args
527:                                        .elementAt(j));
528:                                Identifier name_j = lf2.getName();
529:                                if (name_i.equals(name_j)) {
530:                                    env.error(lf2.getWhere(),
531:                                            "duplicate.argument", name_i);
532:                                    break outer_loop;
533:                                }
534:                            }
535:                        }
536:                    }
537:
538:                    if (getValue() != null) {
539:                        ctx = new Context(ctx, this );
540:
541:                        if (isMethod()) {
542:                            Statement s = (Statement) getValue();
543:                            // initialize vset, indication that each of the arguments
544:                            // to the function has a value
545:
546:                            for (Enumeration e = args.elements(); e
547:                                    .hasMoreElements();) {
548:                                LocalMember f = (LocalMember) e.nextElement();
549:                                vset.addVar(ctx.declare(env, f));
550:                            }
551:
552:                            if (isConstructor()) {
553:                                // Undefine "this" in some constructors, until after
554:                                // the super constructor has been called.
555:                                vset.clearVar(ctx.getThisNumber());
556:
557:                                // If the first thing in the definition isn't a call
558:                                // to either super() or this(), then insert one.
559:                                Expression supCall = s.firstConstructor();
560:                                if ((supCall == null)
561:                                        && (getClassDefinition()
562:                                                .getSuperClass() != null)) {
563:                                    supCall = getDefaultSuperCall(env);
564:                                    Statement scs = new ExpressionStatement(
565:                                            where, supCall);
566:                                    s = Statement.insertStatement(scs, s);
567:                                    setValue(s);
568:                                }
569:                            }
570:
571:                            //System.out.println("VSET = " + vset);
572:                            ClassDeclaration exp[] = getExceptions(env);
573:                            int htsize = (exp.length > 3) ? 17 : 7;
574:                            Hashtable thrown = new Hashtable(htsize);
575:
576:                            vset = s.checkMethod(env, ctx, vset, thrown);
577:
578:                            ClassDeclaration ignore1 = env
579:                                    .getClassDeclaration(idJavaLangError);
580:                            ClassDeclaration ignore2 = env
581:                                    .getClassDeclaration(idJavaLangRuntimeException);
582:
583:                            for (Enumeration e = thrown.keys(); e
584:                                    .hasMoreElements();) {
585:                                ClassDeclaration c = (ClassDeclaration) e
586:                                        .nextElement();
587:                                ClassDefinition def = c.getClassDefinition(env);
588:                                if (def.subClassOf(env, ignore1)
589:                                        || def.subClassOf(env, ignore2)) {
590:                                    continue;
591:                                }
592:
593:                                boolean ok = false;
594:                                if (!isInitializer()) {
595:                                    for (int i = 0; i < exp.length; i++) {
596:                                        if (def.subClassOf(env, exp[i])) {
597:                                            ok = true;
598:                                        }
599:                                    }
600:                                }
601:                                if (!ok) {
602:                                    Node n = (Node) thrown.get(c);
603:                                    long where = n.getWhere();
604:                                    String errorMsg;
605:
606:                                    if (isConstructor()) {
607:                                        if (where == getClassDefinition()
608:                                                .getWhere()) {
609:
610:                                            // If this message is being generated for
611:                                            // a default constructor, we should give
612:                                            // a different error message.  Currently
613:                                            // we check for this by seeing if the
614:                                            // constructor has the same "where" as
615:                                            // its class.  This is a bit kludgy, but
616:                                            // works. (bug id 4034836)
617:                                            errorMsg = "def.constructor.exception";
618:                                        } else {
619:                                            // Constructor with uncaught exception.
620:                                            errorMsg = "constructor.exception";
621:                                        }
622:                                    } else if (isInitializer()) {
623:                                        // Initializer with uncaught exception.
624:                                        errorMsg = "initializer.exception";
625:                                    } else {
626:                                        // Method with uncaught exception.
627:                                        errorMsg = "uncaught.exception";
628:                                    }
629:                                    env.error(where, errorMsg, c.getName());
630:                                }
631:                            }
632:                        } else {
633:                            Hashtable thrown = new Hashtable(3); // small & throw-away
634:                            Expression val = (Expression) getValue();
635:
636:                            vset = val.checkInitializer(env, ctx, vset,
637:                                    getType(), thrown);
638:                            setValue(val.convert(env, ctx, getType(), val));
639:
640:                            // Complain about static final members of inner classes that
641:                            // do not have an initializer that is a constant expression.
642:                            // In general, static members are not permitted for inner
643:                            // classes, but an exception is made for named constants.
644:                            // Other cases of static members, including non-final ones,
645:                            // are handled in 'SourceClass'.  Part of fix for 4095568.
646:                            if (isStatic() && isFinal() && !clazz.isTopLevel()) {
647:                                if (!((Expression) getValue()).isConstant()) {
648:                                    env.error(where, "static.inner.field",
649:                                            getName(), this );
650:                                    setValue(null);
651:                                }
652:                            }
653:
654:                            // Both RuntimeExceptions and Errors should be
655:                            // allowed in initializers.  Fix for bug 4102541.
656:                            ClassDeclaration except = env
657:                                    .getClassDeclaration(idJavaLangThrowable);
658:                            ClassDeclaration ignore1 = env
659:                                    .getClassDeclaration(idJavaLangError);
660:                            ClassDeclaration ignore2 = env
661:                                    .getClassDeclaration(idJavaLangRuntimeException);
662:
663:                            for (Enumeration e = thrown.keys(); e
664:                                    .hasMoreElements();) {
665:                                ClassDeclaration c = (ClassDeclaration) e
666:                                        .nextElement();
667:                                ClassDefinition def = c.getClassDefinition(env);
668:
669:                                if (!def.subClassOf(env, ignore1)
670:                                        && !def.subClassOf(env, ignore2)
671:                                        && def.subClassOf(env, except)) {
672:                                    Node n = (Node) thrown.get(c);
673:                                    env.error(n.getWhere(),
674:                                            "initializer.exception", c
675:                                                    .getName());
676:                                }
677:                            }
678:                        }
679:                        if (env.dump()) {
680:                            getValue().print(System.out);
681:                            System.out.println();
682:                        }
683:                    }
684:                    status = getClassDefinition().getError() ? ERROR : CHECKED;
685:                }
686:
687:                // Initializers (static and instance) must be able to complete normally.
688:                if (isInitializer() && vset.isDeadEnd()) {
689:                    env.error(where, "init.no.normal.completion");
690:                    vset = vset.clearDeadEnd();
691:                }
692:
693:                return vset;
694:            }
695:
696:            // helper to check(): synthesize a missing super() call
697:            private Expression getDefaultSuperCall(Environment env) {
698:                Expression se = null;
699:                ClassDefinition sclass = getClassDefinition().getSuperClass()
700:                        .getClassDefinition();
701:                // does the superclass constructor require an enclosing instance?
702:                ClassDefinition reqc = (sclass == null) ? null : sclass
703:                        .isTopLevel() ? null : sclass.getOuterClass();
704:                ClassDefinition this c = getClassDefinition();
705:                if (reqc != null && !Context.outerLinkExists(env, reqc, this c)) {
706:                    se = new SuperExpression(where, new NullExpression(where));
707:                    env.error(where, "no.default.outer.arg", reqc,
708:                            getClassDefinition());
709:                }
710:                if (se == null) {
711:                    se = new SuperExpression(where);
712:                }
713:                return new MethodExpression(where, se, idInit,
714:                        new Expression[0]);
715:            }
716:
717:            /**
718:             * Inline the field
719:             */
720:            void inline(Environment env) throws ClassNotFound {
721:                switch (status) {
722:                case PARSED:
723:                    check(env);
724:                    inline(env);
725:                    break;
726:
727:                case CHECKED:
728:                    if (env.dump()) {
729:                        System.out.println("[inline field "
730:                                + getClassDeclaration().getName() + "."
731:                                + getName() + "]");
732:                    }
733:                    status = INLINING;
734:                    env = new Environment(env, this );
735:
736:                    if (isMethod()) {
737:                        if ((!isNative()) && (!isAbstract())) {
738:                            Statement s = (Statement) getValue();
739:                            Context ctx = new Context((Context) null, this );
740:                            for (Enumeration e = args.elements(); e
741:                                    .hasMoreElements();) {
742:                                LocalMember local = (LocalMember) e
743:                                        .nextElement();
744:                                ctx.declare(env, local);
745:                            }
746:                            setValue(s.inline(env, ctx));
747:                        }
748:                    } else if (isInnerClass()) {
749:                        // some classes are checked and inlined separately
750:                        ClassDefinition nc = getInnerClass();
751:                        if (nc instanceof  SourceClass && !nc.isLocal()
752:                                && nc.isInsideLocal()) {
753:                            status = INLINING;
754:                            ((SourceClass) nc).inlineLocalClass(env);
755:                        }
756:                        status = INLINED;
757:                        break;
758:                    } else {
759:                        if (getValue() != null) {
760:                            Context ctx = new Context((Context) null, this );
761:                            if (!isStatic()) {
762:                                // Cf. "thisArg" in SourceClass.checkMembers().
763:                                Context ctxInst = new Context(ctx, this );
764:                                LocalMember this Arg = ((SourceClass) clazz)
765:                                        .getThisArgument();
766:                                ctxInst.declare(env, this Arg);
767:                                setValue(((Expression) getValue()).inlineValue(
768:                                        env, ctxInst));
769:                            } else {
770:                                setValue(((Expression) getValue()).inlineValue(
771:                                        env, ctx));
772:                            }
773:                        }
774:                    }
775:                    if (env.dump()) {
776:                        System.out.println("[inlined field "
777:                                + getClassDeclaration().getName() + "."
778:                                + getName() + "]");
779:                        if (getValue() != null) {
780:                            getValue().print(System.out);
781:                            System.out.println();
782:                        } else {
783:                            System.out.println("<empty>");
784:                        }
785:                    }
786:                    status = INLINED;
787:                    break;
788:                }
789:            }
790:
791:            /**
792:             * Get the value of the field (or null if the value can't be determined)
793:             */
794:            public Node getValue(Environment env) throws ClassNotFound {
795:                Node value = getValue();
796:                if (value != null && status != INLINED) {
797:                    // be sure to get the imports right:
798:                    env = ((SourceClass) clazz).setupEnv(env);
799:                    inline(env);
800:                    value = (status == INLINED) ? getValue() : null;
801:                }
802:                return value;
803:            }
804:
805:            public boolean isInlineable(Environment env, boolean fromFinal)
806:                    throws ClassNotFound {
807:                if (super .isInlineable(env, fromFinal)) {
808:                    getValue(env);
809:                    return (status == INLINED)
810:                            && !getClassDefinition().getError();
811:                }
812:                return false;
813:            }
814:
815:            /**
816:             * Get the initial value of the field
817:             */
818:            public Object getInitialValue() {
819:                if (isMethod() || (getValue() == null) || (!isFinal())
820:                        || (status != INLINED)) {
821:                    return null;
822:                }
823:                return ((Expression) getValue()).getValue();
824:            }
825:
826:            /**
827:             * Generate code
828:             */
829:            public void code(Environment env, Assembler asm)
830:                    throws ClassNotFound {
831:                switch (status) {
832:                case PARSED:
833:                    check(env);
834:                    code(env, asm);
835:                    return;
836:
837:                case CHECKED:
838:                    inline(env);
839:                    code(env, asm);
840:                    return;
841:
842:                case INLINED:
843:                    // Actually generate code
844:                    if (env.dump()) {
845:                        System.out.println("[code field "
846:                                + getClassDeclaration().getName() + "."
847:                                + getName() + "]");
848:                    }
849:                    if (isMethod() && (!isNative()) && (!isAbstract())) {
850:                        env = new Environment(env, this );
851:                        Context ctx = new Context((Context) null, this );
852:                        Statement s = (Statement) getValue();
853:
854:                        for (Enumeration e = args.elements(); e
855:                                .hasMoreElements();) {
856:                            LocalMember f = (LocalMember) e.nextElement();
857:                            ctx.declare(env, f);
858:                            //ctx.declare(env, (LocalMember)e.nextElement());
859:                        }
860:
861:                        /*
862:                        if (isConstructor() && ((s == null) || (s.firstConstructor() == null))) {
863:                            ClassDeclaration c = getClassDefinition().getSuperClass();
864:                            if (c != null) {
865:                        	MemberDefinition field = c.getClassDefinition(env).matchMethod(env, getClassDefinition(), idInit);
866:                        	asm.add(getWhere(), opc_aload, new Integer(0));
867:                        	asm.add(getWhere(), opc_invokespecial, field);
868:                        	asm.add(getWhere(), opc_pop);
869:                            }
870:
871:                            // Output initialization code
872:                            for (MemberDefinition f = getClassDefinition().getFirstMember() ; f != null ; f = f.getNextMember()) {
873:                        	if (!f.isStatic()) {
874:                        	    f.codeInit(env, ctx, asm);
875:                        	}
876:                            }
877:                        }
878:                         */
879:                        if (s != null) {
880:                            s.code(env, ctx, asm);
881:                        }
882:                        if (getType().getReturnType().isType(TC_VOID)
883:                                && !isInitializer()) {
884:                            asm.add(getWhere(), opc_return, true);
885:                        }
886:                    }
887:                    return;
888:                }
889:            }
890:
891:            public void codeInit(Environment env, Context ctx, Assembler asm)
892:                    throws ClassNotFound {
893:                if (isMethod()) {
894:                    return;
895:                }
896:                switch (status) {
897:                case PARSED:
898:                    check(env);
899:                    codeInit(env, ctx, asm);
900:                    return;
901:
902:                case CHECKED:
903:                    inline(env);
904:                    codeInit(env, ctx, asm);
905:                    return;
906:
907:                case INLINED:
908:                    // Actually generate code
909:                    if (env.dump()) {
910:                        System.out.println("[code initializer  "
911:                                + getClassDeclaration().getName() + "."
912:                                + getName() + "]");
913:                    }
914:                    if (getValue() != null) {
915:                        Expression e = (Expression) getValue();
916:                        // The JLS Section 8.5 specifies that static (non-final)
917:                        // initializers should be executed in textual order.  Eliding
918:                        // initializations to default values can interfere with this,
919:                        // so the tests for !e.equalsDefault() have been eliminated,
920:                        // below.
921:                        if (isStatic()) {
922:                            if (getInitialValue() == null) {
923:                                // removed: && !e.equalsDefault()) {
924:                                e.codeValue(env, ctx, asm);
925:                                asm.add(getWhere(), opc_putstatic, this );
926:                            }
927:                        } else { // removed: if (!e.equalsDefault()) {
928:                            // This code doesn't appear to be reached for
929:                            // instance initializers.  Code for these is generated
930:                            // in the makeVarInits() method of the class
931:                            // MethodExpression.
932:                            asm.add(getWhere(), opc_aload, new Integer(0));
933:                            e.codeValue(env, ctx, asm);
934:                            asm.add(getWhere(), opc_putfield, this );
935:                        }
936:                    }
937:                    return;
938:                }
939:            }
940:
941:            /**
942:             * Print for debugging
943:             */
944:            public void print(PrintStream out) {
945:                super.print(out);
946:                if (getValue() != null) {
947:                    getValue().print(out);
948:                    out.println();
949:                }
950:            }
951:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.