merge all into single repo
This commit is contained in:
@@ -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>
|
||||
|
||||
+72
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -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
+72
@@ -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();
|
||||
}
|
||||
+46
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
+35
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
+1075
File diff suppressed because it is too large
Load Diff
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user