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.Node;
055: import net.sourceforge.jrefactory.ast.ASTResultType;
056: import net.sourceforge.jrefactory.ast.ASTPrimitiveType;
057: import net.sourceforge.jrefactory.ast.ASTReferenceType;
058: import net.sourceforge.jrefactory.ast.ASTType;
059: import net.sourceforge.jrefactory.ast.ASTName;
060: import net.sourceforge.jrefactory.ast.ASTClassOrInterfaceType;
061: import org.acm.seguin.summary.query.GetTypeSummary;
062:
063: /**
064: * Summarize a type declaration. This object is meant to store the name and
065: * package of some type. This will be used in variable summaries, as well as
066: * for return values and exceptions.
067: *
068: *@author Chris Seguin
069: *@created May 11, 1999
070: */
071: public class TypeDeclSummary extends Summary {
072: // Instance Variables
073: private String typeName;
074: private String packageName;
075: private boolean primitive;
076: private int arrayCount;
077:
078: /**
079: * Creates a type declaration summary.
080: *
081: *@param parentSummary the parent summary
082: */
083: public TypeDeclSummary(Summary parentSummary) {
084: // Initialize the parent class
085: super (parentSummary);
086:
087: // Remember the type name
088: typeName = "void".intern();
089:
090: // The package name doesn't apply
091: packageName = null;
092:
093: // This is a primitive value
094: primitive = true;
095:
096: // This isn't an array (yet)
097: arrayCount = 0;
098: }
099:
100: /**
101: * Creates a type declaration summary from an ASTName object.
102: *
103: *@param parentSummary the parent summary
104: *@param nameNode the ASTName object
105: */
106: public TypeDeclSummary(Summary parentSummary, ASTName nameNode) {
107: // Initialize the parent class
108: super (parentSummary);
109: //System.out.print("TypeDeclSummary("+parentSummary+", "+ nameNode.getImage()+")");
110:
111: // Local Variables
112: int numChildren = nameNode.getNameSize();
113:
114: // Determine the name type
115: typeName = nameNode.getNamePart(numChildren - 1).intern();
116:
117: // Extract the package
118: if (numChildren > 1) {
119: StringBuffer buffer = new StringBuffer(nameNode
120: .getNamePart(0));
121: for (int ndx = 1; ndx < numChildren - 1; ndx++) {
122: buffer.append(".");
123: buffer.append(nameNode.getNamePart(ndx));
124: }
125: packageName = buffer.toString().intern();
126: } else {
127: packageName = null;
128: }
129:
130: // This isn't a primitive value
131: primitive = false;
132:
133: // This isn't an array (yet)
134: arrayCount = 0;
135: //System.out.println(" => typeName="+typeName);
136: }
137:
138: /**
139: * Creates a type declaration summary from an ASTReferenceType object.
140: *
141: *@param parentSummary the parent summary
142: *@param nameNode the ASTName object
143: */
144: public TypeDeclSummary(Summary parentSummary,
145: ASTReferenceType refNode) {
146: // Initialize the parent class
147: super (parentSummary);
148: //System.out.print("TypeDeclSummary(parentSummary, "+ refNode.getImage()+")");
149:
150: if (refNode.jjtGetFirstChild() instanceof ASTClassOrInterfaceType) {
151: ASTClassOrInterfaceType nameNode = (ASTClassOrInterfaceType) refNode
152: .jjtGetFirstChild();
153: // Local Variables
154: int numChildren = nameNode.getNameSize();
155:
156: // Determine the name type
157: typeName = nameNode.getNamePart(numChildren - 1).intern();
158:
159: // Extract the package
160: if (numChildren > 1) {
161: StringBuffer buffer = new StringBuffer(nameNode
162: .getNamePart(0));
163: for (int ndx = 1; ndx < numChildren - 1; ndx++) {
164: buffer.append(".");
165: buffer.append(nameNode.getNamePart(ndx));
166: }
167: packageName = buffer.toString().intern();
168: } else {
169: packageName = null;
170: }
171:
172: // This isn't a primitive value
173: primitive = false;
174:
175: // This isn't an array (yet)
176: arrayCount = 0;
177: } else {
178: ASTPrimitiveType primitiveType = (ASTPrimitiveType) refNode
179: .jjtGetFirstChild();
180: // Remember the type name
181: typeName = primitiveType.getName().intern();
182:
183: // The package name doesn't apply
184: packageName = null;
185:
186: // This is a primitive value
187: primitive = true;
188:
189: // This isn't an array (yet)
190: arrayCount = 0;
191: }
192: //System.out.println(" => typeName="+typeName);
193: }
194:
195: /**
196: * Creates a type declaration summary from an ASTPrimitiveType object.
197: *
198: *@param parentSummary the parent summary
199: *@param primitiveType the ASTPrimitiveType object
200: */
201: public TypeDeclSummary(Summary parentSummary,
202: ASTPrimitiveType primitiveType) {
203: // Initialize the parent class
204: super (parentSummary);
205:
206: // Remember the type name
207: typeName = primitiveType.getName().intern();
208:
209: // The package name doesn't apply
210: packageName = null;
211:
212: // This is a primitive value
213: primitive = true;
214:
215: // This isn't an array (yet)
216: arrayCount = 0;
217: }
218:
219: /**
220: * Creates a type declaration summary from an ASTName object.
221: *
222: *@param parentSummary the parent summary
223: *@param initPackage the package name
224: *@param initType the type name
225: */
226: public TypeDeclSummary(Summary parentSummary, String initPackage,
227: String initType) {
228: super (parentSummary);
229: //System.out.print("TypeDeclSummary("+parentSummary+", "+ initPackage+", "+initType+")");
230: typeName = initType;
231: packageName = initPackage;
232: primitive = false;
233: arrayCount = 0;
234: //System.out.println(" => typeName="+typeName);
235: }
236:
237: public TypeDeclSummary(Summary parentSummary, Class clazz) {
238: super (parentSummary);
239: //System.out.print("TypeDeclSummary(parentSummary, "+clazz+")");
240: if (clazz.isPrimitive()) {
241: if (!"void".equals(clazz.getName())) {
242: typeName = clazz.getName();
243: packageName = null;
244: primitive = true;
245: arrayCount = 0;
246: }
247: } else if (clazz.isArray()) {
248: arrayCount++;
249: Class ac = clazz.getComponentType();
250: while (ac.isArray()) {
251: arrayCount++;
252: ac = ac.getComponentType();
253: }
254: typeName = ac.getName();
255: if (ac.getPackage() == null) {
256: packageName = null;
257: } else {
258: packageName = ac.getPackage().getName();
259: }
260: primitive = false;
261: } else {
262: typeName = clazz.getName();
263: packageName = clazz.getPackage().getName();
264: primitive = false;
265: arrayCount = 0;
266: }
267: //System.out.println(" => typeName="+typeName);
268: }
269:
270: /**
271: * Set the array count
272: *
273: *@param count the number of "[]" pairs
274: */
275: public void setArrayCount(int count) {
276: if (count >= 0) {
277: arrayCount = count;
278: }
279: }
280:
281: /**
282: * Return the number of "[]" pairs
283: *
284: *@return the array count
285: */
286: public int getArrayCount() {
287: return arrayCount;
288: }
289:
290: /**
291: * Is this an array?
292: *
293: *@return true if this is an array
294: */
295: public boolean isArray() {
296: return (arrayCount > 0);
297: }
298:
299: /**
300: * Get the package name
301: *
302: *@return a string containing the name of the package
303: */
304: public String getPackage() {
305: return packageName;
306: }
307:
308: /**
309: * Get the name of the type
310: *
311: *@return a string containing the name of the type
312: */
313: public String getType() {
314: return typeName;
315: }
316:
317: /**
318: * Check if this is a primitive node
319: *
320: *@return true if this is a primitive value
321: */
322: public boolean isPrimitive() {
323: return primitive;
324: }
325:
326: /**
327: * Get long name
328: *
329: *@return the long version of the name (type + package)
330: */
331: public String getLongName() {
332: if (packageName == null) {
333: return typeName;
334: } else {
335: return packageName + "." + typeName;
336: }
337: }
338:
339: /**
340: * Convert this into a string
341: *
342: *@return a string representation of the type
343: */
344: public String toString() {
345: // Add the package and type names
346: if (!isArray()) {
347: return getLongName();
348: }
349:
350: // Start with the long name
351: StringBuffer buffer = new StringBuffer(getLongName());
352:
353: // Append the array counts
354: for (int ndx = 0; ndx < arrayCount; ndx++) {
355: buffer.append("[]");
356: }
357:
358: // Return the result
359: return buffer.toString();
360: }
361:
362: /**
363: * Provide method to visit a node
364: *
365: *@param visitor the visitor
366: *@param data the data for the visit
367: *@return some new data
368: */
369: public Object accept(SummaryVisitor visitor, Object data) {
370: return visitor.visit(this , data);
371: }
372:
373: /**
374: * Check to see if it is equal
375: *
376: *@param other the other item
377: *@return true if they are equal
378: */
379: public boolean equals(Object other) {
380: if (other instanceof TypeDeclSummary) {
381: TypeDeclSummary tds = (TypeDeclSummary) other;
382:
383: boolean sameType = ((typeName == null) && (tds.typeName == null))
384: || ((typeName != null) && typeName
385: .equals(tds.typeName));
386:
387: boolean samePackage = ((packageName == null) && (tds.packageName == null))
388: || ((packageName != null) && packageName
389: .equals(tds.packageName));
390:
391: boolean samePrimitive = (primitive == tds.primitive);
392:
393: boolean sameArray = (arrayCount == tds.arrayCount);
394:
395: return sameType && samePackage && samePrimitive
396: && sameArray;
397: }
398: return super .equals(other);
399: }
400:
401: /**
402: * Gets the same attribute of the TypeDeclSummary object
403: *
404: *@param other Description of the Parameter
405: *@return The same value
406: */
407: public boolean isSame(TypeDeclSummary other) {
408: if (primitive) {
409: if (!other.primitive) {
410: return false;
411: }
412:
413: return typeName.equals(other.typeName);
414: }
415:
416: TypeSummary type1 = GetTypeSummary.query(this );
417: TypeSummary type2 = GetTypeSummary.query(other);
418:
419: return (type1 == type2);
420: }
421:
422: /**
423: * Factory method. Creates a type decl summary object from the type node.
424: *
425: *@param parentSummary the parent summary
426: *@param typeNode the AST node containing the type
427: *@return the new node
428: */
429: public static TypeDeclSummary getTypeDeclSummary(
430: Summary parentSummary, ASTType typeNode) {
431: // Local Variables
432: TypeDeclSummary result;
433: Node typeChild = typeNode.jjtGetFirstChild();
434:
435: if (typeChild instanceof ASTPrimitiveType) {
436: result = new TypeDeclSummary(parentSummary,
437: (ASTPrimitiveType) typeChild);
438: } else {
439: ASTReferenceType reference = (ASTReferenceType) typeChild;
440: result = new TypeDeclSummary(parentSummary, reference);
441: result.setArrayCount(reference.getArrayCount());
442: }
443:
444: return result;
445: }
446:
447: /**
448: * Factory method. Creates a type decl summary object from the type node.
449: *
450: *@param parentSummary the parent summary
451: *@param typeNode the AST node containing the type
452: *@return the new node
453: */
454: public static TypeDeclSummary getTypeDeclSummary(
455: Summary parentSummary, ASTReferenceType typeNode) {
456: // Local Variables
457: TypeDeclSummary result = new TypeDeclSummary(parentSummary,
458: typeNode);
459: result.setArrayCount(typeNode.getArrayCount());
460:
461: return result;
462: }
463:
464: /**
465: * Factory method. Creates a type decl summary object from the type node.
466: *
467: *@param parentSummary the parent summary
468: *@param typeNode the AST node containing the result type
469: *@return the new node
470: */
471: public static TypeDeclSummary getTypeDeclSummary(
472: Summary parentSummary, ASTResultType typeNode) {
473: if (typeNode.hasAnyChildren()) {
474: return getTypeDeclSummary(parentSummary, (ASTType) typeNode
475: .jjtGetFirstChild());
476: } else {
477: return new TypeDeclSummary(parentSummary);
478: }
479: }
480:
481: /**
482: * Gets the name attribute of the TypeDeclSummary object
483: *
484: *@return The name value
485: */
486: public String getName() {
487: return toString();
488: }
489: }
|