01: /*******************************************************************************
02: * Copyright (c) 2000, 2007 IBM Corporation and others.
03: * All rights reserved. This program and the accompanying materials
04: * are made available under the terms of the Eclipse Public License v1.0
05: * which accompanies this distribution, and is available at
06: * http://www.eclipse.org/legal/epl-v10.html
07: *
08: * Contributors:
09: * IBM Corporation - initial API and implementation
10: *******************************************************************************/package org.eclipse.jdt.internal.compiler.ast;
11:
12: import org.eclipse.jdt.internal.compiler.ASTVisitor;
13: import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
14: import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
15: import org.eclipse.jdt.internal.compiler.flow.FlowContext;
16: import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
17: import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
18: import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
19: import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
20:
21: public class ThrowStatement extends Statement {
22:
23: public Expression exception;
24: public TypeBinding exceptionType;
25:
26: public ThrowStatement(Expression exception, int sourceStart,
27: int sourceEnd) {
28: this .exception = exception;
29: this .sourceStart = sourceStart;
30: this .sourceEnd = sourceEnd;
31: }
32:
33: public FlowInfo analyseCode(BlockScope currentScope,
34: FlowContext flowContext, FlowInfo flowInfo) {
35: this .exception.analyseCode(currentScope, flowContext, flowInfo);
36: this .exception.checkNPE(currentScope, flowContext, flowInfo);
37: // need to check that exception thrown is actually caught somewhere
38: flowContext.checkExceptionHandlers(this .exceptionType, this ,
39: flowInfo, currentScope);
40: return FlowInfo.DEAD_END;
41: }
42:
43: /**
44: * Throw code generation
45: *
46: * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
47: * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
48: */
49: public void generateCode(BlockScope currentScope,
50: CodeStream codeStream) {
51: if ((this .bits & ASTNode.IsReachable) == 0)
52: return;
53: int pc = codeStream.position;
54: this .exception.generateCode(currentScope, codeStream, true);
55: codeStream.athrow();
56: codeStream.recordPositionsFrom(pc, this .sourceStart);
57: }
58:
59: public StringBuffer printStatement(int indent, StringBuffer output) {
60: printIndent(indent, output).append("throw "); //$NON-NLS-1$
61: this .exception.printExpression(0, output);
62: return output.append(';');
63: }
64:
65: public void resolve(BlockScope scope) {
66: this .exceptionType = this .exception.resolveType(scope);
67: if (this .exceptionType != null
68: && this .exceptionType.isValidBinding()) {
69: if (this .exceptionType == TypeBinding.NULL) {
70: if (scope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3) {
71: // if compliant with 1.4, this problem will not be reported
72: scope.problemReporter().cannotThrowNull(
73: this .exception);
74: }
75: } else if (exceptionType.findSuperTypeErasingTo(
76: TypeIds.T_JavaLangThrowable, true) == null) {
77: scope.problemReporter().cannotThrowType(this .exception,
78: this .exceptionType);
79: }
80: this .exception.computeConversion(scope, this .exceptionType,
81: this .exceptionType);
82: }
83: }
84:
85: public void traverse(ASTVisitor visitor, BlockScope blockScope) {
86: if (visitor.visit(this, blockScope))
87: this.exception.traverse(visitor, blockScope);
88: visitor.endVisit(this, blockScope);
89: }
90: }
|