Source Code Cross Referenced for JProgram.java in  » Ajax » GWT » com » google » gwt » dev » jjs » ast » 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 » Ajax » GWT » com.google.gwt.dev.jjs.ast 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2007 Google Inc.
003:         * 
004:         * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005:         * use this file except in compliance with the License. You may obtain a copy of
006:         * the License at
007:         * 
008:         * http://www.apache.org/licenses/LICENSE-2.0
009:         * 
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012:         * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013:         * License for the specific language governing permissions and limitations under
014:         * the License.
015:         */
016:        package com.google.gwt.dev.jjs.ast;
017:
018:        import com.google.gwt.core.ext.TreeLogger;
019:        import com.google.gwt.core.ext.UnableToCompleteException;
020:        import com.google.gwt.dev.jdt.FindDeferredBindingSitesVisitor;
021:        import com.google.gwt.dev.jdt.RebindOracle;
022:        import com.google.gwt.dev.jjs.InternalCompilerException;
023:        import com.google.gwt.dev.jjs.SourceInfo;
024:        import com.google.gwt.dev.jjs.ast.js.JClassSeed;
025:        import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;
026:        import com.google.gwt.dev.jjs.ast.js.JsonObject;
027:
028:        import java.util.ArrayList;
029:        import java.util.Arrays;
030:        import java.util.Collection;
031:        import java.util.Comparator;
032:        import java.util.HashMap;
033:        import java.util.HashSet;
034:        import java.util.IdentityHashMap;
035:        import java.util.Iterator;
036:        import java.util.List;
037:        import java.util.Map;
038:        import java.util.Set;
039:        import java.util.TreeSet;
040:
041:        /**
042:         * Root for the AST representing an entire Java program.
043:         */
044:        public class JProgram extends JNode {
045:
046:            private static final Set<String> CODEGEN_TYPES_SET = new HashSet<String>(
047:                    Arrays.asList(new String[] { "com.google.gwt.lang.Array",
048:                            "com.google.gwt.lang.Cast",
049:                            "com.google.gwt.lang.Exceptions", }));
050:
051:            private static final Set<String> INDEX_TYPES_SET = new HashSet<String>(
052:                    Arrays.asList(new String[] { "java.lang.Object",
053:                            "java.lang.String", "java.lang.Class",
054:                            "java.lang.CharSequence", "java.lang.Comparable",
055:                            "java.lang.Enum", "java.lang.Iterable",
056:                            "java.util.Iterator",
057:                            "com.google.gwt.core.client.JavaScriptObject",
058:                            "com.google.gwt.lang.Array" }));
059:
060:            private static final int IS_ARRAY = 2;
061:
062:            private static final int IS_CLASS = 3;
063:
064:            private static final int IS_INTERFACE = 1;
065:
066:            private static final int IS_NULL = 0;
067:
068:            static {
069:                INDEX_TYPES_SET.addAll(CODEGEN_TYPES_SET);
070:            }
071:
072:            public static boolean methodsDoMatch(JMethod method1,
073:                    JMethod method2) {
074:                // static methods cannot match each other
075:                if (method1.isStatic() || method2.isStatic()) {
076:                    return false;
077:                }
078:
079:                // names must be identical
080:                if (!method1.getName().equals(method2.getName())) {
081:                    return false;
082:                }
083:
084:                // original parameter types must be identical
085:                List<JType> params1 = method1.getOriginalParamTypes();
086:                List<JType> params2 = method2.getOriginalParamTypes();
087:                int params1size = params1.size();
088:                if (params1size != params2.size()) {
089:                    return false;
090:                }
091:
092:                for (int i = 0; i < params1size; ++i) {
093:                    if (params1.get(i) != params2.get(i)) {
094:                        return false;
095:                    }
096:                }
097:                return true;
098:            }
099:
100:            private static String dotify(char[][] name) {
101:                StringBuffer result = new StringBuffer();
102:                for (int i = 0; i < name.length; ++i) {
103:                    if (i > 0) {
104:                        result.append('.');
105:                    }
106:
107:                    result.append(name[i]);
108:                }
109:                return result.toString();
110:            }
111:
112:            public final List<JClassType> codeGenTypes = new ArrayList<JClassType>();
113:
114:            public final List<JMethod> entryMethods = new ArrayList<JMethod>();
115:
116:            public final Map<String, HasEnclosingType> jsniMap = new HashMap<String, HasEnclosingType>();
117:
118:            public final JTypeOracle typeOracle = new JTypeOracle(this );
119:
120:            /**
121:             * Sorted to avoid nondeterministic iteration.
122:             */
123:            private final Set<JArrayType> allArrayTypes = new TreeSet<JArrayType>(
124:                    new Comparator<JArrayType>() {
125:                        public int compare(JArrayType o1, JArrayType o2) {
126:                            int comp = o1.getDims() - o2.getDims();
127:                            if (comp != 0) {
128:                                return comp;
129:                            }
130:                            return o1.getName().compareTo(o2.getName());
131:                        }
132:                    });
133:
134:            private final List<JReferenceType> allTypes = new ArrayList<JReferenceType>();
135:
136:            private Map<JType, JClassLiteral> classLiterals = new HashMap<JType, JClassLiteral>();
137:
138:            /**
139:             * Each entry is a HashMap(JType => JArrayType), arranged such that the number
140:             * of dimensions is that index (plus one) at which the JArrayTypes having that
141:             * number of dimensions resides.
142:             */
143:            private final ArrayList<HashMap<JType, JArrayType>> dimensions = new ArrayList<HashMap<JType, JArrayType>>();
144:
145:            private final Map<String, JField> indexedFields = new HashMap<String, JField>();
146:
147:            private final Map<String, JMethod> indexedMethods = new HashMap<String, JMethod>();
148:
149:            private final Map<String, JReferenceType> indexedTypes = new HashMap<String, JReferenceType>();
150:
151:            private final Map<JMethod, JMethod> instanceToStaticMap = new IdentityHashMap<JMethod, JMethod>();
152:
153:            private List<JsonObject> jsonTypeTable;
154:
155:            private final JAbsentArrayDimension literalAbsentArrayDim = new JAbsentArrayDimension(
156:                    this );
157:
158:            private final JBooleanLiteral literalFalse = new JBooleanLiteral(
159:                    this , false);
160:
161:            private final JIntLiteral literalIntNegOne = new JIntLiteral(this ,
162:                    -1);
163:
164:            private final JIntLiteral literalIntOne = new JIntLiteral(this , 1);
165:
166:            private final JIntLiteral literalIntZero = new JIntLiteral(this , 0);
167:
168:            private final JNullLiteral literalNull = new JNullLiteral(this );
169:
170:            private final JBooleanLiteral literalTrue = new JBooleanLiteral(
171:                    this , true);
172:
173:            private final TreeLogger logger;
174:
175:            private JField nullField;
176:
177:            private JMethod nullMethod;
178:
179:            private Map<JReferenceType, Integer> queryIds;
180:
181:            private JMethod rebindCreateMethod;
182:
183:            private final RebindOracle rebindOracle;
184:
185:            private final Map<JMethod, JMethod> staticToInstanceMap = new IdentityHashMap<JMethod, JMethod>();
186:
187:            private final JPrimitiveType typeBoolean = new JPrimitiveType(this ,
188:                    "boolean", "Z", "java.lang.Boolean", literalFalse);
189:
190:            private final JPrimitiveType typeByte = new JPrimitiveType(this ,
191:                    "byte", "B", "java.lang.Byte", literalIntZero);
192:
193:            private final JPrimitiveType typeChar = new JPrimitiveType(this ,
194:                    "char", "C", "java.lang.Character",
195:                    getLiteralChar((char) 0));
196:
197:            private JClassType typeClass;
198:
199:            private final JPrimitiveType typeDouble = new JPrimitiveType(this ,
200:                    "double", "D", "java.lang.Double", getLiteralDouble(0));
201:
202:            private final JPrimitiveType typeFloat = new JPrimitiveType(this ,
203:                    "float", "F", "java.lang.Float", getLiteralFloat(0));
204:
205:            private Map<JClassType, Integer> typeIdMap = new HashMap<JClassType, Integer>();
206:
207:            private final JPrimitiveType typeInt = new JPrimitiveType(this ,
208:                    "int", "I", "java.lang.Integer", literalIntZero);
209:
210:            private JClassType typeJavaLangEnum;
211:
212:            private JClassType typeJavaLangObject;
213:
214:            private final JPrimitiveType typeLong = new JPrimitiveType(this ,
215:                    "long", "J", "java.lang.Long", getLiteralLong(0));
216:
217:            private final Map<String, JReferenceType> typeNameMap = new HashMap<String, JReferenceType>();
218:
219:            private final JNullType typeNull = new JNullType(this );
220:
221:            private final JPrimitiveType typeShort = new JPrimitiveType(this ,
222:                    "short", "S", "java.lang.Short", literalIntZero);
223:
224:            private JClassType typeSpecialJavaScriptObject;
225:
226:            private JClassType typeString;
227:
228:            private final JPrimitiveType typeVoid = new JPrimitiveType(this ,
229:                    "void", "V", "java.lang.Void", null);
230:
231:            public JProgram(TreeLogger logger, RebindOracle rebindOracle) {
232:                super (null, null);
233:                this .logger = logger;
234:                this .rebindOracle = rebindOracle;
235:            }
236:
237:            public void addEntryMethod(JMethod entryPoint) {
238:                if (!entryMethods.contains(entryPoint)) {
239:                    entryMethods.add(entryPoint);
240:                }
241:            }
242:
243:            /**
244:             * Helper to create an assignment, used to initalize fields, etc.
245:             */
246:            public JExpressionStatement createAssignmentStmt(SourceInfo info,
247:                    JExpression lhs, JExpression rhs) {
248:                JBinaryOperation assign = new JBinaryOperation(this , info, lhs
249:                        .getType(), JBinaryOperator.ASG, lhs, rhs);
250:                return assign.makeStatement();
251:            }
252:
253:            public JClassType createClass(SourceInfo info, char[][] name,
254:                    boolean isAbstract, boolean isFinal) {
255:                String sname = dotify(name);
256:                JClassType x = new JClassType(this , info, sname, isAbstract,
257:                        isFinal);
258:
259:                allTypes.add(x);
260:                putIntoTypeMap(sname, x);
261:
262:                if (CODEGEN_TYPES_SET.contains(sname)) {
263:                    codeGenTypes.add(x);
264:                }
265:                if (INDEX_TYPES_SET.contains(sname)) {
266:                    indexedTypes.put(x.getShortName(), x);
267:                    if (sname.equals("java.lang.Object")) {
268:                        typeJavaLangObject = x;
269:                    } else if (sname.equals("java.lang.String")) {
270:                        typeString = x;
271:                    } else if (sname.equals("java.lang.Enum")) {
272:                        typeJavaLangEnum = x;
273:                    } else if (sname.equals("java.lang.Class")) {
274:                        typeClass = x;
275:                    } else if (sname
276:                            .equals("com.google.gwt.core.client.JavaScriptObject")) {
277:                        typeSpecialJavaScriptObject = x;
278:                    }
279:                }
280:
281:                return x;
282:            }
283:
284:            public JEnumType createEnum(SourceInfo info, char[][] name) {
285:                String sname = dotify(name);
286:                JEnumType x = new JEnumType(this , info, sname);
287:
288:                allTypes.add(x);
289:                putIntoTypeMap(sname, x);
290:
291:                return x;
292:            }
293:
294:            public JField createEnumField(SourceInfo info, char[] name,
295:                    JEnumType enclosingType, JClassType type, int ordinal) {
296:                assert (name != null);
297:                assert (type != null);
298:                assert (ordinal >= 0);
299:
300:                String sname = String.valueOf(name);
301:                JEnumField x = new JEnumField(this , info, sname, ordinal,
302:                        enclosingType, type);
303:                List<JEnumField> enumList = enclosingType.enumList;
304:                while (ordinal >= enumList.size()) {
305:                    enumList.add(null);
306:                }
307:
308:                enumList.set(ordinal, x);
309:
310:                enclosingType.fields.add(x);
311:                return x;
312:            }
313:
314:            public JField createField(SourceInfo info, char[] name,
315:                    JReferenceType enclosingType, JType type, boolean isStatic,
316:                    boolean isFinal, boolean hasInitializer) {
317:                assert (name != null);
318:                assert (enclosingType != null);
319:                assert (type != null);
320:
321:                /*
322:                 * MAGIC: filled in during code gen, don't bother synthesizing dummy
323:                 * initializations.
324:                 */
325:                if (enclosingType == typeJavaLangObject) {
326:                    hasInitializer = true;
327:                }
328:
329:                String sname = String.valueOf(name);
330:                JField x = new JField(this , info, sname, enclosingType, type,
331:                        isStatic, isFinal, hasInitializer);
332:
333:                if (indexedTypes.containsValue(enclosingType)) {
334:                    indexedFields.put(enclosingType.getShortName() + '.'
335:                            + sname, x);
336:                }
337:
338:                enclosingType.fields.add(x);
339:                return x;
340:            }
341:
342:            public JInterfaceType createInterface(SourceInfo info, char[][] name) {
343:                String sname = dotify(name);
344:                JInterfaceType x = new JInterfaceType(this , info, sname);
345:
346:                allTypes.add(x);
347:                putIntoTypeMap(sname, x);
348:
349:                if (INDEX_TYPES_SET.contains(sname)) {
350:                    indexedTypes.put(x.getShortName(), x);
351:                }
352:
353:                return x;
354:            }
355:
356:            public JLocal createLocal(SourceInfo info, char[] name, JType type,
357:                    boolean isFinal, JMethodBody enclosingMethodBody) {
358:                assert (name != null);
359:                assert (type != null);
360:                assert (enclosingMethodBody != null);
361:
362:                JLocal x = new JLocal(this , info, String.valueOf(name), type,
363:                        isFinal, enclosingMethodBody);
364:
365:                enclosingMethodBody.locals.add(x);
366:                return x;
367:            }
368:
369:            public JMethod createMethod(SourceInfo info, char[] name,
370:                    JReferenceType enclosingType, JType returnType,
371:                    boolean isAbstract, boolean isStatic, boolean isFinal,
372:                    boolean isPrivate, boolean isNative) {
373:                assert (name != null);
374:                assert (returnType != null);
375:                assert (!isAbstract || !isNative);
376:
377:                String sname = String.valueOf(name);
378:                JMethod x = new JMethod(this , info, sname, enclosingType,
379:                        returnType, isAbstract, isStatic, isFinal, isPrivate);
380:                if (isNative) {
381:                    x.setBody(new JsniMethodBody(this , info));
382:                } else if (!isAbstract) {
383:                    x.setBody(new JMethodBody(this , info));
384:                }
385:
386:                if (sname
387:                        .equals(FindDeferredBindingSitesVisitor.REBIND_MAGIC_METHOD)
388:                        && enclosingType
389:                                .getName()
390:                                .equals(
391:                                        FindDeferredBindingSitesVisitor.REBIND_MAGIC_CLASS)) {
392:                    rebindCreateMethod = x;
393:                } else if (!isPrivate
394:                        && indexedTypes.containsValue(enclosingType)) {
395:                    indexedMethods.put(enclosingType.getShortName() + '.'
396:                            + sname, x);
397:                }
398:
399:                if (enclosingType != null) {
400:                    enclosingType.methods.add(x);
401:                }
402:
403:                return x;
404:            }
405:
406:            public JParameter createParameter(SourceInfo info, char[] name,
407:                    JType type, boolean isFinal, boolean isThis,
408:                    JMethod enclosingMethod) {
409:                assert (name != null);
410:                assert (type != null);
411:                assert (enclosingMethod != null);
412:
413:                JParameter x = new JParameter(this , info, String.valueOf(name),
414:                        type, isFinal, isThis, enclosingMethod);
415:
416:                enclosingMethod.params.add(x);
417:                return x;
418:            }
419:
420:            public JReferenceType generalizeTypes(
421:                    Collection<JReferenceType> types) {
422:                assert (types != null);
423:                assert (!types.isEmpty());
424:                Iterator<JReferenceType> it = types.iterator();
425:                JReferenceType curType = it.next();
426:                while (it.hasNext()) {
427:                    curType = generalizeTypes(curType, it.next());
428:                }
429:                return curType;
430:            }
431:
432:            /**
433:             * Returns a sorted set of array types, so the returned set can be iterated
434:             * over without introducing nondeterminism.
435:             */
436:            public Set<JArrayType> getAllArrayTypes() {
437:                return allArrayTypes;
438:            }
439:
440:            public List<JReferenceType> getDeclaredTypes() {
441:                return allTypes;
442:            }
443:
444:            public JThisRef getExprThisRef(SourceInfo info,
445:                    JClassType enclosingType) {
446:                return new JThisRef(this , info, enclosingType);
447:            }
448:
449:            public JReferenceType getFromTypeMap(
450:                    String qualifiedBinaryOrSourceName) {
451:                String srcTypeName = qualifiedBinaryOrSourceName.replace('$',
452:                        '.');
453:                return typeNameMap.get(srcTypeName);
454:            }
455:
456:            public JField getIndexedField(String string) {
457:                return indexedFields.get(string);
458:            }
459:
460:            public JMethod getIndexedMethod(String string) {
461:                return indexedMethods.get(string);
462:            }
463:
464:            public JReferenceType getIndexedType(String string) {
465:                return indexedTypes.get(string);
466:            }
467:
468:            public JClassType getJavaScriptObject() {
469:                return typeSpecialJavaScriptObject;
470:            }
471:
472:            public List<JsonObject> getJsonTypeTable() {
473:                return jsonTypeTable;
474:            }
475:
476:            public JAbsentArrayDimension getLiteralAbsentArrayDimension() {
477:                return literalAbsentArrayDim;
478:            }
479:
480:            public JBooleanLiteral getLiteralBoolean(boolean z) {
481:                return z ? literalTrue : literalFalse;
482:            }
483:
484:            public JCharLiteral getLiteralChar(char c) {
485:                // could be interned
486:                return new JCharLiteral(this , c);
487:            }
488:
489:            public JClassLiteral getLiteralClass(JType type) {
490:                JClassLiteral result = classLiterals.get(type);
491:                if (result == null) {
492:                    result = new JClassLiteral(this , type);
493:                    classLiterals.put(type, result);
494:                }
495:                return result;
496:            }
497:
498:            public JClassSeed getLiteralClassSeed(JClassType type) {
499:                // could be interned
500:                return new JClassSeed(this , type);
501:            }
502:
503:            public JDoubleLiteral getLiteralDouble(double d) {
504:                // could be interned
505:                return new JDoubleLiteral(this , d);
506:            }
507:
508:            public JFloatLiteral getLiteralFloat(float f) {
509:                // could be interned
510:                return new JFloatLiteral(this , f);
511:            }
512:
513:            public JIntLiteral getLiteralInt(int i) {
514:                switch (i) {
515:                case -1:
516:                    return literalIntNegOne;
517:                case 0:
518:                    return literalIntZero;
519:                case 1:
520:                    return literalIntOne;
521:                default:
522:                    // could be interned
523:                    return new JIntLiteral(this , i);
524:                }
525:            }
526:
527:            public JLongLiteral getLiteralLong(long l) {
528:                return new JLongLiteral(this , l);
529:            }
530:
531:            public JNullLiteral getLiteralNull() {
532:                return literalNull;
533:            }
534:
535:            public JStringLiteral getLiteralString(char[] s) {
536:                // should conslidate so we can build a string table in output code later?
537:                return new JStringLiteral(this , String.valueOf(s));
538:            }
539:
540:            public JStringLiteral getLiteralString(String s) {
541:                // should conslidate so we can build a string table in output code later?
542:                return new JStringLiteral(this , s);
543:            }
544:
545:            public JField getNullField() {
546:                if (nullField == null) {
547:                    nullField = new JField(this , null, "nullField", null,
548:                            typeNull, false, true, true);
549:                }
550:                return nullField;
551:            }
552:
553:            public JMethod getNullMethod() {
554:                if (nullMethod == null) {
555:                    nullMethod = new JMethod(this , null, "nullMethod", null,
556:                            typeNull, false, false, true, true);
557:                }
558:                return nullMethod;
559:            }
560:
561:            public int getQueryId(JReferenceType elementType) {
562:                Integer integer = queryIds.get(elementType);
563:                if (integer == null) {
564:                    return 0;
565:                }
566:
567:                return integer.intValue();
568:            }
569:
570:            public JMethod getRebindCreateMethod() {
571:                return rebindCreateMethod;
572:            }
573:
574:            public JMethod getStaticImpl(JMethod method) {
575:                return instanceToStaticMap.get(method);
576:            }
577:
578:            public JArrayType getTypeArray(JType leafType, int dimensions) {
579:                HashMap<JType, JArrayType> typeToArrayType;
580:
581:                // Create typeToArrayType maps for index slots that don't exist yet.
582:                //
583:                for (int i = this .dimensions.size(); i < dimensions; ++i) {
584:                    typeToArrayType = new HashMap<JType, JArrayType>();
585:                    this .dimensions.add(typeToArrayType);
586:                }
587:
588:                // Get the map for array having this number of dimensions (biased by one
589:                // since we don't store non-arrays in there -- thus index 0 => 1 dim).
590:                //
591:                typeToArrayType = this .dimensions.get(dimensions - 1);
592:
593:                JArrayType arrayType = typeToArrayType.get(leafType);
594:                if (arrayType == null) {
595:                    arrayType = new JArrayType(this , leafType, dimensions);
596:                    arrayType.extnds = typeJavaLangObject;
597:                    allArrayTypes.add(arrayType);
598:
599:                    /*
600:                     * TODO(later): should we setup the various array types as an inheritance
601:                     * heirarchy? Currently we're just doing all the heavy lifting in
602:                     * JTypeOracle. If we tried to setup inheritance, we'd have to recompute
603:                     * JTypeOracle if anything changed, so maybe this is better.
604:                     */
605:                    typeToArrayType.put(leafType, arrayType);
606:                }
607:
608:                return arrayType;
609:            }
610:
611:            public int getTypeId(JClassType classType) {
612:                Integer integer = typeIdMap.get(classType);
613:                if (integer == null) {
614:                    return 0;
615:                }
616:
617:                return integer.intValue();
618:            }
619:
620:            public JClassType getTypeJavaLangClass() {
621:                return typeClass;
622:            }
623:
624:            public JClassType getTypeJavaLangEnum() {
625:                return typeJavaLangEnum;
626:            }
627:
628:            public JClassType getTypeJavaLangObject() {
629:                return typeJavaLangObject;
630:            }
631:
632:            public JClassType getTypeJavaLangString() {
633:                return typeString;
634:            }
635:
636:            public JNullType getTypeNull() {
637:                return typeNull;
638:            }
639:
640:            public JPrimitiveType getTypePrimitiveBoolean() {
641:                return typeBoolean;
642:            }
643:
644:            public JPrimitiveType getTypePrimitiveByte() {
645:                return typeByte;
646:            }
647:
648:            public JPrimitiveType getTypePrimitiveChar() {
649:                return typeChar;
650:            }
651:
652:            public JPrimitiveType getTypePrimitiveDouble() {
653:                return typeDouble;
654:            }
655:
656:            public JPrimitiveType getTypePrimitiveFloat() {
657:                return typeFloat;
658:            }
659:
660:            public JPrimitiveType getTypePrimitiveInt() {
661:                return typeInt;
662:            }
663:
664:            public JPrimitiveType getTypePrimitiveLong() {
665:                return typeLong;
666:            }
667:
668:            public JPrimitiveType getTypePrimitiveShort() {
669:                return typeShort;
670:            }
671:
672:            public JType getTypeVoid() {
673:                return typeVoid;
674:            }
675:
676:            public void initTypeInfo(List<JClassType> classes,
677:                    List<JsonObject> jsonObjects) {
678:                for (int i = 0, c = classes.size(); i < c; ++i) {
679:                    typeIdMap.put(classes.get(i), new Integer(i));
680:                }
681:                this .jsonTypeTable = jsonObjects;
682:            }
683:
684:            public boolean isClinit(JMethod method) {
685:                JReferenceType enclosingType = method.getEnclosingType();
686:                return (enclosingType != null)
687:                        && (method == enclosingType.methods.get(0));
688:            }
689:
690:            public boolean isJavaScriptObject(JType type) {
691:                if (type instanceof  JClassType) {
692:                    return typeOracle.canTriviallyCast((JClassType) type,
693:                            typeSpecialJavaScriptObject);
694:                }
695:                return false;
696:            }
697:
698:            public boolean isStaticImpl(JMethod method) {
699:                return staticToInstanceMap.containsKey(method);
700:            }
701:
702:            public void putIntoTypeMap(String qualifiedBinaryName,
703:                    JReferenceType type) {
704:                // Make it into a source type name.
705:                //
706:                String srcTypeName = qualifiedBinaryName.replace('$', '.');
707:                typeNameMap.put(srcTypeName, type);
708:            }
709:
710:            public void putStaticImpl(JMethod method, JMethod staticImpl) {
711:                instanceToStaticMap.put(method, staticImpl);
712:                staticToInstanceMap.put(staticImpl, method);
713:            }
714:
715:            public JClassType rebind(JType type) {
716:                JType result = type;
717:                // Rebinds are always on a source type name.
718:                String reqType = type.getName().replace('$', '.');
719:                String reboundClassName;
720:                try {
721:                    reboundClassName = rebindOracle.rebind(logger, reqType);
722:                } catch (UnableToCompleteException e) {
723:                    // The fact that we already compute every rebind permutation before
724:                    // compiling should prevent this case from ever happening in real life.
725:                    //
726:                    throw new IllegalStateException(
727:                            "Unexpected failure to rebind '" + reqType + "'");
728:                }
729:                if (reboundClassName != null) {
730:                    result = getFromTypeMap(reboundClassName);
731:                }
732:                assert (result != null);
733:                assert (result instanceof  JClassType);
734:                return (JClassType) result;
735:            }
736:
737:            public void recordQueryIds(Map<JReferenceType, Integer> queryIds) {
738:                this .queryIds = queryIds;
739:            }
740:
741:            /**
742:             * If <code>method</code> is a static impl method, returns the instance
743:             * method that <code>method</code> is the implementation of. Otherwise,
744:             * returns <code>null</code>.
745:             */
746:            public JMethod staticImplFor(JMethod method) {
747:                return staticToInstanceMap.get(method);
748:            }
749:
750:            public JReferenceType strongerType(JReferenceType type1,
751:                    JReferenceType type2) {
752:                if (type1 == type2) {
753:                    return type1;
754:                }
755:
756:                if (typeOracle.canTriviallyCast(type1, type2)) {
757:                    return type1;
758:                }
759:
760:                if (typeOracle.canTriviallyCast(type2, type1)) {
761:                    return type2;
762:                }
763:
764:                // cannot determine a strong type, just return the first one (this makes two
765:                // "unrelated" interfaces work correctly in TypeTightener
766:                return type1;
767:            }
768:
769:            public void traverse(JVisitor visitor, Context ctx) {
770:                if (visitor.visit(this , ctx)) {
771:                    visitor.accept(entryMethods);
772:                    visitor.accept(allTypes);
773:                }
774:                visitor.endVisit(this , ctx);
775:            }
776:
777:            JReferenceType generalizeTypes(JReferenceType type1,
778:                    JReferenceType type2) {
779:                if (type1 == type2) {
780:                    return type1;
781:                }
782:
783:                int classify1 = classifyType(type1);
784:                int classify2 = classifyType(type2);
785:
786:                if (classify1 == IS_NULL) {
787:                    return type2;
788:                }
789:
790:                if (classify2 == IS_NULL) {
791:                    return type1;
792:                }
793:
794:                if (classify1 == classify2) {
795:
796:                    // same basic kind of type
797:                    if (classify1 == IS_INTERFACE) {
798:
799:                        if (typeOracle.canTriviallyCast(type1, type2)) {
800:                            return type2;
801:                        }
802:
803:                        if (typeOracle.canTriviallyCast(type2, type1)) {
804:                            return type1;
805:                        }
806:
807:                        // unrelated
808:                        return typeJavaLangObject;
809:
810:                    } else if (classify1 == IS_ARRAY) {
811:
812:                        JArrayType aType1 = (JArrayType) type1;
813:                        JArrayType aType2 = (JArrayType) type2;
814:                        int dims1 = aType1.getDims();
815:                        int dims2 = aType2.getDims();
816:
817:                        int minDims = Math.min(dims1, dims2);
818:                        /*
819:                         * At a bare minimum, any two arrays generalize to an Object array with
820:                         * one less dim than the lesser of the two; that is, int[][][][] and
821:                         * String[][][] generalize to Object[][]. If minDims is 1, then they
822:                         * just generalize to Object.
823:                         */
824:                        JReferenceType minimalGeneralType;
825:                        if (minDims > 1) {
826:                            minimalGeneralType = getTypeArray(
827:                                    typeJavaLangObject, minDims - 1);
828:                        } else {
829:                            minimalGeneralType = typeJavaLangObject;
830:                        }
831:
832:                        if (dims1 == dims2) {
833:
834:                            // Try to generalize by leaf types
835:                            JType leafType1 = aType1.getLeafType();
836:                            JType leafType2 = aType2.getLeafType();
837:
838:                            if (!(leafType1 instanceof  JReferenceType)
839:                                    || !(leafType2 instanceof  JReferenceType)) {
840:                                return minimalGeneralType;
841:                            }
842:
843:                            /*
844:                             * Both are reference types; the result is the generalization of the
845:                             * leaf types combined with the number of dims; that is, Foo[] and
846:                             * Bar[] generalize to X[] where X is the generalization of Foo and
847:                             * Bar.
848:                             */
849:                            JReferenceType leafRefType1 = (JReferenceType) leafType1;
850:                            JReferenceType leafRefType2 = (JReferenceType) leafType2;
851:                            JReferenceType leafGeneralization = generalizeTypes(
852:                                    leafRefType1, leafRefType2);
853:                            return getTypeArray(leafGeneralization, dims1);
854:
855:                        } else {
856:
857:                            // Conflicting number of dims
858:
859:                            // int[][] and Object[] generalize to Object[]
860:                            JArrayType lesser = dims1 < dims2 ? aType1 : aType2;
861:                            if (lesser.getLeafType() == typeJavaLangObject) {
862:                                return lesser;
863:                            }
864:
865:                            // Totally unrelated
866:                            return minimalGeneralType;
867:                        }
868:
869:                    } else {
870:
871:                        assert (classify1 == IS_CLASS);
872:
873:                        /*
874:                         * see how far each type is from object; walk the one who's farther up
875:                         * until they're even; then walk them up together until they meet (worst
876:                         * case at Object)
877:                         */
878:                        int distance1 = countSuperTypes(type1);
879:                        int distance2 = countSuperTypes(type2);
880:                        for (; distance1 > distance2; --distance1) {
881:                            type1 = type1.extnds;
882:                        }
883:
884:                        for (; distance1 < distance2; --distance2) {
885:                            type2 = type2.extnds;
886:                        }
887:
888:                        while (type1 != type2) {
889:                            type1 = type1.extnds;
890:                            type2 = type2.extnds;
891:                        }
892:
893:                        return type1;
894:                    }
895:                } else {
896:
897:                    // different kinds of types
898:                    int lesser = Math.min(classify1, classify2);
899:                    int greater = Math.max(classify1, classify2);
900:
901:                    JReferenceType tLesser = classify1 > classify2 ? type1
902:                            : type2;
903:                    JReferenceType tGreater = classify1 < classify2 ? type1
904:                            : type2;
905:
906:                    if (lesser == IS_INTERFACE && greater == IS_CLASS) {
907:
908:                        // just see if the class implements the interface
909:                        if (typeOracle.canTriviallyCast(tGreater, tLesser)) {
910:                            return tLesser;
911:                        }
912:
913:                        // unrelated
914:                        return typeJavaLangObject;
915:
916:                    } else {
917:
918:                        // unrelated: the best commonality between an interface and array, or
919:                        // between an array and a class is Object
920:                        return typeJavaLangObject;
921:                    }
922:                }
923:            }
924:
925:            private int classifyType(JReferenceType type) {
926:                if (type instanceof  JNullType) {
927:                    return IS_NULL;
928:                } else if (type instanceof  JInterfaceType) {
929:                    return IS_INTERFACE;
930:                } else if (type instanceof  JArrayType) {
931:                    return IS_ARRAY;
932:                } else if (type instanceof  JClassType) {
933:                    return IS_CLASS;
934:                }
935:                throw new InternalCompilerException("Unknown reference type");
936:            }
937:
938:            private int countSuperTypes(JReferenceType type) {
939:                if (type instanceof  JArrayType) {
940:                    JType leafType = ((JArrayType) type).getLeafType();
941:                    if (leafType instanceof  JReferenceType) {
942:                        // however many steps from Foo[] -> Object[] + 1 for Object[]->Object
943:                        return countSuperTypes((JReferenceType) leafType) + 1;
944:                    } else {
945:                        // primitive array types can only cast up to object
946:                        return 1;
947:                    }
948:                }
949:                int count = 0;
950:                while ((type = type.extnds) != null) {
951:                    ++count;
952:                }
953:                return count;
954:            }
955:
956:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.