KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > eval > CodeSnippetReturnStatement


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.eval;
12
13 import org.eclipse.jdt.internal.compiler.ast.Expression;
14 import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
15 import org.eclipse.jdt.internal.compiler.ast.TryStatement;
16 import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
17 import org.eclipse.jdt.internal.compiler.flow.FlowContext;
18 import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
19 import org.eclipse.jdt.internal.compiler.impl.Constant;
20 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
21 import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
22 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
23 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
24 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
25
26 /**
27  * A return statement inside a code snippet. During the code gen,
28  * it uses a macro to set the result of the code snippet instead
29  * of returning it.
30  */

31 public class CodeSnippetReturnStatement extends ReturnStatement implements InvocationSite, EvaluationConstants {
32     MethodBinding setResultMethod;
33 public CodeSnippetReturnStatement(Expression expr, int s, int e) {
34     super(expr, s, e);
35 }
36
37 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
38     FlowInfo info = super.analyseCode(currentScope, flowContext, flowInfo);
39     // we need to remove this optimization in order to prevent the inlining of the return bytecode
40
// 1GH0AU7: ITPJCORE:ALL - Eval - VerifyError in scrapbook page
41
this.expression.bits &= ~IsReturnedValue;
42     return info;
43 }
44
45 /**
46  * Dump the suitable return bytecode for a return statement
47  *
48  */

49 public void generateReturnBytecode(CodeStream codeStream) {
50     
51     // output the return bytecode
52
codeStream.return_();
53 }
54 public void generateStoreSaveValueIfNecessary(CodeStream codeStream){
55
56     // push receiver
57
codeStream.aload_0();
58
59     // push the 2 parameters of "setResult(Object, Class)"
60
if (this.expression == null || this.expression.resolvedType == TypeBinding.VOID) { // expressionType == VoidBinding if code snippet is the expression "System.out.println()"
61
// push null
62
codeStream.aconst_null();
63
64         // void.class
65
codeStream.generateClassLiteralAccessForType(TypeBinding.VOID, null);
66     } else {
67         // swap with expression
68
int valueTypeID = this.expression.resolvedType.id;
69         if (valueTypeID == T_long || valueTypeID == T_double) {
70             codeStream.dup_x2();
71             codeStream.pop();
72         } else {
73             codeStream.swap();
74         }
75
76         // generate wrapper if needed
77
if (this.expression.resolvedType.isBaseType() && this.expression.resolvedType != TypeBinding.NULL) {
78             codeStream.generateBoxingConversion(this.expression.resolvedType.id);
79         }
80
81         // generate the expression type
82
codeStream.generateClassLiteralAccessForType(this.expression.resolvedType, null);
83     }
84
85     // generate the invoke virtual to "setResult(Object,Class)"
86
codeStream.invokevirtual(this.setResultMethod);
87 }
88 /**
89  * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
90  */

91 public TypeBinding[] genericTypeArguments() {
92     return null;
93 }
94 public boolean isSuperAccess() {
95     return false;
96 }
97 public boolean isTypeAccess() {
98     return false;
99 }
100 public boolean needValue(){
101     return true;
102 }
103 public void prepareSaveValueLocation(TryStatement targetTryStatement){
104         
105     // do nothing: no storage is necessary for snippets
106
}
107 public void resolve(BlockScope scope) {
108     if (this.expression != null) {
109         if (this.expression.resolveType(scope) != null) {
110             TypeBinding javaLangClass = scope.getJavaLangClass();
111             if (!javaLangClass.isValidBinding()) {
112                 scope.problemReporter().codeSnippetMissingClass("java.lang.Class", this.sourceStart, this.sourceEnd); //$NON-NLS-1$
113
return;
114             }
115             TypeBinding javaLangObject = scope.getJavaLangObject();
116             if (!javaLangObject.isValidBinding()) {
117                 scope.problemReporter().codeSnippetMissingClass("java.lang.Object", this.sourceStart, this.sourceEnd); //$NON-NLS-1$
118
return;
119             }
120             TypeBinding[] argumentTypes = new TypeBinding[] {javaLangObject, javaLangClass};
121             this.setResultMethod = scope.getImplicitMethod(SETRESULT_SELECTOR, argumentTypes, this);
122             if (!this.setResultMethod.isValidBinding()) {
123                 scope.problemReporter().codeSnippetMissingMethod(ROOT_FULL_CLASS_NAME, new String JavaDoc(SETRESULT_SELECTOR), new String JavaDoc(SETRESULT_ARGUMENTS), this.sourceStart, this.sourceEnd);
124                 return;
125             }
126             // in constant case, the implicit conversion cannot be left uninitialized
127
if (this.expression.constant != Constant.NotAConstant) {
128                 // fake 'no implicit conversion' (the return type is always void)
129
this.expression.implicitConversion = this.expression.constant.typeID() << 4;
130             }
131         }
132     }
133 }
134 public void setActualReceiverType(ReferenceBinding receiverType) {
135     // ignored
136
}
137 public void setDepth(int depth) {
138     // ignored
139
}
140 public void setFieldIndex(int depth) {
141     // ignored
142
}
143
144 }
145
Popular Tags