Source Code Cross Referenced for TryStatement.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) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.jdt.internal.compiler.ast;
0011:
0012:        import org.eclipse.jdt.internal.compiler.ASTVisitor;
0013:        import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
0014:        import org.eclipse.jdt.internal.compiler.codegen.*;
0015:        import org.eclipse.jdt.internal.compiler.flow.*;
0016:        import org.eclipse.jdt.internal.compiler.impl.Constant;
0017:        import org.eclipse.jdt.internal.compiler.lookup.*;
0018:
0019:        public class TryStatement extends SubRoutineStatement {
0020:
0021:            private final static char[] SECRET_RETURN_ADDRESS_NAME = " returnAddress".toCharArray(); //$NON-NLS-1$
0022:            private final static char[] SECRET_ANY_HANDLER_NAME = " anyExceptionHandler".toCharArray(); //$NON-NLS-1$
0023:            private final static char[] SECRET_RETURN_VALUE_NAME = " returnValue".toCharArray(); //$NON-NLS-1$
0024:
0025:            public Block tryBlock;
0026:            public Block[] catchBlocks;
0027:
0028:            public Argument[] catchArguments;
0029:
0030:            // should rename into subRoutineComplete to be set to false by default
0031:
0032:            public Block finallyBlock;
0033:            BlockScope scope;
0034:
0035:            public UnconditionalFlowInfo subRoutineInits;
0036:            ReferenceBinding[] caughtExceptionTypes;
0037:            boolean[] catchExits;
0038:
0039:            BranchLabel subRoutineStartLabel;
0040:            public LocalVariableBinding anyExceptionVariable,
0041:                    returnAddressVariable, secretReturnValue;
0042:
0043:            ExceptionLabel[] declaredExceptionLabels; // only set while generating code
0044:
0045:            // for inlining/optimizing JSR instructions
0046:            private Object[] reusableJSRTargets;
0047:            private BranchLabel[] reusableJSRSequenceStartLabels;
0048:            private int[] reusableJSRStateIndexes;
0049:            private int reusableJSRTargetsCount = 0;
0050:
0051:            private final static int NO_FINALLY = 0; // no finally block
0052:            private final static int FINALLY_SUBROUTINE = 1; // finally is generated as a subroutine (using jsr/ret bytecodes)
0053:            private final static int FINALLY_DOES_NOT_COMPLETE = 2; // non returning finally is optimized with only one instance of finally block
0054:            private final static int FINALLY_INLINE = 3; // finally block must be inlined since cannot use jsr/ret bytecodes >1.5	
0055:
0056:            // for local variables table attributes
0057:            int mergedInitStateIndex = -1;
0058:            int preTryInitStateIndex = -1;
0059:            int naturalExitMergeInitStateIndex = -1;
0060:            int[] catchExitInitStateIndexes;
0061:
0062:            public FlowInfo analyseCode(BlockScope currentScope,
0063:                    FlowContext flowContext, FlowInfo flowInfo) {
0064:
0065:                // Consider the try block and catch block so as to compute the intersection of initializations and	
0066:                // the minimum exit relative depth amongst all of them. Then consider the subroutine, and append its
0067:                // initialization to the try/catch ones, if the subroutine completes normally. If the subroutine does not
0068:                // complete, then only keep this result for the rest of the analysis
0069:
0070:                // process the finally block (subroutine) - create a context for the subroutine
0071:
0072:                this .preTryInitStateIndex = currentScope.methodScope()
0073:                        .recordInitializationStates(flowInfo);
0074:
0075:                if (this .anyExceptionVariable != null) {
0076:                    this .anyExceptionVariable.useFlag = LocalVariableBinding.USED;
0077:                }
0078:                if (this .returnAddressVariable != null) { // TODO (philippe) if subroutine is escaping, unused
0079:                    this .returnAddressVariable.useFlag = LocalVariableBinding.USED;
0080:                }
0081:                if (this .subRoutineStartLabel == null) {
0082:                    // no finally block -- this is a simplified copy of the else part
0083:                    // process the try block in a context handling the local exceptions.
0084:                    ExceptionHandlingFlowContext handlingContext = new ExceptionHandlingFlowContext(
0085:                            flowContext, this , this .caughtExceptionTypes,
0086:                            this .scope, flowInfo.unconditionalInits());
0087:                    handlingContext.initsOnFinally = new NullInfoRegistry(
0088:                            flowInfo.unconditionalInits());
0089:                    // only try blocks initialize that member - may consider creating a
0090:                    // separate class if needed
0091:
0092:                    FlowInfo tryInfo;
0093:                    if (this .tryBlock.isEmptyBlock()) {
0094:                        tryInfo = flowInfo;
0095:                    } else {
0096:                        tryInfo = this .tryBlock.analyseCode(currentScope,
0097:                                handlingContext, flowInfo.copy());
0098:                        if ((tryInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
0099:                            this .bits |= ASTNode.IsTryBlockExiting;
0100:                    }
0101:
0102:                    // check unreachable catch blocks
0103:                    handlingContext.complainIfUnusedExceptionHandlers(
0104:                            this .scope, this );
0105:
0106:                    // process the catch blocks - computing the minimal exit depth amongst try/catch
0107:                    if (this .catchArguments != null) {
0108:                        int catchCount;
0109:                        this .catchExits = new boolean[catchCount = this .catchBlocks.length];
0110:                        this .catchExitInitStateIndexes = new int[catchCount];
0111:                        for (int i = 0; i < catchCount; i++) {
0112:                            // keep track of the inits that could potentially have led to this exception handler (for final assignments diagnosis)
0113:                            FlowInfo catchInfo;
0114:                            if (this .caughtExceptionTypes[i]
0115:                                    .isUncheckedException(true)) {
0116:                                catchInfo = handlingContext.initsOnFinally
0117:                                        .mitigateNullInfoOf(flowInfo
0118:                                                .unconditionalCopy()
0119:                                                .addPotentialInitializationsFrom(
0120:                                                        handlingContext
0121:                                                                .initsOnException(this .caughtExceptionTypes[i]))
0122:                                                .addPotentialInitializationsFrom(
0123:                                                        tryInfo)
0124:                                                .addPotentialInitializationsFrom(
0125:                                                        handlingContext.initsOnReturn));
0126:                            } else {
0127:                                catchInfo = flowInfo
0128:                                        .unconditionalCopy()
0129:                                        .addPotentialInitializationsFrom(
0130:                                                handlingContext
0131:                                                        .initsOnException(this .caughtExceptionTypes[i]))
0132:                                        .addPotentialInitializationsFrom(
0133:                                                tryInfo
0134:                                                        .nullInfoLessUnconditionalCopy())
0135:                                        // remove null info to protect point of 
0136:                                        // exception null info 
0137:                                        .addPotentialInitializationsFrom(
0138:                                                handlingContext.initsOnReturn
0139:                                                        .nullInfoLessUnconditionalCopy());
0140:                            }
0141:
0142:                            // catch var is always set
0143:                            LocalVariableBinding catchArg = this .catchArguments[i].binding;
0144:                            catchInfo.markAsDefinitelyAssigned(catchArg);
0145:                            catchInfo.markAsDefinitelyNonNull(catchArg);
0146:                            /*
0147:                            "If we are about to consider an unchecked exception handler, potential inits may have occured inside
0148:                            the try block that need to be detected , e.g. 
0149:                            try { x = 1; throwSomething();} catch(Exception e){ x = 2} "
0150:                            "(uncheckedExceptionTypes notNil and: [uncheckedExceptionTypes at: index])
0151:                            ifTrue: [catchInits addPotentialInitializationsFrom: tryInits]."
0152:                             */
0153:                            if (this .tryBlock.statements == null) {
0154:                                catchInfo.setReachMode(FlowInfo.UNREACHABLE);
0155:                            }
0156:                            catchInfo = this .catchBlocks[i].analyseCode(
0157:                                    currentScope, flowContext, catchInfo);
0158:                            this .catchExitInitStateIndexes[i] = currentScope
0159:                                    .methodScope().recordInitializationStates(
0160:                                            catchInfo);
0161:                            this .catchExits[i] = (catchInfo.tagBits & FlowInfo.UNREACHABLE) != 0;
0162:                            tryInfo = tryInfo.mergedWith(catchInfo
0163:                                    .unconditionalInits());
0164:                        }
0165:                    }
0166:                    this .mergedInitStateIndex = currentScope.methodScope()
0167:                            .recordInitializationStates(tryInfo);
0168:
0169:                    // chain up null info registry
0170:                    if (flowContext.initsOnFinally != null) {
0171:                        flowContext.initsOnFinally
0172:                                .add(handlingContext.initsOnFinally);
0173:                    }
0174:
0175:                    return tryInfo;
0176:                } else {
0177:                    InsideSubRoutineFlowContext insideSubContext;
0178:                    FinallyFlowContext finallyContext;
0179:                    UnconditionalFlowInfo subInfo;
0180:                    // analyse finally block first
0181:                    insideSubContext = new InsideSubRoutineFlowContext(
0182:                            flowContext, this );
0183:
0184:                    subInfo = this .finallyBlock.analyseCode(
0185:                            currentScope,
0186:                            finallyContext = new FinallyFlowContext(
0187:                                    flowContext, this .finallyBlock),
0188:                            flowInfo.nullInfoLessUnconditionalCopy())
0189:                            .unconditionalInits();
0190:                    if (subInfo == FlowInfo.DEAD_END) {
0191:                        this .bits |= ASTNode.IsSubRoutineEscaping;
0192:                        this .scope.problemReporter()
0193:                                .finallyMustCompleteNormally(this .finallyBlock);
0194:                    }
0195:                    this .subRoutineInits = subInfo;
0196:                    // process the try block in a context handling the local exceptions.
0197:                    ExceptionHandlingFlowContext handlingContext = new ExceptionHandlingFlowContext(
0198:                            insideSubContext, this , this .caughtExceptionTypes,
0199:                            this .scope, flowInfo.unconditionalInits());
0200:                    handlingContext.initsOnFinally = new NullInfoRegistry(
0201:                            flowInfo.unconditionalInits());
0202:                    // only try blocks initialize that member - may consider creating a
0203:                    // separate class if needed		
0204:
0205:                    FlowInfo tryInfo;
0206:                    if (this .tryBlock.isEmptyBlock()) {
0207:                        tryInfo = flowInfo;
0208:                    } else {
0209:                        tryInfo = this .tryBlock.analyseCode(currentScope,
0210:                                handlingContext, flowInfo.copy());
0211:                        if ((tryInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
0212:                            this .bits |= ASTNode.IsTryBlockExiting;
0213:                    }
0214:
0215:                    // check unreachable catch blocks
0216:                    handlingContext.complainIfUnusedExceptionHandlers(
0217:                            this .scope, this );
0218:
0219:                    // process the catch blocks - computing the minimal exit depth amongst try/catch
0220:                    if (this .catchArguments != null) {
0221:                        int catchCount;
0222:                        this .catchExits = new boolean[catchCount = this .catchBlocks.length];
0223:                        this .catchExitInitStateIndexes = new int[catchCount];
0224:                        for (int i = 0; i < catchCount; i++) {
0225:                            // keep track of the inits that could potentially have led to this exception handler (for final assignments diagnosis)
0226:                            FlowInfo catchInfo;
0227:                            if (this .caughtExceptionTypes[i]
0228:                                    .isUncheckedException(true)) {
0229:                                catchInfo = handlingContext.initsOnFinally
0230:                                        .mitigateNullInfoOf(flowInfo
0231:                                                .unconditionalCopy()
0232:                                                .addPotentialInitializationsFrom(
0233:                                                        handlingContext
0234:                                                                .initsOnException(this .caughtExceptionTypes[i]))
0235:                                                .addPotentialInitializationsFrom(
0236:                                                        tryInfo)
0237:                                                .addPotentialInitializationsFrom(
0238:                                                        handlingContext.initsOnReturn));
0239:                            } else {
0240:                                catchInfo = flowInfo
0241:                                        .unconditionalCopy()
0242:                                        .addPotentialInitializationsFrom(
0243:                                                handlingContext
0244:                                                        .initsOnException(this .caughtExceptionTypes[i]))
0245:                                        .addPotentialInitializationsFrom(
0246:                                                tryInfo
0247:                                                        .nullInfoLessUnconditionalCopy())
0248:                                        // remove null info to protect point of 
0249:                                        // exception null info 
0250:                                        .addPotentialInitializationsFrom(
0251:                                                handlingContext.initsOnReturn
0252:                                                        .nullInfoLessUnconditionalCopy());
0253:                            }
0254:
0255:                            // catch var is always set
0256:                            LocalVariableBinding catchArg = this .catchArguments[i].binding;
0257:                            catchInfo.markAsDefinitelyAssigned(catchArg);
0258:                            catchInfo.markAsDefinitelyNonNull(catchArg);
0259:                            /*
0260:                            "If we are about to consider an unchecked exception handler, potential inits may have occured inside
0261:                            the try block that need to be detected , e.g. 
0262:                            try { x = 1; throwSomething();} catch(Exception e){ x = 2} "
0263:                            "(uncheckedExceptionTypes notNil and: [uncheckedExceptionTypes at: index])
0264:                            ifTrue: [catchInits addPotentialInitializationsFrom: tryInits]."
0265:                             */
0266:                            if (this .tryBlock.statements == null) {
0267:                                catchInfo.setReachMode(FlowInfo.UNREACHABLE);
0268:                            }
0269:                            catchInfo = this .catchBlocks[i].analyseCode(
0270:                                    currentScope, insideSubContext, catchInfo);
0271:                            this .catchExitInitStateIndexes[i] = currentScope
0272:                                    .methodScope().recordInitializationStates(
0273:                                            catchInfo);
0274:                            this .catchExits[i] = (catchInfo.tagBits & FlowInfo.UNREACHABLE) != 0;
0275:                            tryInfo = tryInfo.mergedWith(catchInfo
0276:                                    .unconditionalInits());
0277:                        }
0278:                    }
0279:                    // we also need to check potential multiple assignments of final variables inside the finally block
0280:                    // need to include potential inits from returns inside the try/catch parts - 1GK2AOF
0281:                    finallyContext
0282:                            .complainOnDeferredChecks(
0283:                                    handlingContext.initsOnFinally
0284:                                            .mitigateNullInfoOf((tryInfo.tagBits & FlowInfo.UNREACHABLE) == 0 ? flowInfo
0285:                                                    .unconditionalCopy()
0286:                                                    .addPotentialInitializationsFrom(
0287:                                                            tryInfo).
0288:                                                    // lighten the influence of the try block, which may have 
0289:                                                    // exited at any point
0290:                                                    addPotentialInitializationsFrom(
0291:                                                            insideSubContext.initsOnReturn)
0292:                                                    : insideSubContext.initsOnReturn),
0293:                                    currentScope);
0294:
0295:                    // chain up null info registry
0296:                    if (flowContext.initsOnFinally != null) {
0297:                        flowContext.initsOnFinally
0298:                                .add(handlingContext.initsOnFinally);
0299:                    }
0300:
0301:                    this .naturalExitMergeInitStateIndex = currentScope
0302:                            .methodScope().recordInitializationStates(tryInfo);
0303:                    if (subInfo == FlowInfo.DEAD_END) {
0304:                        this .mergedInitStateIndex = currentScope.methodScope()
0305:                                .recordInitializationStates(subInfo);
0306:                        return subInfo;
0307:                    } else {
0308:                        FlowInfo mergedInfo = tryInfo
0309:                                .addInitializationsFrom(subInfo);
0310:                        this .mergedInitStateIndex = currentScope.methodScope()
0311:                                .recordInitializationStates(mergedInfo);
0312:                        return mergedInfo;
0313:                    }
0314:                }
0315:            }
0316:
0317:            public ExceptionLabel enterAnyExceptionHandler(CodeStream codeStream) {
0318:                if (this .subRoutineStartLabel == null)
0319:                    return null;
0320:                return super .enterAnyExceptionHandler(codeStream);
0321:            }
0322:
0323:            public void enterDeclaredExceptionHandlers(CodeStream codeStream) {
0324:                for (int i = 0, length = this .declaredExceptionLabels == null ? 0
0325:                        : this .declaredExceptionLabels.length; i < length; i++) {
0326:                    this .declaredExceptionLabels[i].placeStart();
0327:                }
0328:            }
0329:
0330:            public void exitAnyExceptionHandler() {
0331:                if (this .subRoutineStartLabel == null)
0332:                    return;
0333:                super .exitAnyExceptionHandler();
0334:            }
0335:
0336:            public void exitDeclaredExceptionHandlers(CodeStream codeStream) {
0337:                for (int i = 0, length = this .declaredExceptionLabels == null ? 0
0338:                        : this .declaredExceptionLabels.length; i < length; i++) {
0339:                    this .declaredExceptionLabels[i].placeEnd();
0340:                }
0341:            }
0342:
0343:            private int finallyMode() {
0344:                if (this .subRoutineStartLabel == null) {
0345:                    return NO_FINALLY;
0346:                } else if (isSubRoutineEscaping()) {
0347:                    return FINALLY_DOES_NOT_COMPLETE;
0348:                } else if (scope.compilerOptions().inlineJsrBytecode) {
0349:                    return FINALLY_INLINE;
0350:                } else {
0351:                    return FINALLY_SUBROUTINE;
0352:                }
0353:            }
0354:
0355:            /**
0356:             * Try statement code generation with or without jsr bytecode use
0357:             *	post 1.5 target level, cannot use jsr bytecode, must instead inline finally block
0358:             * returnAddress is only allocated if jsr is allowed
0359:             */
0360:            public void generateCode(BlockScope currentScope,
0361:                    CodeStream codeStream) {
0362:                if ((this .bits & ASTNode.IsReachable) == 0) {
0363:                    return;
0364:                }
0365:                boolean isStackMapFrameCodeStream = codeStream instanceof  StackMapFrameCodeStream;
0366:                // in case the labels needs to be reinitialized
0367:                // when the code generation is restarted in wide mode
0368:                this .anyExceptionLabel = null;
0369:                this .reusableJSRTargets = null;
0370:                this .reusableJSRSequenceStartLabels = null;
0371:                this .reusableJSRTargetsCount = 0;
0372:
0373:                int pc = codeStream.position;
0374:                int finallyMode = finallyMode();
0375:
0376:                boolean requiresNaturalExit = false;
0377:                // preparing exception labels
0378:                int maxCatches = this .catchArguments == null ? 0
0379:                        : this .catchArguments.length;
0380:                ExceptionLabel[] exceptionLabels;
0381:                if (maxCatches > 0) {
0382:                    exceptionLabels = new ExceptionLabel[maxCatches];
0383:                    for (int i = 0; i < maxCatches; i++) {
0384:                        ExceptionLabel exceptionLabel = new ExceptionLabel(
0385:                                codeStream, this .catchArguments[i].binding.type);
0386:                        exceptionLabel.placeStart();
0387:                        exceptionLabels[i] = exceptionLabel;
0388:                    }
0389:                } else {
0390:                    exceptionLabels = null;
0391:                }
0392:                if (this .subRoutineStartLabel != null) {
0393:                    this .subRoutineStartLabel.initialize(codeStream);
0394:                    this .enterAnyExceptionHandler(codeStream);
0395:                }
0396:                // generate the try block
0397:                try {
0398:                    this .declaredExceptionLabels = exceptionLabels;
0399:                    this .tryBlock.generateCode(this .scope, codeStream);
0400:                } finally {
0401:                    this .declaredExceptionLabels = null;
0402:                }
0403:                boolean tryBlockHasSomeCode = codeStream.position != pc;
0404:                // flag telling if some bytecodes were issued inside the try block
0405:
0406:                // place end positions of user-defined exception labels
0407:                if (tryBlockHasSomeCode) {
0408:                    // natural exit may require subroutine invocation (if finally != null)
0409:                    BranchLabel naturalExitLabel = new BranchLabel(codeStream);
0410:                    BranchLabel postCatchesFinallyLabel = null;
0411:                    for (int i = 0; i < maxCatches; i++) {
0412:                        exceptionLabels[i].placeEnd();
0413:                    }
0414:                    if ((this .bits & ASTNode.IsTryBlockExiting) == 0) {
0415:                        int position = codeStream.position;
0416:                        switch (finallyMode) {
0417:                        case FINALLY_SUBROUTINE:
0418:                        case FINALLY_INLINE:
0419:                            requiresNaturalExit = true;
0420:                            if (this .naturalExitMergeInitStateIndex != -1) {
0421:                                codeStream
0422:                                        .removeNotDefinitelyAssignedVariables(
0423:                                                currentScope,
0424:                                                this .naturalExitMergeInitStateIndex);
0425:                                codeStream.addDefinitelyAssignedVariables(
0426:                                        currentScope,
0427:                                        this .naturalExitMergeInitStateIndex);
0428:                            }
0429:                            codeStream.goto_(naturalExitLabel);
0430:                            break;
0431:                        case NO_FINALLY:
0432:                            if (this .naturalExitMergeInitStateIndex != -1) {
0433:                                codeStream
0434:                                        .removeNotDefinitelyAssignedVariables(
0435:                                                currentScope,
0436:                                                this .naturalExitMergeInitStateIndex);
0437:                                codeStream.addDefinitelyAssignedVariables(
0438:                                        currentScope,
0439:                                        this .naturalExitMergeInitStateIndex);
0440:                            }
0441:                            codeStream.goto_(naturalExitLabel);
0442:                            break;
0443:                        case FINALLY_DOES_NOT_COMPLETE:
0444:                            codeStream.goto_(this .subRoutineStartLabel);
0445:                            break;
0446:                        }
0447:                        codeStream.updateLastRecordedEndPC(this .tryBlock.scope,
0448:                                position);
0449:                        //goto is tagged as part of the try block
0450:                    }
0451:                    /* generate sequence of handler, all starting by storing the TOS (exception
0452:                    thrown) into their own catch variables, the one specified in the source
0453:                    that must denote the handled exception.
0454:                     */
0455:                    this .exitAnyExceptionHandler();
0456:                    if (this .catchArguments != null) {
0457:                        postCatchesFinallyLabel = new BranchLabel(codeStream);
0458:
0459:                        for (int i = 0; i < maxCatches; i++) {
0460:                            /*
0461:                             * This should not happen. For consistency purpose, if the exception label is never used
0462:                             * we also don't generate the corresponding catch block, otherwise we have some
0463:                             * unreachable bytecodes
0464:                             */
0465:                            if (exceptionLabels[i].count == 0)
0466:                                continue;
0467:                            enterAnyExceptionHandler(codeStream);
0468:                            // May loose some local variable initializations : affecting the local variable attributes
0469:                            if (this .preTryInitStateIndex != -1) {
0470:                                codeStream
0471:                                        .removeNotDefinitelyAssignedVariables(
0472:                                                currentScope,
0473:                                                this .preTryInitStateIndex);
0474:                                codeStream
0475:                                        .addDefinitelyAssignedVariables(
0476:                                                currentScope,
0477:                                                this .preTryInitStateIndex);
0478:                            }
0479:                            codeStream
0480:                                    .pushExceptionOnStack(exceptionLabels[i].exceptionType);
0481:                            exceptionLabels[i].place();
0482:                            // optimizing the case where the exception variable is not actually used
0483:                            LocalVariableBinding catchVar;
0484:                            int varPC = codeStream.position;
0485:                            if ((catchVar = this .catchArguments[i].binding).resolvedPosition != -1) {
0486:                                codeStream.store(catchVar, false);
0487:                                catchVar
0488:                                        .recordInitializationStartPC(codeStream.position);
0489:                                codeStream.addVisibleLocalVariable(catchVar);
0490:                            } else {
0491:                                codeStream.pop();
0492:                            }
0493:                            codeStream.recordPositionsFrom(varPC,
0494:                                    this .catchArguments[i].sourceStart);
0495:                            // Keep track of the pcs at diverging point for computing the local attribute
0496:                            // since not passing the catchScope, the block generation will exitUserScope(catchScope)
0497:                            this .catchBlocks[i].generateCode(this .scope,
0498:                                    codeStream);
0499:                            this .exitAnyExceptionHandler();
0500:                            if (!this .catchExits[i]) {
0501:                                switch (finallyMode) {
0502:                                case FINALLY_INLINE:
0503:                                    // inlined finally here can see all merged variables
0504:                                    if (isStackMapFrameCodeStream) {
0505:                                        ((StackMapFrameCodeStream) codeStream)
0506:                                                .pushStateIndex(this .naturalExitMergeInitStateIndex);
0507:                                    }
0508:                                    if (this .catchExitInitStateIndexes[i] != -1) {
0509:                                        codeStream
0510:                                                .removeNotDefinitelyAssignedVariables(
0511:                                                        currentScope,
0512:                                                        this .catchExitInitStateIndexes[i]);
0513:                                        codeStream
0514:                                                .addDefinitelyAssignedVariables(
0515:                                                        currentScope,
0516:                                                        this .catchExitInitStateIndexes[i]);
0517:                                    }
0518:                                    // entire sequence for finally is associated to finally block
0519:                                    this .finallyBlock.generateCode(this .scope,
0520:                                            codeStream);
0521:                                    codeStream.goto_(postCatchesFinallyLabel);
0522:                                    if (isStackMapFrameCodeStream) {
0523:                                        ((StackMapFrameCodeStream) codeStream)
0524:                                                .popStateIndex();
0525:                                    }
0526:                                    break;
0527:                                case FINALLY_SUBROUTINE:
0528:                                    requiresNaturalExit = true;
0529:                                    // fall through
0530:                                case NO_FINALLY:
0531:                                    if (this .naturalExitMergeInitStateIndex != -1) {
0532:                                        codeStream
0533:                                                .removeNotDefinitelyAssignedVariables(
0534:                                                        currentScope,
0535:                                                        this .naturalExitMergeInitStateIndex);
0536:                                        codeStream
0537:                                                .addDefinitelyAssignedVariables(
0538:                                                        currentScope,
0539:                                                        this .naturalExitMergeInitStateIndex);
0540:                                    }
0541:                                    codeStream.goto_(naturalExitLabel);
0542:                                    break;
0543:                                case FINALLY_DOES_NOT_COMPLETE:
0544:                                    codeStream.goto_(this .subRoutineStartLabel);
0545:                                    break;
0546:                                }
0547:                            }
0548:                        }
0549:                    }
0550:                    // extra handler for trailing natural exit (will be fixed up later on when natural exit is generated below)
0551:                    ExceptionLabel naturalExitExceptionHandler = requiresNaturalExit
0552:                            && (finallyMode == FINALLY_SUBROUTINE) ? new ExceptionLabel(
0553:                            codeStream, null)
0554:                            : null;
0555:
0556:                    // addition of a special handler so as to ensure that any uncaught exception (or exception thrown
0557:                    // inside catch blocks) will run the finally block
0558:                    int finallySequenceStartPC = codeStream.position;
0559:                    if (this .subRoutineStartLabel != null
0560:                            && this .anyExceptionLabel.count != 0) {
0561:                        codeStream.pushExceptionOnStack(this .scope
0562:                                .getJavaLangThrowable());
0563:                        if (this .preTryInitStateIndex != -1) {
0564:                            // reset initialization state, as for a normal catch block
0565:                            codeStream.removeNotDefinitelyAssignedVariables(
0566:                                    currentScope, this .preTryInitStateIndex);
0567:                            codeStream.addDefinitelyAssignedVariables(
0568:                                    currentScope, this .preTryInitStateIndex);
0569:                        }
0570:                        this .placeAllAnyExceptionHandler();
0571:                        if (naturalExitExceptionHandler != null)
0572:                            naturalExitExceptionHandler.place();
0573:
0574:                        switch (finallyMode) {
0575:                        case FINALLY_SUBROUTINE:
0576:                            // any exception handler
0577:                            codeStream.store(this .anyExceptionVariable, false);
0578:                            codeStream.jsr(this .subRoutineStartLabel);
0579:                            codeStream.recordPositionsFrom(
0580:                                    finallySequenceStartPC,
0581:                                    this .finallyBlock.sourceStart);
0582:                            int position = codeStream.position;
0583:                            codeStream
0584:                                    .throwAnyException(this .anyExceptionVariable);
0585:                            codeStream.recordPositionsFrom(position,
0586:                                    this .finallyBlock.sourceEnd);
0587:                            // subroutine
0588:                            this .subRoutineStartLabel.place();
0589:                            codeStream.pushExceptionOnStack(this .scope
0590:                                    .getJavaLangThrowable());
0591:                            position = codeStream.position;
0592:                            codeStream.store(this .returnAddressVariable, false);
0593:                            codeStream.recordPositionsFrom(position,
0594:                                    this .finallyBlock.sourceStart);
0595:                            this .finallyBlock.generateCode(this .scope,
0596:                                    codeStream);
0597:                            position = codeStream.position;
0598:                            codeStream
0599:                                    .ret(this .returnAddressVariable.resolvedPosition);
0600:                            codeStream.recordPositionsFrom(position,
0601:                                    this .finallyBlock.sourceEnd);
0602:                            // the ret bytecode is part of the subroutine
0603:                            break;
0604:                        case FINALLY_INLINE:
0605:                            // any exception handler
0606:                            codeStream.store(this .anyExceptionVariable, false);
0607:                            codeStream.addVariable(this .anyExceptionVariable);
0608:                            codeStream.recordPositionsFrom(
0609:                                    finallySequenceStartPC,
0610:                                    this .finallyBlock.sourceStart);
0611:                            // subroutine
0612:                            this .finallyBlock.generateCode(currentScope,
0613:                                    codeStream);
0614:                            position = codeStream.position;
0615:                            codeStream
0616:                                    .throwAnyException(this .anyExceptionVariable);
0617:                            codeStream
0618:                                    .removeVariable(this .anyExceptionVariable);
0619:                            if (this .preTryInitStateIndex != -1) {
0620:                                codeStream
0621:                                        .removeNotDefinitelyAssignedVariables(
0622:                                                currentScope,
0623:                                                this .preTryInitStateIndex);
0624:                            }
0625:                            this .subRoutineStartLabel.place();
0626:                            codeStream.recordPositionsFrom(position,
0627:                                    this .finallyBlock.sourceEnd);
0628:                            break;
0629:                        case FINALLY_DOES_NOT_COMPLETE:
0630:                            // any exception handler
0631:                            codeStream.pop();
0632:                            this .subRoutineStartLabel.place();
0633:                            codeStream.recordPositionsFrom(
0634:                                    finallySequenceStartPC,
0635:                                    this .finallyBlock.sourceStart);
0636:                            // subroutine
0637:                            this .finallyBlock.generateCode(this .scope,
0638:                                    codeStream);
0639:                            break;
0640:                        }
0641:
0642:                        // will naturally fall into subsequent code after subroutine invocation
0643:                        if (requiresNaturalExit) {
0644:                            switch (finallyMode) {
0645:                            case FINALLY_SUBROUTINE:
0646:                                naturalExitLabel.place();
0647:                                int position = codeStream.position;
0648:                                naturalExitExceptionHandler.placeStart();
0649:                                codeStream.jsr(this .subRoutineStartLabel);
0650:                                naturalExitExceptionHandler.placeEnd();
0651:                                codeStream.recordPositionsFrom(position,
0652:                                        this .finallyBlock.sourceEnd);
0653:                                break;
0654:                            case FINALLY_INLINE:
0655:                                // inlined finally here can see all merged variables
0656:                                if (isStackMapFrameCodeStream) {
0657:                                    ((StackMapFrameCodeStream) codeStream)
0658:                                            .pushStateIndex(this .naturalExitMergeInitStateIndex);
0659:                                }
0660:                                if (this .naturalExitMergeInitStateIndex != -1) {
0661:                                    codeStream
0662:                                            .removeNotDefinitelyAssignedVariables(
0663:                                                    currentScope,
0664:                                                    this .naturalExitMergeInitStateIndex);
0665:                                    codeStream
0666:                                            .addDefinitelyAssignedVariables(
0667:                                                    currentScope,
0668:                                                    this .naturalExitMergeInitStateIndex);
0669:                                }
0670:                                naturalExitLabel.place();
0671:                                // entire sequence for finally is associated to finally block
0672:                                this .finallyBlock.generateCode(this .scope,
0673:                                        codeStream);
0674:                                if (postCatchesFinallyLabel != null) {
0675:                                    position = codeStream.position;
0676:                                    // entire sequence for finally is associated to finally block
0677:                                    codeStream.goto_(postCatchesFinallyLabel);
0678:                                    codeStream.recordPositionsFrom(position,
0679:                                            this .finallyBlock.sourceEnd);
0680:                                }
0681:                                if (isStackMapFrameCodeStream) {
0682:                                    ((StackMapFrameCodeStream) codeStream)
0683:                                            .popStateIndex();
0684:                                }
0685:                                break;
0686:                            case FINALLY_DOES_NOT_COMPLETE:
0687:                                break;
0688:                            default:
0689:                                naturalExitLabel.place();
0690:                                break;
0691:                            }
0692:                        }
0693:                        if (postCatchesFinallyLabel != null) {
0694:                            postCatchesFinallyLabel.place();
0695:                        }
0696:                    } else {
0697:                        // no subroutine, simply position end label (natural exit == end)
0698:                        naturalExitLabel.place();
0699:                    }
0700:                } else {
0701:                    // try block had no effect, only generate the body of the finally block if any
0702:                    if (this .subRoutineStartLabel != null) {
0703:                        this .finallyBlock.generateCode(this .scope, codeStream);
0704:                    }
0705:                }
0706:                // May loose some local variable initializations : affecting the local variable attributes
0707:                if (this .mergedInitStateIndex != -1) {
0708:                    codeStream.removeNotDefinitelyAssignedVariables(
0709:                            currentScope, this .mergedInitStateIndex);
0710:                    codeStream.addDefinitelyAssignedVariables(currentScope,
0711:                            this .mergedInitStateIndex);
0712:                }
0713:                codeStream.recordPositionsFrom(pc, this .sourceStart);
0714:            }
0715:
0716:            /**
0717:             * @see SubRoutineStatement#generateSubRoutineInvocation(BlockScope, CodeStream, Object, int, LocalVariableBinding)
0718:             */
0719:            public boolean generateSubRoutineInvocation(
0720:                    BlockScope currentScope, CodeStream codeStream,
0721:                    Object targetLocation, int stateIndex,
0722:                    LocalVariableBinding secretLocal) {
0723:
0724:                boolean isStackMapFrameCodeStream = codeStream instanceof  StackMapFrameCodeStream;
0725:                int finallyMode = finallyMode();
0726:                switch (finallyMode) {
0727:                case FINALLY_DOES_NOT_COMPLETE:
0728:                    codeStream.goto_(this .subRoutineStartLabel);
0729:                    return true;
0730:
0731:                case NO_FINALLY:
0732:                    exitDeclaredExceptionHandlers(codeStream);
0733:                    return false;
0734:                }
0735:                // optimize subroutine invocation sequences, using the targetLocation (if any)
0736:                if (targetLocation != null) {
0737:                    boolean reuseTargetLocation = true;
0738:                    if (this .reusableJSRTargetsCount > 0) {
0739:                        nextReusableTarget: for (int i = 0, count = this .reusableJSRTargetsCount; i < count; i++) {
0740:                            Object reusableJSRTarget = this .reusableJSRTargets[i];
0741:                            differentTarget: {
0742:                                if (targetLocation == reusableJSRTarget)
0743:                                    break differentTarget;
0744:                                if (targetLocation instanceof  Constant
0745:                                        && reusableJSRTarget instanceof  Constant
0746:                                        && ((Constant) targetLocation)
0747:                                                .hasSameValue((Constant) reusableJSRTarget)) {
0748:                                    break differentTarget;
0749:                                }
0750:                                // cannot reuse current target
0751:                                continue nextReusableTarget;
0752:                            }
0753:                            // current target has been used in the past, simply branch to its label
0754:                            if ((this .reusableJSRStateIndexes[i] != stateIndex)
0755:                                    && finallyMode == FINALLY_INLINE
0756:                                    && isStackMapFrameCodeStream) {
0757:                                reuseTargetLocation = false;
0758:                                break nextReusableTarget;
0759:                            } else {
0760:                                codeStream
0761:                                        .goto_(this .reusableJSRSequenceStartLabels[i]);
0762:                                return true;
0763:                            }
0764:                        }
0765:                    } else {
0766:                        this .reusableJSRTargets = new Object[3];
0767:                        this .reusableJSRSequenceStartLabels = new BranchLabel[3];
0768:                        this .reusableJSRStateIndexes = new int[3];
0769:                    }
0770:                    if (reuseTargetLocation) {
0771:                        if (this .reusableJSRTargetsCount == this .reusableJSRTargets.length) {
0772:                            System
0773:                                    .arraycopy(
0774:                                            this .reusableJSRTargets,
0775:                                            0,
0776:                                            this .reusableJSRTargets = new Object[2 * this .reusableJSRTargetsCount],
0777:                                            0, this .reusableJSRTargetsCount);
0778:                            System
0779:                                    .arraycopy(
0780:                                            this .reusableJSRSequenceStartLabels,
0781:                                            0,
0782:                                            this .reusableJSRSequenceStartLabels = new BranchLabel[2 * this .reusableJSRTargetsCount],
0783:                                            0, this .reusableJSRTargetsCount);
0784:                            System
0785:                                    .arraycopy(
0786:                                            this .reusableJSRStateIndexes,
0787:                                            0,
0788:                                            this .reusableJSRStateIndexes = new int[2 * this .reusableJSRTargetsCount],
0789:                                            0, this .reusableJSRTargetsCount);
0790:                        }
0791:                        this .reusableJSRTargets[this .reusableJSRTargetsCount] = targetLocation;
0792:                        BranchLabel reusableJSRSequenceStartLabel = new BranchLabel(
0793:                                codeStream);
0794:                        reusableJSRSequenceStartLabel.place();
0795:                        this .reusableJSRStateIndexes[this .reusableJSRTargetsCount] = stateIndex;
0796:                        this .reusableJSRSequenceStartLabels[this .reusableJSRTargetsCount++] = reusableJSRSequenceStartLabel;
0797:                    }
0798:                }
0799:                if (finallyMode == FINALLY_INLINE) {
0800:                    if (isStackMapFrameCodeStream) {
0801:                        ((StackMapFrameCodeStream) codeStream)
0802:                                .pushStateIndex(stateIndex);
0803:                        if (this .naturalExitMergeInitStateIndex != -1
0804:                                || stateIndex != -1) {
0805:                            // reset initialization state, as for a normal catch block
0806:                            codeStream.removeNotDefinitelyAssignedVariables(
0807:                                    currentScope,
0808:                                    this .naturalExitMergeInitStateIndex);
0809:                            codeStream.addDefinitelyAssignedVariables(
0810:                                    currentScope,
0811:                                    this .naturalExitMergeInitStateIndex);
0812:                        }
0813:                    } else {
0814:                        if (this .naturalExitMergeInitStateIndex != -1) {
0815:                            // reset initialization state, as for a normal catch block
0816:                            codeStream.removeNotDefinitelyAssignedVariables(
0817:                                    currentScope,
0818:                                    this .naturalExitMergeInitStateIndex);
0819:                            codeStream.addDefinitelyAssignedVariables(
0820:                                    currentScope,
0821:                                    this .naturalExitMergeInitStateIndex);
0822:                        }
0823:                    }
0824:                    if (secretLocal != null) {
0825:                        codeStream.addVariable(secretLocal);
0826:                    }
0827:                    // cannot use jsr bytecode, then simply inline the subroutine
0828:                    // inside try block, ensure to deactivate all catch block exception handlers while inlining finally block
0829:                    exitAnyExceptionHandler();
0830:                    exitDeclaredExceptionHandlers(codeStream);
0831:                    this .finallyBlock.generateCode(currentScope, codeStream);
0832:                    if (isStackMapFrameCodeStream) {
0833:                        ((StackMapFrameCodeStream) codeStream).popStateIndex();
0834:                    }
0835:                } else {
0836:                    // classic subroutine invocation, distinguish case of non-returning subroutine
0837:                    codeStream.jsr(this .subRoutineStartLabel);
0838:                    exitAnyExceptionHandler();
0839:                    exitDeclaredExceptionHandlers(codeStream);
0840:                }
0841:                return false;
0842:            }
0843:
0844:            public boolean isSubRoutineEscaping() {
0845:                return (this .bits & ASTNode.IsSubRoutineEscaping) != 0;
0846:            }
0847:
0848:            public StringBuffer printStatement(int indent, StringBuffer output) {
0849:                printIndent(indent, output).append("try \n"); //$NON-NLS-1$
0850:                this .tryBlock.printStatement(indent + 1, output);
0851:
0852:                //catches
0853:                if (this .catchBlocks != null)
0854:                    for (int i = 0; i < this .catchBlocks.length; i++) {
0855:                        output.append('\n');
0856:                        printIndent(indent, output).append("catch ("); //$NON-NLS-1$
0857:                        this .catchArguments[i].print(0, output).append(") "); //$NON-NLS-1$
0858:                        this .catchBlocks[i].printStatement(indent + 1, output);
0859:                    }
0860:                //finally
0861:                if (this .finallyBlock != null) {
0862:                    output.append('\n');
0863:                    printIndent(indent, output).append("finally\n"); //$NON-NLS-1$
0864:                    this .finallyBlock.printStatement(indent + 1, output);
0865:                }
0866:                return output;
0867:            }
0868:
0869:            public void resolve(BlockScope upperScope) {
0870:                // special scope for secret locals optimization.	
0871:                this .scope = new BlockScope(upperScope);
0872:
0873:                BlockScope tryScope = new BlockScope(this .scope);
0874:                BlockScope finallyScope = null;
0875:
0876:                if (this .finallyBlock != null) {
0877:                    if (this .finallyBlock.isEmptyBlock()) {
0878:                        if ((this .finallyBlock.bits & ASTNode.UndocumentedEmptyBlock) != 0) {
0879:                            this .scope.problemReporter()
0880:                                    .undocumentedEmptyBlock(
0881:                                            this .finallyBlock.sourceStart,
0882:                                            this .finallyBlock.sourceEnd);
0883:                        }
0884:                    } else {
0885:                        finallyScope = new BlockScope(this .scope, false); // don't add it yet to parent scope
0886:
0887:                        // provision for returning and forcing the finally block to run
0888:                        MethodScope methodScope = this .scope.methodScope();
0889:
0890:                        // the type does not matter as long as it is not a base type
0891:                        if (!upperScope.compilerOptions().inlineJsrBytecode) {
0892:                            this .returnAddressVariable = new LocalVariableBinding(
0893:                                    TryStatement.SECRET_RETURN_ADDRESS_NAME,
0894:                                    upperScope.getJavaLangObject(),
0895:                                    ClassFileConstants.AccDefault, false);
0896:                            finallyScope
0897:                                    .addLocalVariable(this .returnAddressVariable);
0898:                            this .returnAddressVariable
0899:                                    .setConstant(Constant.NotAConstant); // not inlinable
0900:                        }
0901:                        this .subRoutineStartLabel = new BranchLabel();
0902:
0903:                        this .anyExceptionVariable = new LocalVariableBinding(
0904:                                TryStatement.SECRET_ANY_HANDLER_NAME,
0905:                                this .scope.getJavaLangThrowable(),
0906:                                ClassFileConstants.AccDefault, false);
0907:                        finallyScope
0908:                                .addLocalVariable(this .anyExceptionVariable);
0909:                        this .anyExceptionVariable
0910:                                .setConstant(Constant.NotAConstant); // not inlinable
0911:
0912:                        if (!methodScope.isInsideInitializer()) {
0913:                            MethodBinding methodBinding = ((AbstractMethodDeclaration) methodScope.referenceContext).binding;
0914:                            if (methodBinding != null) {
0915:                                TypeBinding methodReturnType = methodBinding.returnType;
0916:                                if (methodReturnType.id != TypeIds.T_void) {
0917:                                    this .secretReturnValue = new LocalVariableBinding(
0918:                                            TryStatement.SECRET_RETURN_VALUE_NAME,
0919:                                            methodReturnType,
0920:                                            ClassFileConstants.AccDefault,
0921:                                            false);
0922:                                    finallyScope
0923:                                            .addLocalVariable(this .secretReturnValue);
0924:                                    this .secretReturnValue
0925:                                            .setConstant(Constant.NotAConstant); // not inlinable
0926:                                }
0927:                            }
0928:                        }
0929:                        this .finallyBlock.resolveUsing(finallyScope);
0930:                        // force the finally scope to have variable positions shifted after its try scope and catch ones
0931:                        finallyScope.shiftScopes = new BlockScope[this .catchArguments == null ? 1
0932:                                : this .catchArguments.length + 1];
0933:                        finallyScope.shiftScopes[0] = tryScope;
0934:                    }
0935:                }
0936:                this .tryBlock.resolveUsing(tryScope);
0937:
0938:                // arguments type are checked against JavaLangThrowable in resolveForCatch(..)
0939:                if (this .catchBlocks != null) {
0940:                    int length = this .catchArguments.length;
0941:                    TypeBinding[] argumentTypes = new TypeBinding[length];
0942:                    boolean catchHasError = false;
0943:                    for (int i = 0; i < length; i++) {
0944:                        BlockScope catchScope = new BlockScope(this .scope);
0945:                        if (finallyScope != null) {
0946:                            finallyScope.shiftScopes[i + 1] = catchScope;
0947:                        }
0948:                        // side effect on catchScope in resolveForCatch(..)
0949:                        if ((argumentTypes[i] = this .catchArguments[i]
0950:                                .resolveForCatch(catchScope)) == null) {
0951:                            catchHasError = true;
0952:                        }
0953:                        this .catchBlocks[i].resolveUsing(catchScope);
0954:                    }
0955:                    if (catchHasError) {
0956:                        return;
0957:                    }
0958:                    // Verify that the catch clause are ordered in the right way:
0959:                    // more specialized first.
0960:                    this .caughtExceptionTypes = new ReferenceBinding[length];
0961:                    for (int i = 0; i < length; i++) {
0962:                        this .caughtExceptionTypes[i] = (ReferenceBinding) argumentTypes[i];
0963:                        for (int j = 0; j < i; j++) {
0964:                            if (this .caughtExceptionTypes[i]
0965:                                    .isCompatibleWith(argumentTypes[j])) {
0966:                                this .scope.problemReporter()
0967:                                        .wrongSequenceOfExceptionTypesError(
0968:                                                this ,
0969:                                                this .caughtExceptionTypes[i],
0970:                                                i, argumentTypes[j]);
0971:                            }
0972:                        }
0973:                    }
0974:                } else {
0975:                    this .caughtExceptionTypes = new ReferenceBinding[0];
0976:                }
0977:
0978:                if (finallyScope != null) {
0979:                    // add finallyScope as last subscope, so it can be shifted behind try/catch subscopes.
0980:                    // the shifting is necessary to achieve no overlay in between the finally scope and its
0981:                    // sibling in term of local variable positions.
0982:                    this .scope.addSubscope(finallyScope);
0983:                }
0984:            }
0985:
0986:            public void traverse(ASTVisitor visitor, BlockScope blockScope) {
0987:                if (visitor.visit(this , blockScope)) {
0988:                    this .tryBlock.traverse(visitor, this .scope);
0989:                    if (this .catchArguments != null) {
0990:                        for (int i = 0, max = this.catchBlocks.length; i < max; i++) {
0991:                            this.catchArguments[i]
0992:                                    .traverse(visitor, this.scope);
0993:                            this.catchBlocks[i].traverse(visitor, this.scope);
0994:                        }
0995:                    }
0996:                    if (this.finallyBlock != null)
0997:                        this.finallyBlock.traverse(visitor, this.scope);
0998:                }
0999:                visitor.endVisit(this, blockScope);
1000:            }
1001:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.