001: /*
002: * Author: Chris Seguin
003: *
004: * This software has been developed under the copyleft
005: * rules of the GNU General Public License. Please
006: * consult the GNU General Public License for more
007: * details about use and distribution of this software.
008: */
009: package org.acm.seguin.refactor.method;
010:
011: import java.util.Iterator;
012: import java.util.LinkedList;
013: import net.sourceforge.jrefactory.ast.Node;
014: import net.sourceforge.jrefactory.ast.ASTArgumentList;
015: import net.sourceforge.jrefactory.ast.ASTArguments;
016: import net.sourceforge.jrefactory.ast.ASTAssignmentOperator;
017: import net.sourceforge.jrefactory.ast.ASTBlockStatement;
018: import net.sourceforge.jrefactory.ast.ASTExpression;
019: import net.sourceforge.jrefactory.ast.ASTLocalVariableDeclaration;
020: import net.sourceforge.jrefactory.ast.ASTName;
021: import net.sourceforge.jrefactory.ast.ASTPrimaryExpression;
022: import net.sourceforge.jrefactory.ast.ASTPrimaryPrefix;
023: import net.sourceforge.jrefactory.ast.ASTPrimarySuffix;
024: import net.sourceforge.jrefactory.ast.ASTPrimitiveType;
025: import net.sourceforge.jrefactory.ast.ASTStatement;
026: import net.sourceforge.jrefactory.ast.ASTStatementExpression;
027: import net.sourceforge.jrefactory.ast.ASTType;
028: import net.sourceforge.jrefactory.ast.ASTVariableDeclarator;
029: import net.sourceforge.jrefactory.ast.ASTVariableDeclaratorId;
030: import net.sourceforge.jrefactory.ast.ASTVariableInitializer;
031: import net.sourceforge.jrefactory.ast.SimpleNode;
032: import net.sourceforge.jrefactory.build.BuildExpression;
033: import org.acm.seguin.summary.VariableSummary;
034: import org.acm.seguin.summary.TypeDeclSummary;
035:
036: import net.sourceforge.jrefactory.ast.ASTReferenceType;
037: import net.sourceforge.jrefactory.ast.ASTClassOrInterfaceType;
038: import net.sourceforge.jrefactory.parser.JavaParserTreeConstants;
039:
040: /**
041: * Builds the invocation of the method that is extracted for insertion into
042: * the place where the method was extracted
043: *
044: *@author Chris Seguin
045: */
046: class EMBuilder {
047: private String methodName;
048: private boolean isStatement;
049: private LinkedList parameters;
050: private VariableSummary returnSummary;
051: private boolean localVariableNeeded = false;
052:
053: /**
054: * Constructor for the EMBuilder object
055: */
056: public EMBuilder() {
057: returnSummary = null;
058: }
059:
060: /**
061: * Sets the MethodName attribute of the EMBuilder object
062: *
063: *@param value The new MethodName value
064: */
065: public void setMethodName(String value) {
066: methodName = value;
067: }
068:
069: /**
070: * Sets the Statement attribute of the EMBuilder object
071: *
072: *@param value The new Statement value
073: */
074: public void setStatement(boolean value) {
075: isStatement = value;
076: }
077:
078: /**
079: * Sets the Parameters attribute of the EMBuilder object
080: *
081: *@param list The new Parameters value
082: */
083: public void setParameters(LinkedList list) {
084: parameters = list;
085: }
086:
087: /**
088: * Sets the ReturnName attribute of the EMBuilder object
089: *
090: *@param name The new ReturnName value
091: */
092: public void setReturnSummary(VariableSummary value) {
093: returnSummary = value;
094: }
095:
096: /**
097: * Sets the LocalVariableNeeded attribute of the EMBuilder object
098: *
099: *@param value The new LocalVariableNeeded value
100: */
101: public void setLocalVariableNeeded(boolean value) {
102: localVariableNeeded = value;
103: }
104:
105: /**
106: * Builds the statement or assignment or local variable declaration
107: *
108: *@return The resulting value
109: */
110: public Node build() {
111: ASTBlockStatement blockStatement = new ASTBlockStatement(
112: JavaParserTreeConstants.JJTBLOCKSTATEMENT);
113:
114: if (localVariableNeeded) {
115: buildWithLocal(blockStatement);
116: return blockStatement;
117: }
118:
119: ASTStatement statement = new ASTStatement(0);
120: blockStatement.jjtAddChild(statement, 0);
121:
122: ASTStatementExpression stateExpress = new ASTStatementExpression(
123: JavaParserTreeConstants.JJTSTATEMENTEXPRESSION);
124: statement.jjtAddChild(stateExpress, 0);
125:
126: ASTPrimaryExpression primaryExpression = null;
127: if (isStatement && (returnSummary != null)) {
128: buildAssignment(stateExpress);
129: } else {
130: primaryExpression = buildMethodInvocation(stateExpress, 0);
131: }
132:
133: if (isStatement) {
134: return blockStatement;
135: } else {
136: return primaryExpression;
137: }
138: }
139:
140: /**
141: * Builds the assignment
142: *
143: *@param stateExpress Description of Parameter
144: */
145: private void buildAssignment(ASTStatementExpression stateExpress) {
146: // First add what we are returning
147: ASTPrimaryExpression primaryExpression = new ASTPrimaryExpression(
148: JavaParserTreeConstants.JJTPRIMARYEXPRESSION);
149: stateExpress.jjtAddChild(primaryExpression, 0);
150:
151: ASTPrimaryPrefix prefix = new ASTPrimaryPrefix(
152: JavaParserTreeConstants.JJTPRIMARYPREFIX);
153: primaryExpression.jjtAddChild(prefix, 0);
154:
155: ASTName name = new ASTName();
156: name.addNamePart(returnSummary.getName());
157: primaryExpression.jjtAddChild(name, 0);
158:
159: // Now add the assignment operator
160: ASTAssignmentOperator assign = new ASTAssignmentOperator(
161: JavaParserTreeConstants.JJTASSIGNMENTOPERATOR);
162: assign.setName("=");
163: stateExpress.jjtAddChild(assign, 1);
164:
165: // Finally add the rest
166: buildMethodInvocation(stateExpress, 2);
167: }
168:
169: /**
170: * Builds the method invocation
171: *
172: *@param stateExpress Description of Parameter
173: *@param index Description of Parameter
174: *@return Description of the Returned Value
175: */
176: private ASTPrimaryExpression buildMethodInvocation(
177: SimpleNode stateExpress, int index) {
178: ASTPrimaryExpression primaryExpression = new ASTPrimaryExpression(
179: JavaParserTreeConstants.JJTPRIMARYEXPRESSION);
180: stateExpress.jjtAddChild(primaryExpression, index);
181:
182: ASTPrimaryPrefix prefix = new ASTPrimaryPrefix(
183: JavaParserTreeConstants.JJTPRIMARYPREFIX);
184: primaryExpression.jjtAddChild(prefix, 0);
185:
186: ASTName name = new ASTName();
187: name.addNamePart(methodName);
188: primaryExpression.jjtAddChild(name, 0);
189:
190: ASTPrimarySuffix suffix = new ASTPrimarySuffix(
191: JavaParserTreeConstants.JJTPRIMARYSUFFIX);
192: primaryExpression.jjtAddChild(suffix, 1);
193:
194: ASTArguments args = new ASTArguments(
195: JavaParserTreeConstants.JJTARGUMENTS);
196: suffix.jjtAddChild(args, 0);
197:
198: ASTArgumentList argList = new ASTArgumentList(
199: JavaParserTreeConstants.JJTARGUMENTLIST);
200: args.jjtAddChild(argList, 0);
201:
202: int count = 0;
203: BuildExpression be = new BuildExpression();
204: Iterator iter = parameters.iterator();
205: if (iter != null) {
206: while (iter.hasNext()) {
207: VariableSummary next = (VariableSummary) iter.next();
208: ASTExpression expr = be.buildName(next.getName());
209: argList.jjtAddChild(expr, count);
210: count++;
211: }
212: }
213:
214: return primaryExpression;
215: }
216:
217: /**
218: * Builds a local variable declaration
219: *
220: *@param blockStatement the block statement we are inserting into
221: */
222: private void buildWithLocal(ASTBlockStatement blockStatement) {
223: ASTLocalVariableDeclaration statement = new ASTLocalVariableDeclaration(
224: JavaParserTreeConstants.JJTLOCALVARIABLEDECLARATION);
225: blockStatement.jjtAddChild(statement, 0);
226:
227: ASTType type = new ASTType(JavaParserTreeConstants.JJTTYPE);
228: statement.jjtAddChild(type, 0);
229:
230: TypeDeclSummary typeDecl = returnSummary.getTypeDecl();
231: if (typeDecl.getArrayCount() == 0 && typeDecl.isPrimitive()) {
232: ASTPrimitiveType primitiveType = new ASTPrimitiveType(
233: JavaParserTreeConstants.JJTPRIMITIVETYPE);
234: primitiveType.setName(typeDecl.getType());
235: type.jjtAddChild(primitiveType, 0);
236: } else {
237: ASTReferenceType reference = new ASTReferenceType(
238: JavaParserTreeConstants.JJTREFERENCETYPE);
239: type.jjtAddChild(reference, 0);
240: if (typeDecl.isPrimitive()) {
241: ASTPrimitiveType primitiveType = new ASTPrimitiveType(
242: JavaParserTreeConstants.JJTPRIMITIVETYPE);
243: primitiveType.setName(typeDecl.getType());
244: reference.jjtAddChild(primitiveType, 0);
245: } else {
246: ASTClassOrInterfaceType name = new ASTClassOrInterfaceType(
247: JavaParserTreeConstants.JJTCLASSORINTERFACETYPE);
248: name.fromString(typeDecl.getLongName());
249: reference.jjtAddChild(name, 0);
250: }
251: reference.setArrayCount(typeDecl.getArrayCount());
252: }
253:
254: ASTVariableDeclarator varDecl = new ASTVariableDeclarator(
255: JavaParserTreeConstants.JJTVARIABLEDECLARATORID);
256: statement.jjtAddChild(varDecl, 1);
257:
258: ASTVariableDeclaratorId varDeclID = new ASTVariableDeclaratorId(
259: JavaParserTreeConstants.JJTVARIABLEDECLARATORID);
260: varDeclID.setName(returnSummary.getName());
261: varDecl.jjtAddChild(varDeclID, 0);
262:
263: ASTVariableInitializer initializer = new ASTVariableInitializer(
264: JavaParserTreeConstants.JJTVARIABLEINITIALIZER);
265: varDecl.jjtAddChild(initializer, 1);
266:
267: buildMethodInvocation(initializer, 0);
268: }
269: }
|