Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,33 @@
import com.github.gumtreediff.tree.ITree;
import com.github.gumtreediff.tree.TreeContext;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.*;
import java.io.*;
import java.util.*;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

public abstract class AbstractSrcmlTreeGenerator extends TreeGenerator {

private static final String SRCML_CMD = System.getProperty("gumtree.srcml.path", "srcml");

private static final QName LINE = new QName("http://www.srcML.org/srcML/position", "line", "pos");
private static final QName LINE = new QName("http://www.srcML.org/srcML/position", "line", "pos");

private static final QName COLUMN = new QName("http://www.srcML.org/srcML/position", "column", "pos");
private static final QName COLUMN = new QName("http://www.srcML.org/srcML/position", "column", "pos");

private LineReader lr;

Expand All @@ -62,9 +75,9 @@ public TreeContext getTreeContext(String xml) {
if (ev.isStartElement()) {
StartElement s = ev.asStartElement();
String typeLabel = s.getName().getLocalPart();
if (typeLabel.equals("position"))
if (typeLabel.equals("position")) {
setLength(trees.peek(), s);
else {
} else {
int type = typeLabel.hashCode();
ITree t = context.createTree(type, "", typeLabel);

Expand All @@ -79,14 +92,16 @@ public TreeContext getTreeContext(String xml) {
}
} else if (ev.isEndElement()) {
EndElement end = ev.asEndElement();
if (!end.getName().getLocalPart().equals("position"))
if (!end.getName().getLocalPart().equals("position")) {
trees.pop();
}
} else if (ev.isCharacters()) {
Characters chars = ev.asCharacters();
if (!chars.isWhiteSpace()
&& trees.peek().getLabel().equals("")
&& labeled.contains(context.getTypeLabel(trees.peek().getType())))
&& labeled.contains(context.getTypeLabel(trees.peek().getType()))) {
trees.peek().setLabel(chars.getData().trim());
}
}
}
fixPos(context);
Expand All @@ -104,9 +119,9 @@ private void fixPos(TreeContext ctx) {
if (t.getPos() == ITree.NO_VALUE || t.getLength() == ITree.NO_VALUE) {
ITree firstChild = t.getChild(0);
t.setPos(firstChild.getPos());
if (t.getChildren().size() == 1)
if (t.getChildren().size() == 1) {
t.setLength(firstChild.getLength());
else {
} else {
ITree lastChild = t.getChild(t.getChildren().size() - 1);
t.setLength(lastChild.getEndPos() - firstChild.getPos());
}
Expand All @@ -124,8 +139,9 @@ private void setPos(ITree t, StartElement e) {
}

private void setLength(ITree t, StartElement e) {
if (t.getPos() == -1)
if (t.getPos() == -1) {
return;
}
if (e.getAttributeByName(LINE) != null) {
int line = Integer.parseInt(e.getAttributeByName(LINE).getValue());
int column = Integer.parseInt(e.getAttributeByName(COLUMN).getValue());
Expand All @@ -135,7 +151,7 @@ private void setLength(ITree t, StartElement e) {

public String getXml(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", "");
File f = createTempFile();
FileWriter w = new FileWriter(f);
BufferedReader br = new BufferedReader(r);
String line = br.readLine();
Expand All @@ -147,30 +163,48 @@ public String getXml(Reader r) throws IOException {
w.close();
br.close();
ProcessBuilder b = new ProcessBuilder(getArguments(f.getAbsolutePath()));
b.redirectErrorStream(true);
b.directory(f.getParentFile());
try {
Process p = b.start();
StringBuffer buf = new StringBuffer();
StringBuilder buf = new StringBuilder();
br = new BufferedReader(new InputStreamReader(p.getInputStream()));
// TODO Why do we need to read and bufferize everything, when we could/should only use generateFromStream
line = null;
while ((line = br.readLine()) != null)
buf.append(line + "\n");
while ((line = br.readLine()) != null) {
buf.append(line).append("\n");
}

p.waitFor();
if (p.exitValue() != 0) throw new RuntimeException();
if (p.exitValue() != 0) {
throw new RuntimeException();
}
r.close();
String xml = buf.toString();
return xml;
return buf.toString();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} finally {
f.delete();
}
}

private static File DEV_SHM = new File("/dev/shm");

private File createTempFile() throws IOException {
if (DEV_SHM.exists()) {
return Files.createTempFile(DEV_SHM.toPath(), "gumtree", "").toFile();
}
return File.createTempFile("gumtree", "");
}

public abstract String getLanguage();

public String[] getArguments(String file) {
if (IS_UNIX) {
return new String[]{"timeout", "5", SRCML_CMD, "-l", getLanguage(), "--position", file};
}
return new String[]{SRCML_CMD, "-l", getLanguage(), "--position", file};
}

private static String OS = System.getProperty("os.name").toLowerCase();
private static boolean IS_UNIX = (OS.contains("nix") || OS.contains("nux") || OS.contains("aix"));
}