Mod: Parser.java: - Moved client reading and writing methods to the abstract parser class, so that it is not specific to the JavaParser JavaParser.java: - Implemented NodeVisitor._cache. The cache is a stack of data packets. When a node that we want information on is first visited, a new packet of data is pushed onto the stack. The child nodes of that original node than add information to the packet, and when the original node is traversed again on the way up the tree, the data is popped from the cache and added to the symbols. This makes it possible to gather information about various levels of the tree easily. JavaSymbols.java: - Refactor all the insertMethods to simply add a packet of data to the appropriate HashMap. Symbols.java - Add a createCoord method which returns an arraylist representing a point in a document.tags/v1.0^2
@@ -5,11 +5,6 @@ import java.util.List; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Stack; | 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 java.net.Socket; | ||||
import org.eclipse.jdt.core.JavaCore; | import org.eclipse.jdt.core.JavaCore; | ||||
@@ -46,44 +41,8 @@ public class JavaParser extends Parser { | |||||
super(clientSocket); | super(clientSocket); | ||||
} | } | ||||
private String readFromClient() { | |||||
String fromClient = ""; | |||||
try { | |||||
BufferedReader clientReader = new BufferedReader( | |||||
new InputStreamReader(this.clientSocket.getInputStream())); | |||||
int bytes = Integer.parseInt(clientReader.readLine()); | |||||
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 | @Override | ||||
public Symbols genSymbols() { | |||||
protected Symbols genSymbols() { | |||||
char[] source = this.readFromClient().toCharArray(); | char[] source = this.readFromClient().toCharArray(); | ||||
ASTParser parser = ASTParser.newParser(AST.JLS3); | ASTParser parser = ASTParser.newParser(AST.JLS3); | ||||
@@ -118,28 +77,24 @@ public class JavaParser extends Parser { | |||||
this._cache = new Stack<HashMap<String, Object>>(); | 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(); | |||||
public boolean visit(FieldDeclaration node) { | |||||
HashMap<String, Object> data = new HashMap<String, Object>(); | |||||
int sl = this.root.getLineNumber(node.getStartPosition()); | int sl = this.root.getLineNumber(node.getStartPosition()); | ||||
int sc = this.root.getColumnNumber(node.getStartPosition()); | int sc = this.root.getColumnNumber(node.getStartPosition()); | ||||
this.symbols.insertFieldAccess(name, sl, sc, null, null); | |||||
data.put("coord", Symbols.createCoord(sl, sc, null, null)); | |||||
this._cache.push(data); | |||||
return true; | return true; | ||||
} | } | ||||
public boolean visit(FieldDeclaration node) { | |||||
return true; | |||||
public void endVisit(FieldDeclaration node) { | |||||
HashMap<String, Object> data = this._cache.pop(); | |||||
String name = (String)data.remove("name"); | |||||
this.symbols.insertFieldDeclaration(name, data); | |||||
} | } | ||||
public boolean visit(MethodDeclaration node) { | public boolean visit(MethodDeclaration node) { | ||||
HashMap<String, Object> data = new HashMap<String, Object>(); | |||||
Name nameObj = node.getName(); | Name nameObj = node.getName(); | ||||
String name = nameObj.isQualifiedName() ? | String name = nameObj.isQualifiedName() ? | ||||
((QualifiedName) nameObj).getFullyQualifiedName() : | ((QualifiedName) nameObj).getFullyQualifiedName() : | ||||
@@ -152,59 +107,114 @@ public class JavaParser extends Parser { | |||||
int el = this.root.getLineNumber(last.getStartPosition()); | int el = this.root.getLineNumber(last.getStartPosition()); | ||||
int ec = this.root.getColumnNumber(last.getStartPosition()); | int ec = this.root.getColumnNumber(last.getStartPosition()); | ||||
this.symbols.insertMethodDeclaration(name, sl, sc, el, ec); | |||||
data.put("coord", Symbols.createCoord(sl, sc, null, null)); | |||||
data.put("name", name); | |||||
this._cache.push(data); | |||||
return true; | return true; | ||||
} | } | ||||
public void endVisit(MethodDeclaration node) { | |||||
HashMap<String, Object> data = this._cache.pop(); | |||||
String name = (String)data.remove("name"); | |||||
this.symbols.insertMethodDeclaration(name, data); | |||||
} | |||||
public boolean visit(MethodInvocation node) { | public boolean visit(MethodInvocation node) { | ||||
HashMap<String, Object> data = new HashMap<String, Object>(); | |||||
Name nameObj = node.getName(); | Name nameObj = node.getName(); | ||||
String name = nameObj.isQualifiedName() ? | String name = nameObj.isQualifiedName() ? | ||||
((QualifiedName) nameObj).getFullyQualifiedName() : | ((QualifiedName) nameObj).getFullyQualifiedName() : | ||||
((SimpleName) nameObj).getIdentifier(); | ((SimpleName) nameObj).getIdentifier(); | ||||
int sl = this.root.getLineNumber(node.getStartPosition()); | int sl = this.root.getLineNumber(node.getStartPosition()); | ||||
int sc = this.root.getColumnNumber(node.getStartPosition()); | int sc = this.root.getColumnNumber(node.getStartPosition()); | ||||
this.symbols.insertMethodInvocation(name, sl, sc, null, null); | |||||
data.put("coord", Symbols.createCoord(sl, sc, null, null)); | |||||
data.put("name", name); | |||||
this._cache.push(data); | |||||
return true; | return true; | ||||
} | } | ||||
public void endVisit(MethodInvocation node) { | |||||
HashMap<String, Object> data = this._cache.pop(); | |||||
String name = (String)data.remove("name"); | |||||
this.symbols.insertMethodInvocation(name, data); | |||||
} | |||||
public boolean visit(PackageDeclaration node) { | public boolean visit(PackageDeclaration node) { | ||||
Name nameObj = node.getName(); | |||||
String name = nameObj.isQualifiedName() ? | |||||
((QualifiedName) nameObj).getFullyQualifiedName() : | |||||
((SimpleName) nameObj).getIdentifier(); | |||||
HashMap<String, Object> data = new HashMap<String, Object>(); | |||||
this._cache.push(data); | |||||
return true; | |||||
} | |||||
public void endVisit(PackageDeclaration node) { | |||||
HashMap<String, Object> data = this._cache.pop(); | |||||
String name = (String)data.remove("name"); | |||||
this.symbols.setPackage(name); | this.symbols.setPackage(name); | ||||
return true; | |||||
} | } | ||||
public boolean visit(TypeDeclaration node) { | public boolean visit(TypeDeclaration node) { | ||||
Name nameObj = node.getName(); | |||||
String name = nameObj.isQualifiedName() ? | |||||
((QualifiedName) nameObj).getFullyQualifiedName() : | |||||
((SimpleName) nameObj).getIdentifier(); | |||||
HashMap<String, Object> data = new HashMap<String, Object>(); | |||||
int sl = this.root.getLineNumber(node.getStartPosition()); | int sl = this.root.getLineNumber(node.getStartPosition()); | ||||
int sc = this.root.getColumnNumber(node.getStartPosition()); | int sc = this.root.getColumnNumber(node.getStartPosition()); | ||||
data.put("coord", Symbols.createCoord(sl, sc, null, null)); | |||||
this._cache.push(data); | |||||
return true; | |||||
} | |||||
public void endVisit(TypeDeclaration node) { | |||||
HashMap<String, Object> data = this._cache.pop(); | |||||
String name = (String)data.remove("name"); | |||||
if (node.isInterface()) { | if (node.isInterface()) { | ||||
this.symbols.insertInterfaceDeclaration(name, sl, sc, null, null); | |||||
this.symbols.insertInterfaceDeclaration(name, data); | |||||
} else { | } else { | ||||
this.symbols.insertClassDeclaration(name, sl, sc, null, null); | |||||
this.symbols.insertClassDeclaration(name, data); | |||||
} | } | ||||
return true; | |||||
} | } | ||||
public boolean visit(VariableDeclarationFragment node) { | public boolean visit(VariableDeclarationFragment node) { | ||||
Name nameObj = node.getName(); | |||||
String name = nameObj.isQualifiedName() ? | |||||
((QualifiedName) nameObj).getFullyQualifiedName() : | |||||
((SimpleName) nameObj).getIdentifier(); | |||||
HashMap<String, Object> data = new HashMap<String, Object>(); | |||||
int sl = this.root.getLineNumber(node.getStartPosition()); | int sl = this.root.getLineNumber(node.getStartPosition()); | ||||
int sc = this.root.getColumnNumber(node.getStartPosition()); | int sc = this.root.getColumnNumber(node.getStartPosition()); | ||||
this.symbols.insertVariableDeclaration(name, sl, sc, null, null); | |||||
data.put("coord", Symbols.createCoord(sl, sc, null, null)); | |||||
this._cache.push(data); | |||||
return true; | |||||
} | |||||
public void endVisit(VariableDeclarationFragment node) { | |||||
HashMap<String, Object> data = this._cache.pop(); | |||||
String name = (String)data.remove("name"); | |||||
this.symbols.insertVariableDeclaration(name, data); | |||||
} | |||||
public boolean visit(QualifiedName node) { | |||||
if (!this._cache.empty()) { | |||||
HashMap<String, Object> data = this._cache.pop(); | |||||
if(!data.containsKey("name")) { | |||||
String name = node.getFullyQualifiedName(); | |||||
data.put("name", name); | |||||
} | |||||
this._cache.push(data); | |||||
} | |||||
return true; | |||||
} | |||||
public boolean visit(SimpleName node) { | |||||
if (!this._cache.empty()) { | |||||
HashMap<String, Object> data = this._cache.pop(); | |||||
if(!data.containsKey("name")) { | |||||
String name = node.getIdentifier(); | |||||
data.put("name", name); | |||||
} | |||||
this._cache.push(data); | |||||
} | |||||
return true; | return true; | ||||
} | } | ||||
@@ -1,6 +1,12 @@ | |||||
package com.bitshift.parsing.parsers; | package com.bitshift.parsing.parsers; | ||||
import java.io.BufferedReader; | |||||
import java.io.InputStreamReader; | |||||
import java.io.PrintWriter; | |||||
import java.io.IOException; | |||||
import java.net.Socket; | import java.net.Socket; | ||||
import com.bitshift.parsing.symbols.Symbols; | import com.bitshift.parsing.symbols.Symbols; | ||||
public abstract class Parser implements Runnable { | public abstract class Parser implements Runnable { | ||||
@@ -11,7 +17,43 @@ public abstract class Parser implements Runnable { | |||||
this.clientSocket = clientSocket; | this.clientSocket = clientSocket; | ||||
} | } | ||||
abstract Symbols genSymbols(); | |||||
protected String readFromClient() { | |||||
String fromClient = ""; | |||||
try { | |||||
BufferedReader clientReader = new BufferedReader( | |||||
new InputStreamReader(this.clientSocket.getInputStream())); | |||||
int bytes = Integer.parseInt(clientReader.readLine()); | |||||
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; | |||||
} | |||||
protected void writeToClient(String toClient) { | |||||
try { | |||||
PrintWriter clientWriter = new PrintWriter( | |||||
this.clientSocket.getOutputStream(), true); | |||||
clientWriter.println(toClient); | |||||
} catch (IOException ex) { | |||||
} | |||||
} | |||||
protected abstract Symbols genSymbols(); | |||||
public abstract void run(); | public abstract void run(); | ||||
@@ -1,7 +1,6 @@ | |||||
package com.bitshift.parsing.symbols; | package com.bitshift.parsing.symbols; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | |||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import com.bitshift.parsing.symbols.Symbols; | import com.bitshift.parsing.symbols.Symbols; | ||||
@@ -10,19 +9,19 @@ import com.bitshift.parsing.symbols.Symbols; | |||||
public class JavaSymbols extends Symbols { | public class JavaSymbols extends Symbols { | ||||
private String _packageName; | 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; | |||||
private HashMap<String, HashMap<String, Object>> _classes; | |||||
private HashMap<String, HashMap<String, Object>> _interfaces; | |||||
private HashMap<String, HashMap<String, Object>> _methods; | |||||
private HashMap<String, HashMap<String, Object>> _fields; | |||||
private HashMap<String, HashMap<String, Object>> _vars; | |||||
public JavaSymbols() { | public JavaSymbols() { | ||||
_packageName = null; | _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>(); | |||||
_classes = new HashMap<String, HashMap<String, Object>>(); | |||||
_interfaces = new HashMap<String, HashMap<String, Object>>(); | |||||
_methods = new HashMap<String, HashMap<String, Object>>(); | |||||
_fields = new HashMap<String, HashMap<String, Object>>(); | |||||
_vars = new HashMap<String, HashMap<String, Object>>(); | |||||
} | } | ||||
public boolean setPackage(String name) { | public boolean setPackage(String name) { | ||||
@@ -30,118 +29,78 @@ public class JavaSymbols extends Symbols { | |||||
return true; | 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); | |||||
public boolean insertClassDeclaration(String name, HashMap<String, Object> data) { | |||||
this._classes.put(name, data); | |||||
return true; | 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>>)_interfaces.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>>)_interfaces.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(pos); | |||||
this._interfaces.put(name, copy); | |||||
public boolean insertInterfaceDeclaration(String name, HashMap<String, Object> data) { | |||||
this._interfaces.put(name, data); | |||||
return true; | 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>>)_methods.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
public boolean insertMethodDeclaration(String name, HashMap<String, Object> data) { | |||||
HashMap<String, Object> method = this._methods.get(name); | |||||
if (method == null) { | |||||
method = new HashMap<String, Object>(); | |||||
method.put("declaration", data); | |||||
} else { | |||||
method.put("declaration", data); | |||||
} | |||||
copy.add(0, pos); | |||||
this._methods.put(name, copy); | |||||
this._methods.put(name, method); | |||||
return true; | 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>>)_methods.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(pos); | |||||
this._methods.put(name, copy); | |||||
public boolean insertMethodInvocation(String name, HashMap<String, Object> data) { | |||||
HashMap<String, Object> method = this._methods.get(name); | |||||
if (method == null) { | |||||
method = new HashMap<String, Object>(); | |||||
ArrayList<Object> calls = new ArrayList<Object>(10); | |||||
calls.add(data); | |||||
method.put("calls", calls); | |||||
} else { | |||||
ArrayList<Object> calls = (ArrayList<Object>)method.get("calls"); | |||||
calls = (calls == null) ? new ArrayList<Object>(10) : calls; | |||||
calls.add(data); | |||||
method.put("calls", calls); | |||||
} | |||||
this._methods.put(name, method); | |||||
return true; | 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>>)_fields.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>>)_fields.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(pos); | |||||
this._fields.put(name, copy); | |||||
public boolean insertFieldDeclaration(String name, HashMap<String, Object> data) { | |||||
this._fields.put(name, data); | |||||
return true; | 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>>)_vars.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
public boolean insertVariableDeclaration(String name, HashMap<String, Object> data) { | |||||
HashMap<String, Object> var = this._vars.get(name); | |||||
if (var == null) { | |||||
var = new HashMap<String, Object>(); | |||||
var.put("declaration", data); | |||||
} else { | |||||
var.put("declaration", data); | |||||
} | |||||
copy.add(0, pos); | |||||
this._vars.put(name, copy); | |||||
this._vars.put(name, var); | |||||
return true; | 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>>)_vars.get(name); | |||||
copy = (copy == null) ? new ArrayList<List<Integer>>() : copy; | |||||
copy.add(pos); | |||||
this._vars.put(name, copy); | |||||
public boolean insertVariableAccess(String name, HashMap<String, Object> data) { | |||||
HashMap<String, Object> var = this._vars.get(name); | |||||
if (var == null) { | |||||
var = new HashMap<String, Object>(); | |||||
ArrayList<Object> uses = new ArrayList<Object>(10); | |||||
uses.add(data); | |||||
var.put("uses", uses); | |||||
} else { | |||||
ArrayList<Object> uses = (ArrayList<Object>)var.get("uses"); | |||||
uses = (uses == null) ? new ArrayList<Object>(10) : uses; | |||||
uses.add(data); | |||||
var.put("uses", uses); | |||||
} | |||||
this._vars.put(name, var); | |||||
return true; | return true; | ||||
} | } | ||||
@@ -1,9 +1,17 @@ | |||||
package com.bitshift.parsing.symbols; | package com.bitshift.parsing.symbols; | ||||
import java.util.ArrayList; | |||||
public abstract class Symbols { | public abstract class Symbols { | ||||
public Symbols() { | public Symbols() { | ||||
} | } | ||||
public static ArrayList<Integer> createCoord(Integer startLine, Integer startCol, Integer endLine, Integer endCol) { | |||||
ArrayList<Integer> coord = new ArrayList<Integer>(4); | |||||
coord.add(startLine); coord.add(startCol); coord.add(endLine); coord.add(endCol); | |||||
return coord; | |||||
} | |||||
} | } |