package de.ovgu.cide.language.jdt; import java.io.Serializable; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.WeakHashMap; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; import org.eclipse.jdt.core.dom.ArrayInitializer; import org.eclipse.jdt.core.dom.Block; import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; import org.eclipse.jdt.core.dom.ClassInstanceCreation; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.ConstructorInvocation; import org.eclipse.jdt.core.dom.EnumConstantDeclaration; import org.eclipse.jdt.core.dom.EnumDeclaration; import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.ImportDeclaration; import org.eclipse.jdt.core.dom.InfixExpression; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.Name; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.SuperConstructorInvocation; import org.eclipse.jdt.core.dom.SuperMethodInvocation; import org.eclipse.jdt.core.dom.SwitchStatement; import org.eclipse.jdt.core.dom.TryStatement; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.VariableDeclaration; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; public class ASTID implements Serializable { private static final long serialVersionUID = 1L; public final String id; private ASTID(ASTNode node) { this.id = calculateId(node); } private ASTID(ASTNode node, boolean old) { if (old) this.id = calculateId_old(node); else this.id = calculateId(node); } // private ASTID(String id) { // this.id = id; // } private static final Map<ASTNode, ASTID> cache = Collections .synchronizedMap(new WeakHashMap<ASTNode, ASTID>()); public static String id(ASTNode node) { ASTID id = cache.get(node); if (id == null) { id = new ASTID(node); cache.put(node, id); } return id.id; } public static ASTID id_old(ASTNode node) { return new ASTID(node, true); } private static String clean(String str) { str = str.replace('/', '_'); return str.replace(':', '_'); } public static String calculateId(ASTNode node) { if (node == null) return "/"; String id = calculateId(node.getParent()); if (node.getParent() instanceof Block) { Block block = (Block) node.getParent(); int idx = block.statements().indexOf(node); id += "[" + idx + "]"; } if (node.getParent() instanceof ArrayInitializer) { ArrayInitializer block = (ArrayInitializer) node.getParent(); int idx = block.expressions().indexOf(node); id += "[" + idx + "]"; } if (node.getLocationInParent() != null && node.getParent() != null) { id += ":" + node.getLocationInParent().getId(); } if (node.getParent() instanceof TryStatement) { TryStatement trystmt = (TryStatement) node.getParent(); if (trystmt.getBody() == node) id += "[body]"; } // if (node.getLocationInParent() instanceof // ChildListPropertyDescriptor) { // List children = (List) node.getParent().getStructuralProperty( // node.getLocationInParent()); // id += "[" + children.indexOf(node) + "]"; // } id += "/" + clean(node.getClass().getSimpleName()); if (node instanceof TypeDeclaration) { id += ":" + clean(((TypeDeclaration) node).getName().toString()); } if (node instanceof EnumDeclaration) { id += ":" + clean(((EnumDeclaration) node).getName().toString()); } if (node instanceof FieldDeclaration) { for (Object fragment : ((FieldDeclaration) node).fragments()) { id += ":" + clean(((VariableDeclarationFragment) fragment) .getName().toString()); } } if (node instanceof Type) { ITypeBinding b = ((Type) node).resolveBinding(); id += "::" + (b == null ? "null" : b.getQualifiedName()); } if (node instanceof VariableDeclaration) id += ":" + clean(((VariableDeclaration) node).getName().toString()); if (node instanceof EnumConstantDeclaration) id += ":" + clean(((EnumConstantDeclaration) node).getName().toString()); if (node instanceof Name) id += ":" + clean(((Name) node).getFullyQualifiedName()); if (node instanceof ImportDeclaration) id += ":" + clean(((ImportDeclaration) node).getName().toString()); if (node instanceof MethodDeclaration) { Type rt = ((MethodDeclaration) node).getReturnType2(); id += ":" + clean(rt == null ? "void" : rt.toString()); id += ":" + clean(((MethodDeclaration) node).getName().toString()); id += ":" + clean(getParameterTypes(((MethodDeclaration) node) .parameters())); } ChildListPropertyDescriptor[] enumLists = new ChildListPropertyDescriptor[] { SwitchStatement.STATEMENTS_PROPERTY, InfixExpression.EXTENDED_OPERANDS_PROPERTY, TryStatement.CATCH_CLAUSES_PROPERTY, MethodInvocation.ARGUMENTS_PROPERTY, ConstructorInvocation.ARGUMENTS_PROPERTY, ClassInstanceCreation.ARGUMENTS_PROPERTY, SuperConstructorInvocation.ARGUMENTS_PROPERTY, SuperMethodInvocation.ARGUMENTS_PROPERTY }; for (ChildListPropertyDescriptor prop : enumLists) { if (node.getLocationInParent() == prop) { List<?> childList = (List<?>) node.getParent() .getStructuralProperty(prop); int idx = childList.indexOf(node); id += "[" + idx + "]"; } } if (node instanceof CompilationUnit) { // IJavaElement je = ((CompilationUnit) node).getJavaElement(); CompilationUnit cu = ((CompilationUnit) node); id += "["; if (cu.getPackage() != null && cu.getPackage().getName() != null) id += clean(cu.getPackage().getName().getFullyQualifiedName() + "."); if (cu.types() != null && cu.types().size() >= 1 && ((AbstractTypeDeclaration) cu.types().get(0)).getName() != null) id += ((AbstractTypeDeclaration) cu.types().get(0)).getName() .getFullyQualifiedName(); id += "]"; // id += "[" + clean(je.getPath().toPortableString()) + "]"; } return id; } private static String getParameterTypes(List<?> list) { String result = ""; for (Object p : list) { if (p instanceof SingleVariableDeclaration) { Type t = ((SingleVariableDeclaration) p).getType(); if (t != null) result += t.toString() + ";"; } } if (result.length() > 0) result = result.substring(0, result.length() - 1); return "[" + result + "]"; } public boolean equals(Object obj) { if (!(obj instanceof ASTID)) return false; ASTID otherIdentifier = ((ASTID) obj); return id.equals(otherIdentifier.id); } @Override public int hashCode() { return id.hashCode(); } public static String calculateId_old(ASTNode node) { if (node == null) return "/"; String id = calculateId(node.getParent()); if (node.getParent() instanceof Block) { Block block = (Block) node.getParent(); int idx = block.statements().indexOf(node); id += "[" + idx + "]"; } if (node.getLocationInParent() != null && node.getParent() != null) { id += ":" + node.getLocationInParent().getId(); } if (node.getParent() instanceof TryStatement) { TryStatement trystmt = (TryStatement) node.getParent(); if (trystmt.getBody() == node) id += "[body]"; } // if (node.getLocationInParent() instanceof // ChildListPropertyDescriptor) { // List children = (List) node.getParent().getStructuralProperty( // node.getLocationInParent()); // id += "[" + children.indexOf(node) + "]"; // } id += "/" + clean(node.getClass().getSimpleName()); if (node instanceof TypeDeclaration) { id += ":" + clean(((TypeDeclaration) node).getName().toString()); } if (node instanceof FieldDeclaration) { for (Object fragment : ((FieldDeclaration) node).fragments()) { id += ":" + clean(((VariableDeclarationFragment) fragment) .getName().toString()); } } if (node instanceof Type) { ITypeBinding b = ((Type) node).resolveBinding(); id += "::" + (b == null ? "null" : b.getQualifiedName()); } if (node instanceof VariableDeclaration) id += ":" + clean(((VariableDeclaration) node).getName().toString()); if (node instanceof Name) id += ":" + clean(((Name) node).getFullyQualifiedName()); if (node instanceof ImportDeclaration) id += ":" + clean(((ImportDeclaration) node).getName().toString()); if (node instanceof MethodDeclaration) { Type rt = ((MethodDeclaration) node).getReturnType2(); id += ":" + clean(rt == null ? "void" : rt.toString()); id += ":" + clean(((MethodDeclaration) node).getName().toString()); id += ":" + clean(getParameterTypes(((MethodDeclaration) node) .parameters())); } ChildListPropertyDescriptor[] enumLists = new ChildListPropertyDescriptor[] { SwitchStatement.STATEMENTS_PROPERTY, InfixExpression.EXTENDED_OPERANDS_PROPERTY, TryStatement.CATCH_CLAUSES_PROPERTY }; for (ChildListPropertyDescriptor prop : enumLists) { if (node.getLocationInParent() == prop) { List<?> childList = (List<?>) node.getParent() .getStructuralProperty(prop); int idx = childList.indexOf(node); id += "[" + idx + "]"; } } if (node instanceof CompilationUnit) { // IJavaElement je = ((CompilationUnit) node).getJavaElement(); CompilationUnit cu = ((CompilationUnit) node); id += "["; if (cu.getPackage() != null && cu.getPackage().getName() != null) id += clean(cu.getPackage().getName().getFullyQualifiedName() + "."); if (cu.types() != null && cu.types().size() >= 1 && ((AbstractTypeDeclaration) cu.types().get(0)).getName() != null) id += ((AbstractTypeDeclaration) cu.types().get(0)).getName() .getFullyQualifiedName(); id += "]"; // id += "[" + clean(je.getPath().toPortableString()) + "]"; } return id; } }