A semantic search engine for source code https://bitshift.benkurtovic.com/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

223 lines
7.9 KiB

  1. package com.bitshift.parsing.parsers;
  2. import java.util.HashMap;
  3. import java.util.List;
  4. import java.util.Map;
  5. import java.util.Stack;
  6. import java.net.Socket;
  7. import org.eclipse.jdt.core.JavaCore;
  8. import org.eclipse.jdt.core.dom.AST;
  9. import org.eclipse.jdt.core.dom.ASTParser;
  10. import org.eclipse.jdt.core.dom.ASTVisitor;
  11. import org.eclipse.jdt.core.dom.CompilationUnit;
  12. import org.eclipse.jdt.core.dom.ClassInstanceCreation;
  13. import org.eclipse.jdt.core.dom.FieldAccess;
  14. import org.eclipse.jdt.core.dom.FieldDeclaration;
  15. import org.eclipse.jdt.core.dom.MethodDeclaration;
  16. import org.eclipse.jdt.core.dom.MethodInvocation;
  17. import org.eclipse.jdt.core.dom.Name;
  18. import org.eclipse.jdt.core.dom.PackageDeclaration;
  19. import org.eclipse.jdt.core.dom.QualifiedName;
  20. import org.eclipse.jdt.core.dom.QualifiedType;
  21. import org.eclipse.jdt.core.dom.SimpleName;
  22. import org.eclipse.jdt.core.dom.SimpleType;
  23. import org.eclipse.jdt.core.dom.Statement;
  24. import org.eclipse.jdt.core.dom.Type;
  25. import org.eclipse.jdt.core.dom.TypeDeclaration;
  26. import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
  27. import com.bitshift.parsing.parsers.Parser;
  28. import com.bitshift.parsing.symbols.Symbols;
  29. import com.bitshift.parsing.symbols.JavaSymbols;
  30. /*TODO: Work on parsing partial java code.
  31. * Change visits to endVisit and implement a cache for more concise code structure.
  32. * Get rid of unecessary imports.*/
  33. public class JavaParser extends Parser {
  34. public JavaParser(Socket clientSocket) {
  35. super(clientSocket);
  36. }
  37. @Override
  38. protected Symbols genSymbols() {
  39. char[] source = this.readFromClient().toCharArray();
  40. ASTParser parser = ASTParser.newParser(AST.JLS3);
  41. parser.setSource(source);
  42. Map options = JavaCore.getOptions();
  43. parser.setCompilerOptions(options);
  44. CompilationUnit root = (CompilationUnit) parser.createAST(null);
  45. NodeVisitor visitor = new NodeVisitor(root);
  46. root.accept(visitor);
  47. return visitor.symbols;
  48. }
  49. @Override
  50. public void run() {
  51. JavaSymbols symbols = (JavaSymbols) this.genSymbols();
  52. writeToClient(symbols.toString());
  53. }
  54. class NodeVisitor extends ASTVisitor {
  55. protected CompilationUnit root;
  56. protected JavaSymbols symbols;
  57. private Stack<HashMap<String, Object>> _cache;
  58. public NodeVisitor(CompilationUnit root) {
  59. this.root = root;
  60. this.symbols = new JavaSymbols();
  61. this._cache = new Stack<HashMap<String, Object>>();
  62. }
  63. public boolean visit(FieldDeclaration node) {
  64. HashMap<String, Object> data = new HashMap<String, Object>();
  65. int sl = this.root.getLineNumber(node.getStartPosition());
  66. int sc = this.root.getColumnNumber(node.getStartPosition());
  67. data.put("coord", Symbols.createCoord(sl, sc, null, null));
  68. this._cache.push(data);
  69. return true;
  70. }
  71. public void endVisit(FieldDeclaration node) {
  72. HashMap<String, Object> data = this._cache.pop();
  73. String name = (String)data.remove("name");
  74. this.symbols.insertFieldDeclaration(name, data);
  75. }
  76. public boolean visit(MethodDeclaration node) {
  77. HashMap<String, Object> data = new HashMap<String, Object>();
  78. Name nameObj = node.getName();
  79. String name = nameObj.isQualifiedName() ?
  80. ((QualifiedName) nameObj).getFullyQualifiedName() :
  81. ((SimpleName) nameObj).getIdentifier();
  82. List<Statement> statements = node.getBody().statements();
  83. Statement last = statements.get(statements.size() - 1);
  84. int sl = this.root.getLineNumber(node.getStartPosition());
  85. int sc = this.root.getColumnNumber(node.getStartPosition());
  86. int el = this.root.getLineNumber(last.getStartPosition());
  87. int ec = this.root.getColumnNumber(last.getStartPosition());
  88. data.put("coord", Symbols.createCoord(sl, sc, null, null));
  89. data.put("name", name);
  90. this._cache.push(data);
  91. return true;
  92. }
  93. public void endVisit(MethodDeclaration node) {
  94. HashMap<String, Object> data = this._cache.pop();
  95. String name = (String)data.remove("name");
  96. this.symbols.insertMethodDeclaration(name, data);
  97. }
  98. public boolean visit(MethodInvocation node) {
  99. HashMap<String, Object> data = new HashMap<String, Object>();
  100. Name nameObj = node.getName();
  101. String name = nameObj.isQualifiedName() ?
  102. ((QualifiedName) nameObj).getFullyQualifiedName() :
  103. ((SimpleName) nameObj).getIdentifier();
  104. int sl = this.root.getLineNumber(node.getStartPosition());
  105. int sc = this.root.getColumnNumber(node.getStartPosition());
  106. data.put("coord", Symbols.createCoord(sl, sc, null, null));
  107. data.put("name", name);
  108. this._cache.push(data);
  109. return true;
  110. }
  111. public void endVisit(MethodInvocation node) {
  112. HashMap<String, Object> data = this._cache.pop();
  113. String name = (String)data.remove("name");
  114. this.symbols.insertMethodInvocation(name, data);
  115. }
  116. public boolean visit(PackageDeclaration node) {
  117. HashMap<String, Object> data = new HashMap<String, Object>();
  118. this._cache.push(data);
  119. return true;
  120. }
  121. public void endVisit(PackageDeclaration node) {
  122. HashMap<String, Object> data = this._cache.pop();
  123. String name = (String)data.remove("name");
  124. this.symbols.setPackage(name);
  125. }
  126. public boolean visit(TypeDeclaration node) {
  127. HashMap<String, Object> data = new HashMap<String, Object>();
  128. int sl = this.root.getLineNumber(node.getStartPosition());
  129. int sc = this.root.getColumnNumber(node.getStartPosition());
  130. data.put("coord", Symbols.createCoord(sl, sc, null, null));
  131. this._cache.push(data);
  132. return true;
  133. }
  134. public void endVisit(TypeDeclaration node) {
  135. HashMap<String, Object> data = this._cache.pop();
  136. String name = (String)data.remove("name");
  137. if (node.isInterface()) {
  138. this.symbols.insertInterfaceDeclaration(name, data);
  139. } else {
  140. this.symbols.insertClassDeclaration(name, data);
  141. }
  142. }
  143. public boolean visit(VariableDeclarationFragment node) {
  144. HashMap<String, Object> data = new HashMap<String, Object>();
  145. int sl = this.root.getLineNumber(node.getStartPosition());
  146. int sc = this.root.getColumnNumber(node.getStartPosition());
  147. data.put("coord", Symbols.createCoord(sl, sc, null, null));
  148. this._cache.push(data);
  149. return true;
  150. }
  151. public void endVisit(VariableDeclarationFragment node) {
  152. HashMap<String, Object> data = this._cache.pop();
  153. String name = (String)data.remove("name");
  154. this.symbols.insertVariableDeclaration(name, data);
  155. }
  156. public boolean visit(QualifiedName node) {
  157. if (!this._cache.empty()) {
  158. HashMap<String, Object> data = this._cache.pop();
  159. if(!data.containsKey("name")) {
  160. String name = node.getFullyQualifiedName();
  161. data.put("name", name);
  162. }
  163. this._cache.push(data);
  164. }
  165. return true;
  166. }
  167. public boolean visit(SimpleName node) {
  168. if (!this._cache.empty()) {
  169. HashMap<String, Object> data = this._cache.pop();
  170. if(!data.containsKey("name")) {
  171. String name = node.getIdentifier();
  172. data.put("name", name);
  173. }
  174. this._cache.push(data);
  175. }
  176. return true;
  177. }
  178. }
  179. }