001: // This file is part of KeY - Integrated Deductive Software Design
002: // Copyright (C) 2001-2007 Universitaet Karlsruhe, Germany
003: // Universitaet Koblenz-Landau, Germany
004: // Chalmers University of Technology, Sweden
005: //
006: // The KeY system is protected by the GNU General Public License.
007: // See LICENSE.TXT for details.
008: //
009: //
010:
011: // This file is taken from the RECODER library, which is protected by the LGPL,
012: // and modified.
013: /** This class is part of the AST RECODER builds when it parses and resolves Java
014: * programs with meta constructs and schema variables. It is transformed by Recoder2KeY
015: * to a subclass of ...rule.metaconstruct.ProgramMetaConstruct.
016: */package de.uka.ilkd.key.java.recoderext;
017:
018: import recoder.java.*;
019: import recoder.java.reference.MethodReference;
020: import recoder.java.reference.ReferencePrefix;
021: import recoder.java.reference.TypeReference;
022: import recoder.java.reference.TypeReferenceContainer;
023: import recoder.java.statement.JavaStatement;
024: import recoder.list.ExpressionMutableList;
025:
026: public class RMethodBodyStatement extends JavaStatement implements
027: KeYRecoderExtension, TypeReferenceContainer,
028: ExpressionContainer, NamedProgramElement {
029:
030: private TypeReference bodySource;
031: private ProgramVariableSVWrapper resultVar;
032:
033: private ReferencePrefix methodReferencePrefix;
034: private Identifier methodName;
035: private ExpressionMutableList arguments;
036:
037: public RMethodBodyStatement(TypeReference typeRef,
038: ProgramVariableSVWrapper resVar, MethodReference mr) {
039: this .bodySource = typeRef;
040: this .resultVar = resVar;
041: setMethodReference(mr);
042: makeParentRoleValid();
043: }
044:
045: public RMethodBodyStatement(TypeReference typeRef,
046: ProgramVariableSVWrapper resVar, ReferencePrefix prefix,
047: Identifier methodName, ExpressionMutableList arguments) {
048: this .bodySource = typeRef;
049: this .resultVar = resVar;
050: this .methodReferencePrefix = prefix;
051: this .methodName = methodName;
052: this .arguments = arguments;
053: makeParentRoleValid();
054: }
055:
056: public void accept(SourceVisitor visitor) {
057: }
058:
059: public Object deepClone() {
060: return new RMethodBodyStatement((TypeReference) bodySource
061: .deepClone(), (ProgramVariableSVWrapper) resultVar
062: .deepClone(), (ReferencePrefix) methodReferencePrefix
063: .deepClone(), (Identifier) methodName.deepClone(),
064: (ExpressionMutableList) arguments.deepClone());
065: }
066:
067: /**
068: * Set the MethodReference that caused this call.
069: */
070: public void setMethodReference(MethodReference methRef) {
071: this .methodName = methRef.getIdentifier();
072: this .methodReferencePrefix = methRef.getReferencePrefix();
073: this .arguments = methRef.getArguments();
074: }
075:
076: /**
077: * Returns the number of children of this node.
078: * @return an int giving the number of children of this node
079: */
080:
081: public int getChildCount() {
082: int result = 0;
083: if (bodySource != null)
084: result++;
085: if (resultVar != null)
086: result++;
087: if (methodReferencePrefix != null)
088: result++;
089: if (methodName != null)
090: result++;
091: if (arguments != null)
092: result += arguments.size();
093: return result;
094: }
095:
096: /**
097: * Returns the child at the specified index in this node's "virtual"
098: * child array
099: * @param index an index into this node's "virtual" child array
100: * @return the program element at the given position
101: * @exception ArrayIndexOutOfBoundsException if <tt>index</tt> is out
102: * of bounds
103: */
104:
105: public ProgramElement getChildAt(int index) {
106: if (bodySource != null) {
107: if (index == 0)
108: return bodySource;
109: index--;
110: }
111: if (resultVar != null) {
112: if (index == 0)
113: return resultVar;
114: index--;
115: }
116: if (methodReferencePrefix != null) {
117: if (index == 0)
118: return methodReferencePrefix;
119: index--;
120: }
121: if (methodName != null) {
122: if (index == 0)
123: return methodName;
124: index--;
125: }
126: if (arguments != null) {
127: return arguments.getExpression(index);
128: }
129: throw new ArrayIndexOutOfBoundsException();
130: }
131:
132: public int getChildPositionCode(ProgramElement child) {
133: // role 0: bodySource
134: // role 1: resultVar
135: // role 2: prefix
136: // others: arguments
137: if (bodySource == child) {
138: return 0;
139: }
140: if (resultVar == child) {
141: return 1;
142: }
143: if (methodReferencePrefix == child) {
144: return 2;
145: }
146: if (methodName == child) {
147: return 3;
148: }
149:
150: for (int i = 0, sz = arguments.size(); i < sz; i++) {
151: final Expression e = arguments.getExpression(i);
152: if (e == child) {
153: return i + 4;
154: }
155: }
156: return -1;
157: }
158:
159: /**
160: * Ensures that each child has "this" as syntactical parent.
161: */
162: public void makeParentRoleValid() {
163: super .makeParentRoleValid();
164:
165: if (bodySource != null) {
166: bodySource.setParent(this );
167: }
168:
169: if (resultVar != null) {
170: resultVar.setParent(this );
171: }
172:
173: if (methodName != null) {
174: methodName.setParent(this );
175: }
176:
177: if (arguments != null) {
178: for (int i = 0, sz = arguments.size(); i < sz; i++) {
179: arguments.getExpression(i).setExpressionContainer(this );
180: }
181: }
182: }
183:
184: /**
185: * Replace a single child in the current node.
186: * The child to replace is matched by identity and hence must be known
187: * exactly. The replacement element can be null - in that case, the child
188: * is effectively removed.
189: * The parent role of the new child is validated, while the
190: * parent link of the replaced child is left untouched.
191: * @param p the old child.
192: * @param q the new child.
193: * @return true if a replacement has occured, false otherwise.
194: * @exception ClassCastException if the new child cannot take over
195: * the role of the old one.
196: */
197:
198: public boolean replaceChild(ProgramElement p, ProgramElement q) {
199: if (p == null)
200: throw new NullPointerException();
201: if (bodySource == p) {
202: TypeReference r = (TypeReference) q;
203: bodySource = r;
204: if (r != null) {
205: r.setParent(this );
206: }
207: return true;
208: } else if (resultVar == p) {
209: ProgramVariableSVWrapper r = (ProgramVariableSVWrapper) q;
210: resultVar = r;
211: if (r != null) {
212: r.setParent(this );
213: }
214: return true;
215: } else if (methodReferencePrefix == p) {
216: ReferencePrefix rp = (ReferencePrefix) q;
217: methodReferencePrefix = rp;
218: return true;
219: } else if (methodName == p) {
220: Identifier id = (Identifier) q;
221: methodName = id;
222: return true;
223: } else {
224: for (int i = 0, sz = arguments.size(); i < sz; i++) {
225: final Expression e = arguments.getExpression(i);
226: if (e == p) {
227: final Expression exp = e;
228: arguments.set(i, exp);
229: if (exp != null) {
230: exp.setExpressionContainer(this );
231: }
232: return true;
233: }
234: }
235:
236: }
237:
238: return false;
239: }
240:
241: public TypeReference getBodySource() {
242: return bodySource;
243: }
244:
245: public ProgramVariableSVWrapper getResultVar() {
246: return resultVar;
247: }
248:
249: public MethodReference getMethodReference() {
250: return new MethodReference(methodReferencePrefix, methodName,
251: arguments);
252: }
253:
254: public int getTypeReferenceCount() {
255: return bodySource == null ? 0 : 1;
256: }
257:
258: public TypeReference getTypeReferenceAt(int index) {
259: if (bodySource != null && index == 0) {
260: return bodySource;
261: }
262: throw new ArrayIndexOutOfBoundsException();
263: }
264:
265: public int getExpressionCount() {
266: return arguments == null ? 0 : arguments.size();
267:
268: }
269:
270: public Expression getExpressionAt(int index) {
271: if (arguments != null) {
272: return arguments.getExpression(index);
273: }
274: throw new ArrayIndexOutOfBoundsException();
275: }
276:
277: public Identifier getIdentifier() {
278: return methodName;
279: }
280:
281: public void setIdentifier(Identifier methodName) {
282: this .methodName = methodName;
283:
284: }
285:
286: public String getName() {
287: return methodName.toString();
288: }
289: }
|