Source Code Cross Referenced for JavaTypeConverter.java in  » Parser » Rats-Parser-Generators » xtc » lang » 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 » Parser » Rats Parser Generators » xtc.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * xtc - The eXTensible Compiler
003:         * Copyright (C) 2006-2007 IBM Corp.
004:         *
005:         * This program is free software; you can redistribute it and/or
006:         * modify it under the terms of the GNU General Public License
007:         * version 2 as published by the Free Software Foundation.
008:         *
009:         * This program is distributed in the hope that it will be useful,
010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012:         * GNU General Public License for more details.
013:         *
014:         * You should have received a copy of the GNU General Public License
015:         * along with this program; if not, write to the Free Software
016:         * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
017:         * USA.
018:         */
019:        package xtc.lang;
020:
021:        import java.io.File;
022:        import java.util.Iterator;
023:        import java.util.List;
024:
025:        import xtc.lang.JavaEntities.SuperTypesIter;
026:        import xtc.type.IntegerT;
027:        import xtc.type.InterfaceT;
028:        import xtc.type.MethodT;
029:        import xtc.type.NumberT;
030:        import xtc.type.Type;
031:        import xtc.util.SymbolTable;
032:
033:        /**
034:         * Java type conversions and promotions.
035:         * 
036:         * @author Martin Hirzel
037:         * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#27529">JLS 2 &sect;5</a>
038:         */
039:        public final class JavaTypeConverter {
040:            /**
041:             * Perform assignment conversion.  Assumes that src and tgt are
042:             * either not aliases, or if aliases, are already resolved. May
043:             * resolve other aliases, such as supertypes, method parameter and
044:             * return types, etc.
045:             *
046:             * @return The converted type, or null if this kind of conversion does not apply.
047:             * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#184206">JLS 2 &sect;5.2</a>
048:             */
049:            public static Type convertAssigning(final SymbolTable tab,
050:                    final List<File> paths, final Type tgt, final Type src) {
051:                assert JavaEntities.isGeneralRValueT(tgt)
052:                        && JavaEntities.isGeneralRValueT(src);
053:                final Type result = convertAssigningInternal(tab, paths, tgt,
054:                        src);
055:                assert null == result || JavaEntities.isWrappedRValueT(result);
056:                return result;
057:            }
058:
059:            private static Type convertAssigningInternal(final SymbolTable tab,
060:                    final List<File> paths, final Type tgt, final Type src) {
061:                final Type resIdentity = convertIdentity(tgt, src);
062:                if (null != resIdentity)
063:                    return resIdentity;
064:                final Type resWidenPrimitive = widenPrimitive(tgt, src);
065:                if (null != resWidenPrimitive)
066:                    return resWidenPrimitive;
067:                final Type resWidenReference = widenReference(tab, paths, tgt,
068:                        src);
069:                if (null != resWidenReference)
070:                    return resWidenReference;
071:                if (src.hasConstant()) {
072:                    final Type srcRaw = JavaEntities.resolveToRawRValue(src);
073:                    final Type tgtRaw = JavaEntities.resolveToRawRValue(tgt);
074:                    if (srcRaw.isInteger() && tgtRaw.isInteger()) {
075:                        final NumberT srcInt = (IntegerT) srcRaw, tgtInt = (IntegerT) tgtRaw;
076:                        switch (srcInt.getKind()) {
077:                        case BYTE:
078:                        case SHORT:
079:                        case CHAR:
080:                        case INT:
081:                            switch (tgtInt.getKind()) {
082:                            case BYTE:
083:                            case SHORT:
084:                            case CHAR:
085:                                final Type resNarrowPrimitive = narrowPrimitive(
086:                                        tgt, src);
087:                                final Object srcObj = src.getConstant()
088:                                        .getValue();
089:                                final Object resObj = resNarrowPrimitive
090:                                        .getConstant().getValue();
091:                                final long srcVal = srcObj instanceof  Number ? ((Number) srcObj)
092:                                        .longValue()
093:                                        : ((Character) srcObj).charValue();
094:                                final long resVal = resObj instanceof  Number ? ((Number) resObj)
095:                                        .longValue()
096:                                        : ((Character) resObj).charValue();
097:                                if (srcVal == resVal)
098:                                    return resNarrowPrimitive;
099:                            }
100:                        }
101:                    }
102:                }
103:                return null;
104:            }
105:
106:            /**
107:             * Perform casting conversion. Assumes that src and tgt are either
108:             * not aliases, or if aliases, are already resolved. May resolve
109:             * other aliases, such as supertypes, method parameter and return
110:             * types, etc.
111:             * 
112:             * @return The converted type, or null if this kind of conversion does not
113:             *         apply.
114:             * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#20232">JLS 2 &sect;5.5</a>
115:             */
116:            public static Type convertCasting(final SymbolTable tab,
117:                    final List<File> paths, final Type tgt, final Type src) {
118:                assert JavaEntities.isGeneralRValueT(tgt)
119:                        && JavaEntities.isGeneralRValueT(src);
120:                final Type result = convertCastingInternal(tab, paths, tgt, src);
121:                assert null == result || JavaEntities.isGeneralRValueT(result);
122:                return result;
123:            }
124:
125:            private static Type convertCastingInternal(final SymbolTable tab,
126:                    final List<File> paths, final Type tgt, final Type src) {
127:                final Type resIdentity = convertIdentity(tgt, src);
128:                if (null != resIdentity)
129:                    return resIdentity;
130:                final Type resWidenPrimitive = widenPrimitive(tgt, src);
131:                if (null != resWidenPrimitive)
132:                    return resWidenPrimitive;
133:                final Type resNarrowPrimitive = narrowPrimitive(tgt, src);
134:                if (null != resNarrowPrimitive)
135:                    return resNarrowPrimitive;
136:                final Type resWidenReference = widenReference(tab, paths, tgt,
137:                        src);
138:                if (null != resWidenReference)
139:                    return resWidenReference;
140:                final Type resNarrowReference = narrowReference(tab, paths,
141:                        tgt, src);
142:                if (null != resNarrowReference)
143:                    return resNarrowReference;
144:                return null;
145:            }
146:
147:            /**
148:             * Perform identity conversion. Assumes that src and tgt are either
149:             * not aliases, or if aliases, are already resolved.
150:             * 
151:             * @return The converted type, or null if this kind of conversion does not apply.
152:             * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25209">JLS 2 &sect;5.1.1</a>
153:             */
154:            public static Type convertIdentity(final Type tgt, final Type src) {
155:                assert JavaEntities.isGeneralRValueT(tgt)
156:                        && JavaEntities.isGeneralRValueT(src);
157:                final Type result = isIdentical(tgt, src) ? src : null;
158:                assert null == result || JavaEntities.isGeneralRValueT(result);
159:                return result;
160:            }
161:
162:            /**
163:             * Perform method invocation conversion. Assumes that src and tgt
164:             * are either not aliases, or if aliases, are already resolved.  May
165:             * resolve other aliases, such as supertypes, method parameter and
166:             * return types, etc.
167:             * 
168:             * @return The converted type, or null if this kind of conversion does not apply.
169:             * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#12687">JLS 2 &sect;5.3</a>
170:             */
171:            public static Type convertParameterPassing(final SymbolTable tab,
172:                    final List<File> paths, final Type tgt, final Type src) {
173:                assert JavaEntities.isGeneralRValueT(tgt)
174:                        && JavaEntities.isGeneralRValueT(src) : "tgt == " + tgt
175:                        + ", src == " + src;
176:                final Type result = convertParameterPassingInternal(tab, paths,
177:                        tgt, src);
178:                assert null == result || JavaEntities.isGeneralRValueT(result);
179:                return result;
180:            }
181:
182:            private static Type convertParameterPassingInternal(
183:                    final SymbolTable tab, final List<File> paths,
184:                    final Type tgt, final Type src) {
185:                if (isIdentical(tgt, src) || isWiderPrimitive(tgt, src)
186:                        || isWiderReference(tab, paths, tgt, src))
187:                    return tgt;
188:                return null;
189:            }
190:
191:            /**
192:             * Perform string conversion. May resolve JavaEntities.tString(tab)
193:             * if that is an alias.
194:             * 
195:             * @return The converted type, or null if this kind of conversion does not apply.
196:             * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#176886">JLS 2 &sect;5.1.6</a>
197:             * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#186035">JLS 2 &sect;5.4</a>
198:             * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#39990">JLS 2 &sect;15.18.1</a>
199:             */
200:            public static Type convertString(final SymbolTable tab,
201:                    final Type src) {
202:                assert JavaEntities.isGeneralRValueT(src);
203:                final Type result = convertStringInternal(tab, src);
204:                assert null == result || JavaEntities.isWrappedRValueT(result);
205:                return result;
206:            }
207:
208:            private static Type convertStringInternal(final SymbolTable tab,
209:                    final Type src) {
210:                final Type tgt = JavaEntities.tString(tab);
211:                if (src.hasConstant()) {
212:                    if (JavaEntities.isNullT(src))
213:                        return tgt.annotate().constant("null");
214:                    return tgt.annotate().constant(
215:                            src.getConstant().getValue().toString());
216:                }
217:                return tgt;
218:            }
219:
220:            public static boolean isAssignable(final SymbolTable tab,
221:                    final List<File> paths, final Type tgt, final Type src) {
222:                return null != convertAssigning(tab, paths, tgt, src);
223:            }
224:
225:            public static boolean isCastable(final SymbolTable tab,
226:                    final List<File> paths, final Type tgt, final Type src) {
227:                return null != convertCasting(tab, paths, tgt, src);
228:            }
229:
230:            public static boolean isIdentical(final Type x, final Type y) {
231:                if (x.isVoid() || y.isVoid())
232:                    return x.isVoid() && y.isVoid();
233:                assert JavaEntities.isGeneralRValueT(x)
234:                        && JavaEntities.isGeneralRValueT(y);
235:                final Type rawX = JavaEntities.resolveToRawRValue(x);
236:                final Type rawY = JavaEntities.resolveToRawRValue(y);
237:                if (rawX.isArray()) {
238:                    if (!rawY.isArray())
239:                        return false;
240:                    final Type elemX = JavaEntities.arrayElementType(rawX
241:                            .toArray());
242:                    final Type elemY = JavaEntities.arrayElementType(rawY
243:                            .toArray());
244:                    return isIdentical(elemX, elemY);
245:                }
246:                return rawX == rawY;
247:            }
248:
249:            public static boolean isNarrowerPrimitive(final Type tgt,
250:                    final Type src) {
251:                return null != narrowPrimitive(tgt, src);
252:            }
253:
254:            public static boolean isNarrowerReference(final SymbolTable tab,
255:                    final List<File> paths, final Type tgt, final Type src) {
256:                return null != narrowReference(tab, paths, tgt, src);
257:            }
258:
259:            public static boolean isParameterPassable(final SymbolTable tab,
260:                    final List<File> paths, final Type tgt, final Type src) {
261:                return null != convertParameterPassing(tab, paths, tgt, src);
262:            }
263:
264:            public static boolean isPromotableBinaryNumeric(final Type other,
265:                    final Type src) {
266:                final Type t1 = promoteBinaryNumeric(other, src);
267:                final Type t2 = promoteBinaryNumeric(src, other);
268:                return null != t1 && null != t2;
269:            }
270:
271:            /**
272:             * Is src return-type substitutable for tgt? This method implements
273:             * Java 3 Language Specification &sect;8.4.5, unlike the rest of
274:             * this type checker, which deals with Java 2 only.
275:             */
276:            public static boolean isReturnTypeSubstitutable(
277:                    final SymbolTable tab, final List<File> paths,
278:                    final Type tgt, final Type src) {
279:                if (null == tgt || null == src)
280:                    return null == tgt && null == src;
281:                if (JavaEntities.isPrimitiveT(src))
282:                    return isIdentical(src, tgt);
283:                if (JavaEntities.isReferenceT(src))
284:                    return isIdentical(src, tgt)
285:                            || isWiderReference(tab, paths, src, tgt); //contravariant
286:                if (src.isVoid())
287:                    return tgt.isVoid();
288:                assert false;
289:                return false;
290:            }
291:
292:            public static boolean isWiderPrimitive(final Type tgt,
293:                    final Type src) {
294:                return null != widenPrimitive(tgt, src);
295:            }
296:
297:            public static boolean isWiderReference(final SymbolTable tab,
298:                    final List<File> paths, final Type tgt, final Type src) {
299:                return null != widenReference(tab, paths, tgt, src);
300:            }
301:
302:            /**
303:             * Perform narrowing primitive conversion.
304:             * 
305:             * @return The converted type, or null if this kind of conversion does not apply.
306:             * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25363">JLS 2 &sect;5.1.3</a>
307:             */
308:            public static strictfp Type narrowPrimitive(final Type tgt,
309:                    final Type src) {
310:                assert JavaEntities.isGeneralRValueT(tgt)
311:                        && JavaEntities.isGeneralRValueT(src);
312:                final Type result = narrowPrimitiveInternal(tgt, src);
313:                assert null == result || JavaEntities.isGeneralRValueT(result)
314:                        && JavaEntities.resolveToRawRValue(result).isNumber();
315:                return result;
316:            }
317:
318:            private static strictfp Type narrowPrimitiveInternal(
319:                    final Type tgt, final Type src) {
320:                final Type tgtRaw = JavaEntities.resolveToRawRValue(tgt);
321:                final Type srcRaw = JavaEntities.resolveToRawRValue(src);
322:                if (!srcRaw.isNumber() || !tgtRaw.isNumber())
323:                    return null;
324:                final NumberT srcNum = (NumberT) srcRaw, tgtNum = (NumberT) tgtRaw;
325:                final NumberT.Kind srcKind = srcNum.getKind(), tgtKind = tgtNum
326:                        .getKind();
327:                switch (srcKind) {
328:                case BYTE:
329:                    if (NumberT.Kind.CHAR != tgtKind)
330:                        return null;
331:                    break;
332:                case SHORT:
333:                    if (NumberT.Kind.BYTE != tgtKind
334:                            && NumberT.Kind.CHAR != tgtKind)
335:                        return null;
336:                    break;
337:                case CHAR:
338:                    if (NumberT.Kind.BYTE != tgtKind
339:                            && NumberT.Kind.SHORT != tgtKind)
340:                        return null;
341:                    break;
342:                case INT:
343:                    if (NumberT.Kind.BYTE != tgtKind
344:                            && NumberT.Kind.SHORT != tgtKind
345:                            && NumberT.Kind.CHAR != tgtKind)
346:                        return null;
347:                    break;
348:                case LONG:
349:                    if (NumberT.Kind.BYTE != tgtKind
350:                            && NumberT.Kind.SHORT != tgtKind
351:                            && NumberT.Kind.CHAR != tgtKind
352:                            && NumberT.Kind.INT != tgtKind)
353:                        return null;
354:                    break;
355:                case FLOAT:
356:                    if (NumberT.Kind.BYTE != tgtKind
357:                            && NumberT.Kind.SHORT != tgtKind
358:                            && NumberT.Kind.CHAR != tgtKind
359:                            && NumberT.Kind.INT != tgtKind
360:                            && NumberT.Kind.LONG != tgtKind)
361:                        return null;
362:                    break;
363:                case DOUBLE:
364:                    if (NumberT.Kind.BYTE != tgtKind
365:                            && NumberT.Kind.SHORT != tgtKind
366:                            && NumberT.Kind.CHAR != tgtKind
367:                            && NumberT.Kind.INT != tgtKind
368:                            && NumberT.Kind.LONG != tgtKind
369:                            && NumberT.Kind.FLOAT != tgtKind)
370:                        return null;
371:                }
372:                if (src.hasConstant()) {
373:                    final Object obj;
374:                    switch (srcKind) {
375:                    case BYTE: {
376:                        final byte v = ((Byte) src.getConstant().getValue())
377:                                .byteValue();
378:                        switch (tgtKind) {
379:                        case CHAR:
380:                            obj = new Character((char) v);
381:                            break;
382:                        default:
383:                            obj = null;
384:                        }
385:                        break;
386:                    }
387:                    case SHORT: {
388:                        final short v = ((Short) src.getConstant().getValue())
389:                                .shortValue();
390:                        switch (tgtKind) {
391:                        case BYTE:
392:                            obj = new Byte((byte) v);
393:                            break;
394:                        case CHAR:
395:                            obj = new Character((char) v);
396:                            break;
397:                        default:
398:                            obj = null;
399:                        }
400:                        break;
401:                    }
402:                    case CHAR: {
403:                        final char v = ((Character) src.getConstant()
404:                                .getValue()).charValue();
405:                        switch (tgtKind) {
406:                        case BYTE:
407:                            obj = new Byte((byte) v);
408:                            break;
409:                        case SHORT:
410:                            obj = new Short((short) v);
411:                            break;
412:                        default:
413:                            obj = null;
414:                        }
415:                        break;
416:                    }
417:                    case INT: {
418:                        final int v = ((Integer) src.getConstant().getValue())
419:                                .intValue();
420:                        switch (tgtKind) {
421:                        case BYTE:
422:                            obj = new Byte((byte) v);
423:                            break;
424:                        case SHORT:
425:                            obj = new Short((short) v);
426:                            break;
427:                        case CHAR:
428:                            obj = new Character((char) v);
429:                            break;
430:                        default:
431:                            obj = null;
432:                        }
433:                        break;
434:                    }
435:                    case LONG: {
436:                        final long v = ((Long) src.getConstant().getValue())
437:                                .longValue();
438:                        switch (tgtKind) {
439:                        case BYTE:
440:                            obj = new Byte((byte) v);
441:                            break;
442:                        case SHORT:
443:                            obj = new Short((short) v);
444:                            break;
445:                        case CHAR:
446:                            obj = new Character((char) v);
447:                            break;
448:                        case INT:
449:                            obj = new Integer((int) v);
450:                            break;
451:                        default:
452:                            obj = null;
453:                        }
454:                        break;
455:                    }
456:                    case FLOAT: {
457:                        final float v = ((Float) src.getConstant().getValue())
458:                                .floatValue();
459:                        switch (tgtKind) {
460:                        case BYTE:
461:                            obj = new Byte((byte) v);
462:                            break;
463:                        case SHORT:
464:                            obj = new Short((short) v);
465:                            break;
466:                        case CHAR:
467:                            obj = new Character((char) v);
468:                            break;
469:                        case INT:
470:                            obj = new Integer((int) v);
471:                            break;
472:                        case LONG:
473:                            obj = new Long((long) v);
474:                            break;
475:                        default:
476:                            obj = null;
477:                        }
478:                        break;
479:                    }
480:                    case DOUBLE: {
481:                        final double v = ((Double) src.getConstant().getValue())
482:                                .doubleValue();
483:                        switch (tgtKind) {
484:                        case BYTE:
485:                            obj = new Byte((byte) v);
486:                            break;
487:                        case SHORT:
488:                            obj = new Short((short) v);
489:                            break;
490:                        case CHAR:
491:                            obj = new Character((char) v);
492:                            break;
493:                        case INT:
494:                            obj = new Integer((int) v);
495:                            break;
496:                        case LONG:
497:                            obj = new Long((long) v);
498:                            break;
499:                        case FLOAT:
500:                            obj = new Float((float) v);
501:                            break;
502:                        default:
503:                            obj = null;
504:                        }
505:                        break;
506:                    }
507:                    default: {
508:                        obj = null;
509:                        break;
510:                    }
511:                    }
512:                    if (null == obj)
513:                        throw new Error();
514:                    return tgtRaw.annotate().constant(obj);
515:                }
516:                return tgt;
517:            }
518:
519:            /**
520:             * Perform narrowing reference conversion. Assumes that src and tgt
521:             * are either not aliases, or if aliases, are already resolved. May
522:             * resolve other aliases, such as supertypes, method parameter and
523:             * return types, etc.
524:             * 
525:             * @return The converted type, or null if this kind of conversion does not apply.
526:             * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25379">JLS 2 &sect;5.1.5</a>
527:             */
528:            public static Type narrowReference(final SymbolTable tab,
529:                    final List<File> paths, final Type tgt, final Type src) {
530:                assert JavaEntities.isGeneralRValueT(tgt)
531:                        && JavaEntities.isGeneralRValueT(src);
532:                final Type result = narrowReferenceInternal(tab, paths, tgt,
533:                        src);
534:                assert null == result
535:                        || JavaEntities.isGeneralRValueT(result)
536:                        && !JavaEntities.isPrimitiveT(JavaEntities
537:                                .resolveToRawRValue(result));
538:                return result;
539:            }
540:
541:            private static Type narrowReferenceInternal(final SymbolTable tab,
542:                    final List<File> paths, final Type tgt, final Type src) {
543:                if (isIdentical(tgt, src))
544:                    return null; // an identity conversion is not a narrowing conversion
545:                final Type tgtRaw = JavaEntities.resolveToRawRValue(tgt);
546:                if (isIdentical(JavaEntities.tObject(tab), src))
547:                    if (JavaEntities.isWrappedClassT(tgt)
548:                            || JavaEntities.isWrappedInterfaceT(tgt)
549:                            || tgtRaw.isArray())
550:                        return tgt;
551:                if (JavaEntities.isWrappedClassT(src)
552:                        || JavaEntities.isWrappedInterfaceT(src))
553:                    for (final Iterator<Type> i = new SuperTypesIter(tab,
554:                            paths, src); i.hasNext();)
555:                        if (isIdentical(tgt, i.next()))
556:                            return null;
557:                boolean tgtInheritsFromSrc = false;
558:                if (JavaEntities.isWrappedClassT(tgt)
559:                        || JavaEntities.isWrappedInterfaceT(tgt))
560:                    for (final Iterator<Type> i = new SuperTypesIter(tab,
561:                            paths, tgt); i.hasNext();)
562:                        if (isIdentical(i.next(), src)) {
563:                            tgtInheritsFromSrc = true;
564:                            break;
565:                        }
566:                if (JavaEntities.isWrappedClassT(src)) {
567:                    if (JavaEntities.isWrappedClassT(tgt) && tgtInheritsFromSrc)
568:                        return tgt;
569:                    if (JavaEntities.isWrappedInterfaceT(tgt)
570:                            && !src.hasAttribute(JavaEntities
571:                                    .nameToModifier("final")))
572:                        return tgt;
573:                }
574:                final Type srcRaw = JavaEntities.resolveToRawRValue(src);
575:                if (JavaEntities.isWrappedInterfaceT(src)) {
576:                    if (JavaEntities.isWrappedClassT(tgt))
577:                        if (tgtInheritsFromSrc
578:                                || !tgt.hasAttribute(JavaEntities
579:                                        .nameToModifier("final")))
580:                            return tgt;
581:                    if (JavaEntities.isWrappedInterfaceT(tgt)) {
582:                        final List<Type> srcMethods = ((InterfaceT) srcRaw)
583:                                .getMethods();
584:                        final List<Type> tgtMethods = ((InterfaceT) tgtRaw)
585:                                .getMethods();
586:                        if (100 < srcMethods.size() * tgtMethods.size())
587:                            throw new Error(
588:                                    "implement sub-quadratic algorithm here");
589:                        for (final Type wrappedMethA : srcMethods)
590:                            for (final Type wrappedMethB : tgtMethods) {
591:                                final MethodT methA = wrappedMethA.toMethod();
592:                                final MethodT methB = wrappedMethB.toMethod();
593:                                if (methA.getName().equals(methB.getName())
594:                                        && !isIdentical(methA.getResult(),
595:                                                methB.getResult())) {
596:                                    final List<Type> lParamA = methA
597:                                            .getParameters();
598:                                    final List<Type> lParamB = methB
599:                                            .getParameters();
600:                                    if (lParamA.size() == lParamB.size()) {
601:                                        final Iterator<Type> iParamA = lParamA
602:                                                .iterator();
603:                                        final Iterator<Type> iParamB = lParamB
604:                                                .iterator();
605:                                        boolean sameSignature = true;
606:                                        while (sameSignature
607:                                                && iParamA.hasNext()) {
608:                                            final Type a = JavaEntities
609:                                                    .dereference(iParamA.next());
610:                                            final Type b = JavaEntities
611:                                                    .dereference(iParamB.next());
612:                                            sameSignature = isIdentical(a, b);
613:                                        }
614:                                        if (sameSignature)
615:                                            return null;
616:                                    }
617:                                }
618:                            }
619:                        return tgt;
620:                    }
621:                }
622:                if (tgtRaw.isArray() && srcRaw.isArray()) {
623:                    final Type tgtElem = JavaEntities.arrayElementType(tgtRaw
624:                            .toArray());
625:                    final Type srcElem = JavaEntities.arrayElementType(srcRaw
626:                            .toArray());
627:                    if (isNarrowerReference(tab, paths, tgtElem, srcElem))
628:                        return tgt;
629:                }
630:                return null;
631:            }
632:
633:            /**
634:             * Perform binary numeric promotion. Given a binary expression "a op
635:             * b", this method should be called twice: once with src=a and
636:             * other=b, and once with src=b and other=a.
637:             * 
638:             * @param src The type of the operand that is being promoted.
639:             * @param other The type of the other operand.
640:             * @return The converted type of the src operand, or null if this kind of
641:             *         conversion does not apply.
642:             * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#170983">JLS 2 &sect;5.6.2</a>
643:             */
644:            public static Type promoteBinaryNumeric(final Type other,
645:                    final Type src) {
646:                assert JavaEntities.isGeneralRValueT(other)
647:                        && JavaEntities.isGeneralRValueT(src);
648:                final Type result = promoteBinaryNumericInternal(other, src);
649:                assert null == result || JavaEntities.isGeneralRValueT(result)
650:                        && JavaEntities.resolveToRawRValue(result).isNumber();
651:                return result;
652:            }
653:
654:            private static Type promoteBinaryNumericInternal(final Type other,
655:                    final Type src) {
656:                final Type srcRaw = JavaEntities.resolveToRawRValue(src);
657:                final Type otherRaw = JavaEntities.resolveToRawRValue(other);
658:                if (!srcRaw.isNumber() || !otherRaw.isNumber())
659:                    return null;
660:                final NumberT srcNum = (NumberT) srcRaw, otherNum = (NumberT) otherRaw;
661:                final NumberT.Kind srcKind = srcNum.getKind(), otherKind = otherNum
662:                        .getKind();
663:                switch (otherKind) {
664:                case DOUBLE:
665:                    switch (srcKind) {
666:                    case DOUBLE:
667:                        return src;
668:                    }
669:                    return widenPrimitive(other, src);
670:                case FLOAT:
671:                    switch (srcKind) {
672:                    case DOUBLE:
673:                    case FLOAT:
674:                        return src;
675:                    }
676:                    return widenPrimitive(other, src);
677:                case LONG:
678:                    switch (srcKind) {
679:                    case DOUBLE:
680:                    case FLOAT:
681:                    case LONG:
682:                        return src;
683:                    }
684:                    return widenPrimitive(other, src);
685:                default:
686:                    switch (srcKind) {
687:                    case DOUBLE:
688:                    case FLOAT:
689:                    case LONG:
690:                    case INT:
691:                        return src;
692:                    }
693:                    return widenPrimitive(JavaEntities.nameToBaseType("int"),
694:                            src);
695:                }
696:            }
697:
698:            /**
699:             * Perform unary numeric promotion.
700:             * 
701:             * @return The converted type, or null if this kind of conversion does not apply.
702:             * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#170952">JLS 2 &sect;5.6.1</a>
703:             */
704:            public static Type promoteUnaryNumeric(final Type src) {
705:                assert JavaEntities.isGeneralRValueT(src);
706:                final Type result = promoteUnaryNumericInternal(src);
707:                assert null == result || JavaEntities.isGeneralRValueT(result)
708:                        && JavaEntities.resolveToRawRValue(result).isNumber();
709:                return result;
710:            }
711:
712:            private static Type promoteUnaryNumericInternal(final Type src) {
713:                final Type srcRaw = JavaEntities.resolveToRawRValue(src);
714:                if (srcRaw.isNumber()) {
715:                    final NumberT.Kind srcKind = ((NumberT) srcRaw).getKind();
716:                    final Type tgt = JavaEntities.nameToBaseType("int");
717:                    switch (srcKind) {
718:                    case BYTE:
719:                    case SHORT:
720:                    case CHAR:
721:                        return widenPrimitive(tgt, src);
722:                    case INT:
723:                    case LONG:
724:                    case FLOAT:
725:                    case DOUBLE:
726:                        return src;
727:                    }
728:                }
729:                return null;
730:            }
731:
732:            /**
733:             * Perform widening primitive conversion.
734:             * 
735:             * @return The converted type, or null if this kind of conversion does not apply.
736:             * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25214">JLS 2 &sect;5.1.2</a>
737:             */
738:            public static strictfp Type widenPrimitive(final Type tgt,
739:                    final Type src) {
740:                assert JavaEntities.isGeneralRValueT(tgt)
741:                        && JavaEntities.isGeneralRValueT(src);
742:                final Type result = widenPrimitiveInternal(tgt, src);
743:                assert null == result || JavaEntities.isGeneralRValueT(result)
744:                        && JavaEntities.resolveToRawRValue(result).isNumber();
745:                return result;
746:            }
747:
748:            private static strictfp Type widenPrimitiveInternal(final Type tgt,
749:                    final Type src) {
750:                final Type tgtRaw = JavaEntities.resolveToRawRValue(tgt);
751:                final Type srcRaw = JavaEntities.resolveToRawRValue(src);
752:                if (!JavaEntities.isPrimitiveT(srcRaw)
753:                        || !JavaEntities.isPrimitiveT(tgtRaw))
754:                    return null;
755:                if (srcRaw.isBoolean() || tgtRaw.isBoolean())
756:                    return null;
757:                final NumberT srcNum = (NumberT) srcRaw, tgtNum = (NumberT) tgtRaw;
758:                final NumberT.Kind srcKind = srcNum.getKind(), tgtKind = tgtNum
759:                        .getKind();
760:                switch (srcKind) {
761:                case BYTE:
762:                    if (NumberT.Kind.SHORT != tgtKind
763:                            && NumberT.Kind.INT != tgtKind
764:                            && NumberT.Kind.LONG != tgtKind
765:                            && NumberT.Kind.FLOAT != tgtKind
766:                            && NumberT.Kind.DOUBLE != tgtKind)
767:                        return null;
768:                    break;
769:                case SHORT:
770:                    if (NumberT.Kind.INT != tgtKind
771:                            && NumberT.Kind.LONG != tgtKind
772:                            && NumberT.Kind.FLOAT != tgtKind
773:                            && NumberT.Kind.DOUBLE != tgtKind)
774:                        return null;
775:                    break;
776:                case CHAR:
777:                    if (NumberT.Kind.INT != tgtKind
778:                            && NumberT.Kind.LONG != tgtKind
779:                            && NumberT.Kind.FLOAT != tgtKind
780:                            && NumberT.Kind.DOUBLE != tgtKind)
781:                        return null;
782:                    break;
783:                case INT:
784:                    if (NumberT.Kind.LONG != tgtKind
785:                            && NumberT.Kind.FLOAT != tgtKind
786:                            && NumberT.Kind.DOUBLE != tgtKind)
787:                        return null;
788:                    break;
789:                case LONG:
790:                    if (NumberT.Kind.FLOAT != tgtKind
791:                            && NumberT.Kind.DOUBLE != tgtKind)
792:                        return null;
793:                    break;
794:                case FLOAT:
795:                    if (NumberT.Kind.DOUBLE != tgtKind)
796:                        return null;
797:                    break;
798:                case DOUBLE:
799:                    return null;
800:                }
801:                if (src.hasConstant()) {
802:                    final Object obj;
803:                    switch (srcKind) {
804:                    case BYTE: {
805:                        final byte v = ((Byte) src.getConstant().getValue())
806:                                .byteValue();
807:                        switch (tgtKind) {
808:                        case SHORT:
809:                            obj = new Short(v);
810:                            break;
811:                        case INT:
812:                            obj = new Integer(v);
813:                            break;
814:                        case LONG:
815:                            obj = new Long(v);
816:                            break;
817:                        case FLOAT:
818:                            obj = new Float(v);
819:                            break;
820:                        case DOUBLE:
821:                            obj = new Double(v);
822:                            break;
823:                        default:
824:                            obj = null;
825:                        }
826:                        break;
827:                    }
828:                    case SHORT: {
829:                        final short v = ((Short) src.getConstant().getValue())
830:                                .shortValue();
831:                        switch (tgtKind) {
832:                        case INT:
833:                            obj = new Integer(v);
834:                            break;
835:                        case LONG:
836:                            obj = new Long(v);
837:                            break;
838:                        case FLOAT:
839:                            obj = new Float(v);
840:                            break;
841:                        case DOUBLE:
842:                            obj = new Double(v);
843:                            break;
844:                        default:
845:                            obj = null;
846:                        }
847:                        break;
848:                    }
849:                    case CHAR: {
850:                        final char v = ((Character) src.getConstant()
851:                                .getValue()).charValue();
852:                        switch (tgtKind) {
853:                        case INT:
854:                            obj = new Integer(v);
855:                            break;
856:                        case LONG:
857:                            obj = new Long(v);
858:                            break;
859:                        case FLOAT:
860:                            obj = new Float(v);
861:                            break;
862:                        case DOUBLE:
863:                            obj = new Double(v);
864:                            break;
865:                        default:
866:                            obj = null;
867:                        }
868:                        break;
869:                    }
870:                    case INT: {
871:                        final int v = ((Integer) src.getConstant().getValue())
872:                                .intValue();
873:                        switch (tgtKind) {
874:                        case LONG:
875:                            obj = new Long(v);
876:                            break;
877:                        case FLOAT:
878:                            obj = new Float(v);
879:                            break;
880:                        case DOUBLE:
881:                            obj = new Double(v);
882:                            break;
883:                        default:
884:                            obj = null;
885:                        }
886:                        break;
887:                    }
888:                    case LONG: {
889:                        final long v = ((Long) src.getConstant().getValue())
890:                                .longValue();
891:                        switch (tgtKind) {
892:                        case FLOAT:
893:                            obj = new Float(v);
894:                            break;
895:                        case DOUBLE:
896:                            obj = new Double(v);
897:                            break;
898:                        default:
899:                            obj = null;
900:                        }
901:                        break;
902:                    }
903:                    case FLOAT: {
904:                        final float v = ((Float) src.getConstant().getValue())
905:                                .floatValue();
906:                        switch (tgtKind) {
907:                        case DOUBLE:
908:                            obj = new Double(v);
909:                            break;
910:                        default:
911:                            obj = null;
912:                        }
913:                        break;
914:                    }
915:                    default: {
916:                        obj = null;
917:                        break;
918:                    }
919:                    }
920:                    if (null == obj)
921:                        throw new Error();
922:                    return tgtRaw.annotate().constant(obj);
923:                }
924:                return tgt;
925:            }
926:
927:            /**
928:             * Perform widening reference conversion. Assumes that src and tgt
929:             * are either not aliases, or if aliases, are already resolved.  May
930:             * resolve other aliases, such as supertypes, method parameter and
931:             * return types, etc.
932:             * 
933:             * @return The converted type, or null if this kind of conversion does not apply.
934:             * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25215">JLS 2 &sect;5.1.4</a>
935:             */
936:            public static Type widenReference(final SymbolTable tab,
937:                    final List<File> paths, final Type tgt, final Type src) {
938:                assert JavaEntities.isGeneralRValueT(src)
939:                        && JavaEntities.isGeneralRValueT(tgt);
940:                final Type result = widenReferenceInternal(tab, paths, tgt, src);
941:                assert null == result
942:                        || JavaEntities.isGeneralRValueT(result)
943:                        && !JavaEntities.isPrimitiveT(JavaEntities
944:                                .resolveToRawRValue(result));
945:                return result;
946:            }
947:
948:            private static Type widenReferenceInternal(final SymbolTable tab,
949:                    final List<File> paths, final Type tgt, final Type src) {
950:                if (isIdentical(tgt, src))
951:                    return null; // an identity conversion is not a widening conversion
952:                final Type tgtRaw = JavaEntities.resolveToRawRValue(tgt);
953:                if (JavaEntities.isNullT(src))
954:                    if (JavaEntities.isWrappedClassT(tgt)
955:                            || JavaEntities.isWrappedInterfaceT(tgt)
956:                            || tgtRaw.isArray())
957:                        return tgt;
958:                final Type srcRaw = JavaEntities.resolveToRawRValue(src);
959:                if (srcRaw.isClass() || srcRaw.isInterface()) {
960:                    if (isIdentical(tgt, JavaEntities.tObject(tab)))
961:                        return tgt;
962:                    for (Iterator<Type> i = new SuperTypesIter(tab, paths, src); i
963:                            .hasNext();)
964:                        if (isIdentical(tgt, i.next()))
965:                            return tgt;
966:                }
967:                if (srcRaw.isArray()) {
968:                    if (isIdentical(tgt, JavaEntities.tObjectAlias(tab))
969:                            || isIdentical(tgt, JavaEntities.tCloneable(tab))
970:                            || isIdentical(tgt, JavaEntities.tSerializable(tab)))
971:                        return tgt;
972:                    if (tgtRaw.isArray()) {
973:                        final Type tgtElem = JavaEntities
974:                                .arrayElementType(tgtRaw.toArray());
975:                        final Type srcElem = JavaEntities
976:                                .arrayElementType(srcRaw.toArray());
977:                        if (isWiderReference(tab, paths, tgtElem, srcElem))
978:                            return tgt;
979:                    }
980:                }
981:                return null;
982:            }
983:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.