Source Code Cross Referenced for FlowContext.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » compiler » flow » 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.flow 
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:         *******************************************************************************/package org.eclipse.jdt.internal.compiler.flow;
011:
012:        import org.eclipse.jdt.core.compiler.CharOperation;
013:        import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
014:        import org.eclipse.jdt.internal.compiler.ast.ASTNode;
015:        import org.eclipse.jdt.internal.compiler.ast.Expression;
016:        import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
017:        import org.eclipse.jdt.internal.compiler.ast.Reference;
018:        import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
019:        import org.eclipse.jdt.internal.compiler.ast.TryStatement;
020:        import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
021:        import org.eclipse.jdt.internal.compiler.lookup.Binding;
022:        import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
023:        import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
024:        import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
025:        import org.eclipse.jdt.internal.compiler.lookup.Scope;
026:        import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
027:        import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
028:        import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
029:
030:        /**
031:         * Reflects the context of code analysis, keeping track of enclosing
032:         *	try statements, exception handlers, etc...
033:         */
034:        public class FlowContext implements  TypeConstants {
035:
036:            // preempt marks looping contexts
037:            public final static FlowContext NotContinuableContext = new FlowContext(
038:                    null, null);
039:            public ASTNode associatedNode;
040:            public FlowContext parent;
041:            public NullInfoRegistry initsOnFinally;
042:            // only used within try blocks; remembers upstream flow info mergedWith
043:            // any null related operation happening within the try block
044:
045:            boolean deferNullDiagnostic, preemptNullDiagnostic;
046:
047:            public FlowContext(FlowContext parent, ASTNode associatedNode) {
048:                this .parent = parent;
049:                this .associatedNode = associatedNode;
050:                if (parent != null) {
051:                    this .deferNullDiagnostic = parent.deferNullDiagnostic
052:                            || parent.preemptNullDiagnostic;
053:                    this .initsOnFinally = parent.initsOnFinally;
054:                }
055:            }
056:
057:            public BranchLabel breakLabel() {
058:                return null;
059:            }
060:
061:            public void checkExceptionHandlers(TypeBinding raisedException,
062:                    ASTNode location, FlowInfo flowInfo, BlockScope scope) {
063:                // LIGHT-VERSION OF THE EQUIVALENT WITH AN ARRAY OF EXCEPTIONS
064:                // check that all the argument exception types are handled
065:                // JDK Compatible implementation - when an exception type is thrown, 
066:                // all related catch blocks are marked as reachable... instead of those only
067:                // until the point where it is safely handled (Smarter - see comment at the end)
068:                FlowContext traversedContext = this ;
069:                while (traversedContext != null) {
070:                    SubRoutineStatement sub;
071:                    if (((sub = traversedContext.subroutine()) != null)
072:                            && sub.isSubRoutineEscaping()) {
073:                        // traversing a non-returning subroutine means that all unhandled 
074:                        // exceptions will actually never get sent...
075:                        return;
076:                    }
077:
078:                    // filter exceptions that are locally caught from the innermost enclosing 
079:                    // try statement to the outermost ones.
080:                    if (traversedContext instanceof  ExceptionHandlingFlowContext) {
081:                        ExceptionHandlingFlowContext exceptionContext = (ExceptionHandlingFlowContext) traversedContext;
082:                        ReferenceBinding[] caughtExceptions;
083:                        if ((caughtExceptions = exceptionContext.handledExceptions) != Binding.NO_EXCEPTIONS) {
084:                            boolean definitelyCaught = false;
085:                            for (int caughtIndex = 0, caughtCount = caughtExceptions.length; caughtIndex < caughtCount; caughtIndex++) {
086:                                ReferenceBinding caughtException = caughtExceptions[caughtIndex];
087:                                int state = caughtException == null ? Scope.EQUAL_OR_MORE_SPECIFIC /* any exception */
088:                                        : Scope.compareTypes(raisedException,
089:                                                caughtException);
090:                                switch (state) {
091:                                case Scope.EQUAL_OR_MORE_SPECIFIC:
092:                                    exceptionContext.recordHandlingException(
093:                                            caughtException, flowInfo
094:                                                    .unconditionalInits(),
095:                                            raisedException, location,
096:                                            definitelyCaught);
097:                                    // was it already definitely caught ?
098:                                    definitelyCaught = true;
099:                                    break;
100:                                case Scope.MORE_GENERIC:
101:                                    exceptionContext.recordHandlingException(
102:                                            caughtException, flowInfo
103:                                                    .unconditionalInits(),
104:                                            raisedException, location, false);
105:                                    // was not caught already per construction
106:                                }
107:                            }
108:                            if (definitelyCaught)
109:                                return;
110:                        }
111:                        // method treatment for unchecked exceptions
112:                        if (exceptionContext.isMethodContext) {
113:                            if (raisedException.isUncheckedException(false))
114:                                return;
115:
116:                            // anonymous constructors are allowed to throw any exceptions (their thrown exceptions
117:                            // clause will be fixed up later as per JLS 8.6).
118:                            if (exceptionContext.associatedNode instanceof  AbstractMethodDeclaration) {
119:                                AbstractMethodDeclaration method = (AbstractMethodDeclaration) exceptionContext.associatedNode;
120:                                if (method.isConstructor()
121:                                        && method.binding.declaringClass
122:                                                .isAnonymousType()) {
123:
124:                                    exceptionContext
125:                                            .mergeUnhandledException(raisedException);
126:                                    return; // no need to complain, will fix up constructor exceptions						
127:                                }
128:                            }
129:                            break; // not handled anywhere, thus jump to error handling
130:                        }
131:                    }
132:
133:                    traversedContext.recordReturnFrom(flowInfo
134:                            .unconditionalInits());
135:
136:                    if (traversedContext instanceof  InsideSubRoutineFlowContext) {
137:                        ASTNode node = traversedContext.associatedNode;
138:                        if (node instanceof  TryStatement) {
139:                            TryStatement tryStatement = (TryStatement) node;
140:                            flowInfo
141:                                    .addInitializationsFrom(tryStatement.subRoutineInits); // collect inits			
142:                        }
143:                    }
144:                    traversedContext = traversedContext.parent;
145:                }
146:                // if reaches this point, then there are some remaining unhandled exception types.
147:                scope.problemReporter().unhandledException(raisedException,
148:                        location);
149:            }
150:
151:            public void checkExceptionHandlers(TypeBinding[] raisedExceptions,
152:                    ASTNode location, FlowInfo flowInfo, BlockScope scope) {
153:                // check that all the argument exception types are handled
154:                // JDK Compatible implementation - when an exception type is thrown, 
155:                // all related catch blocks are marked as reachable... instead of those only
156:                // until the point where it is safely handled (Smarter - see comment at the end)
157:                int remainingCount; // counting the number of remaining unhandled exceptions
158:                int raisedCount; // total number of exceptions raised
159:                if ((raisedExceptions == null)
160:                        || ((raisedCount = raisedExceptions.length) == 0))
161:                    return;
162:                remainingCount = raisedCount;
163:
164:                // duplicate the array of raised exceptions since it will be updated
165:                // (null replaces any handled exception)
166:                System.arraycopy(raisedExceptions, 0,
167:                        (raisedExceptions = new TypeBinding[raisedCount]), 0,
168:                        raisedCount);
169:                FlowContext traversedContext = this ;
170:
171:                while (traversedContext != null) {
172:                    SubRoutineStatement sub;
173:                    if (((sub = traversedContext.subroutine()) != null)
174:                            && sub.isSubRoutineEscaping()) {
175:                        // traversing a non-returning subroutine means that all unhandled 
176:                        // exceptions will actually never get sent...
177:                        return;
178:                    }
179:                    // filter exceptions that are locally caught from the innermost enclosing 
180:                    // try statement to the outermost ones.
181:                    if (traversedContext instanceof  ExceptionHandlingFlowContext) {
182:                        ExceptionHandlingFlowContext exceptionContext = (ExceptionHandlingFlowContext) traversedContext;
183:                        ReferenceBinding[] caughtExceptions;
184:                        if ((caughtExceptions = exceptionContext.handledExceptions) != Binding.NO_EXCEPTIONS) {
185:                            int caughtCount = caughtExceptions.length;
186:                            boolean[] locallyCaught = new boolean[raisedCount]; // at most
187:
188:                            for (int caughtIndex = 0; caughtIndex < caughtCount; caughtIndex++) {
189:                                ReferenceBinding caughtException = caughtExceptions[caughtIndex];
190:                                for (int raisedIndex = 0; raisedIndex < raisedCount; raisedIndex++) {
191:                                    TypeBinding raisedException;
192:                                    if ((raisedException = raisedExceptions[raisedIndex]) != null) {
193:                                        int state = caughtException == null ? Scope.EQUAL_OR_MORE_SPECIFIC /* any exception */
194:                                                : Scope.compareTypes(
195:                                                        raisedException,
196:                                                        caughtException);
197:                                        switch (state) {
198:                                        case Scope.EQUAL_OR_MORE_SPECIFIC:
199:                                            exceptionContext
200:                                                    .recordHandlingException(
201:                                                            caughtException,
202:                                                            flowInfo
203:                                                                    .unconditionalInits(),
204:                                                            raisedException,
205:                                                            location,
206:                                                            locallyCaught[raisedIndex]);
207:                                            // was already definitely caught ?
208:                                            if (!locallyCaught[raisedIndex]) {
209:                                                locallyCaught[raisedIndex] = true;
210:                                                // remember that this exception has been definitely caught
211:                                                remainingCount--;
212:                                            }
213:                                            break;
214:                                        case Scope.MORE_GENERIC:
215:                                            exceptionContext
216:                                                    .recordHandlingException(
217:                                                            caughtException,
218:                                                            flowInfo
219:                                                                    .unconditionalInits(),
220:                                                            raisedException,
221:                                                            location, false);
222:                                            // was not caught already per construction
223:                                        }
224:                                    }
225:                                }
226:                            }
227:                            // remove locally caught exceptions from the remaining ones
228:                            for (int i = 0; i < raisedCount; i++) {
229:                                if (locallyCaught[i]) {
230:                                    raisedExceptions[i] = null; // removed from the remaining ones.
231:                                }
232:                            }
233:                        }
234:                        // method treatment for unchecked exceptions
235:                        if (exceptionContext.isMethodContext) {
236:                            for (int i = 0; i < raisedCount; i++) {
237:                                TypeBinding raisedException;
238:                                if ((raisedException = raisedExceptions[i]) != null) {
239:                                    if (raisedException
240:                                            .isUncheckedException(false)) {
241:                                        remainingCount--;
242:                                        raisedExceptions[i] = null;
243:                                    }
244:                                }
245:                            }
246:                            // anonymous constructors are allowed to throw any exceptions (their thrown exceptions
247:                            // clause will be fixed up later as per JLS 8.6).
248:                            if (exceptionContext.associatedNode instanceof  AbstractMethodDeclaration) {
249:                                AbstractMethodDeclaration method = (AbstractMethodDeclaration) exceptionContext.associatedNode;
250:                                if (method.isConstructor()
251:                                        && method.binding.declaringClass
252:                                                .isAnonymousType()) {
253:
254:                                    for (int i = 0; i < raisedCount; i++) {
255:                                        TypeBinding raisedException;
256:                                        if ((raisedException = raisedExceptions[i]) != null) {
257:                                            exceptionContext
258:                                                    .mergeUnhandledException(raisedException);
259:                                        }
260:                                    }
261:                                    return; // no need to complain, will fix up constructor exceptions						
262:                                }
263:                            }
264:                            break; // not handled anywhere, thus jump to error handling
265:                        }
266:                    }
267:                    if (remainingCount == 0)
268:                        return;
269:
270:                    traversedContext.recordReturnFrom(flowInfo
271:                            .unconditionalInits());
272:
273:                    if (traversedContext instanceof  InsideSubRoutineFlowContext) {
274:                        ASTNode node = traversedContext.associatedNode;
275:                        if (node instanceof  TryStatement) {
276:                            TryStatement tryStatement = (TryStatement) node;
277:                            flowInfo
278:                                    .addInitializationsFrom(tryStatement.subRoutineInits); // collect inits			
279:                        }
280:                    }
281:                    traversedContext = traversedContext.parent;
282:                }
283:                // if reaches this point, then there are some remaining unhandled exception types.	
284:                nextReport: for (int i = 0; i < raisedCount; i++) {
285:                    TypeBinding exception;
286:                    if ((exception = raisedExceptions[i]) != null) {
287:                        // only one complaint if same exception declared to be thrown more than once
288:                        for (int j = 0; j < i; j++) {
289:                            if (raisedExceptions[j] == exception)
290:                                continue nextReport; // already reported 
291:                        }
292:                        scope.problemReporter().unhandledException(exception,
293:                                location);
294:                    }
295:                }
296:            }
297:
298:            public BranchLabel continueLabel() {
299:                return null;
300:            }
301:
302:            /*
303:             * lookup through break labels
304:             */
305:            public FlowContext getTargetContextForBreakLabel(char[] labelName) {
306:                FlowContext current = this , lastNonReturningSubRoutine = null;
307:                while (current != null) {
308:                    if (current.isNonReturningContext()) {
309:                        lastNonReturningSubRoutine = current;
310:                    }
311:                    char[] currentLabelName;
312:                    if (((currentLabelName = current.labelName()) != null)
313:                            && CharOperation
314:                                    .equals(currentLabelName, labelName)) {
315:                        ((LabeledStatement) current.associatedNode).bits |= ASTNode.LabelUsed;
316:                        if (lastNonReturningSubRoutine == null)
317:                            return current;
318:                        return lastNonReturningSubRoutine;
319:                    }
320:                    current = current.parent;
321:                }
322:                // not found
323:                return null;
324:            }
325:
326:            /*
327:             * lookup through continue labels
328:             */
329:            public FlowContext getTargetContextForContinueLabel(char[] labelName) {
330:                FlowContext current = this ;
331:                FlowContext lastContinuable = null;
332:                FlowContext lastNonReturningSubRoutine = null;
333:
334:                while (current != null) {
335:                    if (current.isNonReturningContext()) {
336:                        lastNonReturningSubRoutine = current;
337:                    } else {
338:                        if (current.isContinuable()) {
339:                            lastContinuable = current;
340:                        }
341:                    }
342:
343:                    char[] currentLabelName;
344:                    if ((currentLabelName = current.labelName()) != null
345:                            && CharOperation
346:                                    .equals(currentLabelName, labelName)) {
347:                        ((LabeledStatement) current.associatedNode).bits |= ASTNode.LabelUsed;
348:
349:                        // matching label found					
350:                        if ((lastContinuable != null)
351:                                && (current.associatedNode.concreteStatement() == lastContinuable.associatedNode)) {
352:
353:                            if (lastNonReturningSubRoutine == null)
354:                                return lastContinuable;
355:                            return lastNonReturningSubRoutine;
356:                        }
357:                        // label is found, but not a continuable location
358:                        return FlowContext.NotContinuableContext;
359:                    }
360:                    current = current.parent;
361:                }
362:                // not found
363:                return null;
364:            }
365:
366:            /*
367:             * lookup a default break through breakable locations
368:             */
369:            public FlowContext getTargetContextForDefaultBreak() {
370:                FlowContext current = this , lastNonReturningSubRoutine = null;
371:                while (current != null) {
372:                    if (current.isNonReturningContext()) {
373:                        lastNonReturningSubRoutine = current;
374:                    }
375:                    if (current.isBreakable() && current.labelName() == null) {
376:                        if (lastNonReturningSubRoutine == null)
377:                            return current;
378:                        return lastNonReturningSubRoutine;
379:                    }
380:                    current = current.parent;
381:                }
382:                // not found
383:                return null;
384:            }
385:
386:            /*
387:             * lookup a default continue amongst continuable locations
388:             */
389:            public FlowContext getTargetContextForDefaultContinue() {
390:                FlowContext current = this , lastNonReturningSubRoutine = null;
391:                while (current != null) {
392:                    if (current.isNonReturningContext()) {
393:                        lastNonReturningSubRoutine = current;
394:                    }
395:                    if (current.isContinuable()) {
396:                        if (lastNonReturningSubRoutine == null)
397:                            return current;
398:                        return lastNonReturningSubRoutine;
399:                    }
400:                    current = current.parent;
401:                }
402:                // not found
403:                return null;
404:            }
405:
406:            public String individualToString() {
407:                return "Flow context"; //$NON-NLS-1$
408:            }
409:
410:            public FlowInfo initsOnBreak() {
411:                return FlowInfo.DEAD_END;
412:            }
413:
414:            public UnconditionalFlowInfo initsOnReturn() {
415:                return FlowInfo.DEAD_END;
416:            }
417:
418:            public boolean isBreakable() {
419:                return false;
420:            }
421:
422:            public boolean isContinuable() {
423:                return false;
424:            }
425:
426:            public boolean isNonReturningContext() {
427:                return false;
428:            }
429:
430:            public boolean isSubRoutine() {
431:                return false;
432:            }
433:
434:            public char[] labelName() {
435:                return null;
436:            }
437:
438:            public void recordBreakFrom(FlowInfo flowInfo) {
439:                // default implementation: do nothing
440:            }
441:
442:            public void recordBreakTo(FlowContext targetContext) {
443:                // default implementation: do nothing
444:            }
445:
446:            public void recordContinueFrom(FlowContext innerFlowContext,
447:                    FlowInfo flowInfo) {
448:                // default implementation: do nothing
449:            }
450:
451:            protected boolean recordFinalAssignment(VariableBinding variable,
452:                    Reference finalReference) {
453:                return true; // keep going
454:            }
455:
456:            /**
457:             * Record a null reference for use by deferred checks. Only looping or 
458:             * finally contexts really record that information.
459:             * @param local the local variable involved in the check
460:             * @param expression the expression within which local lays
461:             * @param status the status against which the check must be performed; one of
462:             * 		{@link #CAN_ONLY_NULL CAN_ONLY_NULL}, {@link #CAN_ONLY_NULL_NON_NULL 
463:             * 		CAN_ONLY_NULL_NON_NULL}, {@link #MAY_NULL MAY_NULL}, 
464:             *      {@link #CAN_ONLY_NON_NULL CAN_ONLY_NON_NULL}, potentially 
465:             *      combined with a context indicator (one of {@link #IN_COMPARISON_NULL},
466:             *      {@link #IN_COMPARISON_NON_NULL}, {@link #IN_ASSIGNMENT} or {@link #IN_INSTANCEOF})
467:             */
468:            protected void recordNullReference(LocalVariableBinding local,
469:                    Expression expression, int status) {
470:                // default implementation: do nothing
471:            }
472:
473:            public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
474:                // default implementation: do nothing
475:            }
476:
477:            public void recordSettingFinal(VariableBinding variable,
478:                    Reference finalReference, FlowInfo flowInfo) {
479:                if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
480:                    // for initialization inside looping statement that effectively loops
481:                    FlowContext context = this ;
482:                    while (context != null) {
483:                        if (!context.recordFinalAssignment(variable,
484:                                finalReference)) {
485:                            break; // no need to keep going
486:                        }
487:                        context = context.parent;
488:                    }
489:                }
490:            }
491:
492:            public static final int CAN_ONLY_NULL_NON_NULL = 0x0000,
493:                    // check against null and non null, with definite values -- comparisons
494:                    CAN_ONLY_NULL = 0x0001,
495:                    // check against null, with definite values -- comparisons
496:                    CAN_ONLY_NON_NULL = 0x0002,
497:                    // check against non null, with definite values -- comparisons
498:                    MAY_NULL = 0x0003,
499:                    // check against null, with potential values -- NPE guard
500:                    CHECK_MASK = 0x00FF, IN_COMPARISON_NULL = 0x0100,
501:                    IN_COMPARISON_NON_NULL = 0x0200,
502:                    // check happened in a comparison
503:                    IN_ASSIGNMENT = 0x0300,
504:                    // check happened in an assignment
505:                    IN_INSTANCEOF = 0x0400,
506:                    // check happened in an instanceof expression
507:                    CONTEXT_MASK = ~CHECK_MASK;
508:
509:            /**
510:             * Record a null reference for use by deferred checks. Only looping or 
511:             * finally contexts really record that information. The context may
512:             * emit an error immediately depending on the status of local against
513:             * flowInfo and its nature (only looping of finally contexts defer part
514:             * of the checks; nonetheless, contexts that are nested into a looping or a
515:             * finally context get affected and delegate some checks to their enclosing
516:             * context).
517:             * @param scope the scope into which the check is performed
518:             * @param local the local variable involved in the check
519:             * @param reference the expression within which local lies
520:             * @param checkType the status against which the check must be performed; one 
521:             * 		of {@link #CAN_ONLY_NULL CAN_ONLY_NULL}, {@link #CAN_ONLY_NULL_NON_NULL 
522:             * 		CAN_ONLY_NULL_NON_NULL}, {@link #MAY_NULL MAY_NULL}, potentially 
523:             *      combined with a context indicator (one of {@link #IN_COMPARISON_NULL},
524:             *      {@link #IN_COMPARISON_NON_NULL}, {@link #IN_ASSIGNMENT} or {@link #IN_INSTANCEOF})
525:             * @param flowInfo the flow info at the check point; deferring contexts will
526:             *  	perform supplementary checks against flow info instances that cannot
527:             *  	be known at the time of calling this method (they are influenced by
528:             * 		code that follows the current point)
529:             */
530:            public void recordUsingNullReference(Scope scope,
531:                    LocalVariableBinding local, Expression reference,
532:                    int checkType, FlowInfo flowInfo) {
533:                if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0
534:                        || flowInfo.isDefinitelyUnknown(local)) {
535:                    return;
536:                }
537:                switch (checkType) {
538:                case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
539:                case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
540:                    if (flowInfo.isDefinitelyNonNull(local)) {
541:                        if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
542:                            scope.problemReporter()
543:                                    .localVariableRedundantCheckOnNonNull(
544:                                            local, reference);
545:                        } else {
546:                            scope.problemReporter()
547:                                    .localVariableNonNullComparedToNull(local,
548:                                            reference);
549:                        }
550:                        return;
551:                    } else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
552:                        return;
553:                    }
554:                case CAN_ONLY_NULL | IN_COMPARISON_NULL:
555:                case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
556:                case CAN_ONLY_NULL | IN_ASSIGNMENT:
557:                case CAN_ONLY_NULL | IN_INSTANCEOF:
558:                    if (flowInfo.isDefinitelyNull(local)) {
559:                        switch (checkType & CONTEXT_MASK) {
560:                        case FlowContext.IN_COMPARISON_NULL:
561:                            scope.problemReporter()
562:                                    .localVariableRedundantCheckOnNull(local,
563:                                            reference);
564:                            return;
565:                        case FlowContext.IN_COMPARISON_NON_NULL:
566:                            scope.problemReporter()
567:                                    .localVariableNullComparedToNonNull(local,
568:                                            reference);
569:                            return;
570:                        case FlowContext.IN_ASSIGNMENT:
571:                            scope.problemReporter()
572:                                    .localVariableRedundantNullAssignment(
573:                                            local, reference);
574:                            return;
575:                        case FlowContext.IN_INSTANCEOF:
576:                            scope.problemReporter()
577:                                    .localVariableNullInstanceof(local,
578:                                            reference);
579:                            return;
580:                        }
581:                    } else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
582:                        return;
583:                    }
584:                    break;
585:                case MAY_NULL:
586:                    if (flowInfo.isDefinitelyNull(local)) {
587:                        scope.problemReporter().localVariableNullReference(
588:                                local, reference);
589:                        return;
590:                    }
591:                    if (flowInfo.isPotentiallyNull(local)) {
592:                        scope.problemReporter()
593:                                .localVariablePotentialNullReference(local,
594:                                        reference);
595:                        return;
596:                    }
597:                    break;
598:                default:
599:                    // never happens
600:                }
601:                if (this .parent != null) {
602:                    this .parent.recordUsingNullReference(scope, local,
603:                            reference, checkType, flowInfo);
604:                }
605:            }
606:
607:            void removeFinalAssignmentIfAny(Reference reference) {
608:                // default implementation: do nothing
609:            }
610:
611:            public SubRoutineStatement subroutine() {
612:                return null;
613:            }
614:
615:            public String toString() {
616:                StringBuffer buffer = new StringBuffer();
617:                FlowContext current = this ;
618:                int parentsCount = 0;
619:                while ((current = current.parent) != null) {
620:                    parentsCount++;
621:                }
622:                FlowContext[] parents = new FlowContext[parentsCount + 1];
623:                current = this ;
624:                int index = parentsCount;
625:                while (index >= 0) {
626:                    parents[index--] = current;
627:                    current = current.parent;
628:                }
629:                for (int i = 0; i < parentsCount; i++) {
630:                    for (int j = 0; j < i; j++)
631:                        buffer.append('\t');
632:                    buffer.append(parents[i].individualToString()).append('\n');
633:                }
634:                buffer.append('*');
635:                for (int j = 0; j < parentsCount + 1; j++)
636:                    buffer.append('\t');
637:                buffer.append(individualToString()).append('\n');
638:                return buffer.toString();
639:            }
640:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.