1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.ast;
12 
13 import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
14 import org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel;
15 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
16 
17 /**
18  * Extra behavior for statements which are generating subroutines
19  */
20 public abstract class SubRoutineStatement extends Statement {
21 
22 	public static final ExceptionLabel[] NO_EXCEPTION_HANDLER = new ExceptionLabel[0];
23 	ExceptionLabel[] anyExceptionLabels = NO_EXCEPTION_HANDLER;
24 	int anyExceptionLabelsCount = 0;
25 
isSubRoutineEscaping()26 	public abstract boolean isSubRoutineEscaping();
27 
generateSubRoutineInvocation(BlockScope currentScope, CodeStream codeStream)28 	public abstract void generateSubRoutineInvocation(BlockScope currentScope, CodeStream codeStream);
29 
enterAnyExceptionHandler(CodeStream codeStream)30 	public ExceptionLabel enterAnyExceptionHandler(CodeStream codeStream) {
31 
32 		int length;
33 		if ((length = this.anyExceptionLabelsCount) == this.anyExceptionLabels.length) {
34 			System.arraycopy(this.anyExceptionLabels, 0 , this.anyExceptionLabels=new ExceptionLabel[length*2 + 1], 0, length);
35 		}
36 		ExceptionLabel exceptionLabel = new ExceptionLabel(codeStream, null);
37 		this.anyExceptionLabels[this.anyExceptionLabelsCount++] = exceptionLabel;
38 		return exceptionLabel;
39 	}
40 
exitAnyExceptionHandler()41 	public void exitAnyExceptionHandler() {
42 		if (this.anyExceptionLabelsCount == 0) return;
43 		ExceptionLabel currentLabel = this.anyExceptionLabels[this.anyExceptionLabelsCount-1];
44 		if (currentLabel.start == currentLabel.codeStream.position) {
45 			// discard empty exception handler
46 			this.anyExceptionLabels[--this.anyExceptionLabelsCount] = null;
47 			currentLabel.codeStream.removeExceptionHandler(currentLabel);
48 		} else {
49 			currentLabel.placeEnd();
50 		}
51 	}
52 
placeAllAnyExceptionHandlers()53 	public void placeAllAnyExceptionHandlers() {
54 
55 		for (int i = 0; i < this.anyExceptionLabelsCount; i++) {
56 			this.anyExceptionLabels[i].place();
57 		}
58 	}
59 
reenterExceptionHandlers(SubRoutineStatement[] subroutines, int max, CodeStream codeStream)60 	public static void reenterExceptionHandlers(SubRoutineStatement[] subroutines, int max, CodeStream codeStream) {
61 		if (subroutines == null) return;
62 		if (max < 0) max = subroutines.length;
63 		for (int i = 0; i < max; i++) {
64 			subroutines[i].enterAnyExceptionHandler(codeStream);
65 		}
66 	}
67 }
68