com.github.gumtreediff.gen.jdt.cd.CdJdtVisitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gen.jdt Show documentation
Show all versions of gen.jdt Show documentation
GumTree tree generator for Java code (Eclipse JDT based).
/*
* This file is part of GumTree.
*
* GumTree 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 3 of the License, or
* (at your option) any later version.
*
* GumTree 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 GumTree. If not, see .
*
* Copyright 2011-2015 Jean-Rémy Falleri
* Copyright 2011-2015 Floréal Morandat
*/
package com.github.gumtreediff.gen.jdt.cd;
import java.util.List;
import java.util.Stack;
import com.github.gumtreediff.gen.jdt.AbstractJdtVisitor;
import org.eclipse.jdt.core.dom.*;
import com.github.gumtreediff.gen.jdt.AbstractJdtVisitor;
import com.github.gumtreediff.tree.ITree;
import com.github.gumtreediff.tree.Tree;
/**
* Combination of two ChangeDistiller's AST visitors:
* JavaASTBodyTransformer and JavaASTChangeDistillerVisitor.
* Modifications are labeled as "@Inria"
*
* INRIA removed fNodeStack since it's inherited with the new
*/
@SuppressWarnings("unused")
public class CdJdtVisitor extends AbstractJdtVisitor {
private static final String COLON_SPACE = ": ";
private boolean fEmptyJavaDoc;
private boolean fInMethodDeclaration;
@Override
public boolean visit(Block node) {
// skip block as it is not interesting
return true;
}
@Override
public void endVisit(Block node) {
// do nothing pop is not needed (see visit(Block))
}
@SuppressWarnings("unchecked")
@Override
public boolean visit(FieldDeclaration node) {
if (node.getJavadoc() != null) {
node.getJavadoc().accept(this);
}
// @Inria
pushNode(node, node.toString());
//
visitListAsNode(EntityType.MODIFIERS, node.modifiers());
node.getType().accept(this);
visitListAsNode(EntityType.FRAGMENTS, node.fragments());
return false;
}
@Override
public void endVisit(FieldDeclaration node) {
// @Inria
popNode();
}
@Override
public boolean visit(Javadoc node) {
String string = "";
// @Inria: exclude doc
if (checkEmptyJavaDoc(string)) {
pushNode(node, string);
} else {
// @TODO not really robust, hopefully there is no nested javadoc comments.
fEmptyJavaDoc = true;
}
return false;
}
@Override
public void endVisit(Javadoc node) {
if (!fEmptyJavaDoc)
popNode();
else
fEmptyJavaDoc = false;
}
private boolean checkEmptyJavaDoc(String doc) {
String[] splittedDoc = doc.split("/\\*+\\s*");
String result = "";
for (String s : splittedDoc) {
result += s;
}
try {
result = result.split("\\s*\\*/")[0];
} catch (ArrayIndexOutOfBoundsException e) {
result = result.replace('/', ' ');
}
result = result.replace('*', ' ').trim();
return !result.equals("");
}
@SuppressWarnings("unchecked")
@Override
public boolean visit(MethodDeclaration node) {
if (node.getJavadoc() != null) {
node.getJavadoc().accept(this);
}
fInMethodDeclaration = true;
// @Inria
pushNode(node, node.getName().toString());
//
visitListAsNode(EntityType.MODIFIERS, node.modifiers());
if (node.getReturnType2() != null) {
node.getReturnType2().accept(this);
}
visitListAsNode(EntityType.TYPE_ARGUMENTS, node.typeParameters());
visitListAsNode(EntityType.PARAMETERS, node.parameters());
visitListAsNode(EntityType.THROW, node.thrownExceptions());
// @Inria
// The body can be null when the method declaration is from a interface
if (node.getBody() != null) {
node.getBody().accept(this);
}
return false;
}
@Override
public void endVisit(MethodDeclaration node) {
fInMethodDeclaration = false;
popNode();
}
@Override
public boolean visit(Modifier node) {
pushNode(node, node.getKeyword().toString());
return false;
}
@Override
public void endVisit(Modifier node) {
popNode();
}
@SuppressWarnings("unchecked")
@Override
public boolean visit(ParameterizedType node) {
pushNode(node, "");
node.getType().accept(this);
visitListAsNode(EntityType.TYPE_ARGUMENTS, node.typeArguments());
return false;
}
@Override
public void endVisit(ParameterizedType node) {
popNode();
}
@Override
public boolean visit(PrimitiveType node) {
String vName = "";
if (fInMethodDeclaration) {
vName += getCurrentParent().getLabel() + COLON_SPACE;
}
pushNode(node, vName + node.getPrimitiveTypeCode().toString());
return false;
}
@Override
public void endVisit(PrimitiveType node) {
popNode();
}
@Override
public boolean visit(QualifiedType node) {
pushNode(node, "");
return true;
}
@Override
public void endVisit(QualifiedType node) {
popNode();
}
@Override
public boolean visit(SimpleType node) {
String vName = "";
if (fInMethodDeclaration) {
vName += getCurrentParent().getLabel() + COLON_SPACE;
}
pushNode(node, vName + node.getName().getFullyQualifiedName());
return false;
}
@Override
public void endVisit(SimpleType node) {
popNode();
}
@Override
public boolean visit(SingleVariableDeclaration node) {
boolean isNotParam = getCurrentParent().getLabel() != EntityType.PARAMETERS.toString();// @inria
pushNode(node, node.getName().getIdentifier());
node.getType().accept(this);
return false;
}
@Override
public void endVisit(SingleVariableDeclaration node) {
popNode();
}
@SuppressWarnings("unchecked")
@Override
public boolean visit(TypeDeclaration node) {
if (node.getJavadoc() != null) {
node.getJavadoc().accept(this);
}
// @Inria
pushNode(node, node.getName().toString());
visitListAsNode(EntityType.MODIFIERS, node.modifiers());
visitListAsNode(EntityType.TYPE_ARGUMENTS, node.typeParameters());
if (node.getSuperclassType() != null) {
node.getSuperclassType().accept(this);
}
visitListAsNode(EntityType.SUPER_INTERFACE_TYPES, node.superInterfaceTypes());
// @Inria
// Change Distiller does not check the changes at Class Field declaration
for (FieldDeclaration fd : node.getFields()) {
fd.accept(this);
}
// @Inria
// Visit Declaration and Body (inside MD visiting)
for (MethodDeclaration md : node.getMethods()) {
md.accept(this);
}
return false;
}
@Override
public void endVisit(TypeDeclaration node) {
popNode();
}
@Override
public boolean visit(TypeDeclarationStatement node) {
// skip, only type declaration is interesting
return true;
}
@Override
public void endVisit(TypeDeclarationStatement node) {
// do nothing
}
@Override
public boolean visit(TypeLiteral node) {
pushNode(node, "");
return true;
}
@Override
public void endVisit(TypeLiteral node) {
popNode();
}
@SuppressWarnings("unchecked")
@Override
public boolean visit(TypeParameter node) {
pushNode(node, node.getName().getFullyQualifiedName());
visitList(node.typeBounds());
return false;
}
@Override
public void endVisit(TypeParameter node) {
popNode();
}
@SuppressWarnings("unchecked")
@Override
public boolean visit(VariableDeclarationExpression node) {
pushNode(node, "");
visitListAsNode(EntityType.MODIFIERS, node.modifiers());
node.getType().accept(this);
visitListAsNode(EntityType.FRAGMENTS, node.fragments());
return false;
}
@Override
public void endVisit(VariableDeclarationExpression node) {
popNode();
}
@Override
public boolean visit(VariableDeclarationFragment node) {
pushNode(node, node.getName().getFullyQualifiedName());
return false;
}
@Override
public void endVisit(VariableDeclarationFragment node) {
popNode();
}
@Override
public boolean visit(WildcardType node) {
String bound = node.isUpperBound() ? "extends" : "super";
pushNode(node, bound);
return true;
}
@Override
public void endVisit(WildcardType node) {
popNode();
}
private void visitList(List list) {
for (ASTNode node : list) {
(node).accept(this);
}
}
private void visitListAsNode(EntityType fakeType, List list) {
int start = startPosition(list);
pushFakeNode(fakeType, start, endPosition(list) - start);
if (!list.isEmpty()) {
// @Inria
// As ChangeDistiller has empty nodes e.g.
// Type Argument, Parameter, Thown,
// the push and pop are before the empty condition check
visitList(list);
}
popNode();
}
private int startPosition(List list) {
if (list.isEmpty())
return -1;
return list.get(0).getStartPosition();
}
private int endPosition(List list) {
if (list.isEmpty())
return 0;
ASTNode n = list.get(list.size() - 1);
return n.getStartPosition() + n.getLength();
}
// /***************BODY VISITOR*************************
private static final String COLON = ":";
@Override
public boolean visit(AssertStatement node) {
String value = node.getExpression().toString();
if (node.getMessage() != null) {
value += COLON + node.getMessage().toString();
}
pushNode(node, value);
return false;
}
@Override
public void endVisit(AssertStatement node) {
popNode();
}
@Override
public boolean visit(BreakStatement node) {
pushNode(node, node.getLabel() != null ? node.getLabel().toString() : "");
return false;
}
@Override
public void endVisit(BreakStatement node) {
popNode();
}
@Override
public boolean visit(CatchClause node) {
pushNode(node, ((SimpleType) node.getException().getType()).getName().getFullyQualifiedName());
// since exception type is used as value, visit children by hand
node.getBody().accept(this);
return false;
}
@Override
public void endVisit(CatchClause node) {
popNode();
}
@Override
public boolean visit(ConstructorInvocation node) {
pushNode(node, node.toString());
return false;
}
@Override
public void endVisit(ConstructorInvocation node) {
popNode();
}
@Override
public boolean visit(ContinueStatement node) {
pushNode(node, node.getLabel() != null ? node.getLabel().toString() : "");
return false;
}
@Override
public void endVisit(ContinueStatement node) {
popNode();
}
@Override
public boolean visit(DoStatement node) {
pushNode(node, node.getExpression().toString());
return true;
}
@Override
public void endVisit(DoStatement node) {
popNode();
}
@Override
public boolean visit(EmptyStatement node) {
pushNode(node, "");
return false;
}
@Override
public void endVisit(EmptyStatement node) {
popNode();
}
@Override
public boolean visit(EnhancedForStatement node) {
pushNode(node, node.getParameter().toString() + COLON + node.getExpression().toString());
return true;
}
@Override
public void endVisit(EnhancedForStatement node) {
popNode();
}
@Override
public boolean visit(ExpressionStatement node) {
pushNode(node.getExpression(), node.toString());
return false;
}
@Override
public void endVisit(ExpressionStatement node) {
popNode();
}
@Override
public boolean visit(ForStatement node) {
String value = "";
if (node.getExpression() != null) {
value = node.getExpression().toString();
}
pushNode(node, value);
return true;
}
@Override
public void endVisit(ForStatement node) {
popNode();
}
@Override
public boolean visit(IfStatement node) {
String expression = node.getExpression().toString();
pushNode(node, expression/* , node.getStartPosition(), node.getLength() */);
Statement stmt = node.getThenStatement();
if (stmt != null) {
pushNode(stmt, expression);
stmt.accept(this);
popNode();
}
stmt = node.getElseStatement();
if (stmt != null) {
pushNode(stmt, expression);
node.getElseStatement().accept(this);
popNode();
}
return false;
}
@Override
public void endVisit(IfStatement node) {
popNode();
}
@Override
public boolean visit(LabeledStatement node) {
pushNode(node, node.getLabel().getFullyQualifiedName());
node.getBody().accept(this);
return false;
}
@Override
public void endVisit(LabeledStatement node) {
popNode();
}
@Override
public boolean visit(ReturnStatement node) {
pushNode(node, node.getExpression() != null ? node.getExpression().toString() : "");
return false;
}
@Override
public void endVisit(ReturnStatement node) {
popNode();
}
@Override
public boolean visit(SuperConstructorInvocation node) {
pushNode(node, node.toString());
return false;
}
@Override
public void endVisit(SuperConstructorInvocation node) {
popNode();
}
@Override
public boolean visit(SwitchCase node) {
pushNode(node, node.getExpression() != null ? node.getExpression().toString() : "default");
return false;
}
@Override
public void endVisit(SwitchCase node) {
popNode();
}
@SuppressWarnings("unchecked")
@Override
public boolean visit(SwitchStatement node) {
pushNode(node, node.getExpression().toString());
visitList(node.statements());
return false;
}
@Override
public void endVisit(SwitchStatement node) {
popNode();
}
@Override
public boolean visit(SynchronizedStatement node) {
pushNode(node, node.getExpression().toString());
return true;
}
@Override
public void endVisit(SynchronizedStatement node) {
popNode();
}
@Override
public boolean visit(ThrowStatement node) {
pushNode(node, node.getExpression().toString());
return false;
}
@Override
public void endVisit(ThrowStatement node) {
popNode();
}
@SuppressWarnings("unchecked")
@Override
public boolean visit(TryStatement node) {
pushNode(node, "");
Statement stmt = node.getBody();
pushNode(stmt, "");
stmt.accept(this);
popNode();
visitListAsNode(EntityType.CATCH_CLAUSES, node.catchClauses());
stmt = node.getFinally();
if (stmt != null) {
// @Inria
pushNode(stmt, "");
stmt.accept(this);
popNode();
}
return false;
}
@Override
public void endVisit(TryStatement node) {
popNode();
}
@Override
public boolean visit(VariableDeclarationStatement node) {
pushNode(node, node.toString());
return false;
}
@Override
public void endVisit(VariableDeclarationStatement node) {
popNode();
}
@Override
public boolean visit(WhileStatement node) {
pushNode(node, node.getExpression().toString());
return true;
}
@Override
public void endVisit(WhileStatement node) {
popNode();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy