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.
 
 
 
 
 
 

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