PageRenderTime 74ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/bundles/plugins-trunk/XML/sidekick/javascript/JavaScriptParser.java

#
Java | 225 lines | 151 code | 15 blank | 59 comment | 48 complexity | 0e0431b1cfd96b83fdff4447a9728082 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * JavaScriptParser.java
  3. * :folding=explicit:collapseFolds=1:
  4. *
  5. * Copyright (C) 2005 by Martin Raspe
  6. * (hertzhaft@biblhertz.it)
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package sidekick.javascript;
  23. import org.gjt.sp.jedit.*;
  24. import org.gjt.sp.util.Log;
  25. import sidekick.enhanced.SourceParser;
  26. import sidekick.SideKickParsedData;
  27. import java.io.*;
  28. import java.util.ArrayList;
  29. import java.util.Stack;
  30. import java.util.regex.Pattern;
  31. import errorlist.*;
  32. /**
  33. * JavaScriptParser: parses perl source and builds a sidekick structure tree
  34. * Parser is based on regular expressions and will therefore
  35. * not able to correctly parse very irregular perl scripts
  36. *
  37. * @author Martin Raspe
  38. * @created March 3, 2005
  39. * @modified $Date: 2010-08-12 14:46:15 +0200 (Thu, 12 Aug 2010) $ by $Author: daleanson $
  40. * @version $Revision: 18336 $
  41. */
  42. public class JavaScriptParser extends SourceParser {
  43. /*
  44. Changes suggested by David Padgett to make the parser
  45. more compatible with namespace/package emulation in JavaScript
  46. my.test.namespace.MyClass = function ...
  47. my.test.namespace.MyClass.prototype.foobar = function ...
  48. my.test.namespace.MyClass.myStaticMethod = function ...
  49. */
  50. Pattern pClassFunction = Pattern.compile("^((\\w+\\.)*[A-Z][\\w]*)\\s*=\\s*function");
  51. Pattern pMethodFunction = Pattern.compile("^([\\w+\\.]+\\w+)\\.([\\w]+)\\s*=\\s*function");
  52. Pattern pPrototypeFunction = Pattern.compile("^([\\w+\\.]+\\w+)\\.prototype\\.([\\w]+)\\s*=\\s*function");
  53. Pattern pAssignedFunction = Pattern.compile("^(\\w+)\\s*=\\s*function");
  54. Pattern pVarFunction = Pattern.compile("^var\\s+(\\w+)\\s*=\\s*function");
  55. Pattern pSimpleFunction = Pattern.compile("^function\\s+(\\w+)");
  56. // var my.test.namespace.MyClass.Object = {...
  57. // my.test.namespace.MyClass.Object = {...
  58. // method_name : function ...
  59. Pattern pObject = Pattern.compile("^((\\w+\\.)*[A-Z][\\w]*)\\s*=[^\\{]*\\{");
  60. Pattern pVarObject = Pattern.compile("^var\\s+((\\w+\\.)*[A-Z][\\w]*)\\s*=[^\\{]*\\{");
  61. Pattern pObjectMethod = Pattern.compile("^(\\w+)\\s*:\\s*function");
  62. /** * Constructs a new Parser object
  63. *
  64. */
  65. public JavaScriptParser() {
  66. super("javascript");
  67. LINE_COMMENT = "//";
  68. COMMENT = "Comments";
  69. MAIN = "(Window)";
  70. USE = "import";
  71. }
  72. /** * Parses the given text and returns a tree model.
  73. *
  74. * @param buffer The buffer to parse.
  75. * @param errorSource An error source to add errors to.
  76. */
  77. protected void parseBuffer(Buffer buffer, DefaultErrorSource errorSource) {
  78. setStartLine( 0 );
  79. parseBuffer( buffer, buffer.getText( 0, buffer.getLength() ), errorSource );
  80. }
  81. public SideKickParsedData parse( Buffer buffer, String text, DefaultErrorSource errorSource ) {
  82. data = new SideKickParsedData(buffer.getName());
  83. packages = new PackageMap(new PackageComparator());
  84. commentList = new ArrayList();
  85. parseBuffer(buffer, text, errorSource);
  86. completePackageAsset(_end, _lastLineNumber);
  87. Log.log(Log.DEBUG, this, "parsing completed");
  88. buildTrees();
  89. Log.log(Log.DEBUG, this, "tree built");
  90. return data;
  91. }
  92. protected void parseBuffer(Buffer buffer, String text, DefaultErrorSource errorSource) {
  93. String line;
  94. String name;
  95. String pkgname;
  96. String[] names;
  97. Stack funcstack = new Stack();
  98. Stack pkgstack = new Stack();
  99. //if (startLine == 0) {
  100. pkgstack.push(MAIN);
  101. //}
  102. boolean in_comment = false;
  103. int buflen = buffer.getLength();
  104. int _tmp;
  105. for (int lineNo = startLine; lineNo < startLine + getLineCount(text); lineNo++) {
  106. _start = buffer.createPosition(buffer.getLineStartOffset(lineNo));
  107. _tmp = buffer.getLineEndOffset(lineNo);
  108. if (_tmp > buflen) _tmp = buflen;
  109. _end = buffer.createPosition(_tmp);
  110. line = buffer.getLineText(lineNo).trim();
  111. // line comment or empty line
  112. if (line.indexOf(LINE_COMMENT) == 0 || line.length() == 0) continue;
  113. // block comment: end
  114. if (in_comment && line.indexOf("*/") != -1 ) {
  115. in_comment = false;
  116. completeAsset(_end);
  117. }
  118. if (in_comment) continue;
  119. // Class = function()
  120. name = find(line, pClassFunction, 1);
  121. if (name != null) {
  122. if (! pkgstack.empty()) pkgstack.pop();
  123. pkgstack.push(name);
  124. addPackageAsset(name, lineNo, _start);
  125. addAsset(SUB_KEY, name, "(constructor)", lineNo, _start);
  126. continue;
  127. }
  128. name = find(line, pObject, 1);
  129. if (name == null)
  130. name = find(line, pVarObject, 1);
  131. // var Object = {
  132. if (name != null) {
  133. if (! pkgstack.empty()) pkgstack.pop();
  134. pkgstack.push(name);
  135. addPackageAsset(name, lineNo, _start);
  136. addLineAsset(SUB_KEY, name, "(assignment)", lineNo, _start, _end);
  137. continue;
  138. }
  139. // check class methods
  140. names = find2(line, pPrototypeFunction);
  141. if (names == null)
  142. names = find2(line, pMethodFunction);
  143. if (names != null) {
  144. pkgname = names[0];
  145. if (pkgstack.empty()) {
  146. pkgstack.push(pkgname);
  147. addPackageAsset(pkgname, lineNo, _start);
  148. }
  149. else if (! pkgname.equals((String) pkgstack.peek())) {
  150. pkgstack.pop();
  151. pkgstack.push(pkgname);
  152. addPackageAsset(pkgname, lineNo, _start);
  153. }
  154. if (! funcstack.empty()) {
  155. funcstack.pop();
  156. completeAsset(_start);
  157. }
  158. funcstack.push(names[1]);
  159. addAsset(SUB_KEY, names[0], names[1], lineNo, _start);
  160. continue;
  161. }
  162. // check functions
  163. name = find(line, pAssignedFunction, 1);
  164. if (name == null)
  165. name = find(line, pVarFunction, 1);
  166. if (name == null)
  167. name = find(line, pObjectMethod, 1);
  168. if (name == null)
  169. name = find(line, pSimpleFunction, 1);
  170. if (name != null) {
  171. if (! funcstack.empty()) {
  172. funcstack.pop();
  173. completeAsset(_start);
  174. }
  175. funcstack.push(name);
  176. addAsset(SUB_KEY, (String) pkgstack.peek(), name, lineNo, _start);
  177. continue;
  178. }
  179. // block comment: start
  180. if (! in_comment && line.indexOf("/*") != -1 ) {
  181. completeAsset(_end);
  182. if (! funcstack.empty()) name = (String) funcstack.peek();
  183. if (name == null) name = (String) pkgstack.peek();
  184. if (name == null) name = "(comment)";
  185. in_comment = true;
  186. addCommentAsset(name, lineNo, _start);
  187. }
  188. }
  189. }
  190. private int getLineCount( CharSequence text ) {
  191. if ( text == null )
  192. return 0;
  193. BufferedReader br = new BufferedReader( new StringReader( text.toString() ) );
  194. String line = null;
  195. int count = 0;
  196. try {
  197. while ( true ) {
  198. line = br.readLine();
  199. if ( line == null )
  200. break;
  201. ++count;
  202. }
  203. }
  204. catch ( Exception e ) {
  205. e.printStackTrace();
  206. }
  207. return count;
  208. }
  209. }