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.

SelectorGeneratorJSOptimal.java 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Copyright 2011, The gwtquery team.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.google.gwt.query.rebind;
  17. import com.google.gwt.core.ext.TreeLogger;
  18. import com.google.gwt.core.ext.UnableToCompleteException;
  19. import com.google.gwt.core.ext.typeinfo.JMethod;
  20. import com.google.gwt.query.client.Selector;
  21. import com.google.gwt.user.rebind.SourceWriter;
  22. import java.util.regex.Pattern;
  23. /**
  24. *
  25. */
  26. public class SelectorGeneratorJSOptimal extends SelectorGeneratorBase {
  27. static class RuleMatcher {
  28. public Pattern re;
  29. public String fnTemplate;
  30. RuleMatcher(String pat, String fnT) {
  31. this.re = Pattern.compile(pat);
  32. this.fnTemplate = fnT;
  33. }
  34. }
  35. protected static Pattern nonSpace = Pattern.compile("\\S/");
  36. protected static final String TRIM_RE_STR = "^\\s+|\\s+$";
  37. protected static Pattern trimRe = Pattern.compile(TRIM_RE_STR);
  38. protected static Pattern tplRe = Pattern.compile("\\{(\\d+)\\}");
  39. protected static Pattern modeRe = Pattern
  40. .compile("^(\\s?[\\/>+~]\\s?|\\s|$)");
  41. protected static Pattern tagTokenRe = Pattern
  42. .compile("^(#)?([a-zA-Z_0-9-\\*]+)");
  43. protected static Pattern nthRe = Pattern.compile("(\\d*)n\\+?(\\d*)");
  44. protected static Pattern nthRe2 = Pattern.compile("\\D");
  45. protected static RuleMatcher[] matchers = new RuleMatcher[] {
  46. new RuleMatcher("^\\.([a-zA-Z_0-9-]+)",
  47. "n = byClassName(n, null, \"{0}\");"),
  48. new RuleMatcher("^\\:([a-zA-Z_0-9-]+)(?:\\(((?:[^ >]*|.*?))\\))?",
  49. "n = byPseudo(n, \"{0}\", \"{1}\");"), new RuleMatcher(
  50. "^(?:([\\[\\{])(?:@)?([a-zA-Z_0-9-]+)\\s?(?:(=|.=)\\s?['\"]?(.*?)[\"']?)?[\\]\\}])",
  51. "n = byAttribute(n, \"{1}\", \"{3}\", \"{2}\", \"{0}\");"),
  52. new RuleMatcher("^#([a-zA-Z_0-9-]+)", "n = byId(n, null, \"{0}\");")};
  53. protected void generateMethodBody(SourceWriter sw, JMethod method,
  54. TreeLogger treeLogger, boolean hasContext)
  55. throws UnableToCompleteException {
  56. String selector = method.getAnnotation(Selector.class).value();
  57. sw.println("return " + wrap(method,
  58. "impl.select(\"" + selector + "\", root)") + ";");
  59. // sw.println("JSArray n = JSArray.create();");
  60. // if(!hasContext) {
  61. // sw.println("Node root = Document.get();");
  62. // }
  63. //
  64. // // add root node as context.
  65. // // TODO: support any context
  66. // sw.println("n.addNode(root);");
  67. // String q = selector, lq = null;
  68. // Matcher lmode = modeRe.matcher(q);
  69. // Matcher mm = null;
  70. // String mode = "";
  71. // if (lmode.lookingAt() && notNull(lmode.group(1))) {
  72. // mode = lmode.group(1).replaceAll(trimReStr, "").trim();
  73. // q = q.replaceFirst("\\Q" + lmode.group(1) + "\\E", "");
  74. // }
  75. //
  76. // while (notNull(q) && !q.equals(lq)) {
  77. // debug("Doing q=" + q);
  78. //
  79. // lq = q;
  80. // Matcher tm = tagTokenRe.matcher(q);
  81. // if (tm.lookingAt()) {
  82. // if ("#".equals(tm.group(1))) {
  83. // sw.println("n = quickId(n, \"" + mode + "\", root, \"" + tm.group(2)
  84. // + "\");");
  85. // } else {
  86. // String tagName = tm.group(2);
  87. // tagName = "".equals(tagName) ? "*" : tagName;
  88. // // sw.println("if (n.size() == 0) { n=JSArray.create(); }");
  89. // String func = "";
  90. // if ("".equals(mode)) {
  91. // func = "getDescendentNodes";
  92. // } else if (">".equals(mode)) {
  93. // func = "getChildNodes";
  94. // } else if ("+".equals(mode)) {
  95. // func = "getSiblingNodes";
  96. // } else if ("~".equals(mode)) {
  97. // func = "getGeneralSiblingNodes";
  98. // } else {
  99. // treeLogger.log(TreeLogger.ERROR, "Error parsing selector, combiner "
  100. // + mode + " not recognized in " + selector, null);
  101. // throw new UnableToCompleteException();
  102. // }
  103. // sw.println("n = " + func + "(n, \"" + tagName + "\");");
  104. // }
  105. // debug("replacing in q, the value " + tm.group(0));
  106. // q = q.replaceFirst("\\Q" + tm.group(0) + "\\E", "");
  107. // } else {
  108. // String func = "";
  109. // String tagName = "*";
  110. // if ("".equals(mode)) {
  111. // func = "getDescendentNodes";
  112. // } else if (">".equals(mode)) {
  113. // func = "getChildNodes";
  114. // } else if ("+".equals(mode)) {
  115. // func = "getSiblingNodes";
  116. // } else if ("~".equals(mode)) {
  117. // func = "getGeneralSiblingNodes";
  118. // } else {
  119. // treeLogger.log(TreeLogger.ERROR, "Error parsing selector, combiner "
  120. // + mode + " not recognized in " + selector, null);
  121. // throw new UnableToCompleteException();
  122. // }
  123. // sw.println("n = " + func + "(n, \"" + tagName + "\");");
  124. // }
  125. //
  126. // while (!(mm = modeRe.matcher(q)).lookingAt()) {
  127. // debug("Looking at " + q);
  128. // boolean matched = false;
  129. // for (RuleMatcher rm : matchers) {
  130. // Matcher rmm = rm.re.matcher(q);
  131. // if (rmm.lookingAt()) {
  132. // String res[] = new String[rmm.groupCount()];
  133. // for (int i = 1; i <= rmm.groupCount(); i++) {
  134. // res[i - 1] = rmm.group(i);
  135. // debug("added param " + res[i - 1]);
  136. // }
  137. // Object[] r = res;
  138. // // inline enum, perhaps type-tightening will allow inlined eval()
  139. // // call
  140. // if (rm.fnTemplate.indexOf("byPseudo") != -1) {
  141. // sw.println("n = Pseudo."+res[0].toUpperCase().replace("-", "_") +
  142. // ".eval(n, \""+res[1]+"\");");
  143. // } else {
  144. // sw.println(MessageFormat.format(rm.fnTemplate, r));
  145. // }
  146. // q = q.replaceFirst("\\Q" + rmm.group(0) + "\\E", "");
  147. // matched = true;
  148. // break;
  149. // }
  150. // }
  151. // if (!matched) {
  152. // treeLogger
  153. // .log(TreeLogger.ERROR, "Error parsing selector at " + q, null);
  154. // throw new UnableToCompleteException();
  155. // }
  156. // }
  157. //
  158. // if (notNull(mm.group(1))) {
  159. // mode = mm.group(1).replaceAll(trimReStr, "");
  160. // debug("replacing q=" + q + " this part: " + mm.group(1));
  161. // q = q.replaceFirst("\\Q" + mm.group(1) + "\\E", "");
  162. // }
  163. // }
  164. // sw.println("return "+wrap(method, "nodup(n)")+";");
  165. }
  166. protected String getImplSuffix() {
  167. return "JS" + super.getImplSuffix();
  168. }
  169. }