/projects/jext-5.0/src/lib/org/gjt/sp/jedit/syntax/JSPTokenMarker.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus · Java · 636 lines · 602 code · 8 blank · 26 comment · 90 complexity · 84a898730699fba5d80ee64132373538 MD5 · raw file

  1. /*
  2. * JSPTokenMarker.java - JSP token marker
  3. * Copyright (C) 2001 by Romain Guy
  4. * Based on HTMLTokenMarker by Slava Pestov & Romain Guy
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. package org.gjt.sp.jedit.syntax;
  21. import javax.swing.text.Segment;
  22. /**
  23. * JSP token marker.
  24. * @author Romain Guy
  25. */
  26. public class JSPTokenMarker extends TokenMarker
  27. {
  28. public static final byte JAVASCRIPT = Token.INTERNAL_FIRST;
  29. public static final byte HTML_LITERAL_QUOTE = Token.INTERNAL_FIRST + 1;
  30. public static final byte HTML_LITERAL_NO_QUOTE = Token.INTERNAL_FIRST + 2;
  31. public static final byte INSIDE_TAG = Token.INTERNAL_FIRST + 3;
  32. public static final byte JSP_NULL = Token.NULL + (Token.INTERNAL_FIRST + 4);
  33. public static final byte JSP_KEYWORD1 = Token.KEYWORD1 + (Token.INTERNAL_FIRST + 4);
  34. public static final byte JSP_KEYWORD2 = Token.KEYWORD2 + (Token.INTERNAL_FIRST + 4);
  35. public static final byte JSP_KEYWORD3 = Token.KEYWORD3 + (Token.INTERNAL_FIRST + 4);
  36. public static final byte JSP_COMMENT1 = Token.COMMENT1 + (Token.INTERNAL_FIRST + 4);
  37. public static final byte JSP_COMMENT2 = Token.COMMENT2 + (Token.INTERNAL_FIRST + 4);
  38. public static final byte JSP_METHOD = Token.METHOD + (Token.INTERNAL_FIRST + 4);
  39. public static final byte JSP_LITERAL1 = Token.LITERAL1 + (Token.INTERNAL_FIRST + 4);
  40. public static final byte JSP_LITERAL2 = Token.LITERAL2 + (Token.INTERNAL_FIRST + 4);
  41. public static final byte JSP_LABEL = Token.LABEL + (Token.INTERNAL_FIRST + 4);
  42. public JSPTokenMarker()
  43. {
  44. this.js = true;
  45. keywords = JavaScriptTokenMarker.getKeywords();
  46. javaKeywords = JavaTokenMarker.getKeywords();
  47. }
  48. public byte markTokensImpl(byte token, Segment line, int lineIndex)
  49. {
  50. char[] array = line.array;
  51. int offset = line.offset;
  52. lastOffset = offset;
  53. lastKeyword = offset;
  54. int length = line.count + offset;
  55. boolean backslash = false;
  56. lastWhitespace = offset - 1;
  57. loop:
  58. for (int i = offset; i < length; i++)
  59. {
  60. int i1 = (i + 1);
  61. char c = array[i];
  62. if (c == '\\')
  63. {
  64. backslash = !backslash;
  65. if (token == JAVASCRIPT || token >= JSP_NULL)
  66. continue;
  67. }
  68. switch (token)
  69. {
  70. case Token.NULL: // HTML text
  71. backslash = false;
  72. switch (c)
  73. {
  74. case '\\':
  75. addToken(i - lastOffset, token);
  76. lastOffset = lastKeyword = i;
  77. token = Token.OPERATOR;
  78. break;
  79. case '<':
  80. addToken(i - lastOffset, token);
  81. lastOffset = lastKeyword = i;
  82. if (SyntaxUtilities.regionMatches(false, line, i1, "!--"))
  83. {
  84. i += 3;
  85. token = Token.COMMENT1;
  86. } else if (js && SyntaxUtilities.regionMatches(true, line, i1, "script")) {
  87. addToken(1, Token.KEYWORD1);
  88. //addToken(6, Token.METHOD);
  89. //lastOffset = lastKeyword = (i += 7);
  90. lastOffset = lastKeyword = i1;
  91. lastWhitespace = i;
  92. token = Token.METHOD;//JAVASCRIPT;
  93. javascript = true;
  94. } else if (SyntaxUtilities.regionMatches(true, line, i1, "%@")) {
  95. addToken(2, Token.OPERATOR);
  96. addToken(1, Token.LABEL);
  97. lastOffset = lastKeyword = (i += 3);
  98. lastWhitespace = (i + 2);
  99. token = JSP_LABEL;
  100. } else if (SyntaxUtilities.regionMatches(true, line, i1, "%=")) {
  101. addToken(3, Token.OPERATOR);
  102. lastOffset = lastKeyword = (i += 3);
  103. lastWhitespace = (i + 2);
  104. token = JSP_NULL;
  105. } else if (SyntaxUtilities.regionMatches(true, line, i1, "%!")) {
  106. addToken(3, Token.OPERATOR);
  107. lastOffset = lastKeyword = (i += 3);
  108. lastWhitespace = (i + 2);
  109. token = JSP_NULL;
  110. } else if (SyntaxUtilities.regionMatches(true, line, i1, "%")) {
  111. addToken(2, Token.OPERATOR);
  112. lastOffset = lastKeyword = (i += 2);
  113. lastWhitespace = i1;
  114. token = JSP_NULL;
  115. } else {
  116. addToken(1, Token.KEYWORD1);
  117. lastOffset = lastKeyword = i1;
  118. token = Token.METHOD;
  119. }
  120. break;
  121. case '&':
  122. addToken(i - lastOffset, token);
  123. lastOffset = lastKeyword = i;
  124. token = Token.KEYWORD2;
  125. break;
  126. }
  127. break;
  128. case Token.OPERATOR:
  129. backslash = false;
  130. if (c != '<')
  131. {
  132. addToken(i1 - lastOffset, token);
  133. lastOffset = lastKeyword = i1;
  134. token = Token.NULL;
  135. }
  136. break;
  137. case Token.METHOD: // Inside a tag
  138. backslash = false;
  139. if (c == '>')
  140. {
  141. addToken(i - lastOffset, token);
  142. addToken(1, Token.KEYWORD1);
  143. lastOffset = lastKeyword = i1;
  144. if (!javascript)
  145. token = Token.NULL;
  146. else
  147. {
  148. javascript = false;
  149. token = JAVASCRIPT;
  150. }
  151. } else if (c == ':') {
  152. addToken(i1 - lastOffset, Token.LITERAL2);
  153. lastOffset = lastKeyword = i1;
  154. } else if (c == ' ' || c == '\t') {
  155. addToken(i1 - lastOffset, token);
  156. lastOffset = lastKeyword = i1;
  157. token = INSIDE_TAG;
  158. }
  159. break;
  160. case INSIDE_TAG:
  161. backslash = false;
  162. if (c == '>')
  163. {
  164. addToken(i - lastOffset, Token.METHOD);
  165. addToken(1, Token.KEYWORD1);
  166. lastOffset = lastKeyword = i1;
  167. if (!javascript)
  168. token = Token.NULL;
  169. else
  170. {
  171. javascript = false;
  172. token = JAVASCRIPT;
  173. }
  174. } else if (c == '/' || c == '?') {
  175. addToken(1, Token.METHOD);
  176. lastOffset = lastKeyword = i1;
  177. token = Token.METHOD;
  178. } else {//if (c != ' ' && c != '\t') {
  179. addToken(i - lastOffset, Token.NULL);
  180. lastOffset = lastKeyword = i;
  181. token = Token.KEYWORD3;
  182. }
  183. break;
  184. case Token.KEYWORD2: // Inside an entity
  185. backslash = false;
  186. if (c == ';')
  187. {
  188. addToken(i1 - lastOffset, token);
  189. lastOffset = lastKeyword = i1;
  190. token = Token.NULL;
  191. }
  192. break;
  193. case Token.KEYWORD3: // Inside an attribute
  194. backslash = false;
  195. if (c == '/' || c == '?')
  196. {
  197. addToken(i - lastOffset, token);
  198. addToken(1, Token.METHOD);
  199. lastOffset = lastKeyword = i1;
  200. //token = INSIDE_TAG;
  201. } else if (c == '=') {
  202. addToken(i - lastOffset, token);
  203. addToken(1, Token.LABEL);
  204. lastOffset = lastKeyword = i1;
  205. if (i1 < array.length && array[i1] == '"')
  206. {
  207. token = HTML_LITERAL_QUOTE;
  208. i++;
  209. } else {
  210. token = HTML_LITERAL_NO_QUOTE;
  211. }
  212. } else if (c == '>') {
  213. addToken(i - lastOffset, token);
  214. addToken(1, Token.KEYWORD1);
  215. lastOffset = lastKeyword = i1;
  216. token = Token.NULL;
  217. } else if (c == ' ' || c == '\t') {
  218. addToken(i1 - lastOffset, token);
  219. lastOffset = lastKeyword = i1;
  220. token = INSIDE_TAG;
  221. }
  222. break;
  223. case HTML_LITERAL_QUOTE:
  224. backslash = false;
  225. if (c == '"')
  226. {
  227. addToken(i1 - lastOffset, Token.LITERAL1);
  228. lastOffset = lastKeyword = i1;
  229. token = INSIDE_TAG;
  230. }
  231. break;
  232. case HTML_LITERAL_NO_QUOTE:
  233. backslash = false;
  234. if (c == ' ' || c == '\t')
  235. {
  236. addToken(i1 - lastOffset, Token.LITERAL1);
  237. lastOffset = lastKeyword = i1;
  238. token = INSIDE_TAG;
  239. } else if (c == '>') {
  240. addToken(i - lastOffset, Token.LITERAL1);
  241. addToken(1, Token.KEYWORD1);
  242. lastOffset = lastKeyword = i1;
  243. token = Token.NULL;
  244. }
  245. break;
  246. case Token.COMMENT1: // Inside a comment
  247. backslash = false;
  248. if (SyntaxUtilities.regionMatches(false, line, i, "-->"))
  249. {
  250. addToken((i + 3) - lastOffset, token);
  251. lastOffset = lastKeyword = i + 3;
  252. token = Token.NULL;
  253. }
  254. break;
  255. case JAVASCRIPT: // Inside a JavaScript
  256. switch (c)
  257. {
  258. case '<':
  259. backslash = false;
  260. doJSKeyword(line, i, c);
  261. if (SyntaxUtilities.regionMatches(true, line, i1, "/script>"))
  262. {
  263. addToken(i - lastOffset, Token.NULL);
  264. addToken(1, Token.KEYWORD1);
  265. addToken(7, Token.METHOD);
  266. addToken(1, Token.KEYWORD1);
  267. lastOffset = lastKeyword = (i += 9);
  268. token = Token.NULL;
  269. }
  270. break;
  271. case '(':
  272. if (backslash)
  273. {
  274. doJSKeyword(line, i, c);
  275. backslash = false;
  276. } else {
  277. if (doJSKeyword(line, i, c))
  278. break;
  279. addToken(lastWhitespace - lastOffset + 1, Token.NULL);
  280. addToken(i - lastWhitespace - 1, Token.METHOD);
  281. addToken(1, Token.NULL);
  282. token = JAVASCRIPT;
  283. lastOffset = lastKeyword = i1;
  284. lastWhitespace = i;
  285. }
  286. break;
  287. case '"':
  288. if (backslash)
  289. backslash = false;
  290. else
  291. {
  292. doJSKeyword(line, i, c);
  293. addToken(i - lastOffset, Token.NULL);
  294. lastOffset = lastKeyword = i;
  295. token = Token.LITERAL1;
  296. }
  297. break;
  298. case '\'':
  299. if (backslash)
  300. backslash = false;
  301. else
  302. {
  303. doJSKeyword(line, i, c);
  304. addToken(i - lastOffset, Token.NULL);
  305. lastOffset = lastKeyword = i;
  306. token = Token.LITERAL2;
  307. }
  308. break;
  309. case '/':
  310. backslash = false;
  311. doJSKeyword(line, i, c);
  312. if (length - i > 1)
  313. {
  314. addToken(i - lastOffset, Token.NULL);
  315. lastOffset = lastKeyword = i;
  316. if (array[i1] == '/')
  317. {
  318. addToken(length - i, Token.COMMENT2);
  319. lastOffset = lastKeyword = length;
  320. break loop;
  321. } else if (array[i1] == '*') {
  322. token = Token.COMMENT2;
  323. }
  324. }
  325. break;
  326. default:
  327. backslash = false;
  328. if (!Character.isLetterOrDigit(c) && c != '_')
  329. doJSKeyword(line, i, c);
  330. if (CTokenMarker.METHOD_DELIMITERS.indexOf(c) != -1)
  331. {
  332. lastWhitespace = i;
  333. }
  334. break;
  335. }
  336. break;
  337. case Token.LITERAL1: // JavaScript "..."
  338. if (backslash)
  339. backslash = false;
  340. else if (c == '"')
  341. {
  342. addToken(i1 - lastOffset, Token.LITERAL1);
  343. lastOffset = lastKeyword = i1;
  344. token = JAVASCRIPT;
  345. }
  346. break;
  347. case Token.LITERAL2: // JavaScript '...'
  348. if (backslash)
  349. backslash = false;
  350. else if (c == '\'')
  351. {
  352. addToken(i1 - lastOffset, Token.LITERAL1);
  353. lastOffset = lastKeyword = i1;
  354. token = JAVASCRIPT;
  355. }
  356. break;
  357. case Token.COMMENT2: // Inside a JavaScript comment
  358. backslash = false;
  359. if (c == '*' && length - i > 1 && array[i1] == '/')
  360. {
  361. addToken((i += 2) - lastOffset, Token.COMMENT1);
  362. lastOffset = lastKeyword = i;
  363. token = JAVASCRIPT;
  364. }
  365. break;
  366. default:
  367. if (token > Token.INTERNAL_FIRST + 3)
  368. {
  369. switch (token)
  370. {
  371. case JSP_NULL:
  372. switch(c)
  373. {
  374. case '%':
  375. backslash = false;
  376. if (length - i > 1 && array[i1] == '>')
  377. {
  378. addToken(i - lastOffset, (byte) (token - (Token.INTERNAL_FIRST + 4)));
  379. addToken(2, Token.OPERATOR);
  380. lastOffset = lastKeyword = (i += 1) + 1;
  381. token = Token.NULL;
  382. } else {
  383. addToken(i - lastOffset, (byte) (token - (Token.INTERNAL_FIRST + 4)));
  384. addToken(1, Token.NULL);
  385. lastOffset = lastKeyword = lastWhitespace = (i += 1);
  386. token = JSP_NULL;
  387. }
  388. break;
  389. case '(':
  390. if (backslash)
  391. {
  392. doJavaKeyword(line, i, c);
  393. backslash = false;
  394. } else {
  395. if (doJavaKeyword(line, i, c))
  396. break;
  397. addToken(lastWhitespace - lastOffset + 1, (byte) (token - (Token.INTERNAL_FIRST + 4)));
  398. addToken(i - lastWhitespace - 1, Token.METHOD);
  399. addToken(1, Token.NULL);
  400. token = JSP_NULL;
  401. lastOffset = lastKeyword = i1;
  402. lastWhitespace = i;
  403. }
  404. break;
  405. case '"':
  406. doJavaKeyword(line, i, c);
  407. if(backslash)
  408. backslash = false;
  409. else
  410. {
  411. addToken(i - lastOffset, (byte) (token - (Token.INTERNAL_FIRST + 4)));
  412. token = JSP_LITERAL1;
  413. lastOffset = lastKeyword = i;
  414. }
  415. break;
  416. case '\'':
  417. doJavaKeyword(line, i, c);
  418. if (backslash)
  419. backslash = false;
  420. else
  421. {
  422. addToken(i - lastOffset, (byte) (token - (Token.INTERNAL_FIRST + 4)));
  423. token = JSP_LITERAL2;
  424. lastOffset = lastKeyword = i;
  425. }
  426. break;
  427. case ':':
  428. if(lastKeyword == offset)
  429. {
  430. if (doJavaKeyword(line, i, c))
  431. break;
  432. backslash = false;
  433. addToken(i1 - lastOffset, Token.LABEL);
  434. lastOffset = lastKeyword = i1;
  435. }
  436. else if(doJavaKeyword(line, i, c))
  437. break;
  438. break;
  439. case '/':
  440. backslash = false;
  441. doJavaKeyword(line, i, c);
  442. if(length - i > 1)
  443. {
  444. switch(array[i1])
  445. {
  446. case '*':
  447. addToken(i - lastOffset, (byte) (token - (Token.INTERNAL_FIRST + 4)));
  448. lastOffset = lastKeyword = i;
  449. if(length - i > 2 && array[i + 2] == '*')
  450. token = JSP_COMMENT2;
  451. else
  452. token = JSP_COMMENT1;
  453. break;
  454. case '/':
  455. addToken(i - lastOffset, (byte) (token - (Token.INTERNAL_FIRST + 4)));
  456. addToken(length - i, Token.COMMENT1);
  457. lastOffset = lastKeyword = length;
  458. break loop;
  459. }
  460. }
  461. break;
  462. default:
  463. backslash = false;
  464. if (!Character.isLetterOrDigit(c) && c != '_')
  465. doJavaKeyword(line, i, c);
  466. if (CTokenMarker.METHOD_DELIMITERS.indexOf(c) != -1)
  467. lastWhitespace = i;
  468. break;
  469. }
  470. break;
  471. case JSP_COMMENT1:
  472. case JSP_COMMENT2:
  473. backslash = false;
  474. if (c == '*' && length - i > 1)
  475. {
  476. if (array[i1] == '/')
  477. {
  478. i++;
  479. addToken((i + 1) - lastOffset, (byte) (token - (Token.INTERNAL_FIRST + 4)));
  480. token = JSP_NULL;
  481. lastOffset = lastKeyword = i + 1;
  482. lastWhitespace = i;
  483. }
  484. }
  485. break;
  486. case JSP_LABEL:
  487. backslash = false;
  488. if (c == ' ' || c == '\t')
  489. {
  490. addToken(i1 - lastOffset, (byte) (token - (Token.INTERNAL_FIRST + 4)));
  491. lastOffset = lastKeyword = i1;
  492. } else if (c == '=') {
  493. addToken(i - lastOffset, Token.KEYWORD3);
  494. addToken(1, Token.LABEL);
  495. lastOffset = lastKeyword = i1;
  496. } else if (c == '\'') {
  497. addToken(i - lastOffset, Token.KEYWORD3);
  498. token = JSP_LITERAL2;
  499. lastOffset = lastKeyword = i;
  500. } else if (c == '"') {
  501. addToken(i - lastOffset, Token.KEYWORD3);
  502. token = JSP_LITERAL1;
  503. lastOffset = lastKeyword = i;
  504. }
  505. break;
  506. case JSP_LITERAL1:
  507. if (backslash)
  508. backslash = false;
  509. else if (c == '"')
  510. {
  511. addToken(i1 - lastOffset, (byte) (token - (Token.INTERNAL_FIRST + 4)));
  512. token = JSP_NULL;
  513. lastOffset = lastKeyword = i1;
  514. lastWhitespace = i;
  515. }
  516. break;
  517. case JSP_LITERAL2:
  518. if (backslash)
  519. backslash = false;
  520. else if (c == '\'')
  521. {
  522. addToken(i1 - lastOffset, (byte) (token - (Token.INTERNAL_FIRST + 4)));
  523. token = JSP_NULL;
  524. lastOffset = lastKeyword = i1;
  525. lastWhitespace = i;
  526. }
  527. break;
  528. default:
  529. throw new InternalError("Invalid state: " + token);
  530. }
  531. } else
  532. throw new InternalError("Invalid state: " + token);
  533. }
  534. }
  535. switch (token)
  536. {
  537. case Token.LITERAL1:
  538. case Token.LITERAL2:
  539. addToken(length - lastOffset, Token.INVALID);
  540. token = JAVASCRIPT;
  541. break;
  542. case Token.KEYWORD2:
  543. addToken(length - lastOffset, Token.INVALID);
  544. token = Token.NULL;
  545. break;
  546. case JAVASCRIPT:
  547. doJSKeyword(line, length, '\0');
  548. addToken(length - lastOffset, Token.NULL);
  549. break;
  550. case Token.COMMENT2:
  551. addToken(length - lastOffset, Token.COMMENT1);
  552. break;
  553. case INSIDE_TAG:
  554. break;
  555. case HTML_LITERAL_QUOTE: case HTML_LITERAL_NO_QUOTE:
  556. addToken(length - lastOffset, Token.LITERAL1);
  557. break;
  558. default:
  559. if (token < JSP_NULL)
  560. addToken(length - lastOffset, token);
  561. else
  562. {
  563. if (token == JSP_NULL)
  564. doJavaKeyword(line, length, '\0');
  565. switch(token)
  566. {
  567. case JSP_LITERAL1:
  568. case JSP_LITERAL2:
  569. addToken(length - lastOffset, Token.INVALID);
  570. token = JSP_NULL;
  571. break;
  572. case JSP_KEYWORD2:
  573. addToken(length - lastOffset, (byte) (token - (Token.INTERNAL_FIRST + 4)));
  574. if (!backslash)
  575. token = JSP_NULL;
  576. break;
  577. default:
  578. addToken(length - lastOffset, (byte) (token - (Token.INTERNAL_FIRST + 4)));
  579. break;
  580. }
  581. }
  582. break;
  583. }
  584. return token;
  585. }
  586. // private members
  587. private KeywordMap keywords;
  588. private KeywordMap javaKeywords;
  589. private boolean js;
  590. private boolean javascript;
  591. private int lastOffset;
  592. private int lastKeyword;
  593. private int lastWhitespace;
  594. private boolean doJSKeyword(Segment line, int i, char c)
  595. {
  596. return doKeyword(line, i, c, true);
  597. }
  598. private boolean doJavaKeyword(Segment line, int i, char c)
  599. {
  600. return doKeyword(line, i, c, false);
  601. }
  602. private boolean doKeyword(Segment line, int i, char c, boolean javaScript)
  603. {
  604. int i1 = i + 1;
  605. int len = i - lastKeyword;
  606. byte id = (javaScript ? keywords : javaKeywords).lookup(line, lastKeyword, len);
  607. if (id != Token.NULL)
  608. {
  609. if (lastKeyword != lastOffset)
  610. addToken(lastKeyword - lastOffset, Token.NULL);
  611. addToken(len, id);
  612. lastKeyword = i1;
  613. lastOffset = i;
  614. lastWhitespace = i;
  615. return true;
  616. }
  617. lastKeyword = i1;
  618. return false;
  619. }
  620. }