/* * CCVisu is a tool for visual graph clustering * and general force-directed graph layout. * This file is part of CCVisu. * * Copyright (C) 2005-2012 Dirk Beyer * * CCVisu is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * CCVisu is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with CCVisu; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Please find the GNU Lesser General Public License in file * license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt * * Dirk Beyer (firstname.lastname@uni-passau.de) * University of Passau, Bavaria, Germany */ package org.sosy_lab.ccvisu.readers.factextractor; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.EnumDeclaration; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.sosy_lab.ccvisu.graph.Relation; import com.google.common.base.Strings; public class EclipseFactVisitor extends ASTVisitor { private static final String RELATION_NAME_PACKAGE_REFERENCE = "refPackage"; private static final String RELATION_NAME_CLASS_REFERENCE = "refClass"; private static final String RELATION_NAME_FUNCTIONCALL = "REFfunction"; private static final String RELATION_NAME_INTERFACE_IMPLEMENTATION = "implements"; private static final String RELATION_NAME_INHERITANCE = "inheritClass"; private static final String RELATION_NAME_PACKAGE_CONTAINS = "pckgContains"; private Relation relation; private ITypeBinding currentTypeBinding; private MethodDeclaration currentMethod; public void reset() { currentTypeBinding = null; currentMethod = null; } public EclipseFactVisitor(Relation relation) { this.relation = relation; } @Override public boolean visit(EnumDeclaration node) { String sourceName = FactUtils.getEnumFullName(node); // Add package relation sourceName = FactUtils.getPackageName(node); String targetName = FactUtils.getEnumFullName(node); addRelation(RELATION_NAME_PACKAGE_CONTAINS, sourceName, targetName); return true; } @Override public boolean visit(TypeDeclaration node) { assert node != null; currentTypeBinding = node.resolveBinding(); // Add inheritance relation String sourceName = FactUtils.getTypeFullName(node); String targetName = FactUtils.getTypeFullName(node.getSuperclassType()); addRelation(RELATION_NAME_INHERITANCE, sourceName, targetName); // Add super interfaces relations for (Object interfaceType : node.superInterfaceTypes()) { targetName = FactUtils.getTypeFullName((Type) interfaceType); addRelation(RELATION_NAME_INTERFACE_IMPLEMENTATION, sourceName, targetName); } // Add 'pckgContains' relation sourceName = FactUtils.getPackageName(node); targetName = FactUtils.getTypeFullName(node); addRelation(RELATION_NAME_PACKAGE_CONTAINS, sourceName, targetName); return true; } @Override public boolean visit(MethodDeclaration node) { if (currentMethod != null) { return false; } currentMethod = node; // EclipseFactUtils.getMethodFullName(currentMethod); // projectStructureInfo.addNodeType(pSourceName, NodeType.METHOD); return true; } @Override public void endVisit(MethodDeclaration node) { if (currentMethod == node) { currentMethod = null; } } @Override public void endVisit(TypeDeclaration node) { if (currentTypeBinding == node.resolveBinding()) { // It can happen that we have just left an inner class - to now let's take // its declaring class as current type currentTypeBinding = node.resolveBinding().getDeclaringClass(); } } @Override public boolean visit(MethodInvocation node) { String sourceName = null; // First add method call if (currentMethod != null) { sourceName = FactUtils.getMethodFullName(currentMethod); } else { // It can happen to be that a method is being called outside of any method, // e.g. from a variable initializer. sourceName = FactUtils.getTypeFullName(currentTypeBinding); } String targetName = FactUtils.getMethodFullName(node); addRelation(RELATION_NAME_FUNCTIONCALL, sourceName, targetName); // Now add class call if (currentMethod != null) { sourceName = FactUtils.getTypeFullName(currentMethod); } else { sourceName = FactUtils.getTypeFullName(currentTypeBinding); } targetName = FactUtils.getTypeFullName(node); addRelation(RELATION_NAME_CLASS_REFERENCE, sourceName, targetName); // Add package call if (currentMethod != null) { sourceName = FactUtils.getPackageName(currentMethod); } else { sourceName = FactUtils.getPackageName(currentTypeBinding); } targetName = FactUtils.getPackageName(node); addRelation(RELATION_NAME_PACKAGE_REFERENCE, sourceName, targetName); return false; } private void addRelation(String relName, String sourceName, String targetName) { if (!Strings.isNullOrEmpty(sourceName) && !Strings.isNullOrEmpty(targetName)) { relation.addTuple(relName, sourceName, targetName); } } }