001: package org.acm.seguin.refactor.type;
002:
003: import net.sourceforge.jrefactory.parser.ChildrenVisitor;
004: import net.sourceforge.jrefactory.ast.ASTName;
005: import net.sourceforge.jrefactory.ast.ASTNameList;
006: import net.sourceforge.jrefactory.ast.ASTGenericNameList;
007: import net.sourceforge.jrefactory.ast.ASTUnmodifiedInterfaceDeclaration;
008: import net.sourceforge.jrefactory.ast.ASTUnmodifiedClassDeclaration;
009: import net.sourceforge.jrefactory.ast.ASTAllocationExpression;
010: import net.sourceforge.jrefactory.ast.ASTPrimaryPrefix;
011: import net.sourceforge.jrefactory.ast.ASTAnnotation;
012: import net.sourceforge.jrefactory.ast.ASTType;
013: import net.sourceforge.jrefactory.ast.ASTReferenceType;
014: import net.sourceforge.jrefactory.ast.ASTClassOrInterfaceType;
015: import net.sourceforge.jrefactory.ast.ASTTypeParameters;
016: import net.sourceforge.jrefactory.ast.ASTMethodDeclaration;
017: import net.sourceforge.jrefactory.ast.ASTConstructorDeclaration;
018: import net.sourceforge.jrefactory.ast.ASTArguments;
019: import net.sourceforge.jrefactory.ast.ASTPrimarySuffix;
020: import net.sourceforge.jrefactory.ast.ASTPrimaryExpression;
021: import net.sourceforge.jrefactory.ast.Node;
022: import org.acm.seguin.summary.TypeSummary;
023: import org.acm.seguin.summary.query.ContainsStatic;
024:
025: /**
026: * Scan through the abstract syntax tree and replace types with a new value.
027: *
028: *@author Chris Seguin
029: *@created September 10, 1999
030: */
031: public class RenameTypeVisitor extends ChildrenVisitor {
032: /**
033: * To visit a node
034: *
035: *@param node The node we are visiting
036: *@param data The rename type data
037: *@return The rename type data
038: */
039: public Object visit(ASTUnmodifiedClassDeclaration node, Object data) {
040: RenameTypeData rtd = (RenameTypeData) data;
041: if (rtd.getOld().getNameSize() == 1) {
042: String oldName = rtd.getOld().getName();
043: if (oldName.equals(node.getName())) {
044: String name = rtd.getNew().getName();
045: node.setName(name);
046: }
047: }
048:
049: int index = 0;
050: if (node.jjtGetChild(index) instanceof ASTClassOrInterfaceType) {
051: if (node.jjtGetChild(index).equals(rtd.getOld())) {
052: node.jjtAddChild(rtd.getNew(), index);
053: }
054: index++;
055: }
056:
057: if (node.jjtGetChild(index) instanceof ASTGenericNameList) {
058: ASTGenericNameList namelist = (ASTGenericNameList) node
059: .jjtGetChild(index);
060: for (int ndx = 0; ndx < namelist.jjtGetNumChildren(); ndx++) {
061: if (namelist.jjtGetChild(ndx).equals(rtd.getOld())) {
062: namelist.jjtAddChild(rtd.getNew(), ndx);
063: }
064: }
065: }
066: return node.childrenAccept(this , data);
067: }
068:
069: /**
070: * To visit a node
071: *
072: *@param node The node we are visiting
073: *@param data The rename type data
074: *@return The rename type data
075: */
076: public Object visit(ASTUnmodifiedInterfaceDeclaration node,
077: Object data) {
078: RenameTypeData rtd = (RenameTypeData) data;
079: if (rtd.getOld().getNameSize() == 1) {
080: String oldName = rtd.getOld().getName();
081: if (oldName.equals(node.getName())) {
082: String name = rtd.getNew().getName();
083: node.setName(name);
084: }
085: }
086:
087: int index = 0;
088: if (node.jjtGetChild(index) instanceof ASTGenericNameList) {
089: ASTGenericNameList namelist = (ASTGenericNameList) node
090: .jjtGetChild(index);
091: for (int ndx = 0; ndx < namelist.jjtGetNumChildren(); ndx++) {
092: if (namelist.jjtGetChild(ndx).equals(rtd.getOld())) {
093: namelist.jjtAddChild(rtd.getNew(), ndx);
094: }
095: }
096: }
097:
098: return node.childrenAccept(this , data);
099: }
100:
101: /**
102: * To visit a node
103: *
104: *@param node The node we are visiting
105: *@param data The rename type data
106: *@return The rename type data
107: */
108: public Object visit(ASTConstructorDeclaration node, Object data) {
109: RenameTypeData rtd = (RenameTypeData) data;
110: if (rtd.getOld().getNameSize() == 1) {
111: String oldName = rtd.getOld().getName();
112: if (oldName.equals(node.getName())) {
113: String name = rtd.getNew().getName();
114: node.setName(name);
115: }
116: }
117:
118: int childNo = node.skipAnnotationsAndTypeParameters();
119: if ((node.jjtGetNumChildren() >= childNo + 2)
120: && (node.jjtGetChild(childNo + 1) instanceof ASTNameList)) {
121: ASTNameList nameList = (ASTNameList) node
122: .jjtGetChild(childNo + 1);
123: processExceptions(nameList, rtd);
124: }
125:
126: return node.childrenAccept(this , data);
127: }
128:
129: /**
130: * Description of the Method
131: *
132: *@param node Description of Parameter
133: *@param data Description of Parameter
134: *@return Description of the Returned Value
135: */
136: public Object visit(ASTMethodDeclaration node, Object data) {
137: int childNo = node.skipAnnotationsAndTypeParameters();
138: if ((node.jjtGetNumChildren() >= childNo + 3)
139: && (node.jjtGetChild(childNo + 2) instanceof ASTNameList)) {
140: ASTNameList nameList = (ASTNameList) node
141: .jjtGetChild(childNo + 2);
142: RenameTypeData rtd = (RenameTypeData) data;
143: processExceptions(nameList, rtd);
144: }
145:
146: return super .visit(node, data);
147: }
148:
149: /**
150: * To visit a node
151: *
152: *@param node The node we are visiting
153: *@param data The rename type data
154: *@return The rename type data
155: */
156: public Object visit(ASTType node, Object data) {
157: if (node.jjtGetNumChildren() == 0) {
158: return data;
159: }
160:
161: //if (node.jjtGetFirstChild() instanceof ASTName) {
162: // ASTName child = (ASTName) node.jjtGetFirstChild();
163: //
164: // RenameTypeData rtd = (RenameTypeData) data;
165: // if (child.equals(rtd.getOld())) {
166: // node.jjtAddChild(rtd.getNew(), 0);
167: // }
168: // else if (child.startsWith(rtd.getOld())) {
169: // node.jjtAddChild(child.changeStartingPart(rtd.getOld(), rtd.getNew()), 0);
170: // }
171: //}
172:
173: return node.childrenAccept(this , data);
174: }
175:
176: /**
177: * To visit a node
178: *
179: *@param node The node we are visiting
180: *@param data The rename type data
181: *@return The rename type data
182: */
183: public Object visit(ASTReferenceType node, Object data) {
184: if (node.jjtGetNumChildren() == 0) {
185: return data;
186: }
187:
188: if (node.jjtGetFirstChild() instanceof ASTClassOrInterfaceType) {
189: ASTClassOrInterfaceType child = (ASTClassOrInterfaceType) node
190: .jjtGetFirstChild();
191:
192: RenameTypeData rtd = (RenameTypeData) data;
193: if (child.equals(rtd.getOld())) {
194: node.jjtAddChild(rtd.getNew(), 0);
195: } else if (child.startsWith(rtd.getOld())) {
196: node.jjtAddChild(child.changeStartingPart(rtd.getOld(),
197: rtd.getNew()), 0);
198: }
199: }
200:
201: return node.childrenAccept(this , data);
202: }
203:
204: /**
205: * To visit a node
206: *
207: *@param node The node we are visiting
208: *@param data The rename type data
209: *@return The rename type data
210: */
211: public Object visit(ASTPrimaryExpression node, Object data) {
212: ASTPrimaryPrefix prefix = (ASTPrimaryPrefix) node
213: .jjtGetFirstChild();
214:
215: if (prefix.jjtGetNumChildren() == 0) {
216: return data;
217: }
218:
219: if (prefix.jjtGetFirstChild() instanceof ASTName) {
220: ASTName child = (ASTName) prefix.jjtGetFirstChild();
221:
222: RenameTypeData rtd = (RenameTypeData) data;
223: if (child.equals(rtd.getOld())) {
224: prefix.jjtAddChild(rtd.getNew(), 0);
225: } else if (child.startsWith(rtd.getOld())) {
226: if (isStatic(rtd, child, isMethod(node))) {
227: ASTName name = child.changeStartingPart(rtd
228: .getOld(), rtd.getNew());
229: prefix.jjtAddChild(name, 0);
230: }
231: }
232: }
233:
234: return node.childrenAccept(this , data);
235: }
236:
237: /**
238: * To visit a node
239: *
240: *@param node The node we are visiting
241: *@param data The rename type data
242: *@return The rename type data
243: */
244: public Object visit(ASTAllocationExpression node, Object data) {
245: if (node.jjtGetNumChildren() == 0) {
246: return data;
247: }
248:
249: if (node.jjtGetFirstChild() instanceof ASTClassOrInterfaceType) {
250: ASTClassOrInterfaceType child = (ASTClassOrInterfaceType) node
251: .jjtGetFirstChild();
252:
253: RenameTypeData rtd = (RenameTypeData) data;
254: if (child.equals(rtd.getOld())) {
255: node.jjtAddChild(rtd.getNew(), 0);
256: } else if (child.startsWith(rtd.getOld())) {
257: node.jjtAddChild(child.changeStartingPart(rtd.getOld(),
258: rtd.getNew()), 0);
259: }
260: }
261:
262: return node.childrenAccept(this , data);
263: }
264:
265: /**
266: * Determines if the node is a method invocation
267: *
268: *@param node the node in question
269: *@return true when we are looking at a method
270: */
271: private boolean isMethod(ASTPrimaryExpression node) {
272: if (node.jjtGetNumChildren() <= 1) {
273: return false;
274: }
275:
276: ASTPrimarySuffix suffix = (ASTPrimarySuffix) node
277: .jjtGetChild(1);
278: return (suffix.jjtGetFirstChild() instanceof ASTArguments);
279: }
280:
281: /**
282: * Gets the Static attribute of the RenameTypeVisitor object
283: *
284: *@param data Description of Parameter
285: *@param name Description of Parameter
286: *@param isMethod Description of Parameter
287: *@return The Static value
288: */
289: private boolean isStatic(RenameTypeData data, ASTName name,
290: boolean isMethod) {
291: int last = name.getNameSize();
292: String value = name.getNamePart(last - 1);
293: TypeSummary typeSummary = data.getTypeSummary();
294: return ContainsStatic.query(typeSummary, value, isMethod);
295: }
296:
297: /**
298: * Description of the Method
299: *
300: *@param nameList Description of Parameter
301: *@param rtd Description of Parameter
302: */
303: private void processExceptions(ASTNameList nameList,
304: RenameTypeData rtd) {
305: int last = nameList.jjtGetNumChildren();
306:
307: for (int ndx = 0; ndx < last; ndx++) {
308: ASTName next = (ASTName) nameList.jjtGetChild(ndx);
309:
310: if (next.equals(rtd.getOld())) {
311: nameList.jjtAddChild(rtd.getNew(), ndx);
312: } else if (next.startsWith(rtd.getOld())) {
313: nameList.jjtAddChild(next.changeStartingPart(rtd
314: .getOld(), rtd.getNew()), ndx);
315: }
316: }
317: }
318: }
|