001: /*
002: * Spoon - http://spoon.gforge.inria.fr/
003: * Copyright (C) 2006 INRIA Futurs <renaud.pawlak@inria.fr>
004: *
005: * This software is governed by the CeCILL-C License under French law and
006: * abiding by the rules of distribution of free software. You can use, modify
007: * and/or redistribute the software under the terms of the CeCILL-C license as
008: * circulated by CEA, CNRS and INRIA at http://www.cecill.info.
009: *
010: * This program is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
013: *
014: * The fact that you are presently reading this means that you have had
015: * knowledge of the CeCILL-C license and that you accept its terms.
016: */
017:
018: package spoon.reflect.eval;
019:
020: import java.util.ArrayList;
021: import java.util.HashMap;
022: import java.util.List;
023: import java.util.Map;
024: import java.util.Map.Entry;
025:
026: import spoon.reflect.code.CtAbstractInvocation;
027: import spoon.reflect.declaration.CtExecutable;
028: import spoon.reflect.reference.CtExecutableReference;
029: import spoon.reflect.reference.CtVariableReference;
030:
031: /**
032: * This class represents a frame of a symbolic evaluation stack.
033: */
034: public class SymbolicStackFrame {
035:
036: /**
037: * Copies a frame from a given one (does not clone stateless info).
038: */
039: public SymbolicStackFrame(SymbolicStackFrame frame) {
040: for (Entry<CtVariableReference<?>, SymbolicInstance<?>> e : frame.variables
041: .entrySet()) {
042: SymbolicInstance<?> i = e.getValue();
043: variables.put(e.getKey(), i == null ? null : i.getClone());
044: }
045: caller = frame.caller == null ? null : frame.caller.getClone();
046: target = frame.target == null ? null : frame.target.getClone();
047: result = frame.result == null ? null : frame.result.getClone();
048: invocation = frame.invocation;
049: executable = frame.executable;
050: if (frame.arguments != null) {
051: arguments = new ArrayList<SymbolicInstance<?>>();
052: for (SymbolicInstance<?> i : frame.arguments) {
053: arguments.add(i == null ? null : i.getClone());
054: }
055: }
056: }
057:
058: /**
059: * Frame equality.
060: */
061: @Override
062: public boolean equals(Object obj) {
063: SymbolicStackFrame f = (SymbolicStackFrame) obj;
064: return (target == null ? target == f.target : target
065: .equals(f.target))
066: && invocation == f.invocation
067: && executable.equals(f.executable)
068: && variables.equals(f.variables);
069: }
070:
071: private Map<CtVariableReference<?>, SymbolicInstance<?>> variables = new HashMap<CtVariableReference<?>, SymbolicInstance<?>>();
072:
073: private SymbolicInstance<?> target;
074:
075: private SymbolicInstance<?> caller;
076:
077: private CtAbstractInvocation<?> invocation;
078:
079: private CtExecutableReference<?> executable;
080:
081: /**
082: * Gets the parent invocation of this frame.
083: */
084: public CtAbstractInvocation<?> getInvocation() {
085: return invocation;
086: }
087:
088: /**
089: * Gets the <code>this</code> value.
090: */
091: public SymbolicInstance<?> getThis() {
092: return target;
093: }
094:
095: /**
096: * Gets the calling instance if applicable.
097: */
098: public SymbolicInstance<?> getCaller() {
099: return caller;
100: }
101:
102: /**
103: * Gets the local variables defined for this frame.
104: */
105: public Map<CtVariableReference<?>, SymbolicInstance<?>> getVariables() {
106: return variables;
107: }
108:
109: List<SymbolicInstance<?>> arguments;
110:
111: /**
112: * Return the arguments (also present in the variables).
113: */
114: public List<SymbolicInstance<?>> getArguments() {
115: return arguments;
116: }
117:
118: /**
119: * Creates a new evalutation stack frame.
120: *
121: * @param invocation
122: * the parent invocation
123: * @param caller
124: * the caller
125: * @param instance
126: * the target (this) of the frame ({@link #getThis()})
127: * @param executable
128: * the executable that corresponds to this frame
129: * @param variables
130: * the local variables defined within this frame (should be a
131: * copy)
132: */
133: public SymbolicStackFrame(CtAbstractInvocation<?> invocation,
134: SymbolicInstance<?> caller, SymbolicInstance<?> instance,
135: CtExecutableReference<?> executable,
136: List<SymbolicInstance<?>> arguments,
137: Map<CtVariableReference<?>, SymbolicInstance<?>> variables) {
138: super ();
139: this .variables = variables;
140: this .caller = caller;
141: this .target = instance;
142: this .invocation = invocation;
143: this .executable = executable;
144: this .arguments = arguments;
145: }
146:
147: /**
148: * A string representation.
149: */
150: @Override
151: public String toString() {
152: return "" + executable.getDeclaringType().getSimpleName()
153: + CtExecutable.EXECUTABLE_SEPARATOR
154: + executable.getSimpleName() + " on " + target
155: + " variables=" + variables + " arguments=" + arguments
156: + " result=" + result;
157: }
158:
159: /**
160: * Gets the executable of the frame.
161: */
162: public CtExecutableReference<?> getExecutable() {
163: return executable;
164: }
165:
166: private SymbolicInstance<?> result = null;
167:
168: /**
169: * Gets the result of this frame execution.
170: */
171: public SymbolicInstance<?> getResult() {
172: return result;
173: }
174:
175: /**
176: * Sets the result of this frame execution.
177: */
178: public void setResult(SymbolicInstance<?> result) {
179: this.result = result;
180: }
181:
182: }
|