001: /* ====================================================================
002: * The JRefactory License, Version 1.0
003: *
004: * Copyright (c) 2001 JRefactory. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by the
021: * JRefactory (http://www.sourceforge.org/projects/jrefactory)."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. The names "JRefactory" must not be used to endorse or promote
026: * products derived from this software without prior written
027: * permission. For written permission, please contact seguin@acm.org.
028: *
029: * 5. Products derived from this software may not be called "JRefactory",
030: * nor may "JRefactory" appear in their name, without prior written
031: * permission of Chris Seguin.
032: *
033: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
034: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
035: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
036: * DISCLAIMED. IN NO EVENT SHALL THE CHRIS SEGUIN OR
037: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
038: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
039: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
040: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
041: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
042: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
043: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
044: * SUCH DAMAGE.
045: * ====================================================================
046: *
047: * This software consists of voluntary contributions made by many
048: * individuals on behalf of JRefactory. For more information on
049: * JRefactory, please see
050: * <http://www.sourceforge.org/projects/jrefactory>.
051: */
052: package org.acm.seguin.summary;
053:
054: import net.sourceforge.jrefactory.ast.ModifierHolder;
055: import java.util.LinkedList;
056: import java.util.Iterator;
057: import org.acm.seguin.summary.query.GetTypeSummary;
058:
059: /**
060: * Stores information about a method
061: *
062: *@author Chris Seguin
063: *@created June 8, 1999
064: */
065: public class MethodSummary extends Summary {
066: // Instance Variables
067: private TypeDeclSummary returnType;
068: private String name;
069: private LinkedList parameterList = null;
070: private LinkedList exceptionList = null;
071: private LinkedList dependencyList = null;
072: private int statementCount = 0;
073: private int blockDepth = 0;
074: private int maxBlockDepth = 0;
075: private int declarationLine = 0;
076:
077: /**
078: * Construct a method from a method declaration node
079: *
080: *@param parent Description of Parameter
081: */
082: public MethodSummary(Summary parent) {
083: super (parent);
084: returnType = null;
085: }
086:
087: /**
088: * Set the name
089: *
090: *@param newName the name of the method
091: */
092: public void setName(String newName) {
093: name = newName.intern();
094: }
095:
096: /**
097: * Set the return
098: *
099: *@param type the return type. For a constructor, this value is null.
100: */
101: public void setReturnType(TypeDeclSummary type) {
102: returnType = type;
103: }
104:
105: /**
106: * Sets the DeclarationLine attribute of the MethodSummary object
107: *
108: *@param value The new DeclarationLine value
109: */
110: public void setDeclarationLine(int value) {
111: declarationLine = value;
112: }
113:
114: /**
115: * Return the name
116: *
117: *@return the name of the method
118: */
119: public String getName() {
120: return name;
121: }
122:
123: /**
124: * Get the return
125: *
126: *@return the return type. For a constructor, this value is null.
127: */
128: public TypeDeclSummary getReturnType() {
129: return returnType;
130: }
131:
132: /**
133: * Get a list of execeptions
134: *
135: *@return an iterator full of exceptions
136: */
137: public Iterator getExceptions() {
138: if (exceptionList == null) {
139: return null;
140: }
141:
142: return exceptionList.iterator();
143: }
144:
145: /**
146: * Get a list of parameters
147: *
148: *@return an iterator over the parameters
149: */
150: public Iterator getParameters() {
151: if (parameterList == null) {
152: return null;
153: }
154:
155: return parameterList.iterator();
156: }
157:
158: /**
159: * Return the number of parameters
160: *
161: *@return the count of parameters to this method
162: */
163: public int getParameterCount() {
164: if (parameterList == null) {
165: return 0;
166: }
167:
168: return parameterList.size();
169: }
170:
171: /**
172: * Return a list of dependencies. This list will contain variable summaries
173: * and type decl summaries.
174: *
175: *@return a list of dependencies.
176: */
177: public Iterator getDependencies() {
178: if (dependencyList == null) {
179: return null;
180: }
181:
182: return dependencyList.iterator();
183: }
184:
185: /**
186: * Get the statement count
187: *
188: *@return the number of statements in the method
189: */
190: public int getStatementCount() {
191: return statementCount;
192: }
193:
194: /**
195: * Gets the NearMiss attribute of the MethodSummary object
196: *
197: *@param other Description of Parameter
198: *@return The NearMiss value
199: */
200: public boolean isNearMiss(MethodSummary other) {
201: return checkSignature(other)
202: && !(checkReturn(other) && checkProtection(other));
203: }
204:
205: /**
206: * Determines if this is really a method or an initializer
207: *
208: *@return true if it is an initializer
209: */
210: public boolean isInitializer() {
211: return name.equals("***Initializer***");
212: }
213:
214: /**
215: * Returns the maximum levels of blocks in a certain code
216: *
217: *@return The MaxBlockDepth value
218: */
219: public int getMaxBlockDepth() {
220: return maxBlockDepth;
221: }
222:
223: /**
224: * Gets the DeclarationLine attribute of the MethodSummary object
225: *
226: *@return The DeclarationLine value
227: */
228: public int getDeclarationLine() {
229: return declarationLine;
230: }
231:
232: /**
233: * Determine if this is a constructor
234: *
235: *@return The Constructor value
236: */
237: public boolean isConstructor() {
238: return (returnType == null) && !isInitializer();
239: }
240:
241: /**
242: * Convert this to a string
243: *
244: *@return a string representation of this object
245: */
246: public String toString() {
247: // Start with method name
248: StringBuffer buffer = new StringBuffer(getName());
249: buffer.append("(");
250:
251: // Add parameters
252: Iterator iter = getParameters();
253: if (iter != null) {
254: while (iter.hasNext()) {
255: Object next = iter.next();
256: buffer.append(next.toString());
257: if (iter.hasNext()) {
258: buffer.append(", ");
259: }
260: }
261: }
262:
263: // Add return type
264: if (returnType == null) {
265: buffer.append(")");
266: } else {
267: buffer.append(") : ");
268: buffer.append(returnType.toString());
269: }
270:
271: // Return the result
272: return buffer.toString();
273: }
274:
275: /**
276: * Provide method to visit a node
277: *
278: *@param visitor the visitor
279: *@param data the data for the visit
280: *@return some new data
281: */
282: public Object accept(SummaryVisitor visitor, Object data) {
283: return visitor.visit(this , data);
284: }
285:
286: /**
287: * Increments the statement count
288: */
289: public void incrStatementCount() {
290: statementCount++;
291: }
292:
293: /**
294: * Description of the Method
295: *
296: *@param other Description of Parameter
297: *@return Description of the Returned Value
298: */
299: public boolean equals(Object other) {
300: if (other instanceof MethodSummary) {
301: MethodSummary temp = (MethodSummary) other;
302:
303: return checkSignature(temp) && checkReturn(temp)
304: && checkProtection(temp);
305: }
306: return false;
307: }
308:
309: /**
310: * Notes to the method summary that there is a block in the code
311: */
312: public void beginBlock() {
313: blockDepth++;
314: if (blockDepth > maxBlockDepth) {
315: maxBlockDepth = blockDepth;
316: }
317: }
318:
319: /**
320: * Notes to the method summary that the block in the code is complete
321: */
322: public void endBlock() {
323: blockDepth--;
324: }
325:
326: /**
327: * Determines if their signatures are the same
328: *
329: *@param other the oether method
330: *@return true if they have the same signatures
331: */
332: public boolean checkSignature(MethodSummary other) {
333: if (!name.equals(other.getName())) {
334: return false;
335: }
336:
337: Iterator params1 = getParameters();
338: Iterator params2 = other.getParameters();
339:
340: if (params1 == null) {
341: return (params2 == null);
342: }
343:
344: if (params2 == null) {
345: return false;
346: }
347:
348: while (params1.hasNext() && params2.hasNext()) {
349: ParameterSummary next1 = (ParameterSummary) params1.next();
350: ParameterSummary next2 = (ParameterSummary) params2.next();
351:
352: if (!next1.getTypeDecl().isSame(next2.getTypeDecl())) {
353: return false;
354: }
355: }
356:
357: return (params1.hasNext() == params2.hasNext());
358: }
359:
360: /**
361: * Add the formal parameters
362: *
363: *@param except Description of Parameter
364: */
365: protected void add(TypeDeclSummary except) {
366: if (except != null) {
367: if (exceptionList == null) {
368: initExceptionList();
369: }
370:
371: exceptionList.add(except);
372: }
373: }
374:
375: /**
376: * Add the formal parameters
377: *
378: *@param param the next formal parameter
379: */
380: protected void add(ParameterSummary param) {
381: if (param != null) {
382: if (parameterList == null) {
383: initParameterList();
384: }
385:
386: parameterList.add(param);
387: }
388: }
389:
390: /**
391: * Adds a variable dependency
392: *
393: *@param dependsOn a variable that this method is depending on - local
394: * variable or something in an anonymous class.
395: */
396: protected void addDependency(Summary dependsOn) {
397: if (dependsOn != null) {
398: if (dependencyList == null) {
399: initDependencyList();
400: }
401:
402: if (!dependencyList.contains(dependsOn)) {
403: dependencyList.add(dependsOn);
404: }
405: }
406: }
407:
408: /**
409: * Initialize the parameter list
410: */
411: private void initParameterList() {
412: parameterList = new LinkedList();
413: }
414:
415: /**
416: * Initialize the exception list
417: */
418: private void initExceptionList() {
419: exceptionList = new LinkedList();
420: }
421:
422: /**
423: * Initialize the dependency list
424: */
425: private void initDependencyList() {
426: dependencyList = new LinkedList();
427: }
428:
429: /**
430: * Determines if they have the same return value
431: *
432: *@param other Description of Parameter
433: *@return Description of the Returned Value
434: */
435: private boolean checkReturn(MethodSummary other) {
436: return getReturnType().isSame(other.getReturnType());
437: }
438:
439: /**
440: * Determines if they have the same protections
441: *
442: *@param other Description of Parameter
443: *@return Description of the Returned Value
444: */
445: private boolean checkProtection(MethodSummary other) {
446: //ModifierHolder mh1 = getModifiers();
447: //ModifierHolder mh2 = other.getModifiers();
448:
449: return (isPublic() == other.isPublic())
450: && (isProtected() == other.isProtected())
451: && (isPackage() == other.isPackage())
452: && (isPrivate() == other.isPrivate());
453: }
454: }
|