0001: /* ====================================================================
0002: * The JRefactory License, Version 1.0
0003: *
0004: * Copyright (c) 2001 JRefactory. All rights reserved.
0005: *
0006: * Redistribution and use in source and binary forms, with or without
0007: * modification, are permitted provided that the following conditions
0008: * are met:
0009: *
0010: * 1. Redistributions of source code must retain the above copyright
0011: * notice, this list of conditions and the following disclaimer.
0012: *
0013: * 2. Redistributions in binary form must reproduce the above copyright
0014: * notice, this list of conditions and the following disclaimer in
0015: * the documentation and/or other materials provided with the
0016: * distribution.
0017: *
0018: * 3. The end-user documentation included with the redistribution,
0019: * if any, must include the following acknowledgment:
0020: * "This product includes software developed by the
0021: * JRefactory (http://www.sourceforge.org/projects/jrefactory)."
0022: * Alternately, this acknowledgment may appear in the software itself,
0023: * if and wherever such third-party acknowledgments normally appear.
0024: *
0025: * 4. The names "JRefactory" must not be used to endorse or promote
0026: * products derived from this software without prior written
0027: * permission. For written permission, please contact seguin@acm.org.
0028: *
0029: * 5. Products derived from this software may not be called "JRefactory",
0030: * nor may "JRefactory" appear in their name, without prior written
0031: * permission of Chris Seguin.
0032: *
0033: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0034: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0035: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0036: * DISCLAIMED. IN NO EVENT SHALL THE CHRIS SEGUIN OR
0037: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0038: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0039: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0040: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0041: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0042: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0043: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0044: * SUCH DAMAGE.
0045: * ====================================================================
0046: *
0047: * This software consists of voluntary contributions made by many
0048: * individuals on behalf of JRefactory. For more information on
0049: * JRefactory, please see
0050: * <http://www.sourceforge.org/projects/jrefactory>.
0051: */
0052: package org.acm.seguin.summary;
0053:
0054: import net.sourceforge.jrefactory.ast.Node;
0055: import net.sourceforge.jrefactory.ast.SimpleNode;
0056: import net.sourceforge.jrefactory.ast.ASTInterfaceBody;
0057: import net.sourceforge.jrefactory.ast.ASTTryStatement;
0058: import net.sourceforge.jrefactory.ast.ASTSynchronizedStatement;
0059: import net.sourceforge.jrefactory.ast.ASTThrowStatement;
0060: import net.sourceforge.jrefactory.ast.ASTReturnStatement;
0061: import net.sourceforge.jrefactory.ast.ASTForUpdate;
0062: import net.sourceforge.jrefactory.ast.ASTStatementExpressionList;
0063: import net.sourceforge.jrefactory.ast.ASTForInit;
0064: import net.sourceforge.jrefactory.ast.ASTForStatement;
0065: import net.sourceforge.jrefactory.ast.ASTDoStatement;
0066: import net.sourceforge.jrefactory.ast.ASTWhileStatement;
0067: import net.sourceforge.jrefactory.ast.ASTIfStatement;
0068: import net.sourceforge.jrefactory.ast.ASTSwitchLabel;
0069: import net.sourceforge.jrefactory.ast.ASTSwitchStatement;
0070: import net.sourceforge.jrefactory.ast.ASTEmptyStatement;
0071: import net.sourceforge.jrefactory.ast.ASTBlockStatement;
0072: import net.sourceforge.jrefactory.ast.ASTBlock;
0073: import net.sourceforge.jrefactory.ast.ASTStatement;
0074: import net.sourceforge.jrefactory.ast.ASTAllocationExpression;
0075: import net.sourceforge.jrefactory.ast.ASTArgumentList;
0076: import net.sourceforge.jrefactory.ast.ASTArguments;
0077: import net.sourceforge.jrefactory.ast.ASTNullLiteral;
0078: import net.sourceforge.jrefactory.ast.ASTPrimaryExpression;
0079: import net.sourceforge.jrefactory.ast.ASTCastExpression;
0080: import net.sourceforge.jrefactory.ast.ASTPreDecrementExpression;
0081: import net.sourceforge.jrefactory.ast.ASTPreIncrementExpression;
0082: import net.sourceforge.jrefactory.ast.ASTInstanceOfExpression;
0083: import net.sourceforge.jrefactory.ast.ASTAndExpression;
0084: import net.sourceforge.jrefactory.ast.ASTExclusiveOrExpression;
0085: import net.sourceforge.jrefactory.ast.ASTInclusiveOrExpression;
0086: import net.sourceforge.jrefactory.ast.ASTConditionalAndExpression;
0087: import net.sourceforge.jrefactory.ast.ASTConditionalOrExpression;
0088: import net.sourceforge.jrefactory.ast.ASTConditionalExpression;
0089: import net.sourceforge.jrefactory.ast.ASTExpression;
0090: import net.sourceforge.jrefactory.ast.ASTNameList;
0091: import net.sourceforge.jrefactory.ast.ASTResultType;
0092: import net.sourceforge.jrefactory.ast.ASTFormalParameters;
0093: import net.sourceforge.jrefactory.ast.ASTVariableInitializer;
0094: import net.sourceforge.jrefactory.ast.ASTVariableDeclarator;
0095: import net.sourceforge.jrefactory.ast.ASTInterfaceMemberDeclaration;
0096: import net.sourceforge.jrefactory.ast.ASTClassBodyDeclaration;
0097: import net.sourceforge.jrefactory.ast.ASTClassBody;
0098: import net.sourceforge.jrefactory.ast.ASTTypeDeclaration;
0099: import net.sourceforge.jrefactory.ast.ASTCompilationUnit;
0100: import net.sourceforge.jrefactory.ast.ASTPackageDeclaration;
0101: import net.sourceforge.jrefactory.ast.ASTArrayInitializer;
0102: import net.sourceforge.jrefactory.ast.ASTContinueStatement;
0103: import net.sourceforge.jrefactory.ast.ASTBreakStatement;
0104: import net.sourceforge.jrefactory.ast.ASTStatementExpression;
0105: import net.sourceforge.jrefactory.ast.ASTLocalVariableDeclaration;
0106: import net.sourceforge.jrefactory.ast.ASTBooleanLiteral;
0107: import net.sourceforge.jrefactory.ast.ASTPrimarySuffix;
0108: import net.sourceforge.jrefactory.ast.ASTPrimaryPrefix;
0109: import net.sourceforge.jrefactory.ast.ASTPostfixExpression;
0110: import net.sourceforge.jrefactory.ast.ASTUnaryExpressionNotPlusMinus;
0111: import net.sourceforge.jrefactory.ast.ASTUnaryExpression;
0112: import net.sourceforge.jrefactory.ast.ASTMultiplicativeExpression;
0113: import net.sourceforge.jrefactory.ast.ASTAdditiveExpression;
0114: import net.sourceforge.jrefactory.ast.ASTShiftExpression;
0115: import net.sourceforge.jrefactory.ast.ASTRelationalExpression;
0116: import net.sourceforge.jrefactory.ast.ASTEqualityExpression;
0117: import net.sourceforge.jrefactory.ast.ASTAssignmentOperator;
0118: import net.sourceforge.jrefactory.ast.ASTPrimitiveType;
0119: import net.sourceforge.jrefactory.ast.ASTType;
0120: import net.sourceforge.jrefactory.ast.ASTInitializer;
0121: import net.sourceforge.jrefactory.ast.ASTExplicitConstructorInvocation;
0122: import net.sourceforge.jrefactory.ast.ASTFormalParameter;
0123: import net.sourceforge.jrefactory.ast.ASTFieldDeclaration;
0124: import net.sourceforge.jrefactory.ast.ASTNestedInterfaceDeclaration;
0125: import net.sourceforge.jrefactory.ast.ASTMethodDeclaration;
0126: import net.sourceforge.jrefactory.ast.ASTInterfaceDeclaration;
0127: import net.sourceforge.jrefactory.ast.ASTNestedClassDeclaration;
0128: import net.sourceforge.jrefactory.ast.ASTVariableDeclaratorId;
0129: import net.sourceforge.jrefactory.ast.ASTImportDeclaration;
0130: import net.sourceforge.jrefactory.ast.ASTConstructorDeclaration;
0131: import net.sourceforge.jrefactory.ast.ASTUnmodifiedInterfaceDeclaration;
0132: import net.sourceforge.jrefactory.ast.ASTUnmodifiedClassDeclaration;
0133: import net.sourceforge.jrefactory.ast.ASTLiteral;
0134: import net.sourceforge.jrefactory.ast.ASTClassDeclaration;
0135: import net.sourceforge.jrefactory.ast.ASTMethodDeclarator;
0136: import net.sourceforge.jrefactory.ast.ASTLabeledStatement;
0137: import net.sourceforge.jrefactory.ast.ASTArrayDimsAndInits;
0138: import net.sourceforge.jrefactory.ast.ASTName;
0139: import java.io.*;
0140: import java.util.Enumeration;
0141:
0142: import net.sourceforge.jrefactory.ast.ASTTypeParameterList;
0143: import net.sourceforge.jrefactory.ast.ASTTypeParameter;
0144: import net.sourceforge.jrefactory.ast.ASTTypeArguments;
0145: import net.sourceforge.jrefactory.ast.ASTReferenceTypeList;
0146: import net.sourceforge.jrefactory.ast.ASTReferenceType;
0147: import net.sourceforge.jrefactory.ast.ASTClassOrInterfaceType;
0148: import net.sourceforge.jrefactory.ast.ASTTypeParameters;
0149: import net.sourceforge.jrefactory.ast.ASTGenericNameList;
0150: import net.sourceforge.jrefactory.ast.ASTEnumDeclaration;
0151: import net.sourceforge.jrefactory.ast.ASTEnumElement;
0152: import net.sourceforge.jrefactory.ast.ASTIdentifier;
0153:
0154: /**
0155: * This object visits an abstract syntax tree with the purpose of gathering
0156: * summary information.
0157: * @FIXME: add Enum, Generics, etc.
0158: *@author Chris Seguin
0159: *@author Mike Atkinson
0160: *@created May 30, 1999
0161: */
0162: public class SummaryLoadVisitor extends LineCountVisitor {
0163: private int anonCount = 1;
0164:
0165: /**
0166: * Visits an enum declaration
0167: *
0168: *@param node the node we are visiting
0169: *@param data the state we are in
0170: *@return nothing of interest
0171: */
0172: public Object visit(ASTEnumDeclaration node, Object data) {
0173: // Convert the data into the correct form
0174: SummaryLoaderState state = (SummaryLoaderState) data;
0175:
0176: if (state.getCode() == SummaryLoaderState.IGNORE) {
0177: return super .visit(node, data);
0178: }
0179:
0180: int start = getLineCount() + 1;
0181:
0182: int oldCode = state.getCode();
0183:
0184: state.setCode(SummaryLoaderState.LOAD_CLASSBODY);
0185:
0186: super .visit(node, data);
0187:
0188: state.setCode(oldCode);
0189:
0190: return data;
0191: }
0192:
0193: /**
0194: * Visits a package declaration
0195: *
0196: *@param node the node we are visiting
0197: *@param data the state we are in
0198: *@return nothing of interest
0199: */
0200: public Object visit(ASTPackageDeclaration node, Object data) {
0201: // Convert the data into the correct form
0202: SummaryLoaderState state = (SummaryLoaderState) data;
0203:
0204: // Get the name
0205: ASTName name = (ASTName) node.jjtGetFirstChild();
0206:
0207: // Lookup the summary
0208: PackageSummary packageSummary = PackageSummary
0209: .getPackageSummary(name.getName());
0210:
0211: // Create the file summary
0212: if (state.getCode() == SummaryLoaderState.INITIALIZE) {
0213: state.startSummary(new FileSummary(packageSummary, state
0214: .getFile()));
0215: state.setCode(SummaryLoaderState.LOAD_FILE);
0216: }
0217:
0218: return super .visit(node, data);
0219: }
0220:
0221: /**
0222: * Visits an import statement
0223: *
0224: *@param node the node we are visiting
0225: *@param data the state we are in
0226: *@return nothing of interest
0227: */
0228: public Object visit(ASTImportDeclaration node, Object data) {
0229: // Convert the data into the correct form
0230: SummaryLoaderState state = (SummaryLoaderState) data;
0231:
0232: // Get the current file summary - add the import
0233: FileSummary current = (FileSummary) state.getCurrentSummary();
0234: ImportSummary importSummary = new ImportSummary(current, node);
0235: current.add(importSummary);
0236:
0237: int start = getLineCount() + 1;
0238:
0239: // Done
0240: Object obj = super .visit(node, data);
0241:
0242: int end = getLineCount();
0243: importSummary.setStartLine(start);
0244: importSummary.setEndLine(end);
0245:
0246: return obj;
0247: }
0248:
0249: /**
0250: * Visits a type declaration
0251: *
0252: *@param node the node we are visiting
0253: *@param data the state we are in
0254: *@return nothing of interest
0255: */
0256: public Object visit(ASTTypeDeclaration node, Object data) {
0257: // Convert the data into the correct form
0258: SummaryLoaderState state = (SummaryLoaderState) data;
0259:
0260: if (state.getCode() == SummaryLoaderState.IGNORE) {
0261: return super .visit(node, data);
0262: }
0263:
0264: int start = getLineCount() + 1;
0265:
0266: // Get the current file summary
0267: FileSummary current = (FileSummary) state.getCurrentSummary();
0268:
0269: // Create Type Summary
0270: TypeSummary next = new TypeSummary(current, node);
0271: current.add(next);
0272:
0273: // Set the next type summary as the current summary
0274: state.startSummary(next);
0275: int oldCode = state.getCode();
0276: state.setCode(SummaryLoaderState.LOAD_TYPE);
0277:
0278: // Traverse Children
0279: super .visit(node, data);
0280:
0281: // Back to loading the file
0282: state.finishSummary();
0283: state.setCode(oldCode);
0284:
0285: int end = getLineCount();
0286: next.setStartLine(start);
0287: next.setEndLine(end);
0288:
0289: // Done
0290: return data;
0291: }
0292:
0293: /**
0294: * Visits a class declaration
0295: *
0296: *@param node the node we are visiting
0297: *@param data the state we are in
0298: *@return nothing of interest
0299: */
0300: public Object visit(ASTClassDeclaration node, Object data) {
0301: // Convert the data into the correct form
0302: SummaryLoaderState state = (SummaryLoaderState) data;
0303:
0304: if (state.getCode() == SummaryLoaderState.IGNORE) {
0305: return super .visit(node, data);
0306: }
0307:
0308: int start = getLineCount() + 1;
0309:
0310: // Get the current type summary
0311: TypeSummary current = (TypeSummary) state.getCurrentSummary();
0312:
0313: // Save the modifiers
0314: current.copyModifiers(node);
0315:
0316: // Traverse the children
0317: return super .visit(node, data);
0318: }
0319:
0320: /**
0321: * Visits a class declaration
0322: *
0323: *@param node the node we are visiting
0324: *@param data the state we are in
0325: *@return nothing of interest
0326: */
0327: public Object visit(ASTUnmodifiedClassDeclaration node, Object data) {
0328: // Convert the data into the correct form
0329: SummaryLoaderState state = (SummaryLoaderState) data;
0330:
0331: if (state.getCode() == SummaryLoaderState.IGNORE) {
0332: return super .visit(node, data);
0333: }
0334:
0335: int start = getLineCount() + 1;
0336:
0337: int code = state.getCode();
0338:
0339: // Get the current type summary
0340: Summary currentSummary = state.getCurrentSummary();
0341: TypeSummary current;
0342:
0343: if (currentSummary instanceof TypeSummary) {
0344: current = (TypeSummary) currentSummary;
0345: } else {
0346: // Create Type Summary
0347: current = new TypeSummary(currentSummary, node);
0348: ((MethodSummary) currentSummary).addDependency(current);
0349: state.startSummary(current);
0350: }
0351:
0352: // Remember the name
0353: current.setName(node.getName().intern());
0354:
0355: // Iterate through the children
0356: // Add the class body
0357: state.setCode(SummaryLoaderState.LOAD_TYPE);
0358: super .visit(node, data);
0359:
0360: state.setCode(code);
0361:
0362: // This is a class
0363: current.setInterface(false);
0364:
0365: if (currentSummary instanceof TypeSummary) {
0366: } else {
0367: state.finishSummary();
0368: }
0369:
0370: return data;
0371: }
0372:
0373: /**
0374: * Visit the items in the class body
0375: *
0376: *@param node the node we are visiting
0377: *@param data the state we are in
0378: *@return nothing of interest
0379: */
0380: public Object visit(ASTClassBody node, Object data) {
0381: // Convert the data into the correct form
0382: SummaryLoaderState state = (SummaryLoaderState) data;
0383:
0384: if (state.getCode() == SummaryLoaderState.IGNORE) {
0385: return super .visit(node, data);
0386: }
0387:
0388: int start = getLineCount() + 1;
0389:
0390: int oldCode = state.getCode();
0391:
0392: state.setCode(SummaryLoaderState.LOAD_CLASSBODY);
0393:
0394: super .visit(node, data);
0395:
0396: state.setCode(oldCode);
0397:
0398: return data;
0399: }
0400:
0401: /**
0402: * Visit a class that is nested in another class
0403: *
0404: *@param node the node we are visiting
0405: *@param data the state we are in
0406: *@return nothing of interest
0407: */
0408: public Object visit(ASTNestedClassDeclaration node, Object data) {
0409: // Convert the data into the correct form
0410: SummaryLoaderState state = (SummaryLoaderState) data;
0411:
0412: if (state.getCode() == SummaryLoaderState.IGNORE) {
0413: return super .visit(node, data);
0414: }
0415:
0416: int start = getLineCount() + 1;
0417:
0418: int code = state.getCode();
0419:
0420: // Get the current type summary
0421: Summary current = state.getCurrentSummary();
0422:
0423: TypeSummary nested = new TypeSummary(current, node);
0424:
0425: // Add it in
0426: if (current instanceof TypeSummary) {
0427: ((TypeSummary) current).add(nested);
0428: } else {
0429: ((MethodSummary) current).addDependency(nested);
0430: }
0431:
0432: // Continue deeper
0433: state.startSummary(nested);
0434: state.setCode(SummaryLoaderState.LOAD_TYPE);
0435:
0436: // Save the modifiers
0437: nested.copyModifiers(node);
0438:
0439: // Traverse the children
0440: super .visit(node, data);
0441:
0442: int end = getLineCount();
0443: nested.setStartLine(start);
0444: nested.setEndLine(end);
0445:
0446: // Finish the summary
0447: state.finishSummary();
0448: state.setCode(code);
0449:
0450: // Return something
0451: return data;
0452: }
0453:
0454: /**
0455: * Visit an interface declaration
0456: *
0457: *@param node the node we are visiting
0458: *@param data the state we are in
0459: *@return nothing of interest
0460: */
0461: public Object visit(ASTInterfaceDeclaration node, Object data) {
0462: // Convert the data into the correct form
0463: SummaryLoaderState state = (SummaryLoaderState) data;
0464:
0465: if (state.getCode() == SummaryLoaderState.IGNORE) {
0466: return super .visit(node, data);
0467: }
0468:
0469: int start = getLineCount() + 1;
0470:
0471: // Get the current type summary
0472: TypeSummary current = (TypeSummary) state.getCurrentSummary();
0473:
0474: // Save the modifiers
0475: current.copyModifiers(node);
0476:
0477: // Traverse the children
0478: return super .visit(node, data);
0479: }
0480:
0481: /**
0482: * Visit an interface that is nested in a class
0483: *
0484: *@param node the node we are visiting
0485: *@param data the state we are in
0486: *@return nothing of interest
0487: */
0488: public Object visit(ASTNestedInterfaceDeclaration node, Object data) {
0489: // Convert the data into the correct form
0490: SummaryLoaderState state = (SummaryLoaderState) data;
0491:
0492: if (state.getCode() == SummaryLoaderState.IGNORE) {
0493: return super .visit(node, data);
0494: }
0495:
0496: int start = getLineCount() + 1;
0497:
0498: int code = state.getCode();
0499:
0500: // Get the current type summary
0501: Summary current = state.getCurrentSummary();
0502:
0503: // Create the new nested type summary
0504: TypeSummary nested = new TypeSummary(current, node);
0505:
0506: // Add it in
0507: if (current instanceof TypeSummary) {
0508: ((TypeSummary) current).add(nested);
0509: } else {
0510: ((MethodSummary) current).addDependency(nested);
0511: }
0512:
0513: // Continue deeper
0514: state.startSummary(nested);
0515: state.setCode(SummaryLoaderState.LOAD_TYPE);
0516:
0517: // Save the modifiers
0518: nested.copyModifiers(node);
0519:
0520: // Traverse the children
0521: super .visit(node, data);
0522:
0523: int end = getLineCount();
0524: nested.setStartLine(start);
0525: nested.setEndLine(end);
0526:
0527: // Finish the summary
0528: state.finishSummary();
0529: state.setCode(code);
0530:
0531: // Return something
0532: return data;
0533: }
0534:
0535: /**
0536: * Visit an interface
0537: *
0538: *@param node the node we are visiting
0539: *@param data the state we are in
0540: *@return nothing of interest
0541: */
0542: public Object visit(ASTUnmodifiedInterfaceDeclaration node,
0543: Object data) {
0544: // Convert the data into the correct form
0545: SummaryLoaderState state = (SummaryLoaderState) data;
0546:
0547: if (state.getCode() == SummaryLoaderState.IGNORE) {
0548: return super .visit(node, data);
0549: }
0550:
0551: int start = getLineCount() + 1;
0552:
0553: int code = state.getCode();
0554:
0555: // Get the current type summary
0556: Summary currentSummary = state.getCurrentSummary();
0557: TypeSummary current;
0558:
0559: if (currentSummary instanceof TypeSummary) {
0560: current = (TypeSummary) currentSummary;
0561: } else {
0562: // Create Type Summary
0563: current = new TypeSummary(currentSummary, node);
0564: ((MethodSummary) currentSummary).addDependency(current);
0565: state.startSummary(current);
0566: }
0567:
0568: // Remember the name
0569: current.setName(node.getName().intern());
0570:
0571: // Iterate through the children of the interface
0572: state.setCode(SummaryLoaderState.LOAD_TYPE);
0573:
0574: super .visit(node, data);
0575:
0576: state.setCode(code);
0577:
0578: // This is an interface
0579: current.setInterface(true);
0580:
0581: if (currentSummary instanceof TypeSummary) {
0582: } else {
0583: state.finishSummary();
0584: }
0585:
0586: // Done
0587: return data;
0588: }
0589:
0590: /**
0591: * Visit the body of an interface
0592: *
0593: *@param node the node we are visiting
0594: *@param data the state we are in
0595: *@return nothing of interest
0596: */
0597: public Object visit(ASTInterfaceBody node, Object data) {
0598: // Convert the data into the correct form
0599: SummaryLoaderState state = (SummaryLoaderState) data;
0600:
0601: if (state.getCode() == SummaryLoaderState.IGNORE) {
0602: return super .visit(node, data);
0603: }
0604:
0605: int start = getLineCount() + 1;
0606:
0607: int oldCode = state.getCode();
0608:
0609: state.setCode(SummaryLoaderState.LOAD_CLASSBODY);
0610:
0611: super .visit(node, data);
0612:
0613: state.setCode(oldCode);
0614:
0615: return data;
0616: }
0617:
0618: /**
0619: * Visit a field declaration
0620: *
0621: *@param node the node we are visiting
0622: *@param data the state we are in
0623: *@return nothing of interest
0624: */
0625: public Object visit(ASTFieldDeclaration node, Object data) {
0626: // Convert the data into the correct form
0627: SummaryLoaderState state = (SummaryLoaderState) data;
0628:
0629: if (state.getCode() == SummaryLoaderState.IGNORE) {
0630: return super .visit(node, data);
0631: }
0632:
0633: int start = getLineCount() + 1;
0634: int code = state.getCode();
0635: state.setCode(SummaryLoaderState.IGNORE);
0636: countFieldStart(node, data);
0637:
0638: state.setCode(code);
0639:
0640: // Get the current type summary
0641: TypeSummary current = (TypeSummary) state.getCurrentSummary();
0642:
0643: // Local Variables
0644: FieldSummary result = null;
0645: int last = node.jjtGetNumChildren();
0646: ASTType type = (ASTType) node.jjtGetFirstChild();
0647:
0648: // Create a summary for each field
0649: for (int ndx = 1; ndx < last; ndx++) {
0650: Node next = node.jjtGetChild(ndx);
0651: result = new FieldSummary(current, type,
0652: (ASTVariableDeclaratorId) next.jjtGetFirstChild());
0653:
0654: // Count anything on the declarator
0655: state.setCode(SummaryLoaderState.IGNORE);
0656: next.jjtGetFirstChild().jjtAccept(this , data);
0657: state.setCode(code);
0658:
0659: // Continue setting up the field summary
0660: result.copyModifiers(node);
0661: result.setStartLine(start);
0662:
0663: // Load the initializer
0664: if (next.jjtGetNumChildren() > 1) {
0665: loadInitializer(current, state, (SimpleNode) next
0666: .jjtGetChild(1), node.isStatic());
0667: }
0668:
0669: // Finish setting variables for the field summary
0670: countLines(node.getSpecial("comma." + (ndx - 1)));
0671: result.setEndLine(getLineCount());
0672: current.add(result);
0673: }
0674: countLines(node.getSpecial("semicolon"));
0675: if (result != null) {
0676: result.setEndLine(getLineCount());
0677: }
0678:
0679: return data;
0680: }
0681:
0682: /**
0683: * Visits a method
0684: *
0685: *@param node the node we are visiting
0686: *@param data the state we are in
0687: *@return nothing of interest
0688: */
0689: public Object visit(ASTMethodDeclaration node, Object data) {
0690: // Convert the data into the correct form
0691: SummaryLoaderState state = (SummaryLoaderState) data;
0692:
0693: if (state.getCode() == SummaryLoaderState.IGNORE) {
0694: return super .visit(node, data);
0695: }
0696:
0697: int start = getLineCount() + 1;
0698:
0699: countMethodHeader(node, data);
0700:
0701: int declStart = getLineCount();
0702:
0703: int code = state.getCode();
0704:
0705: if (code == SummaryLoaderState.LOAD_CLASSBODY) {
0706: int child = (node.jjtGetChild(1) instanceof ASTResultType) ? 2
0707: : 1;
0708: ASTMethodDeclarator decl = (ASTMethodDeclarator) node
0709: .jjtGetChild(child);
0710:
0711: // Get the current type summary
0712: TypeSummary current = (TypeSummary) state
0713: .getCurrentSummary();
0714: MethodSummary methodSummary = new MethodSummary(current);
0715: state.startSummary(methodSummary);
0716: current.add(methodSummary);
0717:
0718: // Load the method summary
0719: // Remember the modifiers
0720: methodSummary.copyModifiers(node);
0721:
0722: // Load the method names
0723: methodSummary.setName(decl.getName());
0724:
0725: // Load the return type
0726: loadMethodReturn(node, methodSummary, decl.getArrayCount());
0727:
0728: // Load the parameters
0729: loadMethodParams(decl, state);
0730:
0731: // Load the exceptions
0732: loadMethodExceptions(node, state, 2);
0733:
0734: // Initialize the dependency list
0735: loadMethodBody(node, state);
0736:
0737: // Done
0738: state.setCode(SummaryLoaderState.LOAD_CLASSBODY);
0739: state.finishSummary();
0740:
0741: int end = getLineCount();
0742: methodSummary.setStartLine(start);
0743: methodSummary.setDeclarationLine(declStart);
0744: methodSummary.setEndLine(end);
0745:
0746: return data;
0747: } else {
0748: int child = (node.jjtGetChild(1) instanceof ASTResultType) ? 2
0749: : 1;
0750: ASTMethodDeclarator decl = (ASTMethodDeclarator) node
0751: .jjtGetChild(child);
0752: System.out.println("Encountered a method in state: "
0753: + code);
0754: System.out.println(" name=" + decl.getName());
0755: return data;
0756: }
0757: }
0758:
0759: /*
0760: public Object visit(ASTInstanceOfExpression node, Object data) {
0761: SummaryLoaderState state = (SummaryLoaderState) data;
0762:
0763: int childCount = node.jjtGetNumChildren();
0764: if (childCount==2) {
0765: MethodSummary methodSummary = (MethodSummary) state.getCurrentSummary();
0766: ASTReferenceType reference = (ASTReferenceType)node.jjtGetChild(1);
0767: methodSummary.addDependency(new TypeDeclSummary(methodSummary, (ASTName)reference.jjtGetFirstChild()));
0768: }
0769:
0770: return super.visit(node, data);
0771: }
0772: */
0773: /**
0774: * Visit a formal parameter
0775: *
0776: *@param node the node we are visiting
0777: *@param data the state we are in
0778: *@return nothing of interest
0779: */
0780: public Object visit(ASTFormalParameter node, Object data) {
0781: // Convert the data into the correct form
0782: SummaryLoaderState state = (SummaryLoaderState) data;
0783:
0784: if (state.getCode() == SummaryLoaderState.IGNORE) {
0785: return super .visit(node, data);
0786: }
0787:
0788: int start = getLineCount() + 1;
0789:
0790: int code = state.getCode();
0791:
0792: if (code == SummaryLoaderState.LOAD_PARAMETERS) {
0793: // Local Variables
0794: MethodSummary methodSummary = (MethodSummary) state
0795: .getCurrentSummary();
0796:
0797: // For each variable create a summary
0798: methodSummary.add(new ParameterSummary(methodSummary,
0799: (ASTType) node.jjtGetFirstChild(),
0800: (ASTVariableDeclaratorId) node.jjtGetChild(1)));
0801:
0802: // Continue with the state
0803: return state;
0804: } else {
0805: // Get the parent
0806: MethodSummary parent = (MethodSummary) state
0807: .getCurrentSummary();
0808:
0809: // Add the dependency
0810: parent.addDependency(new ParameterSummary(parent,
0811: (ASTType) node.jjtGetFirstChild(),
0812: (ASTVariableDeclaratorId) node.jjtGetChild(1)));
0813:
0814: // Return something
0815: return data;
0816: }
0817: }
0818:
0819: /**
0820: * Visit a constructor
0821: *
0822: *@param node the node we are visiting
0823: *@param data the state we are in
0824: *@return nothing of interest
0825: */
0826: public Object visit(ASTConstructorDeclaration node, Object data) {
0827: // Convert the data into the correct form
0828: SummaryLoaderState state = (SummaryLoaderState) data;
0829:
0830: if (state.getCode() == SummaryLoaderState.IGNORE) {
0831: return super .visit(node, data);
0832: }
0833:
0834: int code = state.getCode();
0835:
0836: if (code == SummaryLoaderState.LOAD_CLASSBODY) {
0837: int start = getLineCount() + 1;
0838:
0839: countConstructorHeader(node);
0840:
0841: int declStart = getLineCount();
0842:
0843: // Get the current type summary
0844: TypeSummary current = (TypeSummary) state
0845: .getCurrentSummary();
0846: MethodSummary methodSummary = new MethodSummary(current);
0847: current.add(methodSummary);
0848: state.startSummary(methodSummary);
0849:
0850: // Load the constructor
0851: // Remember the modifiers
0852: methodSummary.copyModifiers(node);
0853:
0854: // Load the method names
0855: methodSummary.setName(node.getName());
0856:
0857: // Load the parameters
0858: loadMethodParams(node, state);
0859:
0860: // Load the exceptions
0861: loadMethodExceptions(node, state, 1);
0862:
0863: // Initialize the dependency list
0864: methodSummary.beginBlock();
0865: int childNo = node.skipAnnotationsAndTypeParameters();
0866: state.setCode(SummaryLoaderState.LOAD_METHODBODY);
0867: int last = node.jjtGetNumChildren();
0868: for (int ndx = childNo + 1; ndx < last; ndx++) {
0869: SimpleNode body = (SimpleNode) node.jjtGetChild(ndx);
0870: if (body instanceof ASTExplicitConstructorInvocation) {
0871: body.jjtAccept(this , data);
0872: } else if (body instanceof ASTBlockStatement) {
0873: body.jjtAccept(this , data);
0874: }
0875: }
0876: methodSummary.endBlock();
0877:
0878: // Done
0879: state.setCode(SummaryLoaderState.LOAD_CLASSBODY);
0880: state.finishSummary();
0881:
0882: countLines(node.getSpecial("end"));
0883: int end = getLineCount();
0884: methodSummary.setStartLine(start);
0885: methodSummary.setDeclarationLine(declStart);
0886: methodSummary.setEndLine(end);
0887:
0888: return data;
0889: } else {
0890: System.out.println("Encountered a constructor in state: "
0891: + code);
0892: System.out.println(" name=" + node.getName());
0893: return data;
0894: }
0895: }
0896:
0897: /**
0898: * Visit an initializer
0899: *
0900: *@param node the node we are visiting
0901: *@param data the state we are in
0902: *@return nothing of interest
0903: */
0904: public Object visit(ASTInitializer node, Object data) {
0905: // Convert the data into the correct form
0906: SummaryLoaderState state = (SummaryLoaderState) data;
0907:
0908: if (state.getCode() == SummaryLoaderState.IGNORE) {
0909: return super .visit(node, data);
0910: }
0911:
0912: int start = getLineCount() + 1;
0913:
0914: int code = state.getCode();
0915:
0916: if (code == SummaryLoaderState.LOAD_CLASSBODY) {
0917: // Get the current type summary
0918: TypeSummary current = (TypeSummary) state
0919: .getCurrentSummary();
0920:
0921: int last = node.jjtGetNumChildren();
0922: SimpleNode body = (SimpleNode) node.jjtGetChild(last - 1);
0923: if (body instanceof ASTBlock) {
0924: loadInitializer(current, state, body, node
0925: .isUsingStatic());
0926: }
0927:
0928: return data;
0929: } else {
0930: System.out.println("Encountered a initializer in state: "
0931: + code);
0932: return data;
0933: }
0934: }
0935:
0936: /**
0937: * Visit a type
0938: *
0939: *@param node the node we are visiting
0940: *@param data the state we are in
0941: *@return nothing of interest
0942: */
0943: public Object visit(ASTType node, Object data) {
0944: // Convert the data into the correct form
0945: SummaryLoaderState state = (SummaryLoaderState) data;
0946:
0947: if (state.getCode() == SummaryLoaderState.IGNORE) {
0948: return super .visit(node, data);
0949: }
0950:
0951: if (state.getCurrentSummary() instanceof TypeSummary) {
0952: // FIXME??? this is an annotation???
0953: return data;
0954: }
0955: MethodSummary parent = (MethodSummary) state
0956: .getCurrentSummary();
0957:
0958: // Add the dependency
0959: if (node.jjtGetFirstChild() instanceof ASTReferenceType) {
0960: // reference type dependencies are handled by their own visitor.
0961: } else if (node.jjtGetFirstChild() instanceof ASTPrimitiveType) {
0962: parent.addDependency(TypeDeclSummary.getTypeDeclSummary(
0963: parent, node));
0964: }
0965:
0966: // Return the data
0967: return super .visit(node, data);
0968: }
0969:
0970: /**
0971: * Visit a type
0972: *
0973: *@param node the node we are visiting
0974: *@param data the state we are in
0975: *@return nothing of interest
0976: */
0977: public Object visit(ASTReferenceType node, Object data) {
0978: // Convert the data into the correct form
0979: SummaryLoaderState state = (SummaryLoaderState) data;
0980:
0981: if (state.getCode() == SummaryLoaderState.IGNORE) {
0982: return super .visit(node, data);
0983: }
0984:
0985: if (state.getCurrentSummary() instanceof MethodSummary) {
0986: MethodSummary parent = (MethodSummary) state
0987: .getCurrentSummary();
0988: parent.addDependency(TypeDeclSummary.getTypeDeclSummary(
0989: parent, node)); // Add the dependency
0990: } else if (state.getCurrentSummary() instanceof TypeSummary) {
0991: TypeSummary parent = (TypeSummary) state
0992: .getCurrentSummary();
0993: } else {
0994: }
0995:
0996: return super .visit(node, data); // Return the data
0997: }
0998:
0999: /**
1000: * Visit a return type
1001: *
1002: *@param node the node we are visiting
1003: *@param data the state we are in
1004: *@return nothing of interest
1005: */
1006: public Object visit(ASTResultType node, Object data) {
1007: // Convert the data into the correct form
1008: SummaryLoaderState state = (SummaryLoaderState) data;
1009:
1010: if (state.getCode() == SummaryLoaderState.IGNORE) {
1011: return super .visit(node, data);
1012: }
1013:
1014: int start = getLineCount() + 1;
1015:
1016: MethodSummary parent = (MethodSummary) state
1017: .getCurrentSummary();
1018:
1019: // Add the dependency
1020: parent.addDependency(TypeDeclSummary.getTypeDeclSummary(parent,
1021: node));
1022:
1023: // Return the data
1024: return data;
1025: }
1026:
1027: /**
1028: * Visit a name
1029: *
1030: *@param node the node we are visiting
1031: *@param data the state we are in
1032: *@return nothing of interest
1033: */
1034: public Object visit(ASTClassOrInterfaceType node, Object data) {
1035: // Convert the data into the correct form
1036: SummaryLoaderState state = (SummaryLoaderState) data;
1037:
1038: if (state.getCode() == SummaryLoaderState.IGNORE) {
1039: return super .visit(node, data);
1040: }
1041:
1042: int code = state.getCode();
1043:
1044: // Get the current type summary
1045: if (code == SummaryLoaderState.LOAD_TYPE) {
1046: TypeSummary current = (TypeSummary) state
1047: .getCurrentSummary();
1048: current.setParentClass(new TypeDeclSummary(current, node));
1049: }
1050:
1051: return super .visit(node, data);
1052: }
1053:
1054: /**
1055: * Visit a name
1056: * // FIXME? is this required?
1057: *@param node the node we are visiting
1058: *@param data the state we are in
1059: *@return nothing of interest
1060: */
1061: public Object visit(ASTName node, Object data) {
1062: // Convert the data into the correct form
1063: SummaryLoaderState state = (SummaryLoaderState) data;
1064:
1065: if (state.getCode() == SummaryLoaderState.IGNORE) {
1066: return super .visit(node, data);
1067: }
1068:
1069: int code = state.getCode();
1070:
1071: // Get the current type summary
1072: if (code == SummaryLoaderState.LOAD_TYPE) {
1073: TypeSummary current = (TypeSummary) state
1074: .getCurrentSummary();
1075: current.setParentClass(new TypeDeclSummary(current, node));
1076: }
1077:
1078: return super .visit(node, data);
1079: }
1080:
1081: /**
1082: * Visit a list of names
1083: *
1084: *@param node the node we are visiting
1085: *@param data the state we are in
1086: *@return nothing of interest
1087: */
1088: public Object visit(ASTNameList node, Object data) {
1089: // Convert the data into the correct form
1090: SummaryLoaderState state = (SummaryLoaderState) data;
1091:
1092: if (state.getCode() == SummaryLoaderState.IGNORE) {
1093: return super .visit(node, data);
1094: }
1095:
1096: int code = state.getCode();
1097:
1098: // Get the current type summary
1099: if (code == SummaryLoaderState.LOAD_TYPE) {
1100: TypeSummary current = (TypeSummary) state
1101: .getCurrentSummary();
1102:
1103: // Local Variables
1104: int last = node.jjtGetNumChildren();
1105:
1106: // For each interface it implements create a summary
1107: state.setCode(SummaryLoaderState.IGNORE);
1108: for (int ndx = 0; ndx < last; ndx++) {
1109: countLines(node.getSpecial("comma." + (ndx - 1)));
1110: ASTName next = (ASTName) node.jjtGetChild(ndx);
1111: current.add(new TypeDeclSummary(current, next));
1112: next.jjtAccept(this , data);
1113: }
1114: state.setCode(code);
1115:
1116: return data;
1117: } else if (code == SummaryLoaderState.LOAD_EXCEPTIONS) {
1118: // Local Variables
1119: int last = node.jjtGetNumChildren();
1120: MethodSummary methodSummary = (MethodSummary) state
1121: .getCurrentSummary();
1122:
1123: // For each variable create a summary
1124: state.setCode(SummaryLoaderState.IGNORE);
1125: for (int ndx = 0; ndx < last; ndx++) {
1126: countLines(node.getSpecial("comma." + (ndx - 1)));
1127: ASTName next = (ASTName) node.jjtGetChild(ndx);
1128: methodSummary.add(new TypeDeclSummary(methodSummary,
1129: next));
1130: next.jjtAccept(this , data);
1131: }
1132: state.setCode(code);
1133:
1134: // Return something
1135: return data;
1136: } else {
1137: return super .visit(node, data);
1138: }
1139: }
1140:
1141: /**
1142: * Visit a list of names
1143: *
1144: *@param node the node we are visiting
1145: *@param data the state we are in
1146: *@return nothing of interest
1147: */
1148: public Object visit(ASTGenericNameList node, Object data) {
1149: // Convert the data into the correct form
1150: SummaryLoaderState state = (SummaryLoaderState) data;
1151:
1152: if (state.getCode() == SummaryLoaderState.IGNORE) {
1153: return super .visit(node, data);
1154: }
1155:
1156: int code = state.getCode();
1157:
1158: // Get the current type summary
1159: if (code == SummaryLoaderState.LOAD_TYPE) {
1160: TypeSummary current = (TypeSummary) state
1161: .getCurrentSummary();
1162:
1163: // Local Variables
1164: int last = node.jjtGetNumChildren();
1165:
1166: // For each interface it implements create a summary
1167: state.setCode(SummaryLoaderState.IGNORE);
1168: for (int ndx = 0; ndx < last; ndx++) {
1169: Node child = node.jjtGetChild(ndx);
1170: if (child instanceof ASTClassOrInterfaceType) {
1171: countLines(node.getSpecial("comma." + (ndx - 1)));
1172: current.add(new TypeDeclSummary(current,
1173: (ASTClassOrInterfaceType) child));
1174: }
1175: child.jjtAccept(this , data);
1176: }
1177: state.setCode(code);
1178:
1179: return data;
1180: } else if (code == SummaryLoaderState.LOAD_EXCEPTIONS) {
1181: // Local Variables
1182: int last = node.jjtGetNumChildren();
1183: MethodSummary methodSummary = (MethodSummary) state
1184: .getCurrentSummary();
1185:
1186: // For each variable create a summary
1187: state.setCode(SummaryLoaderState.IGNORE);
1188: for (int ndx = 0; ndx < last; ndx++) {
1189: Node child = node.jjtGetChild(ndx);
1190: if (child instanceof ASTClassOrInterfaceType) {
1191: countLines(node.getSpecial("comma." + (ndx - 1)));
1192: methodSummary.add(new TypeDeclSummary(
1193: methodSummary,
1194: (ASTClassOrInterfaceType) child));
1195: }
1196: child.jjtAccept(this , data);
1197: }
1198: state.setCode(code);
1199:
1200: // Return something
1201: return data;
1202: } else {
1203: return super .visit(node, data);
1204: }
1205: }
1206:
1207: /**
1208: * Visit an expression
1209: *
1210: *@param node the node we are visiting
1211: *@param data the state we are in
1212: *@return nothing of interest
1213: */
1214: public Object visit(ASTPrimaryExpression node, Object data) {
1215: // Convert the data into the correct form
1216: SummaryLoaderState state = (SummaryLoaderState) data;
1217:
1218: if (state.getCode() == SummaryLoaderState.IGNORE) {
1219: return super .visit(node, data);
1220: }
1221:
1222: int start = getLineCount() + 1;
1223:
1224: // Local Variables
1225: ASTName name = null;
1226:
1227: // Check out the prefix
1228: ASTPrimaryPrefix prefix = (ASTPrimaryPrefix) node
1229: .jjtGetFirstChild();
1230: if (!prefix.hasAnyChildren()) {
1231: // Count the lines
1232: countLines(node.getSpecial("this"));
1233: countLines(node.getSpecial("id"));
1234:
1235: // It is entirely controlled by the name of the node
1236: String prefixName = prefix.getName();
1237:
1238: // Create the name
1239: name = new ASTName();
1240:
1241: // Check out the name
1242: if (prefixName.equals("this")) {
1243: name.addNamePart(prefixName);
1244: } else {
1245: // FIXME name could be of the form "super" ("." "super")*
1246: name.addNamePart("super");
1247: name.addNamePart(prefixName.substring(7, prefixName
1248: .length()));
1249: }
1250: } else if (prefix.jjtGetFirstChild() instanceof ASTName) {
1251: // Count the items in the name
1252: int code = state.getCode();
1253: state.setCode(SummaryLoaderState.IGNORE);
1254: super .visit(prefix, data);
1255: state.setCode(code);
1256:
1257: // Remember the name
1258: name = (ASTName) prefix.jjtGetFirstChild();
1259: } else {
1260: // Our work is done here
1261: return super .visit(node, data);
1262: }
1263:
1264: if (state.getCurrentSummary() instanceof TypeSummary) {
1265: // FIXME??? this is an annotation???
1266: return data;
1267: }
1268: // Get the parent
1269: MethodSummary parent = (MethodSummary) state
1270: .getCurrentSummary();
1271:
1272: // Check out the suffix
1273: boolean isMessageSend = false;
1274: int suffixCount = node.jjtGetNumChildren();
1275: boolean sentLast = false;
1276: if (suffixCount > 1) {
1277: for (int ndx = 1; ndx < suffixCount; ndx++) {
1278: ASTPrimarySuffix suffix = (ASTPrimarySuffix) node
1279: .jjtGetChild(ndx);
1280: if (!suffix.hasAnyChildren()) {
1281: // Count the lines
1282: countLines(node.getSpecial("dot"));
1283: countLines(node.getSpecial("id"));
1284:
1285: name = new ASTName();
1286: name.addNamePart(suffix.getName());
1287: sentLast = false;
1288: } else if (suffix.jjtGetFirstChild() instanceof ASTArguments) {
1289: addAccess(parent, name, true);
1290: sentLast = true;
1291: super .visit((SimpleNode) suffix.jjtGetFirstChild(),
1292: data);
1293: } else if (suffix.jjtGetFirstChild() instanceof ASTReferenceTypeList) {
1294: if (suffix.getName() != null
1295: && !suffix.getName().equals("")) {
1296: if (name == null) {
1297: name = new ASTName();
1298: }
1299: name.addNamePart(suffix.getName());
1300: }
1301: super .visit((SimpleNode) suffix.jjtGetFirstChild(),
1302: data);
1303: } else if (!sentLast) {
1304: addAccess(parent, name, false);
1305: sentLast = true;
1306:
1307: // Count the lines
1308: countLines(node.getSpecial("["));
1309: countLines(node.getSpecial("]"));
1310: countLines(node.getSpecial("dot"));
1311: countLines(node.getSpecial("id"));
1312:
1313: super .visit((SimpleNode) suffix.jjtGetFirstChild(),
1314: data);
1315: }
1316: }
1317: }
1318:
1319: // Get the parent
1320: if (!sentLast) {
1321: addAccess(parent, name, false);
1322: }
1323:
1324: // Return some value
1325: return data;
1326: }
1327:
1328: /**
1329: * Visit an allocation
1330: *
1331: *@param node the node we are visiting
1332: *@param data the state we are in
1333: *@return nothing of interest
1334: */
1335: public Object visit(ASTAllocationExpression node, Object data) {
1336: // Convert the data into the correct form
1337: SummaryLoaderState state = (SummaryLoaderState) data;
1338:
1339: if (state.getCode() == SummaryLoaderState.IGNORE) {
1340: return super .visit(node, data);
1341: }
1342:
1343: int start = getLineCount() + 1;
1344:
1345: MethodSummary parent = (MethodSummary) state
1346: .getCurrentSummary();
1347:
1348: // Add the dependency
1349: Node child = node.jjtGetFirstChild();
1350: TypeDeclSummary parentClass = null;
1351: if (child instanceof ASTClassOrInterfaceType) {
1352: parentClass = new TypeDeclSummary(parent,
1353: (ASTClassOrInterfaceType) child);
1354: } else if (child instanceof ASTPrimitiveType) {
1355: parentClass = new TypeDeclSummary(parent,
1356: (ASTPrimitiveType) child);
1357: }
1358: parent.addDependency(parentClass);
1359:
1360: // Count the lines in the type and before
1361: countLines(node.getSpecial("id"));
1362: int code = state.getCode();
1363: state.setCode(SummaryLoaderState.IGNORE);
1364: child.jjtAccept(this , data);
1365: state.setCode(code);
1366:
1367: int last = node.jjtGetNumChildren();
1368: for (int ndx = 1; ndx < last; ndx++) {
1369: Node next = node.jjtGetChild(ndx);
1370: if (next instanceof ASTClassBody) {
1371: // Create Type Summary
1372: TypeSummary typeSummary = new TypeSummary(parent, null);
1373: typeSummary.setName("Anonymous" + anonCount);
1374: anonCount++;
1375: typeSummary.setParentClass(parentClass);
1376:
1377: parent.addDependency(typeSummary);
1378:
1379: // Set the next type summary as the current summary
1380: state.startSummary(typeSummary);
1381: int oldCode = state.getCode();
1382: state.setCode(SummaryLoaderState.LOAD_TYPE);
1383:
1384: // Traverse Children
1385: next.jjtAccept(this , data);
1386:
1387: // Back to loading the file
1388: state.finishSummary();
1389: state.setCode(oldCode);
1390: } else {
1391: ((SimpleNode) next).jjtAccept(this , data);
1392: }
1393: }
1394:
1395: int end = getLineCount();
1396: parentClass.setStartLine(start);
1397: parentClass.setEndLine(end);
1398:
1399: // Return the data
1400: return data;
1401: }
1402:
1403: /**
1404: * Visit a statement
1405: *
1406: *@param node the node we are visiting
1407: *@param data the state we are in
1408: *@return nothing of interest
1409: */
1410: public Object visit(ASTStatement node, Object data) {
1411: // Convert the data into the correct form
1412: SummaryLoaderState state = (SummaryLoaderState) data;
1413:
1414: if (state.getCode() == SummaryLoaderState.IGNORE) {
1415: return super .visit(node, data);
1416: }
1417:
1418: Node child = node.jjtGetFirstChild();
1419: if (child instanceof ASTBlock) {
1420: // Don't count blocks as statements
1421: } else {
1422: MethodSummary parent = (MethodSummary) state
1423: .getCurrentSummary();
1424: parent.incrStatementCount();
1425: }
1426:
1427: return super .visit(node, data);
1428: }
1429:
1430: /**
1431: * Explicit constructor invocation gets one statement count
1432: *
1433: *@param node Description of Parameter
1434: *@param data Description of Parameter
1435: *@return Description of the Returned Value
1436: */
1437: public Object visit(ASTExplicitConstructorInvocation node,
1438: Object data) {
1439: // Convert the data into the correct form
1440: SummaryLoaderState state = (SummaryLoaderState) data;
1441:
1442: if (state.getCode() == SummaryLoaderState.IGNORE) {
1443: return super .visit(node, data);
1444: }
1445:
1446: MethodSummary parent = (MethodSummary) state
1447: .getCurrentSummary();
1448: parent.incrStatementCount();
1449:
1450: return super .visit(node, data);
1451: }
1452:
1453: /**
1454: * Visit the local variables
1455: *
1456: *@param node the node we are visiting
1457: *@param data the state we are in
1458: *@return nothing of interest
1459: */
1460: public Object visit(ASTLocalVariableDeclaration node, Object data) {
1461: // Convert the data into the correct form
1462: SummaryLoaderState state = (SummaryLoaderState) data;
1463:
1464: if (state.getCode() == SummaryLoaderState.IGNORE) {
1465: return super .visit(node, data);
1466: }
1467:
1468: int start = getLineCount() + 1;
1469: countLocalVariable(node, data);
1470: int end = getLineCount();
1471:
1472: MethodSummary parent = (MethodSummary) state
1473: .getCurrentSummary();
1474:
1475: parent.incrStatementCount();
1476:
1477: // Get the field summaries
1478: LocalVariableSummary[] result = LocalVariableSummary.createNew(
1479: parent, node);
1480:
1481: // Add the dependencies into the method
1482: int last = result.length;
1483: for (int ndx = 0; ndx < last; ndx++) {
1484: parent.addDependency(result[ndx]);
1485: result[ndx].setStartLine(start);
1486: result[ndx].setEndLine(end);
1487: }
1488:
1489: // Return some result
1490: return data;
1491: }
1492:
1493: /**
1494: * Description of the Method
1495: *
1496: *@param node Description of Parameter
1497: *@param data Description of Parameter
1498: */
1499: protected void forInit(ASTLocalVariableDeclaration node, Object data) {
1500: // Convert the data into the correct form
1501: SummaryLoaderState state = (SummaryLoaderState) data;
1502:
1503: if (state.getCode() == SummaryLoaderState.IGNORE) {
1504: super .visit(node, data);
1505: return;
1506: }
1507:
1508: int start = getLineCount() + 1;
1509: countLocalVariable(node, data);
1510: int end = getLineCount();
1511:
1512: MethodSummary parent = (MethodSummary) state
1513: .getCurrentSummary();
1514:
1515: // Get the field summaries
1516: LocalVariableSummary[] result = LocalVariableSummary.createNew(
1517: parent, node);
1518:
1519: // Add the dependencies into the method
1520: int last = result.length;
1521: for (int ndx = 0; ndx < last; ndx++) {
1522: parent.addDependency(result[ndx]);
1523: result[ndx].setStartLine(start);
1524: result[ndx].setEndLine(end);
1525: }
1526: }
1527:
1528: /**
1529: * Visits a block in the parse tree. This code counts the block depth
1530: * associated with a method. Deeply nested blocks in a method is a sign of
1531: * poor design.
1532: *
1533: *@param node the block node
1534: *@param data the information that is used to traverse the tree
1535: *@return data is returned
1536: */
1537: public Object visit(ASTBlock node, Object data) {
1538: // Convert the data into the correct form
1539: SummaryLoaderState state = (SummaryLoaderState) data;
1540:
1541: if (state.getCode() == SummaryLoaderState.IGNORE) {
1542: return super .visit(node, data);
1543: }
1544:
1545: // Get the current file summary
1546: Summary current = state.getCurrentSummary();
1547: if (current instanceof MethodSummary) {
1548: ((MethodSummary) current).beginBlock();
1549: }
1550:
1551: Object result = super .visit(node, data);
1552:
1553: if (current instanceof MethodSummary) {
1554: ((MethodSummary) current).endBlock();
1555: }
1556:
1557: return result;
1558: }
1559:
1560: /**
1561: * A switch statement counts as a block, even though it does not use the
1562: * block parse token.
1563: *
1564: *@param node the switch node in the parse tree
1565: *@param data the data used to visit this parse tree
1566: *@return the data
1567: */
1568: public Object visit(ASTSwitchStatement node, Object data) {
1569: // Convert the data into the correct form
1570: SummaryLoaderState state = (SummaryLoaderState) data;
1571:
1572: if (state.getCode() == SummaryLoaderState.IGNORE) {
1573: return super .visit(node, data);
1574: }
1575:
1576: // Get the current file summary
1577: Summary current = state.getCurrentSummary();
1578: if (current instanceof MethodSummary) {
1579: ((MethodSummary) current).beginBlock();
1580: }
1581:
1582: Object result = super .visit(node, data);
1583:
1584: if (current instanceof MethodSummary) {
1585: ((MethodSummary) current).endBlock();
1586: }
1587:
1588: return result;
1589: }
1590:
1591: /**
1592: * Adds an access to the method
1593: *
1594: *@param parent the parent
1595: *@param name the name
1596: *@param isMessageSend is this a message send
1597: */
1598: protected void addAccess(MethodSummary parent, ASTName name,
1599: boolean isMessageSend) {
1600: // Record the access
1601: if (isMessageSend) {
1602: // Add the dependency
1603: parent.addDependency(new MessageSendSummary(parent,
1604: (ASTName) name));
1605: } else {
1606: // Add the dependency
1607: parent.addDependency(new FieldAccessSummary(parent,
1608: (ASTName) name));
1609: }
1610: }
1611:
1612: /**
1613: * Description of the Method
1614: *
1615: *@param current Description of Parameter
1616: *@param state Description of Parameter
1617: *@param body Description of Parameter
1618: *@param isStatic Description of Parameter
1619: */
1620: void loadInitializer(TypeSummary current, SummaryLoaderState state,
1621: SimpleNode body, boolean isStatic) {
1622: MethodSummary methodSummary = current.getInitializer(isStatic);
1623: state.startSummary(methodSummary);
1624:
1625: // Load the method summary's dependency list
1626: int oldCode = state.getCode();
1627: state.setCode(SummaryLoaderState.LOAD_METHODBODY);
1628: body.jjtAccept(this , state);
1629:
1630: // Done
1631: state.setCode(oldCode);
1632: state.finishSummary();
1633: }
1634:
1635: /**
1636: * Counts the lines associated with the field declaration and the
1637: * associated type
1638: *
1639: *@param node the field declaration
1640: *@param data the data for the visitor
1641: */
1642: private void countFieldStart(ASTFieldDeclaration node, Object data) {
1643: // Print any tokens
1644: countLines(node.getSpecial("static"));
1645: countLines(node.getSpecial("transient"));
1646: countLines(node.getSpecial("volatile"));
1647: countLines(node.getSpecial("final"));
1648: countLines(node.getSpecial("public"));
1649: countLines(node.getSpecial("protected"));
1650: countLines(node.getSpecial("private"));
1651:
1652: // Handle the first two children (which are required)
1653: Node next = node.jjtGetFirstChild();
1654: next.jjtAccept(this , data);
1655: }
1656:
1657: /**
1658: * Description of the Method
1659: *
1660: *@param node Description of Parameter
1661: *@param data Description of Parameter
1662: */
1663: private void countMethodHeader(ASTMethodDeclaration node,
1664: Object data) {
1665: countLines(node.getSpecial("public"));
1666: countLines(node.getSpecial("protected"));
1667: countLines(node.getSpecial("private"));
1668: countLines(node.getSpecial("static"));
1669: countLines(node.getSpecial("abstract"));
1670: countLines(node.getSpecial("final"));
1671: countLines(node.getSpecial("native"));
1672: countLines(node.getSpecial("synchronized"));
1673: int childNo = 0;
1674: Node child = node.jjtGetFirstChild();
1675: if (child instanceof ASTTypeParameters) {
1676: countLines(getInitialToken((ASTTypeParameters) child));
1677: child = node.jjtGetChild(++childNo);
1678: }
1679: countLines(getInitialToken((ASTResultType) child));
1680: countLines(node.getSpecial("throws"));
1681: countLines(node.getSpecial("semicolon"));
1682: }
1683:
1684: /**
1685: * Description of the Method
1686: *
1687: *@param node Description of Parameter
1688: */
1689: private void countConstructorHeader(ASTConstructorDeclaration node) {
1690: countLines(node.getSpecial("public"));
1691: countLines(node.getSpecial("protected"));
1692: countLines(node.getSpecial("private"));
1693: countLines(node.getSpecial("id"));
1694: countLines(node.getSpecial("throws"));
1695: countLines(node.getSpecial("begin"));
1696: countLines(node.getSpecial("@"));
1697: }
1698:
1699: /**
1700: * Description of the Method
1701: *
1702: *@param decl Description of Parameter
1703: *@param state Description of Parameter
1704: */
1705: private void loadMethodParams(SimpleNode decl,
1706: SummaryLoaderState state) {
1707: Node child = decl.jjtGetFirstChild();
1708: if (child instanceof ASTTypeParameters) {
1709: child = decl.jjtGetChild(1);
1710: }
1711: if (!(child instanceof ASTFormalParameters)) {
1712: System.out.println("ERROR! Not formal parameters");
1713: return;
1714: }
1715: state.setCode(SummaryLoaderState.LOAD_PARAMETERS);
1716: child.jjtAccept(this , state);
1717: }
1718:
1719: /**
1720: * Description of the Method
1721: *
1722: *@param node Description of Parameter
1723: *@param methodSummary Description of Parameter
1724: *@param count Description of Parameter
1725: */
1726: private void loadMethodReturn(ASTMethodDeclaration node,
1727: MethodSummary methodSummary, int count) {
1728: int childNo = node.skipAnnotationsAndTypeParameters();
1729: TypeDeclSummary returnType = TypeDeclSummary
1730: .getTypeDeclSummary(methodSummary, (ASTResultType) node
1731: .jjtGetChild(childNo));
1732: returnType.setArrayCount(returnType.getArrayCount() + count);
1733: methodSummary.setReturnType(returnType);
1734: }
1735:
1736: /**
1737: * Description of the Method
1738: *
1739: *@param node Description of Parameter
1740: *@param state Description of Parameter
1741: *@param index Description of Parameter
1742: */
1743: private void loadMethodExceptions(SimpleNode node,
1744: SummaryLoaderState state, int index) {
1745: if (node.jjtGetNumChildren() > index) {
1746: Node child = node.jjtGetChild(index);
1747: if (child instanceof ASTNameList) {
1748: state.setCode(SummaryLoaderState.LOAD_EXCEPTIONS);
1749: child.jjtAccept(this , state);
1750: }
1751: }
1752: }
1753:
1754: /**
1755: * Description of the Method
1756: *
1757: *@param node Description of Parameter
1758: *@param state Description of Parameter
1759: */
1760: private void loadMethodBody(ASTMethodDeclaration node,
1761: SummaryLoaderState state) {
1762: state.setCode(SummaryLoaderState.LOAD_METHODBODY);
1763: int last = node.jjtGetNumChildren();
1764: SimpleNode body = (SimpleNode) node.jjtGetChild(last - 1);
1765: if (body instanceof ASTBlock) {
1766: body.jjtAccept(this , state);
1767: }
1768: }
1769:
1770: /**
1771: * Description of the Method
1772: *
1773: *@param node Description of the Parameter
1774: *@param data Description of the Parameter
1775: */
1776: private void countLocalVariable(ASTLocalVariableDeclaration node,
1777: Object data) {
1778: // Traverse the children
1779: int last = node.jjtGetNumChildren();
1780:
1781: // Print the final token
1782: if (node.isUsingFinal()) {
1783: countLines(node.getSpecial("final"));
1784: }
1785:
1786: // Convert the data into the correct form
1787: SummaryLoaderState state = (SummaryLoaderState) data;
1788:
1789: // The first child is special - it is the type
1790: int code = state.getCode();
1791: state.setCode(SummaryLoaderState.IGNORE);
1792: node.jjtGetFirstChild().jjtAccept(this , data);
1793: state.setCode(code);
1794:
1795: // Traverse the rest of the children
1796: for (int ndx = 1; ndx < last; ndx++) {
1797: countLines(node.getSpecial("comma." + (ndx - 1)));
1798: // Visit the child
1799: node.jjtGetChild(ndx).jjtAccept(this, data);
1800: }
1801: }
1802: }
|