public void complainIfUnusedExceptionHandlers(BlockScope scope,TryStatement tryStatement) { // report errors for unreachable exception handlers for (int index = 0, count = this.handledExceptions.length; index < count; index++) { int cacheIndex = index / ExceptionHandlingFlowContext.BitCacheSize; int bitMask = 1 << (index % ExceptionHandlingFlowContext.BitCacheSize); if ((this.isReached[cacheIndex] & bitMask) == 0) { scope.problemReporter().unreachableCatchBlock( this.handledExceptions[index], getExceptionType(index)); } else { if ((this.isNeeded[cacheIndex] & bitMask) == 0) { scope.problemReporter().hiddenCatchBlock( this.handledExceptions[index], getExceptionType(index)); } } } }
@Override public void endVisit(TryStatement x, BlockScope scope) { try { SourceInfo info = makeSourceInfo(x); JBlock finallyBlock = pop(x.finallyBlock); List<JBlock> catchBlocks = pop(x.catchBlocks); JBlock tryBlock = pop(x.tryBlock); List<JLocalRef> catchArgs = new ArrayList<JLocalRef>(); if (x.catchBlocks != null) { for (Argument argument : x.catchArguments) { JLocal local = (JLocal) curMethod.locals.get(argument.binding); catchArgs.add(new JLocalRef(info, local)); } } push(new JTryStatement(info, tryBlock, catchArgs, catchBlocks, finallyBlock)); } catch (Throwable e) { throw translateException(x, e); } }
/** * Certain ECJ versions that only go up to -source 6 report that they support -source 7 and even fail to error when -source 7 is applied. * We detect this and correctly say that no more than -source 6 is supported. (when this is the case, this method returns false). */ private static boolean ecjSupportsJava7Features() { try { TryStatement.class.getDeclaredField("resources"); return true; } catch (NoSuchFieldException e) { return false; } }
/** * Finds the thrown exceptions minus the ones that are already caught in previous catch blocks. * Exception is already caught even if its super type is being caught. Also computes, separately, * a list comprising of (a)those exceptions that have been caught already and (b)those exceptions that are thrown * by the method and whose super type has been caught already. * @param tryStatement * @param scope */ public void processThrownExceptions(TryStatement tryStatement, BlockScope scope) { this.thrownExceptions = new SimpleSet(); this.exceptionsStack = new Stack(); this.caughtExceptions = new SimpleSet(); this.discouragedExceptions = new SimpleSet(); tryStatement.traverse(this, scope); removeCaughtExceptions(tryStatement, true /*remove unchecked exceptions this time*/); }
public ExceptionHandlingFlowContext( FlowContext parent, TryStatement tryStatement, ReferenceBinding[] handledExceptions, int [] exceptionToCatchBlockMap, FlowContext initializationParent, BlockScope scope, FlowInfo flowInfo) { this(parent, tryStatement, handledExceptions, exceptionToCatchBlockMap, tryStatement.catchArguments, initializationParent, scope, flowInfo.unconditionalInits()); this.initsOnFinally = flowInfo.unconditionalCopy(); }
@Override public boolean visit(TryStatement x, BlockScope scope) { try { if (x.catchBlocks != null) { for (Argument argument : x.catchArguments) { createLocal(argument); } } return true; } catch (Throwable e) { throw translateException(x, e); } }
@Override public boolean visit(TryStatement node, BlockScope scope) { fixPositions(setGeneratedBy(node, source)); return super.visit(node, scope); }
private void removeCaughtExceptions(TryStatement tryStatement, boolean recordUncheckedCaughtExceptions) { Argument[] catchArguments = tryStatement.catchArguments; int length = catchArguments == null ? 0 : catchArguments.length; for (int i = 0; i < length; i++) { if (catchArguments[i].type instanceof UnionTypeReference) { UnionTypeReference unionTypeReference = (UnionTypeReference) catchArguments[i].type; TypeBinding caughtException; for (int j = 0; j < unionTypeReference.typeReferences.length; j++) { caughtException = unionTypeReference.typeReferences[j].resolvedType; if ((caughtException instanceof ReferenceBinding) && caughtException.isValidBinding()) { // might be null when its the completion node if (recordUncheckedCaughtExceptions) { // is in outermost try-catch. Remove all caught exceptions, unchecked or checked removeCaughtException((ReferenceBinding)caughtException); this.caughtExceptions.add(caughtException); } else { // is in some inner try-catch. Discourage already caught checked exceptions // from being proposed in an outer catch. if (!caughtException.isUncheckedException(true)) { this.discouragedExceptions.add(caughtException); } } } } } else { TypeBinding exception = catchArguments[i].type.resolvedType; if ((exception instanceof ReferenceBinding) && exception.isValidBinding()) { if (recordUncheckedCaughtExceptions) { // is in outermost try-catch. Remove all caught exceptions, unchecked or checked removeCaughtException((ReferenceBinding)exception); this.caughtExceptions.add(exception); } else { // is in some inner try-catch. Discourage already caught checked exceptions // from being proposed in an outer catch if (!exception.isUncheckedException(true)) { this.discouragedExceptions.add(exception); } } } } } }
private void formatTryResources( TryStatement tryStatement, boolean spaceBeforeOpenParen, boolean spaceBeforeClosingParen, boolean spaceBeforeFirstResource, boolean spaceBeforeSemicolon, boolean spaceAfterSemicolon, int tryResourcesAligment) { LocalDeclaration[] resources = tryStatement.resources; int length = resources != null ? resources.length : 0; if (length > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, spaceBeforeOpenParen); if (spaceBeforeFirstResource) { this.scribe.space(); } Alignment resourcesAlignment = this.scribe.createAlignment( Alignment.TRY_RESOURCES, tryResourcesAligment, // make sure alignment options for try with resources takes precedence Alignment.R_OUTERMOST, length, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(resourcesAlignment); boolean ok = false; do { switch (tryResourcesAligment & Alignment.SPLIT_MASK) { case Alignment.M_COMPACT_SPLIT: case Alignment.M_NEXT_PER_LINE_SPLIT: resourcesAlignment.startingColumn = this.scribe.column; break; } try { for (int i = 0; i < length; i++) { if (i > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, spaceBeforeSemicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (this.scribe.lastNumberOfNewLines == 1) { // a new line has been inserted while printing the comment // hence we need to use the break indentation level before printing next token... this.scribe.indentationLevel = resourcesAlignment.breakIndentationLevel; } } this.scribe.alignFragment(resourcesAlignment, i); if (i == 0) { int fragmentIndentation = resourcesAlignment.fragmentIndentations[0]; if ((resourcesAlignment.mode & Alignment.M_INDENT_ON_COLUMN) != 0 && fragmentIndentation > 0) { this.scribe.indentationLevel = fragmentIndentation; } } else if (spaceAfterSemicolon) { this.scribe.space(); } resources[i].traverse(this, null); resourcesAlignment.startingColumn = -1; } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(resourcesAlignment, true); if (isNextToken(TerminalTokens.TokenNameSEMICOLON)) { // take care of trailing semicolon this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, spaceBeforeSemicolon); } this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, spaceBeforeClosingParen); } }
/** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.TryStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(TryStatement tryStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNametry); formatTryResources( tryStatement, this.preferences.insert_space_before_opening_paren_in_try, this.preferences.insert_space_before_closing_paren_in_try, this.preferences.insert_space_after_opening_paren_in_try, this.preferences.insert_space_before_semicolon_in_try_resources, this.preferences.insert_space_after_semicolon_in_try_resources, this.preferences.alignment_for_resources_in_try); tryStatement.tryBlock.traverse(this, scope); if (tryStatement.catchArguments != null) { for (int i = 0, max = tryStatement.catchBlocks.length; i < max; i++) { if (this.preferences.insert_new_line_before_catch_in_try_statement) { this.scribe.printNewLine(); } this.scribe.printNextToken(TerminalTokens.TokenNamecatch, this.preferences.insert_space_after_closing_brace_in_block); final int line = this.scribe.line; this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_catch); if (this.preferences.insert_space_after_opening_paren_in_catch) { this.scribe.space(); } tryStatement.catchArguments[i].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_catch); formatLeftCurlyBrace(line, this.preferences.brace_position_for_block); tryStatement.catchBlocks[i].traverse(this, scope); } } if (tryStatement.finallyBlock != null) { if (this.preferences.insert_new_line_before_finally_in_try_statement) { this.scribe.printNewLine(); } this.scribe.printNextToken(TerminalTokens.TokenNamefinally, this.preferences.insert_space_after_closing_brace_in_block); tryStatement.finallyBlock.traverse(this, scope); } return false; }
protected void consumeStatementTry(boolean withFinally, boolean hasResources) { // TryStatement ::= 'try' Block Catches // TryStatement ::= 'try' Block Catchesopt Finally // TryStatementWithResources ::= 'try' ResourceSpecification TryBlock Catchesopt // TryStatementWithResources ::= 'try' ResourceSpecification TryBlock Catchesopt Finally int length; TryStatement tryStmt = new TryStatement(); //finally if (withFinally) { this.astLengthPtr--; tryStmt.finallyBlock = (Block) this.astStack[this.astPtr--]; } //catches are handle by two <argument-block> [see statementCatch] if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) { if (length == 1) { tryStmt.catchBlocks = new Block[] {(Block) this.astStack[this.astPtr--]}; tryStmt.catchArguments = new Argument[] {(Argument) this.astStack[this.astPtr--]}; } else { Block[] bks = (tryStmt.catchBlocks = new Block[length]); Argument[] args = (tryStmt.catchArguments = new Argument[length]); while (length-- > 0) { bks[length] = (Block) this.astStack[this.astPtr--]; args[length] = (Argument) this.astStack[this.astPtr--]; } } } //try this.astLengthPtr--; tryStmt.tryBlock = (Block) this.astStack[this.astPtr--]; if (hasResources) { // get the resources length = this.astLengthStack[this.astLengthPtr--]; LocalDeclaration[] resources = new LocalDeclaration[length]; System.arraycopy( this.astStack, (this.astPtr -= length) + 1, resources, 0, length); tryStmt.resources = resources; if (this.options.sourceLevel < ClassFileConstants.JDK1_7) { problemReporter().autoManagedResourcesNotBelow17(resources); } } //positions tryStmt.sourceEnd = this.endStatementPosition; tryStmt.sourceStart = this.intStack[this.intPtr--]; pushOnAstStack(tryStmt); }
@Override public boolean visit(TryStatement node, BlockScope scope) { setGeneratedBy(node, source); applyOffsetASTNode(node); return super.visit(node, scope); }
public void prepareSaveValueLocation(TryStatement targetTryStatement){ // do nothing: no storage is necessary for snippets }