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


001:        /*
002:         * Copyright 1994-2003 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.tree;
027:
028:        import sun.tools.java.*;
029:        import sun.tools.asm.Assembler;
030:        import java.util.Hashtable;
031:
032:        /**
033:         * WARNING: The contents of this source file are not part of any
034:         * supported API.  Code that depends on them does so at its own risk:
035:         * they are subject to change or removal without notice.
036:         */
037:        public class NewInstanceExpression extends NaryExpression {
038:            MemberDefinition field;
039:            Expression outerArg;
040:            ClassDefinition body;
041:
042:            // Access method for constructor, if needed.
043:            MemberDefinition implMethod = null;
044:
045:            /**
046:             * Constructor
047:             */
048:            public NewInstanceExpression(long where, Expression right,
049:                    Expression args[]) {
050:                super (NEWINSTANCE, where, Type.tError, right, args);
051:            }
052:
053:            public NewInstanceExpression(long where, Expression right,
054:                    Expression args[], Expression outerArg, ClassDefinition body) {
055:                this (where, right, args);
056:                this .outerArg = outerArg;
057:                this .body = body;
058:            }
059:
060:            /**
061:             * From the "new" in an expression of the form outer.new InnerCls(...),
062:             * return the "outer" expression, or null if there is none.
063:             */
064:            public Expression getOuterArg() {
065:                return outerArg;
066:            }
067:
068:            int precedence() {
069:                return 100;
070:            }
071:
072:            public Expression order() {
073:                // act like a method or field reference expression:
074:                if (outerArg != null
075:                        && opPrecedence[FIELD] > outerArg.precedence()) {
076:                    UnaryExpression e = (UnaryExpression) outerArg;
077:                    outerArg = e.right;
078:                    e.right = order();
079:                    return e;
080:                }
081:                return this ;
082:            }
083:
084:            /**
085:             * Check expression type
086:             */
087:            public Vset checkValue(Environment env, Context ctx, Vset vset,
088:                    Hashtable exp) {
089:                // What type?
090:                ClassDefinition def = null;
091:
092:                Expression alreadyChecked = null;
093:
094:                try {
095:                    if (outerArg != null) {
096:                        vset = outerArg.checkValue(env, ctx, vset, exp);
097:
098:                        // Remember the expression that we already checked
099:                        // so that we don't attempt to check it again when
100:                        // it appears as an argument to the constructor.
101:                        // Fix for 4030426.
102:                        alreadyChecked = outerArg;
103:
104:                        // Check outerArg and the type name together.
105:                        Identifier typeName = FieldExpression
106:                                .toIdentifier(right);
107:
108:                        // According to the inner classes spec, the type name in a
109:                        // qualified 'new' expression must be a single identifier.
110:                        if (typeName != null && typeName.isQualified()) {
111:                            env.error(where, "unqualified.name.required",
112:                                    typeName);
113:                        }
114:
115:                        if (typeName == null || !outerArg.type.isType(TC_CLASS)) {
116:                            if (!outerArg.type.isType(TC_ERROR)) {
117:                                env.error(where, "invalid.field.reference",
118:                                        idNew, outerArg.type);
119:                            }
120:                            outerArg = null;
121:                        } else {
122:                            // Don't perform checks on components of qualified name
123:                            // ('getQualifiedClassDefinition'), because a qualified
124:                            // name is illegal in this context, and will have previously
125:                            // been reported as an error.
126:                            ClassDefinition oc = env
127:                                    .getClassDefinition(outerArg.type);
128:                            Identifier nm = oc.resolveInnerClass(env, typeName);
129:                            right = new TypeExpression(right.where, Type
130:                                    .tClass(nm));
131:                            // Check access directly, since we're not calling toType().
132:                            env.resolve(right.where, ctx.field
133:                                    .getClassDefinition(), right.type);
134:                            // and fall through to env.getClassDefinition() below
135:                        }
136:                    }
137:
138:                    if (!(right instanceof  TypeExpression)) {
139:                        // The call to 'toType' should perform component access checks.
140:                        right = new TypeExpression(right.where, right.toType(
141:                                env, ctx));
142:                    }
143:
144:                    if (right.type.isType(TC_CLASS))
145:                        def = env.getClassDefinition(right.type);
146:                } catch (AmbiguousClass ee) {
147:                    env.error(where, "ambig.class", ee.name1, ee.name2);
148:                } catch (ClassNotFound ee) {
149:                    env.error(where, "class.not.found", ee.name, ctx.field);
150:                }
151:
152:                Type t = right.type;
153:                boolean hasErrors = t.isType(TC_ERROR);
154:
155:                if (!t.isType(TC_CLASS)) {
156:                    if (!hasErrors) {
157:                        env.error(where, "invalid.arg.type", t, opNames[op]);
158:                        hasErrors = true;
159:                    }
160:                }
161:
162:                // If we failed to find a class or a class was ambiguous, def
163:                // may be null.  Bail out.  This allows us to report multiple
164:                // unfound or ambiguous classes rather than tripping over an
165:                // internal compiler error.
166:                if (def == null) {
167:                    type = Type.tError;
168:                    return vset;
169:                }
170:
171:                // Add an extra argument, maybe.
172:                Expression args[] = this .args;
173:                args = NewInstanceExpression.insertOuterLink(env, ctx, where,
174:                        def, outerArg, args);
175:                if (args.length > this .args.length)
176:                    outerArg = args[0]; // recopy the checked arg
177:                else if (outerArg != null)
178:                    // else set it to void (maybe it has a side-effect)
179:                    outerArg = new CommaExpression(outerArg.where, outerArg,
180:                            null);
181:
182:                // Compose a list of argument types
183:                Type argTypes[] = new Type[args.length];
184:
185:                for (int i = 0; i < args.length; i++) {
186:                    // Don't check 'outerArg' again. Fix for 4030426.
187:                    if (args[i] != alreadyChecked) {
188:                        vset = args[i].checkValue(env, ctx, vset, exp);
189:                    }
190:                    argTypes[i] = args[i].type;
191:                    hasErrors = hasErrors || argTypes[i].isType(TC_ERROR);
192:                }
193:
194:                try {
195:                    // Check if there are any type errors in the arguments
196:                    if (hasErrors) {
197:                        type = Type.tError;
198:                        return vset;
199:                    }
200:
201:                    // Get the source class that this declaration appears in.
202:                    ClassDefinition sourceClass = ctx.field
203:                            .getClassDefinition();
204:
205:                    ClassDeclaration c = env.getClassDeclaration(t);
206:
207:                    // If this is an anonymous class, handle it specially now.
208:                    if (body != null) {
209:                        // The current package.
210:                        Identifier packageName = sourceClass.getName()
211:                                .getQualifier();
212:
213:                        // This is an anonymous class.
214:                        ClassDefinition super Def = null;
215:                        if (def.isInterface()) {
216:                            // For interfaces, our superclass is java.lang.Object.
217:                            // We could just assume that java.lang.Object has
218:                            // one constructor with no arguments in the code
219:                            // that follows, but we don't.  This way, if Object
220:                            // grows a new constructor (unlikely) then the
221:                            // compiler should handle it.
222:                            super Def = env.getClassDefinition(idJavaLangObject);
223:                        } else {
224:                            // Otherwise, def is actually our superclass.
225:                            super Def = def;
226:                        }
227:                        // Try to find a matching constructor in our superclass.
228:                        MemberDefinition constructor = super Def
229:                                .matchAnonConstructor(env, packageName,
230:                                        argTypes);
231:                        if (constructor != null) {
232:                            // We've found one.  Process the body.
233:                            //
234:                            // Note that we are passing in the constructors' argument
235:                            // types, rather than the argument types of the actual
236:                            // expressions, to checkLocalClass().  Previously,
237:                            // the expression types were passed in.  This could
238:                            // lead to trouble when one of the argument types was
239:                            // the special internal type tNull.  (bug 4054689).
240:                            if (tracing)
241:                                env
242:                                        .dtEvent("NewInstanceExpression.checkValue: ANON CLASS "
243:                                                + body + " SUPER " + def);
244:                            vset = body.checkLocalClass(env, ctx, vset, def,
245:                                    args, constructor.getType()
246:                                            .getArgumentTypes());
247:
248:                            // Set t to be the true type of this expression.
249:                            // (bug 4102056).
250:                            t = body.getClassDeclaration().getType();
251:
252:                            def = body;
253:                        }
254:                    } else {
255:                        // Check if it is an interface
256:                        if (def.isInterface()) {
257:                            env.error(where, "new.intf", c);
258:                            return vset;
259:                        }
260:
261:                        // Check for abstract class
262:                        if (def.mustBeAbstract(env)) {
263:                            env.error(where, "new.abstract", c);
264:                            return vset;
265:                        }
266:                    }
267:
268:                    // Get the constructor that the "new" expression should call.
269:                    field = def.matchMethod(env, sourceClass, idInit, argTypes);
270:
271:                    // Report an error if there is no matching constructor.
272:                    if (field == null) {
273:                        MemberDefinition anyInit = def.findAnyMethod(env,
274:                                idInit);
275:                        if (anyInit != null
276:                                && new MethodExpression(where, right, anyInit,
277:                                        args).diagnoseMismatch(env, args,
278:                                        argTypes))
279:                            return vset;
280:                        String sig = c.getName().getName().toString();
281:                        sig = Type.tMethod(Type.tError, argTypes).typeString(
282:                                sig, false, false);
283:                        env.error(where, "unmatched.constr", sig, c);
284:                        return vset;
285:                    }
286:
287:                    if (field.isPrivate()) {
288:                        ClassDefinition cdef = field.getClassDefinition();
289:                        if (cdef != sourceClass) {
290:                            // Use access method.
291:                            implMethod = cdef.getAccessMember(env, ctx, field,
292:                                    false);
293:                        }
294:                    }
295:
296:                    // Check for abstract anonymous class
297:                    if (def.mustBeAbstract(env)) {
298:                        env.error(where, "new.abstract", c);
299:                        return vset;
300:                    }
301:
302:                    if (field.reportDeprecated(env)) {
303:                        env.error(where, "warn.constr.is.deprecated", field,
304:                                field.getClassDefinition());
305:                    }
306:
307:                    // According to JLS 6.6.2, a protected constructor may be accessed
308:                    // by a class instance creation expression only from within the
309:                    // package in which it is defined.
310:                    if (field.isProtected()
311:                            && !(sourceClass.getName().getQualifier()
312:                                    .equals(field.getClassDeclaration()
313:                                            .getName().getQualifier()))) {
314:                        env.error(where, "invalid.protected.constructor.use",
315:                                sourceClass);
316:                    }
317:
318:                } catch (ClassNotFound ee) {
319:                    env.error(where, "class.not.found", ee.name, opNames[op]);
320:                    return vset;
321:
322:                } catch (AmbiguousMember ee) {
323:                    env.error(where, "ambig.constr", ee.field1, ee.field2);
324:                    return vset;
325:                }
326:
327:                // Cast arguments
328:                argTypes = field.getType().getArgumentTypes();
329:                for (int i = 0; i < args.length; i++) {
330:                    args[i] = convert(env, ctx, argTypes[i], args[i]);
331:                }
332:                if (args.length > this .args.length) {
333:                    outerArg = args[0]; // recopy the checked arg
334:                    // maintain an accurate tree
335:                    for (int i = 1; i < args.length; i++) {
336:                        this .args[i - 1] = args[i];
337:                    }
338:                }
339:
340:                // Throw the declared exceptions.
341:                ClassDeclaration exceptions[] = field.getExceptions(env);
342:                for (int i = 0; i < exceptions.length; i++) {
343:                    if (exp.get(exceptions[i]) == null) {
344:                        exp.put(exceptions[i], this );
345:                    }
346:                }
347:
348:                type = t;
349:
350:                return vset;
351:            }
352:
353:            /**
354:             * Given a list of arguments for a constructor,
355:             * return a possibly modified list which includes the hidden
356:             * argument which initializes the uplevel self pointer.
357:             * @arg def the class which perhaps contains an outer link.
358:             * @arg outerArg if non-null, an explicit location in which to construct.
359:             */
360:            public static Expression[] insertOuterLink(Environment env,
361:                    Context ctx, long where, ClassDefinition def,
362:                    Expression outerArg, Expression args[]) {
363:                if (!def.isTopLevel() && !def.isLocal()) {
364:                    Expression args2[] = new Expression[1 + args.length];
365:                    System.arraycopy(args, 0, args2, 1, args.length);
366:                    try {
367:                        if (outerArg == null)
368:                            outerArg = ctx.findOuterLink(env, where, def
369:                                    .findAnyMethod(env, idInit));
370:                    } catch (ClassNotFound e) {
371:                        // die somewhere else
372:                    }
373:                    args2[0] = outerArg;
374:                    args = args2;
375:                }
376:                return args;
377:            }
378:
379:            /**
380:             * Check void expression
381:             */
382:            public Vset check(Environment env, Context ctx, Vset vset,
383:                    Hashtable exp) {
384:                return checkValue(env, ctx, vset, exp);
385:            }
386:
387:            /**
388:             * Inline
389:             */
390:            final int MAXINLINECOST = Statement.MAXINLINECOST;
391:
392:            public Expression copyInline(Context ctx) {
393:                NewInstanceExpression e = (NewInstanceExpression) super 
394:                        .copyInline(ctx);
395:                if (outerArg != null) {
396:                    e.outerArg = outerArg.copyInline(ctx);
397:                }
398:                return e;
399:            }
400:
401:            Expression inlineNewInstance(Environment env, Context ctx,
402:                    Statement s) {
403:                if (env.dump()) {
404:                    System.out.println("INLINE NEW INSTANCE " + field + " in "
405:                            + ctx.field);
406:                }
407:                LocalMember v[] = LocalMember.copyArguments(ctx, field);
408:                Statement body[] = new Statement[v.length + 2];
409:
410:                int o = 1;
411:                if (outerArg != null && !outerArg.type.isType(TC_VOID)) {
412:                    o = 2;
413:                    body[1] = new VarDeclarationStatement(where, v[1], outerArg);
414:                } else if (outerArg != null) {
415:                    body[0] = new ExpressionStatement(where, outerArg);
416:                }
417:                for (int i = 0; i < args.length; i++) {
418:                    body[i + o] = new VarDeclarationStatement(where, v[i + o],
419:                            args[i]);
420:                }
421:                //System.out.print("BEFORE:"); s.print(System.out); System.out.println();
422:                body[body.length - 1] = (s != null) ? s.copyInline(ctx, false)
423:                        : null;
424:                //System.out.print("COPY:"); body[body.length - 1].print(System.out); System.out.println();
425:                //System.out.print("AFTER:"); s.print(System.out); System.out.println();
426:                LocalMember.doneWithArguments(ctx, v);
427:
428:                return new InlineNewInstanceExpression(where, type, field,
429:                        new CompoundStatement(where, body)).inline(env, ctx);
430:            }
431:
432:            public Expression inline(Environment env, Context ctx) {
433:                return inlineValue(env, ctx);
434:            }
435:
436:            public Expression inlineValue(Environment env, Context ctx) {
437:                if (body != null) {
438:                    body.inlineLocalClass(env);
439:                }
440:                ClassDefinition refc = field.getClassDefinition();
441:                UplevelReference r = refc.getReferencesFrozen();
442:                if (r != null) {
443:                    r.willCodeArguments(env, ctx);
444:                }
445:                //right = right.inlineValue(env, ctx);
446:
447:                try {
448:                    if (outerArg != null) {
449:                        if (outerArg.type.isType(TC_VOID))
450:                            outerArg = outerArg.inline(env, ctx);
451:                        else
452:                            outerArg = outerArg.inlineValue(env, ctx);
453:                    }
454:                    for (int i = 0; i < args.length; i++) {
455:                        args[i] = args[i].inlineValue(env, ctx);
456:                    }
457:                    // This 'false' that fy put in is inexplicable to me
458:                    // the decision to not inline new instance expressions
459:                    // should be revisited.  - dps
460:                    if (false && env.opt() && field.isInlineable(env, false)
461:                            && (!ctx.field.isInitializer())
462:                            && ctx.field.isMethod()
463:                            && (ctx.getInlineMemberContext(field) == null)) {
464:                        Statement s = (Statement) field.getValue(env);
465:                        if ((s == null)
466:                                || (s.costInline(MAXINLINECOST, env, ctx) < MAXINLINECOST)) {
467:                            return inlineNewInstance(env, ctx, s);
468:                        }
469:                    }
470:                } catch (ClassNotFound e) {
471:                    throw new CompilerError(e);
472:                }
473:                if (outerArg != null && outerArg.type.isType(TC_VOID)) {
474:                    Expression e = outerArg;
475:                    outerArg = null;
476:                    return new CommaExpression(where, e, this );
477:                }
478:                return this ;
479:            }
480:
481:            public int costInline(int thresh, Environment env, Context ctx) {
482:                if (body != null) {
483:                    return thresh; // don't copy classes...
484:                }
485:                if (ctx == null) {
486:                    return 2 + super .costInline(thresh, env, ctx);
487:                }
488:                // sourceClass is the current class trying to inline this method
489:                ClassDefinition sourceClass = ctx.field.getClassDefinition();
490:                try {
491:                    // We only allow the inlining if the current class can access 
492:                    // the field and the field's class;
493:                    if (sourceClass.permitInlinedAccess(env, field
494:                            .getClassDeclaration())
495:                            && sourceClass.permitInlinedAccess(env, field)) {
496:                        return 2 + super .costInline(thresh, env, ctx);
497:                    }
498:                } catch (ClassNotFound e) {
499:                }
500:                return thresh;
501:            }
502:
503:            /**
504:             * Code
505:             */
506:            public void code(Environment env, Context ctx, Assembler asm) {
507:                codeCommon(env, ctx, asm, false);
508:            }
509:
510:            public void codeValue(Environment env, Context ctx, Assembler asm) {
511:                codeCommon(env, ctx, asm, true);
512:            }
513:
514:            private void codeCommon(Environment env, Context ctx,
515:                    Assembler asm, boolean forValue) {
516:                asm.add(where, opc_new, field.getClassDeclaration());
517:                if (forValue) {
518:                    asm.add(where, opc_dup);
519:                }
520:
521:                ClassDefinition refc = field.getClassDefinition();
522:                UplevelReference r = refc.getReferencesFrozen();
523:
524:                if (r != null) {
525:                    r.codeArguments(env, ctx, asm, where, field);
526:                }
527:
528:                if (outerArg != null) {
529:                    outerArg.codeValue(env, ctx, asm);
530:                    switch (outerArg.op) {
531:                    case THIS:
532:                    case SUPER:
533:                    case NEW:
534:                        // guaranteed non-null
535:                        break;
536:                    case FIELD: {
537:                        MemberDefinition f = ((FieldExpression) outerArg).field;
538:                        if (f != null && f.isNeverNull()) {
539:                            break;
540:                        }
541:                        // else fall through:
542:                    }
543:                    default:
544:                        // Test for nullity by invoking some trivial operation
545:                        // that can throw a NullPointerException.
546:                        try {
547:                            ClassDefinition c = env
548:                                    .getClassDefinition(idJavaLangObject);
549:                            MemberDefinition getc = c.getFirstMatch(idGetClass);
550:                            asm.add(where, opc_dup);
551:                            asm.add(where, opc_invokevirtual, getc);
552:                            asm.add(where, opc_pop);
553:                        } catch (ClassNotFound e) {
554:                        }
555:                    }
556:                }
557:
558:                if (implMethod != null) {
559:                    // Constructor call will be via an access method.
560:                    // Pass 'null' as the value of the dummy argument.
561:                    asm.add(where, opc_aconst_null);
562:                }
563:
564:                for (int i = 0; i < args.length; i++) {
565:                    args[i].codeValue(env, ctx, asm);
566:                }
567:                asm.add(where, opc_invokespecial,
568:                        ((implMethod != null) ? implMethod : field));
569:            }
570:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.