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


001:        /*
002:         * Copyright 1999-2006 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 com.sun.tools.javac.comp;
027:
028:        import java.util.*;
029:
030:        import com.sun.tools.javac.code.*;
031:        import com.sun.tools.javac.code.Symbol.*;
032:        import com.sun.tools.javac.tree.*;
033:        import com.sun.tools.javac.tree.JCTree.*;
034:        import com.sun.tools.javac.util.*;
035:        import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
036:        import com.sun.tools.javac.util.List;
037:
038:        import static com.sun.tools.javac.code.Flags.*;
039:        import static com.sun.tools.javac.code.Kinds.*;
040:        import static com.sun.tools.javac.code.TypeTags.*;
041:
042:        /** This pass translates Generic Java to conventional Java.
043:         *
044:         *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
045:         *  you write code that depends on this, you do so at your own risk.
046:         *  This code and its internal interfaces are subject to change or
047:         *  deletion without notice.</b>
048:         */
049:        @Version("@(#)TransTypes.java	1.94 07/05/05")
050:        public class TransTypes extends TreeTranslator {
051:            /** The context key for the TransTypes phase. */
052:            protected static final Context.Key<TransTypes> transTypesKey = new Context.Key<TransTypes>();
053:
054:            /** Get the instance for this context. */
055:            public static TransTypes instance(Context context) {
056:                TransTypes instance = context.get(transTypesKey);
057:                if (instance == null)
058:                    instance = new TransTypes(context);
059:                return instance;
060:            }
061:
062:            private Name.Table names;
063:            private Log log;
064:            private Symtab syms;
065:            private TreeMaker make;
066:            private Enter enter;
067:            private boolean allowEnums;
068:            private Types types;
069:            private final Resolve resolve;
070:
071:            /**
072:             * Flag to indicate whether or not to generate bridge methods.
073:             * For pre-Tiger source there is no need for bridge methods, so it
074:             * can be skipped to get better performance for -source 1.4 etc.
075:             */
076:            private final boolean addBridges;
077:
078:            protected TransTypes(Context context) {
079:                context.put(transTypesKey, this );
080:                names = Name.Table.instance(context);
081:                log = Log.instance(context);
082:                syms = Symtab.instance(context);
083:                enter = Enter.instance(context);
084:                overridden = new HashMap<MethodSymbol, MethodSymbol>();
085:                Source source = Source.instance(context);
086:                allowEnums = source.allowEnums();
087:                addBridges = source.addBridges();
088:                types = Types.instance(context);
089:                make = TreeMaker.instance(context);
090:                resolve = Resolve.instance(context);
091:            }
092:
093:            /** A hashtable mapping bridge methods to the methods they override after
094:             *  type erasure.
095:             */
096:            Map<MethodSymbol, MethodSymbol> overridden;
097:
098:            /** Construct an attributed tree for a cast of expression to target type,
099:             *  unless it already has precisely that type.
100:             *  @param tree    The expression tree.
101:             *  @param target  The target type.
102:             */
103:            JCExpression cast(JCExpression tree, Type target) {
104:                int oldpos = make.pos;
105:                make.at(tree.pos);
106:                if (!types.isSameType(tree.type, target)) {
107:                    if (!resolve.isAccessible(env, target.tsym))
108:                        resolve.logAccessError(env, tree, target);
109:                    tree = make.TypeCast(make.Type(target), tree).setType(
110:                            target);
111:                }
112:                make.pos = oldpos;
113:                return tree;
114:            }
115:
116:            /** Construct an attributed tree to coerce an expression to some erased
117:             *  target type, unless the expression is already assignable to that type.
118:             *  If target type is a constant type, use its base type instead.
119:             *  @param tree    The expression tree.
120:             *  @param target  The target type.
121:             */
122:            JCExpression coerce(JCExpression tree, Type target) {
123:                Type btarget = target.baseType();
124:                if (tree.type.isPrimitive() == target.isPrimitive()) {
125:                    return types.isAssignable(tree.type, btarget,
126:                            Warner.noWarnings) ? tree : cast(tree, btarget);
127:                }
128:                return tree;
129:            }
130:
131:            /** Given an erased reference type, assume this type as the tree's type.
132:             *  Then, coerce to some given target type unless target type is null.
133:             *  This operation is used in situations like the following:
134:             *
135:             *  class Cell<A> { A value; }
136:             *  ...
137:             *  Cell<Integer> cell;
138:             *  Integer x = cell.value;
139:             *
140:             *  Since the erasure of Cell.value is Object, but the type
141:             *  of cell.value in the assignment is Integer, we need to
142:             *  adjust the original type of cell.value to Object, and insert
143:             *  a cast to Integer. That is, the last assignment becomes:
144:             *
145:             *  Integer x = (Integer)cell.value;
146:             *
147:             *  @param tree       The expression tree whose type might need adjustment.
148:             *  @param erasedType The expression's type after erasure.
149:             *  @param target     The target type, which is usually the erasure of the
150:             *                    expression's original type.
151:             */
152:            JCExpression retype(JCExpression tree, Type erasedType, Type target) {
153:                //      System.err.println("retype " + tree + " to " + erasedType);//DEBUG
154:                if (erasedType.tag > lastBaseTag) {
155:                    if (target != null && target.isPrimitive())
156:                        target = erasure(tree.type);
157:                    tree.type = erasedType;
158:                    if (target != null)
159:                        return coerce(tree, target);
160:                }
161:                return tree;
162:            }
163:
164:            /** Translate method argument list, casting each argument
165:             *  to its corresponding type in a list of target types.
166:             *  @param _args            The method argument list.
167:             *  @param parameters       The list of target types.
168:             *  @param varargsElement   The erasure of the varargs element type,
169:             *  or null if translating a non-varargs invocation
170:             */
171:            <T extends JCTree> List<T> translateArgs(List<T> _args,
172:                    List<Type> parameters, Type varargsElement) {
173:                if (parameters.isEmpty())
174:                    return _args;
175:                List<T> args = _args;
176:                while (parameters.tail.nonEmpty()) {
177:                    args.head = translate(args.head, parameters.head);
178:                    args = args.tail;
179:                    parameters = parameters.tail;
180:                }
181:                Type parameter = parameters.head;
182:                assert varargsElement != null || args.length() == 1;
183:                if (varargsElement != null) {
184:                    while (args.nonEmpty()) {
185:                        args.head = translate(args.head, varargsElement);
186:                        args = args.tail;
187:                    }
188:                } else {
189:                    args.head = translate(args.head, parameter);
190:                }
191:                return _args;
192:            }
193:
194:            /** Add a bridge definition and enter corresponding method symbol in
195:             *  local scope of origin.
196:             *
197:             *  @param pos     The source code position to be used for the definition.
198:             *  @param meth    The method for which a bridge needs to be added
199:             *  @param impl    That method's implementation (possibly the method itself)
200:             *  @param origin  The class to which the bridge will be added
201:             *  @param hypothetical
202:             *                 True if the bridge method is not strictly necessary in the
203:             *                 binary, but is represented in the symbol table to detect
204:             *                 erasure clashes.
205:             *  @param bridges The list buffer to which the bridge will be added
206:             */
207:            void addBridge(DiagnosticPosition pos, MethodSymbol meth,
208:                    MethodSymbol impl, ClassSymbol origin,
209:                    boolean hypothetical, ListBuffer<JCTree> bridges) {
210:                make.at(pos);
211:                Type origType = types.memberType(origin.type, meth);
212:                Type origErasure = erasure(origType);
213:
214:                // Create a bridge method symbol and a bridge definition without a body.
215:                Type bridgeType = meth.erasure(types);
216:                long flags = impl.flags() & AccessFlags | SYNTHETIC | BRIDGE;
217:                if (hypothetical)
218:                    flags |= HYPOTHETICAL;
219:                MethodSymbol bridge = new MethodSymbol(flags, meth.name,
220:                        bridgeType, origin);
221:                if (!hypothetical) {
222:                    JCMethodDecl md = make.MethodDef(bridge, null);
223:
224:                    // The bridge calls this.impl(..), if we have an implementation
225:                    // in the current class, super.impl(...) otherwise.
226:                    JCExpression receiver = (impl.owner == origin) ? make
227:                            .This(origin.erasure(types)) : make
228:                            .Super(types.super type(origin.type).tsym
229:                                    .erasure(types), origin);
230:
231:                    // The type returned from the original method.
232:                    Type calltype = erasure(impl.type.getReturnType());
233:
234:                    // Construct a call of  this.impl(params), or super.impl(params),
235:                    // casting params and possibly results as needed.
236:                    JCExpression call = make.Apply(
237:                            null,
238:                            make.Select(receiver, impl).setType(calltype),
239:                            translateArgs(make.Idents(md.params), origErasure
240:                                    .getParameterTypes(), null)).setType(
241:                            calltype);
242:                    JCStatement stat = (origErasure.getReturnType().tag == VOID) ? make
243:                            .Exec(call)
244:                            : make.Return(coerce(call, bridgeType
245:                                    .getReturnType()));
246:                    md.body = make.Block(0, List.of(stat));
247:
248:                    // Add bridge to `bridges' buffer
249:                    bridges.append(md);
250:                }
251:
252:                // Add bridge to scope of enclosing class and `overridden' table.
253:                origin.members().enter(bridge);
254:                overridden.put(bridge, meth);
255:            }
256:
257:            /** Add bridge if given symbol is a non-private, non-static member
258:             *  of the given class, which is either defined in the class or non-final
259:             *  inherited, and one of the two following conditions holds:
260:             *  1. The method's type changes in the given class, as compared to the
261:             *     class where the symbol was defined, (in this case
262:             *     we have extended a parameterized class with non-trivial parameters).
263:             *  2. The method has an implementation with a different erased return type.
264:             *     (in this case we have used co-variant returns).
265:             *  If a bridge already exists in some other class, no new bridge is added.
266:             *  Instead, it is checked that the bridge symbol overrides the method symbol.
267:             *  (Spec ???).
268:             *  todo: what about bridges for privates???
269:             *
270:             *  @param pos     The source code position to be used for the definition.
271:             *  @param sym     The symbol for which a bridge might have to be added.
272:             *  @param origin  The class in which the bridge would go.
273:             *  @param bridges The list buffer to which the bridge would be added.
274:             */
275:            void addBridgeIfNeeded(DiagnosticPosition pos, Symbol sym,
276:                    ClassSymbol origin, ListBuffer<JCTree> bridges) {
277:                if (sym.kind == MTH && sym.name != names.init
278:                        && (sym.flags() & (PRIVATE | SYNTHETIC | STATIC)) == 0
279:                        && sym.isMemberOf(origin, types)) {
280:                    MethodSymbol meth = (MethodSymbol) sym;
281:                    MethodSymbol bridge = meth.binaryImplementation(origin,
282:                            types);
283:                    MethodSymbol impl = meth
284:                            .implementation(origin, types, true);
285:                    if (bridge == null
286:                            || bridge == meth
287:                            || (impl != null && !bridge.owner.isSubClass(
288:                                    impl.owner, types))) {
289:                        // No bridge was added yet.
290:                        if (impl != null
291:                                && isBridgeNeeded(meth, impl, origin.type)) {
292:                            addBridge(pos, meth, impl, origin, bridge == impl,
293:                                    bridges);
294:                        } else if (impl == meth
295:                                && impl.owner != origin
296:                                && (impl.flags() & FINAL) == 0
297:                                && (meth.flags() & (ABSTRACT | PUBLIC)) == PUBLIC
298:                                && (origin.flags() & PUBLIC) > (impl.owner
299:                                        .flags() & PUBLIC)) {
300:                            // this is to work around a horrible but permanent 
301:                            // reflection design error. 
302:                            addBridge(pos, meth, impl, origin, false, bridges);
303:                        }
304:                    } else if ((bridge.flags() & SYNTHETIC) != 0) {
305:                        MethodSymbol other = overridden.get(bridge);
306:                        if (other != null && other != meth) {
307:                            if (impl == null
308:                                    || !impl.overrides(other, origin, types,
309:                                            true)) {
310:                                // Bridge for other symbol pair was added
311:                                log.error(pos,
312:                                        "name.clash.same.erasure.no.override",
313:                                        other, other.location(origin.type,
314:                                                types), meth, meth.location(
315:                                                origin.type, types));
316:                            }
317:                        }
318:                    } else if (!bridge.overrides(meth, origin, types, true)) {
319:                        // Accidental binary override without source override.
320:                        if (bridge.owner == origin
321:                                || types.asSuper(bridge.owner.type, meth.owner) == null)
322:                            // Don't diagnose the problem if it would already
323:                            // have been reported in the superclass
324:                            log.error(pos,
325:                                    "name.clash.same.erasure.no.override",
326:                                    bridge,
327:                                    bridge.location(origin.type, types), meth,
328:                                    meth.location(origin.type, types));
329:                    }
330:                }
331:            }
332:
333:            // where
334:            /**
335:             * @param method The symbol for which a bridge might have to be added
336:             * @param impl The implementation of method
337:             * @param dest The type in which the bridge would go
338:             */
339:            private boolean isBridgeNeeded(MethodSymbol method,
340:                    MethodSymbol impl, Type dest) {
341:                if (impl != method) {
342:                    // If either method or impl have different erasures as
343:                    // members of dest, a bridge is needed.
344:                    Type method_erasure = method.erasure(types);
345:                    if (!isSameMemberWhenErased(dest, method, method_erasure))
346:                        return true;
347:                    Type impl_erasure = impl.erasure(types);
348:                    if (!isSameMemberWhenErased(dest, impl, impl_erasure))
349:                        return true;
350:
351:                    // If the erasure of the return type is different, a
352:                    // bridge is needed.
353:                    return !types.isSameType(impl_erasure.getReturnType(),
354:                            method_erasure.getReturnType());
355:                } else {
356:                    // method and impl are the same...
357:                    if ((method.flags() & ABSTRACT) != 0) {
358:                        // ...and abstract so a bridge is not needed.
359:                        // Concrete subclasses will bridge as needed.
360:                        return false;
361:                    }
362:
363:                    // The erasure of the return type is always the same
364:                    // for the same symbol.  Reducing the three tests in
365:                    // the other branch to just one:
366:                    return !isSameMemberWhenErased(dest, method, method
367:                            .erasure(types));
368:                }
369:            }
370:
371:            /**
372:             * Lookup the method as a member of the type.  Compare the
373:             * erasures.
374:             * @param type the class where to look for the method
375:             * @param method the method to look for in class
376:             * @param erasure the erasure of method
377:             */
378:            private boolean isSameMemberWhenErased(Type type,
379:                    MethodSymbol method, Type erasure) {
380:                return types.isSameType(
381:                        erasure(types.memberType(type, method)), erasure);
382:            }
383:
384:            void addBridges(DiagnosticPosition pos, TypeSymbol i,
385:                    ClassSymbol origin, ListBuffer<JCTree> bridges) {
386:                for (Scope.Entry e = i.members().elems; e != null; e = e.sibling)
387:                    addBridgeIfNeeded(pos, e.sym, origin, bridges);
388:                for (List<Type> l = types.interfaces(i.type); l.nonEmpty(); l = l.tail)
389:                    addBridges(pos, l.head.tsym, origin, bridges);
390:            }
391:
392:            /** Add all necessary bridges to some class appending them to list buffer.
393:             *  @param pos     The source code position to be used for the bridges.
394:             *  @param origin  The class in which the bridges go.
395:             *  @param bridges The list buffer to which the bridges are added.
396:             */
397:            void addBridges(DiagnosticPosition pos, ClassSymbol origin,
398:                    ListBuffer<JCTree> bridges) {
399:                Type st = types.super type(origin.type);
400:                while (st.tag == CLASS) {
401:                    //          if (isSpecialization(st))
402:                    addBridges(pos, st.tsym, origin, bridges);
403:                    st = types.super type(st);
404:                }
405:                for (List<Type> l = types.interfaces(origin.type); l.nonEmpty(); l = l.tail)
406:                    //          if (isSpecialization(l.head))
407:                    addBridges(pos, l.head.tsym, origin, bridges);
408:            }
409:
410:            /* ************************************************************************
411:             * Visitor methods
412:             *************************************************************************/
413:
414:            /** Visitor argument: proto-type.
415:             */
416:            private Type pt;
417:
418:            /** Visitor method: perform a type translation on tree.
419:             */
420:            public <T extends JCTree> T translate(T tree, Type pt) {
421:                Type prevPt = this .pt;
422:                try {
423:                    this .pt = pt;
424:                    return translate(tree);
425:                } finally {
426:                    this .pt = prevPt;
427:                }
428:            }
429:
430:            /** Visitor method: perform a type translation on list of trees.
431:             */
432:            public <T extends JCTree> List<T> translate(List<T> trees, Type pt) {
433:                Type prevPt = this .pt;
434:                List<T> res;
435:                try {
436:                    this .pt = pt;
437:                    res = translate(trees);
438:                } finally {
439:                    this .pt = prevPt;
440:                }
441:                return res;
442:            }
443:
444:            public void visitClassDef(JCClassDecl tree) {
445:                translateClass(tree.sym);
446:                result = tree;
447:            }
448:
449:            JCMethodDecl currentMethod = null;
450:
451:            public void visitMethodDef(JCMethodDecl tree) {
452:                JCMethodDecl previousMethod = currentMethod;
453:                try {
454:                    currentMethod = tree;
455:                    tree.restype = translate(tree.restype, null);
456:                    tree.typarams = List.nil();
457:                    tree.params = translateVarDefs(tree.params);
458:                    tree.thrown = translate(tree.thrown, null);
459:                    tree.body = translate(tree.body, tree.sym.erasure(types)
460:                            .getReturnType());
461:                    tree.type = erasure(tree.type);
462:                    result = tree;
463:                } finally {
464:                    currentMethod = previousMethod;
465:                }
466:
467:                // Check that we do not introduce a name clash by erasing types.
468:                for (Scope.Entry e = tree.sym.owner.members().lookup(tree.name); e.sym != null; e = e
469:                        .next()) {
470:                    if (e.sym != tree.sym
471:                            && types.isSameType(erasure(e.sym.type), tree.type)) {
472:                        log.error(tree.pos(), "name.clash.same.erasure",
473:                                tree.sym, e.sym);
474:                        return;
475:                    }
476:                }
477:            }
478:
479:            public void visitVarDef(JCVariableDecl tree) {
480:                tree.vartype = translate(tree.vartype, null);
481:                tree.init = translate(tree.init, tree.sym.erasure(types));
482:                tree.type = erasure(tree.type);
483:                result = tree;
484:            }
485:
486:            public void visitDoLoop(JCDoWhileLoop tree) {
487:                tree.body = translate(tree.body);
488:                tree.cond = translate(tree.cond, syms.booleanType);
489:                result = tree;
490:            }
491:
492:            public void visitWhileLoop(JCWhileLoop tree) {
493:                tree.cond = translate(tree.cond, syms.booleanType);
494:                tree.body = translate(tree.body);
495:                result = tree;
496:            }
497:
498:            public void visitForLoop(JCForLoop tree) {
499:                tree.init = translate(tree.init, null);
500:                if (tree.cond != null)
501:                    tree.cond = translate(tree.cond, syms.booleanType);
502:                tree.step = translate(tree.step, null);
503:                tree.body = translate(tree.body);
504:                result = tree;
505:            }
506:
507:            public void visitForeachLoop(JCEnhancedForLoop tree) {
508:                tree.var = translate(tree.var, null);
509:                Type iterableType = tree.expr.type;
510:                tree.expr = translate(tree.expr, erasure(tree.expr.type));
511:                if (types.elemtype(tree.expr.type) == null)
512:                    tree.expr.type = iterableType; // preserve type for Lower
513:                tree.body = translate(tree.body);
514:                result = tree;
515:            }
516:
517:            public void visitSwitch(JCSwitch tree) {
518:                Type selsuper  = types.super type(tree.selector.type);
519:                boolean enumSwitch = selsuper  != null
520:                        && selsuper .tsym == syms.enumSym;
521:                Type target = enumSwitch ? erasure(tree.selector.type)
522:                        : syms.intType;
523:                tree.selector = translate(tree.selector, target);
524:                tree.cases = translateCases(tree.cases);
525:                result = tree;
526:            }
527:
528:            public void visitCase(JCCase tree) {
529:                tree.pat = translate(tree.pat, null);
530:                tree.stats = translate(tree.stats);
531:                result = tree;
532:            }
533:
534:            public void visitSynchronized(JCSynchronized tree) {
535:                tree.lock = translate(tree.lock, erasure(tree.lock.type));
536:                tree.body = translate(tree.body);
537:                result = tree;
538:            }
539:
540:            public void visitConditional(JCConditional tree) {
541:                tree.cond = translate(tree.cond, syms.booleanType);
542:                tree.truepart = translate(tree.truepart, erasure(tree.type));
543:                tree.falsepart = translate(tree.falsepart, erasure(tree.type));
544:                tree.type = erasure(tree.type);
545:                result = tree;
546:            }
547:
548:            public void visitIf(JCIf tree) {
549:                tree.cond = translate(tree.cond, syms.booleanType);
550:                tree.thenpart = translate(tree.thenpart);
551:                tree.elsepart = translate(tree.elsepart);
552:                result = tree;
553:            }
554:
555:            public void visitExec(JCExpressionStatement tree) {
556:                tree.expr = translate(tree.expr, null);
557:                result = tree;
558:            }
559:
560:            public void visitReturn(JCReturn tree) {
561:                tree.expr = translate(tree.expr, currentMethod.sym.erasure(
562:                        types).getReturnType());
563:                result = tree;
564:            }
565:
566:            public void visitThrow(JCThrow tree) {
567:                tree.expr = translate(tree.expr, erasure(tree.expr.type));
568:                result = tree;
569:            }
570:
571:            public void visitAssert(JCAssert tree) {
572:                tree.cond = translate(tree.cond, syms.booleanType);
573:                if (tree.detail != null)
574:                    tree.detail = translate(tree.detail,
575:                            erasure(tree.detail.type));
576:                result = tree;
577:            }
578:
579:            public void visitApply(JCMethodInvocation tree) {
580:                tree.meth = translate(tree.meth, null);
581:                Symbol meth = TreeInfo.symbol(tree.meth);
582:                Type mt = meth.erasure(types);
583:                List<Type> argtypes = mt.getParameterTypes();
584:                if (allowEnums && meth.name == names.init
585:                        && meth.owner == syms.enumSym)
586:                    argtypes = argtypes.tail.tail;
587:                if (tree.varargsElement != null)
588:                    tree.varargsElement = types.erasure(tree.varargsElement);
589:                else
590:                    assert tree.args.length() == argtypes.length();
591:                tree.args = translateArgs(tree.args, argtypes,
592:                        tree.varargsElement);
593:
594:                // Insert casts of method invocation results as needed.
595:                result = retype(tree, mt.getReturnType(), pt);
596:            }
597:
598:            public void visitNewClass(JCNewClass tree) {
599:                if (tree.encl != null)
600:                    tree.encl = translate(tree.encl, erasure(tree.encl.type));
601:                tree.clazz = translate(tree.clazz, null);
602:                if (tree.varargsElement != null)
603:                    tree.varargsElement = types.erasure(tree.varargsElement);
604:                tree.args = translateArgs(tree.args, tree.constructor.erasure(
605:                        types).getParameterTypes(), tree.varargsElement);
606:                tree.def = translate(tree.def, null);
607:                tree.type = erasure(tree.type);
608:                result = tree;
609:            }
610:
611:            public void visitNewArray(JCNewArray tree) {
612:                tree.elemtype = translate(tree.elemtype, null);
613:                translate(tree.dims, syms.intType);
614:                tree.elems = translate(tree.elems, (tree.type == null) ? null
615:                        : erasure(types.elemtype(tree.type)));
616:                tree.type = erasure(tree.type);
617:
618:                result = tree;
619:            }
620:
621:            public void visitParens(JCParens tree) {
622:                tree.expr = translate(tree.expr, pt);
623:                tree.type = erasure(tree.type);
624:                result = tree;
625:            }
626:
627:            public void visitAssign(JCAssign tree) {
628:                tree.lhs = translate(tree.lhs, null);
629:                tree.rhs = translate(tree.rhs, erasure(tree.lhs.type));
630:                tree.type = erasure(tree.type);
631:                result = tree;
632:            }
633:
634:            public void visitAssignop(JCAssignOp tree) {
635:                tree.lhs = translate(tree.lhs, null);
636:                tree.rhs = translate(tree.rhs, erasure(tree.rhs.type));
637:                tree.type = erasure(tree.type);
638:                result = tree;
639:            }
640:
641:            public void visitUnary(JCUnary tree) {
642:                tree.arg = translate(tree.arg, tree.operator.type
643:                        .getParameterTypes().head);
644:                result = tree;
645:            }
646:
647:            public void visitBinary(JCBinary tree) {
648:                tree.lhs = translate(tree.lhs, tree.operator.type
649:                        .getParameterTypes().head);
650:                tree.rhs = translate(tree.rhs, tree.operator.type
651:                        .getParameterTypes().tail.head);
652:                result = tree;
653:            }
654:
655:            public void visitTypeCast(JCTypeCast tree) {
656:                tree.clazz = translate(tree.clazz, null);
657:                tree.type = erasure(tree.type);
658:                tree.expr = translate(tree.expr, tree.type);
659:                result = tree;
660:            }
661:
662:            public void visitTypeTest(JCInstanceOf tree) {
663:                tree.expr = translate(tree.expr, null);
664:                tree.clazz = translate(tree.clazz, null);
665:                result = tree;
666:            }
667:
668:            public void visitIndexed(JCArrayAccess tree) {
669:                tree.indexed = translate(tree.indexed,
670:                        erasure(tree.indexed.type));
671:                tree.index = translate(tree.index, syms.intType);
672:
673:                // Insert casts of indexed expressions as needed.
674:                result = retype(tree, types.elemtype(tree.indexed.type), pt);
675:            }
676:
677:            // There ought to be nothing to rewrite here;
678:            // we don't generate code.
679:            public void visitAnnotation(JCAnnotation tree) {
680:                result = tree;
681:            }
682:
683:            public void visitIdent(JCIdent tree) {
684:                Type et = tree.sym.erasure(types);
685:
686:                // Map type variables to their bounds.
687:                if (tree.sym.kind == TYP && tree.sym.type.tag == TYPEVAR) {
688:                    result = make.at(tree.pos).Type(et);
689:                } else
690:                // Map constants expressions to themselves.
691:                if (tree.type.constValue() != null) {
692:                    result = tree;
693:                }
694:                // Insert casts of variable uses as needed.
695:                else if (tree.sym.kind == VAR) {
696:                    result = retype(tree, et, pt);
697:                } else {
698:                    tree.type = erasure(tree.type);
699:                    result = tree;
700:                }
701:            }
702:
703:            public void visitSelect(JCFieldAccess tree) {
704:                Type t = tree.selected.type;
705:                if (t.isCompound()
706:                        || (t.tag == TYPEVAR && t.getUpperBound().isCompound())) {
707:                    if ((tree.sym.flags() & IPROXY) != 0) {
708:                        tree.sym = ((MethodSymbol) tree.sym).implemented(
709:                                (TypeSymbol) tree.sym.owner, types);
710:                    }
711:                    tree.selected = cast(translate(tree.selected, erasure(t)),
712:                            erasure(tree.sym.owner.type));
713:                } else
714:                    tree.selected = translate(tree.selected, erasure(t));
715:
716:                // Map constants expressions to themselves.
717:                if (tree.type.constValue() != null) {
718:                    result = tree;
719:                }
720:                // Insert casts of variable uses as needed.
721:                else if (tree.sym.kind == VAR) {
722:                    result = retype(tree, tree.sym.erasure(types), pt);
723:                } else {
724:                    tree.type = erasure(tree.type);
725:                    result = tree;
726:                }
727:            }
728:
729:            public void visitTypeArray(JCArrayTypeTree tree) {
730:                tree.elemtype = translate(tree.elemtype, null);
731:                tree.type = erasure(tree.type);
732:                result = tree;
733:            }
734:
735:            /** Visitor method for parameterized types.
736:             */
737:            public void visitTypeApply(JCTypeApply tree) {
738:                // Delete all type parameters.
739:                result = translate(tree.clazz, null);
740:            }
741:
742:            /**************************************************************************
743:             * utility methods
744:             *************************************************************************/
745:
746:            private Type erasure(Type t) {
747:                return types.erasure(t);
748:            }
749:
750:            /**************************************************************************
751:             * main method
752:             *************************************************************************/
753:
754:            private Env<AttrContext> env;
755:
756:            void translateClass(ClassSymbol c) {
757:                Type st = types.super type(c.type);
758:
759:                // process superclass before derived
760:                if (st.tag == CLASS)
761:                    translateClass((ClassSymbol) st.tsym);
762:
763:                Env<AttrContext> myEnv = enter.typeEnvs.remove(c);
764:                if (myEnv == null)
765:                    return;
766:                Env<AttrContext> oldEnv = env;
767:                try {
768:                    env = myEnv;
769:                    // class has not been translated yet
770:
771:                    TreeMaker savedMake = make;
772:                    Type savedPt = pt;
773:                    make = make.forToplevel(env.toplevel);
774:                    pt = null;
775:                    try {
776:                        JCClassDecl tree = (JCClassDecl) env.tree;
777:                        tree.typarams = List.nil();
778:                        super .visitClassDef(tree);
779:                        make.at(tree.pos);
780:                        if (addBridges) {
781:                            ListBuffer<JCTree> bridges = new ListBuffer<JCTree>();
782:                            if ((tree.sym.flags() & INTERFACE) == 0)
783:                                addBridges(tree.pos(), tree.sym, bridges);
784:                            tree.defs = bridges.toList().prependList(tree.defs);
785:                        }
786:                        tree.type = erasure(tree.type);
787:                    } finally {
788:                        make = savedMake;
789:                        pt = savedPt;
790:                    }
791:                } finally {
792:                    env = oldEnv;
793:                }
794:            }
795:
796:            /** Translate a toplevel class definition.
797:             *  @param cdef    The definition to be translated.
798:             */
799:            public JCTree translateTopLevelClass(JCTree cdef, TreeMaker make) {
800:                // note that this method does NOT support recursion.
801:                this.make = make;
802:                pt = null;
803:                return translate(cdef, null);
804:            }
805:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.