@@ -1,22 +1,23 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<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/xsd/maven-4.0.0.xsd"> | |||||
<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> | <modelVersion>4.0.0</modelVersion> | ||||
<prerequisites> | |||||
<maven>3.0.0</maven> | |||||
</prerequisites> | |||||
<groupId>org.bitshift.parsing</groupId> | |||||
<groupId>com.bitshift.parsing</groupId> | |||||
<artifactId>parsing</artifactId> | <artifactId>parsing</artifactId> | ||||
<version>0.1</version> | |||||
<name>Java Parser for Bitshift</name> | |||||
<properties> | |||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||||
</properties> | |||||
<packaging>jar</packaging> | |||||
<version>1.0-SNAPSHOT</version> | |||||
<name>parsing</name> | |||||
<url>http://maven.apache.org</url> | |||||
<dependencies> | <dependencies> | ||||
<dependency> | <dependency> | ||||
<groupId>junit</groupId> | |||||
<artifactId>junit</artifactId> | |||||
<version>3.8.1</version> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.eclipse.jdt</groupId> | <groupId>org.eclipse.jdt</groupId> | ||||
<artifactId>core</artifactId> | <artifactId>core</artifactId> | ||||
<version>3.3.0-v_771</version> | <version>3.3.0-v_771</version> | ||||
@@ -26,74 +27,16 @@ | |||||
<build> | <build> | ||||
<plugins> | <plugins> | ||||
<plugin> | <plugin> | ||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-compiler-plugin</artifactId> | |||||
<version>3.1</version> | |||||
<groupId>org.codehaus.mojo</groupId> | |||||
<artifactId>exec-maven-plugin</artifactId> | |||||
<version>1.2.1</version> | |||||
<configuration> | <configuration> | ||||
<source>1.7</source> | |||||
<target>1.7</target> | |||||
<encoding>UTF-8</encoding> | |||||
<mainClass>com.bitshift.parsing.Parse</mainClass> | |||||
<arguments> | |||||
</arguments> | |||||
</configuration> | </configuration> | ||||
</plugin> | </plugin> | ||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-source-plugin</artifactId> | |||||
<version>2.2.1</version> | |||||
<executions> | |||||
<execution> | |||||
<id>attach-sources</id> | |||||
<goals> | |||||
<goal>jar</goal> | |||||
</goals> | |||||
</execution> | |||||
</executions> | |||||
</plugin> | |||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-jar-plugin</artifactId> | |||||
<version>2.4</version> | |||||
<configuration> | |||||
<archive> | |||||
<manifest> | |||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries> | |||||
</manifest> | |||||
</archive> | |||||
</configuration> | |||||
</plugin> | |||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-shade-plugin</artifactId> | |||||
<version>1.6</version> | |||||
<configuration> | |||||
<createDependencyReducedPom>true</createDependencyReducedPom> | |||||
<filters> | |||||
<filter> | |||||
<artifact>*:*</artifact> | |||||
<excludes> | |||||
<exclude>META-INF/*.SF</exclude> | |||||
<exclude>META-INF/*.DSA</exclude> | |||||
<exclude>META-INF/*.RSA</exclude> | |||||
</excludes> | |||||
</filter> | |||||
</filters> | |||||
</configuration> | |||||
<executions> | |||||
<execution> | |||||
<phase>package</phase> | |||||
<goals> | |||||
<goal>shade</goal> | |||||
</goals> | |||||
<configuration> | |||||
<transformers> | |||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" /> | |||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> | |||||
<mainClass>org.bishift.parsing.Parse</mainClass> | |||||
</transformer> | |||||
</transformers> | |||||
</configuration> | |||||
</execution> | |||||
</executions> | |||||
</plugin> | |||||
</plugins> | </plugins> | ||||
</build> | </build> | ||||
</project> | </project> |
@@ -0,0 +1,33 @@ | |||||
package com.bitshift.parsing; | |||||
import java.io.BufferedReader; | |||||
import java.io.InputStreamReader; | |||||
import java.io.PrintWriter; | |||||
import java.io.IOException; | |||||
import java.net.ServerSocket; | |||||
import java.net.Socket; | |||||
import com.bitshift.parsing.parsers.JavaParser; | |||||
public class Parse { | |||||
public static void main(String[] args) { | |||||
String fromClient; | |||||
String toClient; | |||||
try { | |||||
ServerSocket server = new ServerSocket(5002); | |||||
while(true) { | |||||
Socket clientSocket = server.accept(); | |||||
JavaParser parser = new JavaParser(clientSocket); | |||||
Thread parserTask = new Thread(parser); | |||||
parserTask.start(); | |||||
} | |||||
} catch (IOException ex) { | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,3 @@ | |||||
package com.bitshift.parsing.parsers; | |||||
import com.bitshift.parsing.parsers.Parser; |
@@ -0,0 +1,215 @@ | |||||
package com.bitshift.parsing.parsers; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.Stack; | |||||
import java.io.BufferedReader; | |||||
import java.io.InputStreamReader; | |||||
import java.io.PrintWriter; | |||||
import java.io.IOException; | |||||
import java.net.Socket; | |||||
import org.eclipse.jdt.core.JavaCore; | |||||
import org.eclipse.jdt.core.dom.AST; | |||||
import org.eclipse.jdt.core.dom.ASTParser; | |||||
import org.eclipse.jdt.core.dom.ASTVisitor; | |||||
import org.eclipse.jdt.core.dom.CompilationUnit; | |||||
import org.eclipse.jdt.core.dom.ClassInstanceCreation; | |||||
import org.eclipse.jdt.core.dom.FieldAccess; | |||||
import org.eclipse.jdt.core.dom.FieldDeclaration; | |||||
import org.eclipse.jdt.core.dom.MethodDeclaration; | |||||
import org.eclipse.jdt.core.dom.MethodInvocation; | |||||
import org.eclipse.jdt.core.dom.Name; | |||||
import org.eclipse.jdt.core.dom.PackageDeclaration; | |||||
import org.eclipse.jdt.core.dom.QualifiedName; | |||||
import org.eclipse.jdt.core.dom.QualifiedType; | |||||
import org.eclipse.jdt.core.dom.SimpleName; | |||||
import org.eclipse.jdt.core.dom.SimpleType; | |||||
import org.eclipse.jdt.core.dom.Statement; | |||||
import org.eclipse.jdt.core.dom.Type; | |||||
import org.eclipse.jdt.core.dom.TypeDeclaration; | |||||
import org.eclipse.jdt.core.dom.VariableDeclarationFragment; | |||||
import com.bitshift.parsing.parsers.Parser; | |||||
import com.bitshift.parsing.symbols.Symbols; | |||||
import com.bitshift.parsing.symbols.JavaSymbols; | |||||
/*TODO: Work on parsing partial java code. | |||||
* Change visits to endVisit and implement a cache for more concise code structure. | |||||
* Get rid of unecessary imports. | |||||
* Fix column and line numbers.*/ | |||||
public class JavaParser extends Parser { | |||||
public JavaParser(Socket clientSocket) { | |||||
super(clientSocket); | |||||
} | |||||
private String readFromClient() { | |||||
String fromClient = ""; | |||||
try { | |||||
BufferedReader clientReader = new BufferedReader( | |||||
new InputStreamReader(this.clientSocket.getInputStream())); | |||||
int bytes = Integer.parseInt(clientReader.readLine()); | |||||
System.out.println(bytes); | |||||
StringBuilder builder = new StringBuilder(); | |||||
int i = 0; | |||||
while(i < bytes) { | |||||
char aux = (char)clientReader.read(); | |||||
builder.append(aux); | |||||
i++; | |||||
} | |||||
fromClient = builder.toString(); | |||||
} catch (IOException ex) { | |||||
} | |||||
return fromClient; | |||||
} | |||||
private void writeToClient(String toClient) { | |||||
try { | |||||
PrintWriter clientWriter = new PrintWriter( | |||||
this.clientSocket.getOutputStream(), true); | |||||
clientWriter.println(toClient); | |||||
} catch (IOException ex) { | |||||
} | |||||
} | |||||
@Override | |||||
public Symbols genSymbols() { | |||||
char[] source = this.readFromClient().toCharArray(); | |||||
ASTParser parser = ASTParser.newParser(AST.JLS3); | |||||
parser.setSource(source); | |||||
Map options = JavaCore.getOptions(); | |||||
parser.setCompilerOptions(options); | |||||
CompilationUnit root = (CompilationUnit) parser.createAST(null); | |||||
NodeVisitor visitor = new NodeVisitor(root); | |||||
root.accept(visitor); | |||||
return visitor.symbols; | |||||
} | |||||
@Override | |||||
public void run() { | |||||
JavaSymbols symbols = (JavaSymbols) this.genSymbols(); | |||||
System.out.println(symbols.toString()); | |||||
writeToClient(symbols.toString()); | |||||
} | |||||
class NodeVisitor extends ASTVisitor { | |||||
protected CompilationUnit root; | |||||
protected JavaSymbols symbols; | |||||
private Stack<HashMap<String, Object>> _cache; | |||||
public NodeVisitor(CompilationUnit root) { | |||||
this.root = root; | |||||
this.symbols = new JavaSymbols(); | |||||
this._cache = new Stack<HashMap<String, Object>>(); | |||||
} | |||||
public boolean visit(ClassInstanceCreation node) { | |||||
return true; | |||||
} | |||||
public boolean visit(FieldAccess node) { | |||||
Name nameObj = node.getName(); | |||||
String name = nameObj.isQualifiedName() ? | |||||
((QualifiedName) nameObj).getFullyQualifiedName() : | |||||
((SimpleName) nameObj).getIdentifier(); | |||||
int sl = this.root.getLineNumber(node.getStartPosition()) - 1; | |||||
int sc = this.root.getColumnNumber(node.getStartPosition()) - 1; | |||||
this.symbols.insertFieldAccess(name, sl, sc, null, null); | |||||
return true; | |||||
} | |||||
public boolean visit(FieldDeclaration node) { | |||||
return true; | |||||
} | |||||
public boolean visit(MethodDeclaration node) { | |||||
Name nameObj = node.getName(); | |||||
String name = nameObj.isQualifiedName() ? | |||||
((QualifiedName) nameObj).getFullyQualifiedName() : | |||||
((SimpleName) nameObj).getIdentifier(); | |||||
List<Statement> statements = node.getBody().statements(); | |||||
Statement last = statements.get(statements.size() - 1); | |||||
int sl = this.root.getLineNumber(node.getStartPosition()) - 1; | |||||
int sc = this.root.getColumnNumber(node.getStartPosition()) - 1; | |||||
int el = this.root.getLineNumber(last.getStartPosition()) - 1; | |||||
int ec = this.root.getColumnNumber(last.getStartPosition()) - 1; | |||||
this.symbols.insertMethodDeclaration(name, sl, sc, el, ec); | |||||
return true; | |||||
} | |||||
public boolean visit(MethodInvocation node) { | |||||
Name nameObj = node.getName(); | |||||
String name = nameObj.isQualifiedName() ? | |||||
((QualifiedName) nameObj).getFullyQualifiedName() : | |||||
((SimpleName) nameObj).getIdentifier(); | |||||
int sl = this.root.getLineNumber(node.getStartPosition()) - 1; | |||||
int sc = this.root.getColumnNumber(node.getStartPosition()) - 1; | |||||
this.symbols.insertMethodInvocation(name, sl, sc, null, null); | |||||
return true; | |||||
} | |||||
public boolean visit(PackageDeclaration node) { | |||||
Name nameObj = node.getName(); | |||||
String name = nameObj.isQualifiedName() ? | |||||
((QualifiedName) nameObj).getFullyQualifiedName() : | |||||
((SimpleName) nameObj).getIdentifier(); | |||||
this.symbols.setPackage(name); | |||||
return true; | |||||
} | |||||
public boolean visit(TypeDeclaration node) { | |||||
Name nameObj = node.getName(); | |||||
String name = nameObj.isQualifiedName() ? | |||||
((QualifiedName) nameObj).getFullyQualifiedName() : | |||||
((SimpleName) nameObj).getIdentifier(); | |||||
int sl = this.root.getLineNumber(node.getStartPosition()) - 1; | |||||
int sc = this.root.getColumnNumber(node.getStartPosition()) - 1; | |||||
if (node.isInterface()) { | |||||
this.symbols.insertInterfaceDeclaration(name, sl, sc, null, null); | |||||
} else { | |||||
this.symbols.insertClassDeclaration(name, sl, sc, null, null); | |||||
} | |||||
return true; | |||||
} | |||||
public boolean visit(VariableDeclarationFragment node) { | |||||
Name nameObj = node.getName(); | |||||
String name = nameObj.isQualifiedName() ? | |||||
((QualifiedName) nameObj).getFullyQualifiedName() : | |||||
((SimpleName) nameObj).getIdentifier(); | |||||
int sl = this.root.getLineNumber(node.getStartPosition()) - 1; | |||||
int sc = this.root.getColumnNumber(node.getStartPosition()) - 1; | |||||
this.symbols.insertVariableDeclaration(name, sl, sc, null, null); | |||||
return true; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,19 @@ | |||||
package com.bitshift.parsing.parsers; | |||||
import java.net.Socket; | |||||
import com.bitshift.parsing.symbols.Symbols; | |||||
public abstract class Parser implements Runnable { | |||||
protected Socket clientSocket; | |||||
public Parser(Socket clientSocket) { | |||||
this.clientSocket = clientSocket; | |||||
} | |||||
abstract Symbols genSymbols(); | |||||
public abstract void run(); | |||||
} | |||||
@@ -0,0 +1 @@ | |||||
package com.bitshift.parsing.symbols; |
@@ -0,0 +1,159 @@ | |||||
package com.bitshift.parsing.symbols; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.HashMap; | |||||
import java.util.ArrayList; | |||||
import com.bitshift.parsing.symbols.Symbols; | |||||
/*TODO: Overwrite toString.*/ | |||||
public class JavaSymbols extends Symbols { | |||||
private String _packageName; | |||||
private Map<String, Object> _classes; | |||||
private Map<String, Object> _interfaces; | |||||
private Map<String, Object> _methods; | |||||
private Map<String, Object> _fields; | |||||
private Map<String, Object> _vars; | |||||
public JavaSymbols() { | |||||
_packageName = null; | |||||
_classes = new HashMap<String, Object>(); | |||||
_interfaces = new HashMap<String, Object>(); | |||||
_methods = new HashMap<String, Object>(); | |||||
_fields = new HashMap<String, Object>(); | |||||
_vars = new HashMap<String, Object>(); | |||||
} | |||||
public boolean setPackage(String name) { | |||||
_packageName = name; | |||||
return true; | |||||
} | |||||
public boolean insertClassDeclaration(String name, Integer startLine, Integer startCol, Integer endLine, Integer endCol) { | |||||
List<Integer> pos = new ArrayList<Integer>(4); | |||||
pos.add(startLine); pos.add(startCol); pos.add(endLine); pos.add(endCol); | |||||
List<List<Integer>> copy = (List<List<Integer>>)_classes.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(0, pos); | |||||
this._classes.put(name, copy); | |||||
return true; | |||||
} | |||||
public boolean insertClassInstance(String name, Integer startLine, Integer startCol, Integer endLine, Integer endCol) { | |||||
List<Integer> pos = new ArrayList<Integer>(4); | |||||
pos.add(startLine); pos.add(startCol); pos.add(endLine); pos.add(endCol); | |||||
List<List<Integer>> copy = (List<List<Integer>>)_classes.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(pos); | |||||
this._classes.put(name, copy); | |||||
return true; | |||||
} | |||||
public boolean insertInterfaceDeclaration(String name, Integer startLine, Integer startCol, Integer endLine, Integer endCol) { | |||||
List<Integer> pos = new ArrayList<Integer>(4); | |||||
pos.add(startLine); pos.add(startCol); pos.add(endLine); pos.add(endCol); | |||||
List<List<Integer>> copy = (List<List<Integer>>)_classes.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(0, pos); | |||||
this._interfaces.put(name, copy); | |||||
return true; | |||||
} | |||||
public boolean insertInterfaceInstance(String name, Integer startLine, Integer startCol, Integer endLine, Integer endCol) { | |||||
List<Integer> pos = new ArrayList<Integer>(4); | |||||
pos.add(startLine); pos.add(startCol); pos.add(endLine); pos.add(endCol); | |||||
List<List<Integer>> copy = (List<List<Integer>>)_classes.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(pos); | |||||
this._interfaces.put(name, copy); | |||||
return true; | |||||
} | |||||
public boolean insertMethodDeclaration(String name, Integer startLine, Integer startCol, Integer endLine, Integer endCol) { | |||||
List<Integer> pos = new ArrayList<Integer>(4); | |||||
pos.add(startLine); pos.add(startCol); pos.add(endLine); pos.add(endCol); | |||||
List<List<Integer>> copy = (List<List<Integer>>)_classes.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(0, pos); | |||||
this._methods.put(name, copy); | |||||
return true; | |||||
} | |||||
public boolean insertMethodInvocation(String name, Integer startLine, Integer startCol, Integer endLine, Integer endCol) { | |||||
List<Integer> pos = new ArrayList<Integer>(4); | |||||
pos.add(startLine); pos.add(startCol); pos.add(endLine); pos.add(endCol); | |||||
List<List<Integer>> copy = (List<List<Integer>>)_classes.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(pos); | |||||
this._methods.put(name, copy); | |||||
return true; | |||||
} | |||||
public boolean insertFieldDeclaration(String name, Integer startLine, Integer startCol, Integer endLine, Integer endCol) { | |||||
List<Integer> pos = new ArrayList<Integer>(4); | |||||
pos.add(startLine); pos.add(startCol); pos.add(endLine); pos.add(endCol); | |||||
List<List<Integer>> copy = (List<List<Integer>>)_classes.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(0, pos); | |||||
this._fields.put(name, copy); | |||||
return true; | |||||
} | |||||
public boolean insertFieldAccess(String name, Integer startLine, Integer startCol, Integer endLine, Integer endCol) { | |||||
List<Integer> pos = new ArrayList<Integer>(4); | |||||
pos.add(startLine); pos.add(startCol); pos.add(endLine); pos.add(endCol); | |||||
List<List<Integer>> copy = (List<List<Integer>>)_classes.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(pos); | |||||
this._fields.put(name, copy); | |||||
return true; | |||||
} | |||||
public boolean insertVariableDeclaration(String name, Integer startLine, Integer startCol, Integer endLine, Integer endCol) { | |||||
List<Integer> pos = new ArrayList<Integer>(4); | |||||
pos.add(startLine); pos.add(startCol); pos.add(endLine); pos.add(endCol); | |||||
List<List<Integer>> copy = (List<List<Integer>>)_classes.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(0, pos); | |||||
this._vars.put(name, copy); | |||||
return true; | |||||
} | |||||
public boolean insertVariableAccess(String name, Integer startLine, Integer startCol, Integer endLine, Integer endCol) { | |||||
List<Integer> pos = new ArrayList<Integer>(4); | |||||
pos.add(startLine); pos.add(startCol); pos.add(endLine); pos.add(endCol); | |||||
List<List<Integer>> copy = (List<List<Integer>>)_classes.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(pos); | |||||
this._vars.put(name, copy); | |||||
return true; | |||||
} | |||||
public String toString() { | |||||
StringBuilder builder = new StringBuilder(); | |||||
builder.append("classes:" + this._classes + ","); | |||||
builder.append("interfaces:" + this._interfaces + ","); | |||||
builder.append("methods:" + this._methods + ","); | |||||
builder.append("fields:" + this._fields + ","); | |||||
builder.append("vars:" + this._vars + ","); | |||||
return "{" + builder.toString() + "}"; | |||||
} | |||||
} | |||||
@@ -0,0 +1,9 @@ | |||||
package com.bitshift.parsing.symbols; | |||||
public abstract class Symbols { | |||||
public Symbols() { | |||||
} | |||||
} |