merge all into single repo

This commit is contained in:
fixminer
2020-04-06 20:40:32 +02:00
parent 9dcdb6aafc
commit 3c91dd7ea3
524 changed files with 1272301 additions and 1531 deletions
+68
View File
@@ -0,0 +1,68 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.gumtreediff</groupId>
<artifactId>gumtree</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>
<artifactId>gen.jdt</artifactId>
<packaging>jar</packaging>
<name>Gumtree JDT Tree Generator</name>
<dependencies>
<dependency>
<groupId>edu.lu.uni</groupId>
<artifactId>simple-utils</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.gumtreediff</groupId>
<artifactId>core</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<!-- <dependency>
<groupId>edu.lu.uni.serval</groupId>
<artifactId>CommitParser</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency> -->
<!-- Logger -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
<dependency>
<groupId>org.eclipse.core</groupId>
<artifactId>runtime</artifactId>
<version>3.10.0-v20140318-2214</version>
</dependency>
<dependency>
<groupId>org.eclipse.birt.runtime</groupId>
<artifactId>org.eclipse.core.resources</artifactId>
<version>3.10.0.v20150423-0755</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.eclipse.tycho/org.eclipse.jdt.core -->
<dependency>
<groupId>org.eclipse.tycho</groupId>
<artifactId>org.eclipse.jdt.core</artifactId>
<version>3.12.2.v20161117-1814</version>
</dependency>
<!-- <dependency>
<groupId>org.eclipse.tycho</groupId>
<artifactId>org.eclipse.jdt.core</artifactId>
<version>3.12.0.v20160516-2131</version>
</dependency> -->
</dependencies>
</project>
@@ -0,0 +1,72 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright 2011-2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
* Copyright 2011-2015 Floréal Morandat <florealm@gmail.com>
*/
package com.github.gumtreediff.gen.jdt;
import com.github.gumtreediff.gen.TreeGenerator;
import com.github.gumtreediff.tree.TreeContext;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Map;
public abstract class AbstractJdtTreeGenerator extends TreeGenerator {
private static char[] readerToCharArray(Reader r) throws IOException {
StringBuilder fileData = new StringBuilder();
try (BufferedReader br = new BufferedReader(r)) {
char[] buf = new char[10];
int numRead = 0;
while ((numRead = br.read(buf)) != -1) {
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[1024];
}
}
return fileData.toString().toCharArray();
}
@Override
public TreeContext generate(Reader r) throws IOException {
return generate(r, ASTParser.K_COMPILATION_UNIT);
}
@Override
public TreeContext generate(Reader r, int astParserType) throws IOException {
ASTParser parser = ASTParser.newParser(AST.JLS8);
parser.setKind(astParserType);
Map<String, String> pOptions = JavaCore.getOptions();
pOptions.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
pOptions.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
pOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
pOptions.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED);
parser.setCompilerOptions(pOptions);
parser.setSource(readerToCharArray(r));
AbstractJdtVisitor v = createVisitor();
parser.createAST(null).accept(v);
return v.getTreeContext();
}
protected abstract AbstractJdtVisitor createVisitor();
}
@@ -0,0 +1,80 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright 2011-2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
* Copyright 2011-2015 Floréal Morandat <florealm@gmail.com>
*/
package com.github.gumtreediff.gen.jdt;
import java.util.ArrayDeque;
import java.util.Deque;
import com.github.gumtreediff.gen.jdt.cd.EntityType;
import com.github.gumtreediff.tree.ITree;
import com.github.gumtreediff.tree.TreeContext;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
public abstract class AbstractJdtVisitor extends ASTVisitor {
protected TreeContext context = new TreeContext();
private Deque<ITree> trees = new ArrayDeque<>();
public AbstractJdtVisitor() {
super(true);
}
public TreeContext getTreeContext() {
return context;
}
protected void pushNode(ASTNode n, String label) {
int type = n.getNodeType();
String typeName = n.getClass().getSimpleName();
push(type, typeName, label, n.getStartPosition(), n.getLength());
}
protected void pushFakeNode(EntityType n, int startPosition, int length) {
int type = -n.ordinal(); // Fake types have negative types (but does it matter ?)
String typeName = n.name();
push(type, typeName, "", startPosition, length);
}
protected void push(int type, String typeName, String label, int startPosition, int length) {
ITree t = context.createTree(type, label, typeName);
t.setPos(startPosition);
t.setLength(length);
if (trees.isEmpty())
context.setRoot(t);
else {
ITree parent = trees.peek();
t.setParentAndUpdateChildren(parent);
}
trees.push(t);
}
protected ITree getCurrentParent() {
return trees.peek();
}
protected void popNode() {
trees.pop();
}
}
@@ -0,0 +1,35 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright 2011-2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
* Copyright 2011-2015 Floréal Morandat <florealm@gmail.com>
*/
package com.github.gumtreediff.gen.jdt;
import com.github.gumtreediff.gen.Register;
import com.github.gumtreediff.gen.Registry;
@Register(id = "java-jdt", accept = "\\.java$", priority = Registry.Priority.MAXIMUM)
public class JdtTreeGenerator extends AbstractJdtTreeGenerator {
@Override
protected AbstractJdtVisitor createVisitor() {
return new JdtVisitor();
}
}
@@ -0,0 +1,83 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright 2011-2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
* Copyright 2011-2015 Floréal Morandat <florealm@gmail.com> *
*/
package com.github.gumtreediff.gen.jdt;
import org.eclipse.jdt.core.dom.*;
public class JdtVisitor extends AbstractJdtVisitor {
public JdtVisitor() {
super();
}
@Override
public void preVisit(ASTNode n) {
if (! (n instanceof Comment || n instanceof TagElement || n instanceof TextElement)) {
pushNode(n, getLabel(n));
}
}
protected String getLabel(ASTNode n) {
if (n instanceof Name) return ((Name) n).getFullyQualifiedName();
if (n instanceof Type) return n.toString();
if (n instanceof Modifier) return n.toString();
if (n instanceof StringLiteral) return ((StringLiteral) n).getEscapedValue();
if (n instanceof NumberLiteral) return ((NumberLiteral) n).getToken();
if (n instanceof CharacterLiteral) return ((CharacterLiteral) n).getEscapedValue();
if (n instanceof BooleanLiteral) return ((BooleanLiteral) n).toString();
if (n instanceof InfixExpression) return ((InfixExpression) n).getOperator().toString();
if (n instanceof PrefixExpression) return ((PrefixExpression) n).getOperator().toString();
if (n instanceof PostfixExpression) return ((PostfixExpression) n).getOperator().toString();
if (n instanceof Assignment) return ((Assignment) n).getOperator().toString();
// if (n instanceof TextElement) return n.toString();
// if (n instanceof TagElement) return ((TagElement) n).getTagName();
return "";
}
@Override
public boolean visit(Javadoc node) {
return false;
}
@Override
public boolean visit(TagElement e) {
return false;
}
@Override
public boolean visit(TextElement node) {
return false;
}
@Override
public boolean visit(QualifiedName name) {
return false;
}
@Override
public void postVisit(ASTNode n) {
if (! (n instanceof Comment || n instanceof TagElement || n instanceof TextElement)) {
popNode();
}
}
}
@@ -0,0 +1,33 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright 2011-2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
* Copyright 2011-2015 Floréal Morandat <florealm@gmail.com>
*/
package com.github.gumtreediff.gen.jdt.cd;
import com.github.gumtreediff.gen.Register;
import com.github.gumtreediff.gen.jdt.AbstractJdtVisitor;
import com.github.gumtreediff.gen.jdt.AbstractJdtTreeGenerator;
@Register(id = "java-jdt-cd")
public class CdJdtTreeGenerator extends AbstractJdtTreeGenerator {
@Override
protected AbstractJdtVisitor createVisitor() {
return new CdJdtVisitor();
}
}
@@ -0,0 +1,658 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright 2011-2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
* Copyright 2011-2015 Floréal Morandat <florealm@gmail.com>
*/
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) {
pushNode(node, "Block");
return true;
}
@Override
public void endVisit(Block node) {
popNode();
}
@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.thrownExceptionTypes());
// @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());
Expression exp = node.getInitializer();
if (exp != null) {
pushNode(exp, exp.toString());
}
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<ASTNode> list) {
for (ASTNode node : list) {
(node).accept(this);
}
}
private void visitListAsNode(EntityType fakeType, List<ASTNode> 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<ASTNode> list) {
if (list.isEmpty())
return -1;
return list.get(0).getStartPosition();
}
private int endPosition(List<ASTNode> 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, node.getException().toString());
// 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, "ThenBlock");
stmt.accept(this);
popNode();
}
stmt = node.getElseStatement();
if (stmt != null) {
pushNode(stmt, "ElseBlock");
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, "try");
Statement stmt = node.getBody();
pushNode(stmt, "TryBody");
stmt.accept(this);
popNode();
visitListAsNode(EntityType.CATCH_CLAUSES, node.catchClauses());
stmt = node.getFinally();
if (stmt != null) {
// @Inria
pushNode(stmt, "Finally");
stmt.accept(this);
popNode();
}
return false;
}
@Override
public void endVisit(TryStatement node) {
popNode();
}
@Override
public boolean visit(VariableDeclarationStatement node) {
pushNode(node, node.toString());
Type type = node.getType();
type.accept(this);
List<?> fragments = node.fragments();
for (Object obj : fragments) {
VariableDeclarationFragment fragment = (VariableDeclarationFragment) obj;
fragment.accept(this);
}
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();
}
}
@@ -0,0 +1,215 @@
/*
* Copyright 2009 University of Zurich, Switzerland
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.gumtreediff.gen.jdt.cd;
/**
* All types for source code entities that are used by ChangeDistiller to build up the AST (abstract syntax tree). Most
* are taken from {@link org.eclipse.jdt.core.dom.ASTNode}.
*
* @author zubi
*/
public enum EntityType {
ANNOTATION_TYPE_DECLARATION(true),
ANNOTATION_TYPE_MEMBER_DECLARATION(true),
ARGUMENTS(false),
ARRAY_ACCESS(true),
ARRAY_CREATION(true),
ARRAY_DIMENSION(true),
ARRAY_INITIALIZER(true),
ARRAY_TYPE(true),
ASSERT_STATEMENT(true),
ASSIGNMENT(true),
ATTRIBUTE(false),
BLOCK(false),
BLOCK_COMMENT(true),
BODY(false),
BODY_DECLARATIONS(false),
BOOLEAN_LITERAL(true),
BREAK_STATEMENT(true),
CAST_EXPRESSION(true),
CATCH_CLAUSE(true),
CATCH_CLAUSES(false),
CHARACTER_LITERAL(true),
CLASS(false),
CLASS_INSTANCE_CREATION(true),
COMPILATION_UNIT(true),
CONDITIONAL_EXPRESSION(true),
CONSTRUCTOR_INVOCATION(true),
CONTINUE_STATEMENT(true),
DO_STATEMENT(true),
ELSE_STATEMENT(true),
EMPTY_STATEMENT(true),
ENHANCED_FOR_STATEMENT(true),
ENUM_CONSTANT_DECLARATION(true),
ENUM_CONSTANTS(false),
ENUM_DECLARATION(true),
EXPRESSION_STATEMENT(true),
EXTENDED_OPERANDS(false),
FIELD_ACCESS(true),
FIELD_DECLARATION(true),
FINALLY(false),
FOR_STATEMENT(true),
FRAGMENTS(false),
IF_STATEMENT(true),
IMPORT_DECLARATION(true),
INFIX_EXPRESSION(true),
INITIALIZER(true),
INITIALIZERS(false),
INSTANCEOF_EXPRESSION(true),
JAVADOC(true),
LABELED_STATEMENT(true),
LINE_COMMENT(true),
MARKER_ANNOTATION(true),
MEMBER_REF(true),
MEMBER_VALUE_PAIR(true),
METHOD(false),
METHOD_DECLARATION(true),
METHOD_INVOCATION(true),
METHOD_REF(true),
METHOD_REF_PARAMETER(true),
MODIFIER(true),
MODIFIERS(false),
NORMAL_ANNOTATION(true),
NULL_LITERAL(true),
NUMBER_LITERAL(true),
PACKAGE_DECLARATION(true),
PARAMETERIZED_TYPE(true),
PARAMETERS(false),
PARENTHESIZED_EXPRESSION(true),
POSTFIX_EXPRESSION(true),
PREFIX_EXPRESSION(true),
PRIMITIVE_TYPE(true),
QUALIFIED_NAME(true),
QUALIFIED_TYPE(true),
RETURN_STATEMENT(true),
ROOT_NODE(true),
SIMPLE_NAME(true),
SIMPLE_TYPE(true),
SINGLE_MEMBER_ANNOTATION(true),
SINGLE_VARIABLE_DECLARATION(true),
STRING_LITERAL(true),
SUPER_CONSTRUCTOR_INVOCATION(true),
SUPER_FIELD_ACCESS(true),
SUPER_INTERFACE_TYPES(false),
SUPER_METHOD_INVOCATION(true),
SWITCH_CASE(true),
SWITCH_STATEMENT(true),
SYNCHRONIZED_STATEMENT(true),
TAG_ELEMENT(true),
TEXT_ELEMENT(true),
THEN_STATEMENT(true),
THIS_EXPRESSION(true),
THROW(false),
THROW_STATEMENT(true),
TRY_STATEMENT(true),
TYPE_ARGUMENTS(false),
TYPE_DECLARATION(true),
TYPE_DECLARATION_STATEMENT(true),
TYPE_LITERAL(true),
TYPE_PARAMETER(true),
UPDATERS(false),
VARIABLE_DECLARATION_EXPRESSION(true),
VARIABLE_DECLARATION_FRAGMENT(true),
VARIABLE_DECLARATION_STATEMENT(true),
WHILE_STATEMENT(true),
WILDCARD_TYPE(true);
private final boolean fIsValidChange;
private EntityType(boolean isValidChange) {
fIsValidChange = isValidChange;
}
/**
* Returns number of defined entity types.
*
* @return number of entity types.
*/
public static int getNumberOfEntityTypes() {
return values().length;
}
/**
* Returns whether changes occurred on this source code entity type are extracted by ChangeDistiller or not (e.g.
* changes in the <code>finally</code> clause are ignored).
*
* @return <code>true</code> if changes on this entity type are considered and extracted, <code>false</code>
* otherwise.
*/
public boolean isValidChange() {
return fIsValidChange;
}
/**
* Returns whether the given entity type is a type of a type declaration or not.
*
* @param type
* to analyze
* @return <code>true</code> if given entity type is a type, <code>false</code> otherwise.
*/
public static boolean isType(EntityType type) {
switch (type) {
case ARRAY_TYPE:
case PARAMETERIZED_TYPE:
case PRIMITIVE_TYPE:
case QUALIFIED_TYPE:
case SIMPLE_TYPE:
case WILDCARD_TYPE:
return true;
default:
return false;
}
}
/**
* Returns whether the given entity type is a statement or not.
*
* @param type
* to analyze
* @return <code>true</code> if given entity type is a statement, <code>false</code> otherwise.
*/
public static boolean isAtStatementLevel(EntityType type) {
switch (type) {
case ASSERT_STATEMENT:
case ASSIGNMENT:
case BREAK_STATEMENT:
case CATCH_CLAUSE:
case CLASS_INSTANCE_CREATION:
case CONSTRUCTOR_INVOCATION:
case CONTINUE_STATEMENT:
case DO_STATEMENT:
case FINALLY:
case FOR_STATEMENT:
case IF_STATEMENT:
case LABELED_STATEMENT:
case METHOD_INVOCATION:
case RETURN_STATEMENT:
case SUPER_CONSTRUCTOR_INVOCATION:
case SUPER_METHOD_INVOCATION:
case SWITCH_CASE:
case SWITCH_STATEMENT:
case SYNCHRONIZED_STATEMENT:
case THROW_STATEMENT:
case TRY_STATEMENT:
case VARIABLE_DECLARATION_STATEMENT:
case WHILE_STATEMENT:
case ENHANCED_FOR_STATEMENT:
return true;
default:
return false;
}
}
}
@@ -0,0 +1,33 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright 2011-2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
* Copyright 2011-2015 Floréal Morandat <florealm@gmail.com>
*/
package edu.lu.uni.serval.gen.jdt.exp;
import com.github.gumtreediff.gen.Register;
import com.github.gumtreediff.gen.jdt.AbstractJdtVisitor;
import com.github.gumtreediff.gen.jdt.AbstractJdtTreeGenerator;
@Register(id = "java-jdt-cd")
public class ExpJdtTreeGenerator extends AbstractJdtTreeGenerator {
@Override
protected AbstractJdtVisitor createVisitor() {
return new ExpJdtVisitor();
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,72 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright 2011-2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
* Copyright 2011-2015 Floréal Morandat <florealm@gmail.com>
*/
package edu.lu.uni.serval.gen.jdt.rawToken;
import com.github.gumtreediff.gen.TreeGenerator;
import com.github.gumtreediff.tree.TreeContext;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Map;
public abstract class AbstractRawTokenJdtTreeGenerator extends TreeGenerator {
private static char[] readerToCharArray(Reader r) throws IOException {
StringBuilder fileData = new StringBuilder();
try (BufferedReader br = new BufferedReader(r)) {
char[] buf = new char[10];
int numRead = 0;
while ((numRead = br.read(buf)) != -1) {
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[1024];
}
}
return fileData.toString().toCharArray();
}
@Override
public TreeContext generate(Reader r) throws IOException {
return generate(r, ASTParser.K_COMPILATION_UNIT);
}
@Override
public TreeContext generate(Reader r, int astParserType) throws IOException {
ASTParser parser = ASTParser.newParser(AST.JLS8);
parser.setKind(astParserType);
Map<String, String> pOptions = JavaCore.getOptions();
pOptions.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
pOptions.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
pOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
pOptions.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED);
parser.setCompilerOptions(pOptions);
parser.setSource(readerToCharArray(r));
AbstractRawTokenJdtVisitor v = createVisitor();
parser.createAST(null).accept(v);
return v.getTreeContext();
}
protected abstract AbstractRawTokenJdtVisitor createVisitor();
}
@@ -0,0 +1,46 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright 2011-2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
* Copyright 2011-2015 Floréal Morandat <florealm@gmail.com>
*/
package edu.lu.uni.serval.gen.jdt.rawToken;
import com.github.gumtreediff.gen.jdt.AbstractJdtVisitor;
import org.eclipse.jdt.core.dom.ASTNode;
/**
* Create AbstractRowTokenJdtVisitor by extending AbstractJdtVisitor and overriding pushNode method.
*
* Remove the ASTNode type in trees.
*
* @author kui.liu
*
*/
public abstract class AbstractRawTokenJdtVisitor extends AbstractJdtVisitor {
public AbstractRawTokenJdtVisitor() {
super();
}
@Override
protected void pushNode(ASTNode n, String label) {
push(0, "", label, n.getStartPosition(), n.getLength());
}
}
@@ -0,0 +1,35 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright 2011-2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
* Copyright 2011-2015 Floréal Morandat <florealm@gmail.com>
*/
package edu.lu.uni.serval.gen.jdt.rawToken;
import com.github.gumtreediff.gen.Register;
import com.github.gumtreediff.gen.Registry;
@Register(id = "java-jdt", accept = "\\.java$", priority = Registry.Priority.MAXIMUM)
public class RawTokenJdtTreeGenerator extends AbstractRawTokenJdtTreeGenerator {
@Override
protected AbstractRawTokenJdtVisitor createVisitor() {
return new RawTokenJdtVisitor();
}
}
@@ -0,0 +1,99 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright 2011-2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
* Copyright 2011-2015 Floréal Morandat <florealm@gmail.com>
*/
package edu.lu.uni.serval.gumtree;
import com.github.gumtreediff.gen.Register;
import com.github.gumtreediff.gen.TreeGenerator;
import com.github.gumtreediff.io.TreeIoUtils;
import com.github.gumtreediff.tree.TreeContext;
import com.github.gumtreediff.tree.TreeContext.MetadataSerializers;
import com.github.gumtreediff.tree.TreeContext.MetadataUnserializers;
import java.io.*;
import java.util.Arrays;
import java.util.regex.Pattern;
@Register(id = "c-cocci", accept = "\\.[ch]$")
public class CTreeGenerator extends TreeGenerator {
private static final String COCCI_CMD = System.getProperty("gumtree.cgum.path", "cgum");
private static final MetadataSerializers defaultSerializers = new MetadataSerializers();
private static final MetadataUnserializers defaultUnserializers = new MetadataUnserializers();
static {
defaultSerializers.add("lines", x -> Arrays.toString((int[]) x));
Pattern comma = Pattern.compile(", ");
defaultUnserializers.add("lines", x -> {
String[] v = comma.split(x.substring(1, x.length() - 2), 4);
int[] ints = new int[v.length];
for (int i = 0; i < ints.length; i++) {
ints[i] = Integer.parseInt(v[i]);
}
return ints;
});
}
@Override
public TreeContext generate(Reader r) throws IOException {
//FIXME this is not efficient but I am not sure how to speed up things here.
File f = File.createTempFile("gumtree", ".c");
FileWriter w = new FileWriter(f);
BufferedReader br = new BufferedReader(r);
String line = br.readLine();
while (line != null) {
w.append(line);
w.append(System.lineSeparator());
line = br.readLine();
}
w.close();
br.close();
ProcessBuilder b = new ProcessBuilder("/Users/haoyetian/Documents/Lu_code/cgum/cgum", f.getAbsolutePath());
b.directory(f.getParentFile());
try {
Process p = b.start();
StringBuffer buf = new StringBuffer();
br = new BufferedReader(new InputStreamReader(p.getInputStream()));
// TODO Why do we need to read and bufferize eveything, when we could/should only use generateFromStream
line = null;
while ((line = br.readLine()) != null)
buf.append(line + "\n");
p.waitFor();
if (p.exitValue() != 0)
throw new RuntimeException(
String.format("cgum Error [%d] %s\n", p.exitValue(), buf.toString())
);
r.close();
String xml = buf.toString();
TreeContext treeContext = TreeIoUtils.fromXml(CTreeGenerator.defaultUnserializers).generateFromString(xml);
return treeContext;
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
f.delete();
}
}
@Override
protected TreeContext generate(Reader r, int astParserType) throws IOException {
return null;
}
}
@@ -0,0 +1,82 @@
package edu.lu.uni.serval.gumtree;
import java.io.File;
import java.util.List;
import java.util.Set;
import com.github.gumtreediff.matchers.Mapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.gumtreediff.actions.ActionGenerator;
import com.github.gumtreediff.actions.model.Action;
import com.github.gumtreediff.matchers.Matcher;
import com.github.gumtreediff.matchers.Matchers;
import com.github.gumtreediff.tree.ITree;
import com.github.gumtreediff.gen.*;
import edu.lu.uni.serval.gumtree.GumTreeGenerator.GumTreeType;
public class GumTreeComparer {
private static Logger log = LoggerFactory.getLogger(GumTreeComparer.class);
public List<Action> compareTwoFilesWithGumTree(File prevFile, File revFile) {
// Generate GumTree.
ITree oldTree = null;
ITree newTree = null;
try {
oldTree = new GumTreeGenerator().generateITreeForJavaFile(prevFile, GumTreeType.EXP_JDT);
newTree = new GumTreeGenerator().generateITreeForJavaFile(revFile, GumTreeType.EXP_JDT);
} catch (Exception e) {
if (oldTree == null) {
log.info("Null GumTree of Previous File: " + prevFile.getPath());
} else if (newTree == null) {
log.info("Null GumTree of Revised File: " + revFile.getPath());
}
}
if (oldTree != null && newTree != null) {
Matcher m = Matchers.getInstance().getMatcher(oldTree, newTree);
m.match();
ActionGenerator ag = new ActionGenerator(oldTree, newTree, m.getMappings());
ag.generate();
List<Action> actions = ag.getActions(); // change actions from bug to patch
return actions;
}
return null;
}
public List<Action> compareCFilesWithGumTree(File prevFile, File revFile) {
// Generate GumTree.
ITree oldTree = null;
ITree newTree = null;
try {
// oldTree = new GumTreeGenerator().generateITreeForCFileForCode(prevFile);
// newTree = new GumTreeGenerator().generateITreeForCFileForCode(revFile);
// oldTree = new SrcmlCppTreeGenerator().generateFromFile(prevFile);
// newTree = new SrcmlCppTreeGenerator().generateFromFile(revFile);
} catch (Exception e) {
if (oldTree == null) {
log.info("Null GumTree of Previous File: " + prevFile.getPath());
} else if (newTree == null) {
log.info("Null GumTree of Revised File: " + revFile.getPath());
}
}
if (oldTree != null && newTree != null) {
Matcher m = Matchers.getInstance().getMatcher(oldTree, newTree);
m.match();
ActionGenerator ag = new ActionGenerator(oldTree, newTree, m.getMappings());
ag.generate();
List<Action> actions = ag.getActions(); // change actions from bug to patch
return actions;
}
return null;
}
}
@@ -0,0 +1,111 @@
package edu.lu.uni.serval.gumtree;
import java.io.File;
import java.io.IOException;
import org.eclipse.jdt.core.dom.ASTParser;
import com.github.gumtreediff.tree.ITree;
import com.github.gumtreediff.tree.TreeContext;
import edu.lu.uni.serval.gen.jdt.exp.ExpJdtTreeGenerator;
import edu.lu.uni.serval.gen.jdt.rawToken.RawTokenJdtTreeGenerator;
public class GumTreeGenerator {
public enum GumTreeType {
EXP_JDT,
RAW_TOKEN,
}
public ITree generateITreeForJavaFile(File javaFile, GumTreeType type) {
ITree gumTree = null;
try {
TreeContext tc = null;
switch (type) {
case EXP_JDT:
tc = new ExpJdtTreeGenerator().generateFromFile(javaFile);
break;
case RAW_TOKEN:
tc = new RawTokenJdtTreeGenerator().generateFromFile(javaFile);
break;
default:
break;
}
if (tc != null){
gumTree = tc.getRoot();
}
} catch (IOException e) {
e.printStackTrace();
}
return gumTree;
}
public ITree generateITreeForJavaFile(String javaFile, GumTreeType type) {
ITree gumTree = null;
try {
TreeContext tc = null;
switch (type) {
case EXP_JDT:
tc = new ExpJdtTreeGenerator().generateFromFile(javaFile);
break;
case RAW_TOKEN:
tc = new RawTokenJdtTreeGenerator().generateFromFile(javaFile);
break;
default:
break;
}
if (tc != null){
gumTree = tc.getRoot();
}
} catch (IOException e) {
e.printStackTrace();
}
return gumTree;
}
public ITree generateITreeForCodeBlock(String codeBlock, GumTreeType type) {
ITree gumTree = null;
try {
TreeContext tc = null;
switch (type) {
case EXP_JDT:
tc = new ExpJdtTreeGenerator().generateFromString(codeBlock, ASTParser.K_STATEMENTS);
break;
case RAW_TOKEN:
tc = new RawTokenJdtTreeGenerator().generateFromString(codeBlock, ASTParser.K_STATEMENTS);
break;
default:
break;
}
if (tc != null){
gumTree = tc.getRoot();
}
} catch (IOException e) {
e.printStackTrace();
}
return gumTree;
}
public ITree generateITreeForCFileForCode(File javaFile) {
ITree gumTree = null;
try {
TreeContext tc = null;
tc = new CTreeGenerator().generateFromFile(javaFile);
if (tc != null){
gumTree = tc.getRoot();
}
} catch (IOException e) {
e.printStackTrace();
}
return gumTree;
}
}
@@ -0,0 +1,113 @@
package edu.lu.uni.serval.gumtree;
import com.github.gumtreediff.actions.ActionGenerator;
import com.github.gumtreediff.actions.model.Action;
import com.github.gumtreediff.gen.Generators;
import com.github.gumtreediff.io.ActionsIoUtils;
import com.github.gumtreediff.matchers.MappingStore;
import com.github.gumtreediff.matchers.Matcher;
import com.github.gumtreediff.matchers.Matchers;
import com.github.gumtreediff.tree.ITree;
import java.io.File;
import java.io.IOException;
import java.util.List;
import com.github.gumtreediff.tree.TreeContext;
import com.github.gumtreediff.tree.TreeUtils;
import edu.lu.uni.serval.gen.jdt.exp.ExpJdtTreeGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Created by anilkoyuncu on 13/03/2018.
*/
public class TestGum {
private static Logger log = LoggerFactory.getLogger(TestGum.class);
public static void main(String[] args) {
String root = "/Users/haoyetian/Documents/Lu_code/";
// File oldFile = new File(root +"/revFiles/"+"5eb845_5c1c61_spring-rabbit#src#main#java#org#springframework#amqp#rabbit#listener#DirectMessageListenerContainer.java");
File oldFile = new File(root +"first.c");
// File newFile = new File(root +"/prevFiles/prev_"+"5eb845_5c1c61_spring-rabbit#src#main#java#org#springframework#amqp#rabbit#listener#DirectMessageListenerContainer.java");
File newFile = new File(root +"second.c");
// List<Action> gumTreeResults = compareTwoFilesWithGumTree(root,newFile,oldFile);
List<Action> gumTreeResults = new GumTreeComparer().compareCFilesWithGumTree(oldFile, newFile);
}
public static List<Action> compareTwoFilesWithGumTree(String root, File prevFile, File revFile) {
// Generate GumTree.
ITree oldTree = null;
ITree newTree = null;
try {
oldTree = new GumTreeGenerator().generateITreeForJavaFile(prevFile, GumTreeGenerator.GumTreeType.EXP_JDT);
newTree = new GumTreeGenerator().generateITreeForJavaFile(revFile, GumTreeGenerator.GumTreeType.EXP_JDT);
} catch (Exception e) {
if (oldTree == null) {
log.info("Null GumTree of Previous File: " + prevFile.getPath());
} else if (newTree == null) {
log.info("Null GumTree of Revised File: " + revFile.getPath());
}
}
if (oldTree != null && newTree != null) {
Matcher m = Matchers.getInstance().getMatcher(oldTree, newTree);
m.match();
ActionGenerator ag = new ActionGenerator(oldTree, newTree, m.getMappings());
ag.generate();
List<Action> actions = ag.getActions(); // change actions from bug to patch
try {
TreeContext tc = new ExpJdtTreeGenerator().generateFromFile(prevFile);
ActionsIoUtils.ActionSerializer serializer = OutputFormat.TEXT.getSerializer(
tc, actions, m.getMappings());
log.info(serializer.toString());
} catch (Exception e) {
e.printStackTrace();
}
return actions;
}
return null;
}
enum OutputFormat { // TODO make a registry for that also ?
TEXT {
@Override
ActionsIoUtils.ActionSerializer getSerializer(TreeContext sctx, List<Action> actions, MappingStore mappings)
throws IOException {
return ActionsIoUtils.toText(sctx, actions, mappings);
}
},
XML {
@Override
ActionsIoUtils.ActionSerializer getSerializer(TreeContext sctx, List<Action> actions, MappingStore mappings)
throws IOException {
return ActionsIoUtils.toXml(sctx, actions, mappings);
}
},
JSON {
@Override
ActionsIoUtils.ActionSerializer getSerializer(TreeContext sctx, List<Action> actions, MappingStore mappings)
throws IOException {
return ActionsIoUtils.toJson(sctx, actions, mappings);
}
};
abstract ActionsIoUtils.ActionSerializer getSerializer(TreeContext sctx, List<Action> actions,
MappingStore mappings) throws IOException;
}
}
@@ -0,0 +1,57 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright 2011-2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
* Copyright 2011-2015 Floréal Morandat <florealm@gmail.com>
*/
package com.github.gumtreediff.gen.jdt;
import java.io.IOException;
import org.junit.Test;
import com.github.gumtreediff.tree.ITree;
import static org.junit.Assert.*;
public class TestJdtGenerator {
@Test
public void testSimpleSyntax() throws IOException {
String input = "public class Foo { public int foo; }";
ITree tree = new JdtTreeGenerator().generateFromString(input).getRoot();
assertEquals(15, tree.getType());
assertEquals(9, tree.getSize());
}
@Test
public void testJava5Syntax() throws IOException {
String input = "public class Foo<A> { public List<A> foo; public void foo() "
+ "{ for (A f : foo) { System.out.println(f); } } }";
ITree tree = new JdtTreeGenerator().generateFromString(input).getRoot();
assertEquals(15, tree.getType());
assertEquals(32, tree.getSize());
}
@Test
public void testJava8Syntax() throws IOException {
String input = "public class Foo { public void foo(){ new ArrayList<Object>().stream().forEach(a -> {}); } }";
ITree tree = new JdtTreeGenerator().generateFromString(input).getRoot();
assertEquals(15, tree.getType());
assertEquals(24, tree.getSize());
}
}