Source Code Cross Referenced for CastExpression.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » compiler » 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 » IDE Eclipse » jdt » org.eclipse.jdt.internal.compiler.ast 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *     Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
011:         *******************************************************************************/package org.eclipse.jdt.internal.compiler.ast;
012:
013:        import org.eclipse.jdt.internal.compiler.ASTVisitor;
014:        import org.eclipse.jdt.internal.compiler.impl.*;
015:        import org.eclipse.jdt.internal.compiler.codegen.*;
016:        import org.eclipse.jdt.internal.compiler.flow.*;
017:        import org.eclipse.jdt.internal.compiler.lookup.*;
018:        import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
019:
020:        public class CastExpression extends Expression {
021:
022:            public Expression expression;
023:            public Expression type;
024:            public TypeBinding expectedType; // when assignment conversion to a given expected type: String s = (String) t;
025:
026:            //expression.implicitConversion holds the cast for baseType casting 
027:            public CastExpression(Expression expression, Expression type) {
028:                this .expression = expression;
029:                this .type = type;
030:                type.bits |= IgnoreRawTypeCheck; // no need to worry about raw type usage
031:            }
032:
033:            public FlowInfo analyseCode(BlockScope currentScope,
034:                    FlowContext flowContext, FlowInfo flowInfo) {
035:
036:                return expression.analyseCode(currentScope, flowContext,
037:                        flowInfo).unconditionalInits();
038:            }
039:
040:            /**
041:             * Complain if assigned expression is cast, but not actually used as such, e.g. Object o = (List) object;
042:             */
043:            public static void checkNeedForAssignedCast(BlockScope scope,
044:                    TypeBinding expectedType, CastExpression rhs) {
045:
046:                if (scope.compilerOptions().getSeverity(
047:                        CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore)
048:                    return;
049:
050:                TypeBinding castedExpressionType = rhs.expression.resolvedType;
051:                //	int i = (byte) n; // cast still had side effect
052:                // double d = (float) n; // cast to float is unnecessary
053:                if (castedExpressionType == null
054:                        || rhs.resolvedType.isBaseType())
055:                    return;
056:                //if (castedExpressionType.id == T_null) return; // tolerate null expression cast
057:                if (castedExpressionType.isCompatibleWith(expectedType)) {
058:                    scope.problemReporter().unnecessaryCast(rhs);
059:                }
060:            }
061:
062:            /**
063:             * Casting an enclosing instance will considered as useful if removing it would actually bind to a different type
064:             */
065:            public static void checkNeedForEnclosingInstanceCast(
066:                    BlockScope scope, Expression enclosingInstance,
067:                    TypeBinding enclosingInstanceType, TypeBinding memberType) {
068:
069:                if (scope.compilerOptions().getSeverity(
070:                        CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore)
071:                    return;
072:
073:                TypeBinding castedExpressionType = ((CastExpression) enclosingInstance).expression.resolvedType;
074:                if (castedExpressionType == null)
075:                    return; // cannot do better
076:                // obvious identity cast
077:                if (castedExpressionType == enclosingInstanceType) {
078:                    scope.problemReporter().unnecessaryCast(
079:                            (CastExpression) enclosingInstance);
080:                } else if (castedExpressionType == TypeBinding.NULL) {
081:                    return; // tolerate null enclosing instance cast
082:                } else {
083:                    TypeBinding alternateEnclosingInstanceType = castedExpressionType;
084:                    if (castedExpressionType.isBaseType()
085:                            || castedExpressionType.isArrayType())
086:                        return; // error case
087:                    if (memberType == scope.getMemberType(memberType
088:                            .sourceName(),
089:                            (ReferenceBinding) alternateEnclosingInstanceType)) {
090:                        scope.problemReporter().unnecessaryCast(
091:                                (CastExpression) enclosingInstance);
092:                    }
093:                }
094:            }
095:
096:            /**
097:             * Only complain for identity cast, since other type of casts may be useful: e.g.  ~((~(long) 0) << 32)  is different from: ~((~0) << 32) 
098:             */
099:            public static void checkNeedForArgumentCast(BlockScope scope,
100:                    int operator, int operatorSignature, Expression expression,
101:                    int expressionTypeId) {
102:
103:                if (scope.compilerOptions().getSeverity(
104:                        CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore)
105:                    return;
106:
107:                // check need for left operand cast
108:                int alternateLeftTypeId = expressionTypeId;
109:                if ((expression.bits & UnnecessaryCast) == 0
110:                        && expression.resolvedType.isBaseType()) {
111:                    // narrowing conversion on base type may change value, thus necessary
112:                    return;
113:                } else {
114:                    TypeBinding alternateLeftType = ((CastExpression) expression).expression.resolvedType;
115:                    if (alternateLeftType == null)
116:                        return; // cannot do better
117:                    if ((alternateLeftTypeId = alternateLeftType.id) == expressionTypeId) { // obvious identity cast
118:                        scope.problemReporter().unnecessaryCast(
119:                                (CastExpression) expression);
120:                        return;
121:                    } else if (alternateLeftTypeId == T_null) {
122:                        alternateLeftTypeId = expressionTypeId; // tolerate null argument cast
123:                        return;
124:                    }
125:                }
126:                /*		tolerate widening cast in unary expressions, as may be used when combined in binary expressions (41680)
127:                 int alternateOperatorSignature = OperatorExpression.OperatorSignatures[operator][(alternateLeftTypeId << 4) + alternateLeftTypeId];
128:                 // (cast)  left   Op (cast)  right --> result
129:                 //  1111   0000       1111   0000     1111
130:                 //  <<16   <<12       <<8    <<4       <<0
131:                 final int CompareMASK = (0xF<<16) + (0xF<<8) + 0xF; // mask hiding compile-time types
132:                 if ((operatorSignature & CompareMASK) == (alternateOperatorSignature & CompareMASK)) { // same promotions and result
133:                 scope.problemReporter().unnecessaryCastForArgument((CastExpression)expression,  TypeBinding.wellKnownType(scope, expression.implicitConversion >> 4)); 
134:                 }
135:                 */
136:            }
137:
138:            /**
139:             * Cast expressions will considered as useful if removing them all would actually bind to a different method
140:             * (no fine grain analysis on per casted argument basis, simply separate widening cast from narrowing ones)
141:             */
142:            public static void checkNeedForArgumentCasts(BlockScope scope,
143:                    Expression receiver, TypeBinding receiverType,
144:                    MethodBinding binding, Expression[] arguments,
145:                    TypeBinding[] argumentTypes,
146:                    final InvocationSite invocationSite) {
147:
148:                if (scope.compilerOptions().getSeverity(
149:                        CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore)
150:                    return;
151:
152:                int length = argumentTypes.length;
153:
154:                // iterate over arguments, and retrieve original argument types (before cast)
155:                TypeBinding[] rawArgumentTypes = argumentTypes;
156:                for (int i = 0; i < length; i++) {
157:                    Expression argument = arguments[i];
158:                    if (argument instanceof  CastExpression) {
159:                        // narrowing conversion on base type may change value, thus necessary
160:                        if ((argument.bits & UnnecessaryCast) == 0
161:                                && argument.resolvedType.isBaseType()) {
162:                            continue;
163:                        }
164:                        TypeBinding castedExpressionType = ((CastExpression) argument).expression.resolvedType;
165:                        if (castedExpressionType == null)
166:                            return; // cannot do better
167:                        // obvious identity cast
168:                        if (castedExpressionType == argumentTypes[i]) {
169:                            scope.problemReporter().unnecessaryCast(
170:                                    (CastExpression) argument);
171:                        } else if (castedExpressionType == TypeBinding.NULL) {
172:                            continue; // tolerate null argument cast
173:                        } else if ((argument.implicitConversion & BOXING) != 0) {
174:                            continue; // boxing has a side effect: (int) char   is not boxed as simple char
175:                        } else {
176:                            if (rawArgumentTypes == argumentTypes) {
177:                                System
178:                                        .arraycopy(
179:                                                rawArgumentTypes,
180:                                                0,
181:                                                rawArgumentTypes = new TypeBinding[length],
182:                                                0, length);
183:                            }
184:                            // retain original argument type
185:                            rawArgumentTypes[i] = castedExpressionType;
186:                        }
187:                    }
188:                }
189:                // perform alternate lookup with original types
190:                if (rawArgumentTypes != argumentTypes) {
191:                    checkAlternateBinding(scope, receiver, receiverType,
192:                            binding, arguments, argumentTypes,
193:                            rawArgumentTypes, invocationSite);
194:                }
195:            }
196:
197:            /**
198:             * Check binary operator casted arguments 
199:             */
200:            public static void checkNeedForArgumentCasts(BlockScope scope,
201:                    int operator, int operatorSignature, Expression left,
202:                    int leftTypeId, boolean leftIsCast, Expression right,
203:                    int rightTypeId, boolean rightIsCast) {
204:
205:                if (scope.compilerOptions().getSeverity(
206:                        CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore)
207:                    return;
208:
209:                // check need for left operand cast
210:                int alternateLeftTypeId = leftTypeId;
211:                if (leftIsCast) {
212:                    if ((left.bits & UnnecessaryCast) == 0
213:                            && left.resolvedType.isBaseType()) {
214:                        // narrowing conversion on base type may change value, thus necessary
215:                        leftIsCast = false;
216:                    } else {
217:                        TypeBinding alternateLeftType = ((CastExpression) left).expression.resolvedType;
218:                        if (alternateLeftType == null)
219:                            return; // cannot do better
220:                        if ((alternateLeftTypeId = alternateLeftType.id) == leftTypeId) { // obvious identity cast
221:                            scope.problemReporter().unnecessaryCast(
222:                                    (CastExpression) left);
223:                            leftIsCast = false;
224:                        } else if (alternateLeftTypeId == T_null) {
225:                            alternateLeftTypeId = leftTypeId; // tolerate null argument cast
226:                            leftIsCast = false;
227:                        }
228:                    }
229:                }
230:                // check need for right operand cast
231:                int alternateRightTypeId = rightTypeId;
232:                if (rightIsCast) {
233:                    if ((right.bits & UnnecessaryCast) == 0
234:                            && right.resolvedType.isBaseType()) {
235:                        // narrowing conversion on base type may change value, thus necessary
236:                        rightIsCast = false;
237:                    } else {
238:                        TypeBinding alternateRightType = ((CastExpression) right).expression.resolvedType;
239:                        if (alternateRightType == null)
240:                            return; // cannot do better
241:                        if ((alternateRightTypeId = alternateRightType.id) == rightTypeId) { // obvious identity cast
242:                            scope.problemReporter().unnecessaryCast(
243:                                    (CastExpression) right);
244:                            rightIsCast = false;
245:                        } else if (alternateRightTypeId == T_null) {
246:                            alternateRightTypeId = rightTypeId; // tolerate null argument cast
247:                            rightIsCast = false;
248:                        }
249:                    }
250:                }
251:                if (leftIsCast || rightIsCast) {
252:                    if (alternateLeftTypeId > 15 || alternateRightTypeId > 15) { // must convert String + Object || Object + String
253:                        if (alternateLeftTypeId == T_JavaLangString) {
254:                            alternateRightTypeId = T_JavaLangObject;
255:                        } else if (alternateRightTypeId == T_JavaLangString) {
256:                            alternateLeftTypeId = T_JavaLangObject;
257:                        } else {
258:                            return; // invalid operator
259:                        }
260:                    }
261:                    int alternateOperatorSignature = OperatorExpression.OperatorSignatures[operator][(alternateLeftTypeId << 4)
262:                            + alternateRightTypeId];
263:                    // (cast)  left   Op (cast)  right --> result
264:                    //  1111   0000       1111   0000     1111
265:                    //  <<16   <<12       <<8    <<4       <<0
266:                    final int CompareMASK = (0xF << 16) + (0xF << 8) + 0xF; // mask hiding compile-time types
267:                    if ((operatorSignature & CompareMASK) == (alternateOperatorSignature & CompareMASK)) { // same promotions and result
268:                        if (leftIsCast)
269:                            scope.problemReporter().unnecessaryCast(
270:                                    (CastExpression) left);
271:                        if (rightIsCast)
272:                            scope.problemReporter().unnecessaryCast(
273:                                    (CastExpression) right);
274:                    }
275:                }
276:            }
277:
278:            private static void checkAlternateBinding(BlockScope scope,
279:                    Expression receiver, TypeBinding receiverType,
280:                    MethodBinding binding, Expression[] arguments,
281:                    TypeBinding[] originalArgumentTypes,
282:                    TypeBinding[] alternateArgumentTypes,
283:                    final InvocationSite invocationSite) {
284:
285:                InvocationSite fakeInvocationSite = new InvocationSite() {
286:                    public TypeBinding[] genericTypeArguments() {
287:                        return null;
288:                    }
289:
290:                    public boolean isSuperAccess() {
291:                        return invocationSite.isSuperAccess();
292:                    }
293:
294:                    public boolean isTypeAccess() {
295:                        return invocationSite.isTypeAccess();
296:                    }
297:
298:                    public void setActualReceiverType(
299:                            ReferenceBinding actualReceiverType) { /* ignore */
300:                    }
301:
302:                    public void setDepth(int depth) { /* ignore */
303:                    }
304:
305:                    public void setFieldIndex(int depth) { /* ignore */
306:                    }
307:
308:                    public int sourceStart() {
309:                        return 0;
310:                    }
311:
312:                    public int sourceEnd() {
313:                        return 0;
314:                    }
315:                };
316:                MethodBinding bindingIfNoCast;
317:                if (binding.isConstructor()) {
318:                    bindingIfNoCast = scope.getConstructor(
319:                            (ReferenceBinding) receiverType,
320:                            alternateArgumentTypes, fakeInvocationSite);
321:                } else {
322:                    bindingIfNoCast = receiver.isImplicitThis() ? scope
323:                            .getImplicitMethod(binding.selector,
324:                                    alternateArgumentTypes, fakeInvocationSite)
325:                            : scope.getMethod(receiverType, binding.selector,
326:                                    alternateArgumentTypes, fakeInvocationSite);
327:                }
328:                if (bindingIfNoCast == binding) {
329:                    int argumentLength = originalArgumentTypes.length;
330:                    if (binding.isVarargs()) {
331:                        int paramLength = binding.parameters.length;
332:                        if (paramLength == argumentLength) {
333:                            int varargsIndex = paramLength - 1;
334:                            ArrayBinding varargsType = (ArrayBinding) binding.parameters[varargsIndex];
335:                            TypeBinding lastArgType = alternateArgumentTypes[varargsIndex];
336:                            // originalType may be compatible already, but cast mandated
337:                            // to clarify between varargs/non-varargs call
338:                            if (varargsType.dimensions != lastArgType
339:                                    .dimensions()) {
340:                                return;
341:                            }
342:                            if (lastArgType.isCompatibleWith(varargsType
343:                                    .elementsType())
344:                                    && lastArgType
345:                                            .isCompatibleWith(varargsType)) {
346:                                return;
347:                            }
348:                        }
349:                    }
350:                    for (int i = 0; i < argumentLength; i++) {
351:                        if (originalArgumentTypes[i] != alternateArgumentTypes[i]) {
352:                            scope.problemReporter().unnecessaryCast(
353:                                    (CastExpression) arguments[i]);
354:                        }
355:                    }
356:                }
357:            }
358:
359:            public boolean checkUnsafeCast(Scope scope, TypeBinding castType,
360:                    TypeBinding expressionType, TypeBinding match,
361:                    boolean isNarrowing) {
362:                if (match == castType) {
363:                    if (!isNarrowing
364:                            && match == this .resolvedType.leafComponentType()) { // do not tag as unnecessary when recursing through upper bounds
365:                        tagAsUnnecessaryCast(scope, castType);
366:                    }
367:                    return true;
368:                }
369:                if (match != null
370:                        && match.isProvablyDistinctFrom(
371:                                isNarrowing ? expressionType : castType, 0)) {
372:                    return false;
373:                }
374:                switch (castType.kind()) {
375:                case Binding.PARAMETERIZED_TYPE:
376:                    if (castType.isBoundParameterizedType()) {
377:                        if (match == null) { // unrelated types
378:                            this .bits |= UnsafeCast;
379:                            return true;
380:                        }
381:                        switch (match.kind()) {
382:                        case Binding.PARAMETERIZED_TYPE:
383:                            if (isNarrowing) {
384:                                // [JLS 5.5] T <: S
385:                                if (expressionType.isRawType()
386:                                        || !expressionType
387:                                                .isEquivalentTo(match)) {
388:                                    this .bits |= UnsafeCast;
389:                                    return true;
390:                                }
391:                                // [JLS 5.5] S has no subtype X != T, such that |X| == |T|
392:                                TypeBinding genericCastType = castType
393:                                        .erasure(); // jump to generic type
394:                                TypeBinding genericMatch = genericCastType
395:                                        .findSuperTypeWithSameErasure(expressionType);
396:                                if (genericMatch == match) {
397:                                    this .bits |= UnsafeCast;
398:                                }
399:                                return true;
400:                            } else {
401:                                // [JLS 5.5] T >: S
402:                                if (!match.isEquivalentTo(castType)) {
403:                                    this .bits |= UnsafeCast;
404:                                    return true;
405:                                }
406:                            }
407:                            break;
408:                        case Binding.RAW_TYPE:
409:                            this .bits |= UnsafeCast; // upcast since castType is known to be bound paramType
410:                            return true;
411:                        default:
412:                            if (isNarrowing) {
413:                                // match is not parameterized or raw, then any other subtype of match will erase  to |T|
414:                                this .bits |= UnsafeCast;
415:                                return true;
416:                            }
417:                            break;
418:                        }
419:                    }
420:                    break;
421:                case Binding.ARRAY_TYPE:
422:                    TypeBinding leafType = castType.leafComponentType();
423:                    if (isNarrowing
424:                            && (leafType.isBoundParameterizedType() || leafType
425:                                    .isTypeVariable())) {
426:                        this .bits |= UnsafeCast;
427:                        return true;
428:                    }
429:                    break;
430:                case Binding.TYPE_PARAMETER:
431:                    this .bits |= UnsafeCast;
432:                    return true;
433:                }
434:                if (!isNarrowing
435:                        && match == this .resolvedType.leafComponentType()) { // do not tag as unnecessary when recursing through upper bounds
436:                    tagAsUnnecessaryCast(scope, castType);
437:                }
438:                return true;
439:            }
440:
441:            /**
442:             * Cast expression code generation
443:             *
444:             * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
445:             * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
446:             * @param valueRequired boolean
447:             */
448:            public void generateCode(BlockScope currentScope,
449:                    CodeStream codeStream, boolean valueRequired) {
450:
451:                int pc = codeStream.position;
452:                boolean needRuntimeCheckcast = (this .bits & GenerateCheckcast) != 0;
453:                if (constant != Constant.NotAConstant) {
454:                    if (valueRequired || needRuntimeCheckcast) { // Added for: 1F1W9IG: IVJCOM:WINNT - Compiler omits casting check
455:                        codeStream.generateConstant(constant,
456:                                implicitConversion);
457:                        if (needRuntimeCheckcast) {
458:                            codeStream.checkcast(this .resolvedType);
459:                        }
460:                        if (!valueRequired) {
461:                            // the resolveType cannot be double or long
462:                            codeStream.pop();
463:                        }
464:                    }
465:                    codeStream.recordPositionsFrom(pc, this .sourceStart);
466:                    return;
467:                }
468:                expression.generateCode(currentScope, codeStream, valueRequired
469:                        || needRuntimeCheckcast);
470:                if (needRuntimeCheckcast
471:                        && this .expression.postConversionType(currentScope) != this .resolvedType
472:                                .erasure()) { // no need to issue a checkcast if already done as genericCast
473:                    codeStream.checkcast(this .resolvedType);
474:                }
475:                if (valueRequired) {
476:                    codeStream.generateImplicitConversion(implicitConversion);
477:                } else if (needRuntimeCheckcast) {
478:                    codeStream.pop();
479:                }
480:                codeStream.recordPositionsFrom(pc, this .sourceStart);
481:            }
482:
483:            public Expression innermostCastedExpression() {
484:                Expression current = this .expression;
485:                while (current instanceof  CastExpression) {
486:                    current = ((CastExpression) current).expression;
487:                }
488:                return current;
489:            }
490:
491:            /**
492:             * @see org.eclipse.jdt.internal.compiler.ast.Expression#localVariableBinding()
493:             */
494:            public LocalVariableBinding localVariableBinding() {
495:                return this .expression.localVariableBinding();
496:            }
497:
498:            public int nullStatus(FlowInfo flowInfo) {
499:                return this .expression.nullStatus(flowInfo);
500:            }
501:
502:            /**
503:             * @see org.eclipse.jdt.internal.compiler.ast.Expression#optimizedBooleanConstant()
504:             */
505:            public Constant optimizedBooleanConstant() {
506:                switch (this .resolvedType.id) {
507:                case T_boolean:
508:                case T_JavaLangBoolean:
509:                    return this .expression.optimizedBooleanConstant();
510:                }
511:                return Constant.NotAConstant;
512:            }
513:
514:            public StringBuffer printExpression(int indent, StringBuffer output) {
515:
516:                output.append('(');
517:                type.print(0, output).append(") "); //$NON-NLS-1$
518:                return expression.printExpression(0, output);
519:            }
520:
521:            public TypeBinding resolveType(BlockScope scope) {
522:                // compute a new constant if the cast is effective
523:
524:                // due to the fact an expression may start with ( and that a cast can also start with (
525:                // the field is an expression....it can be a TypeReference OR a NameReference Or
526:                // any kind of Expression <-- this last one is invalid.......
527:
528:                constant = Constant.NotAConstant;
529:                implicitConversion = T_undefined;
530:
531:                if ((type instanceof  TypeReference)
532:                        || (type instanceof  NameReference)
533:                        && ((type.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0) { // no extra parenthesis around type: ((A))exp
534:
535:                    TypeBinding castType = this .resolvedType = type
536:                            .resolveType(scope);
537:                    //expression.setExpectedType(this.resolvedType); // needed in case of generic method invocation			
538:                    TypeBinding expressionType = expression.resolveType(scope);
539:                    if (castType != null) {
540:                        if (expressionType != null) {
541:                            boolean isLegal = checkCastTypesCompatibility(
542:                                    scope, castType, expressionType,
543:                                    this .expression);
544:                            if (isLegal) {
545:                                this .expression.computeConversion(scope,
546:                                        castType, expressionType);
547:                                if ((this .bits & UnsafeCast) != 0) { // unsafe cast
548:                                    scope.problemReporter().unsafeCast(this ,
549:                                            scope);
550:                                } else {
551:                                    if (castType.isRawType()
552:                                            && scope
553:                                                    .compilerOptions()
554:                                                    .getSeverity(
555:                                                            CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore) {
556:                                        scope.problemReporter()
557:                                                .rawTypeReference(this .type,
558:                                                        castType);
559:                                    }
560:                                    if ((this .bits & (UnnecessaryCast | DisableUnnecessaryCastCheck)) == UnnecessaryCast) { // unnecessary cast 
561:                                        if (!isIndirectlyUsed()) // used for generic type inference or boxing ?
562:                                            scope.problemReporter()
563:                                                    .unnecessaryCast(this );
564:                                    }
565:                                }
566:                            } else { // illegal cast
567:                                scope.problemReporter().typeCastError(this ,
568:                                        castType, expressionType);
569:                                this .bits |= DisableUnnecessaryCastCheck; // disable further secondary diagnosis
570:                            }
571:                        }
572:                        this .resolvedType = castType.capture(scope,
573:                                this .sourceEnd);
574:                    }
575:                    return this .resolvedType;
576:                } else { // expression as a cast
577:                    TypeBinding expressionType = expression.resolveType(scope);
578:                    if (expressionType == null)
579:                        return null;
580:                    scope.problemReporter().invalidTypeReference(type);
581:                    return null;
582:                }
583:            }
584:
585:            /**
586:             * @see org.eclipse.jdt.internal.compiler.ast.Expression#setExpectedType(org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
587:             */
588:            public void setExpectedType(TypeBinding expectedType) {
589:                this .expectedType = expectedType;
590:            }
591:
592:            /**
593:             * Determines whether apparent unnecessary cast wasn't actually used to
594:             * perform return type inference of generic method invocation or boxing.
595:             */
596:            private boolean isIndirectlyUsed() {
597:                if (this .expression instanceof  MessageSend) {
598:                    MethodBinding method = ((MessageSend) this .expression).binding;
599:                    if (method instanceof  ParameterizedGenericMethodBinding
600:                            && ((ParameterizedGenericMethodBinding) method).inferredReturnType) {
601:                        if (this .expectedType == null)
602:                            return true;
603:                        if (this .resolvedType != this .expectedType)
604:                            return true;
605:                    }
606:                }
607:                if (this .expectedType != null
608:                        && this .resolvedType.isBaseType()
609:                        && !this .resolvedType
610:                                .isCompatibleWith(this .expectedType)) {
611:                    // boxing: Short s = (short) _byte
612:                    return true;
613:                }
614:                return false;
615:            }
616:
617:            /**
618:             * @see org.eclipse.jdt.internal.compiler.ast.Expression#tagAsNeedCheckCast()
619:             */
620:            public void tagAsNeedCheckCast() {
621:                this .bits |= GenerateCheckcast;
622:            }
623:
624:            /**
625:             * @see org.eclipse.jdt.internal.compiler.ast.Expression#tagAsUnnecessaryCast(Scope, TypeBinding)
626:             */
627:            public void tagAsUnnecessaryCast(Scope scope, TypeBinding castType) {
628:                if (this .expression.resolvedType == null)
629:                    return; // cannot do better if expression is not bound
630:                this .bits |= UnnecessaryCast;
631:            }
632:
633:            public void traverse(ASTVisitor visitor, BlockScope blockScope) {
634:
635:                if (visitor.visit(this, blockScope)) {
636:                    type.traverse(visitor, blockScope);
637:                    expression.traverse(visitor, blockScope);
638:                }
639:                visitor.endVisit(this, blockScope);
640:            }
641:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.