Ast.java 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413
  1. package org.ssssssss.magicapi.expression.parsing;
  2. import org.apache.commons.lang3.StringUtils;
  3. import org.apache.commons.lang3.exception.ExceptionUtils;
  4. import org.ssssssss.magicapi.expression.ExpressionError;
  5. import org.ssssssss.magicapi.expression.ExpressionError.TemplateException;
  6. import org.ssssssss.magicapi.expression.ExpressionTemplate;
  7. import org.ssssssss.magicapi.expression.ExpressionTemplateContext;
  8. import org.ssssssss.magicapi.expression.interpreter.AbstractReflection;
  9. import org.ssssssss.magicapi.expression.interpreter.AstInterpreter;
  10. import org.ssssssss.magicapi.expression.interpreter.JavaReflection;
  11. import javax.xml.transform.Source;
  12. import java.io.IOException;
  13. import java.lang.reflect.Array;
  14. import java.lang.reflect.InvocationTargetException;
  15. import java.util.*;
  16. import java.util.concurrent.atomic.AtomicInteger;
  17. /** Templates are parsed into an abstract syntax tree (AST) nodes by a Parser. This class contains all AST node types. */
  18. public abstract class Ast {
  19. /** Base class for all AST nodes. A node minimally stores the {@link Span} that references its location in the
  20. * {@link Source}. **/
  21. public abstract static class Node {
  22. private final Span span;
  23. public Node (Span span) {
  24. this.span = span;
  25. }
  26. /** Returns the {@link Span} referencing this node's location in the {@link Source}. **/
  27. public Span getSpan () {
  28. return span;
  29. }
  30. @Override
  31. public String toString () {
  32. return span.getText();
  33. }
  34. public abstract Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException;
  35. }
  36. /** A text node represents an "un-templated" span in the source that should be emitted verbatim. **/
  37. public static class Text extends Node {
  38. private final String content;
  39. public Text (Span text) {
  40. super(text);
  41. String unescapedValue = text.getText();
  42. StringBuilder builder = new StringBuilder();
  43. CharacterStream stream = new CharacterStream(unescapedValue);
  44. while (stream.hasMore()) {
  45. if (stream.match("\\{", true)) {
  46. builder.append('{');
  47. } else if (stream.match("\\}", true)) {
  48. builder.append('}');
  49. } else {
  50. builder.append(stream.consume());
  51. }
  52. }
  53. content = builder.toString();
  54. }
  55. /** Returns the UTF-8 representation of this text node. **/
  56. public String getContent () {
  57. return content;
  58. }
  59. @Override
  60. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  61. return null;
  62. }
  63. }
  64. /** All expressions are subclasses of this node type. Expressions are separated into unary operations (!, -), binary operations
  65. * (+, -, *, /, etc.) and ternary operations (?:). */
  66. public abstract static class Expression extends Node {
  67. public Expression (Span span) {
  68. super(span);
  69. }
  70. }
  71. /** An unary operation node represents a logical or numerical negation. **/
  72. public static class UnaryOperation extends Expression {
  73. public static enum UnaryOperator {
  74. Not, Negate, Positive;
  75. public static UnaryOperator getOperator (Token op) {
  76. if (op.getType() == TokenType.Not) {
  77. return UnaryOperator.Not;
  78. }
  79. if (op.getType() == TokenType.Plus) {
  80. return UnaryOperator.Positive;
  81. }
  82. if (op.getType() == TokenType.Minus) {
  83. return UnaryOperator.Negate;
  84. }
  85. ExpressionError.error("Unknown unary operator " + op + ".", op.getSpan());
  86. return null; // not reached
  87. }
  88. }
  89. private final UnaryOperator operator;
  90. private final Expression operand;
  91. public UnaryOperation (Token operator, Expression operand) {
  92. super(operator.getSpan());
  93. this.operator = UnaryOperator.getOperator(operator);
  94. this.operand = operand;
  95. }
  96. public UnaryOperator getOperator () {
  97. return operator;
  98. }
  99. public Expression getOperand () {
  100. return operand;
  101. }
  102. @Override
  103. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  104. Object operand = getOperand().evaluate(template, context);
  105. if (getOperator() == UnaryOperator.Negate) {
  106. if (operand instanceof Integer) {
  107. return -(Integer)operand;
  108. } else if (operand instanceof Float) {
  109. return -(Float)operand;
  110. } else if (operand instanceof Double) {
  111. return -(Double)operand;
  112. } else if (operand instanceof Byte) {
  113. return -(Byte)operand;
  114. } else if (operand instanceof Short) {
  115. return -(Short)operand;
  116. } else if (operand instanceof Long) {
  117. return -(Long)operand;
  118. } else {
  119. ExpressionError.error("Operand of operator '" + getOperator().name() + "' must be a number, got " + operand, getSpan());
  120. return null; // never reached
  121. }
  122. } else if (getOperator() == UnaryOperator.Not) {
  123. if (!(operand instanceof Boolean)) {
  124. ExpressionError.error("Operand of operator '" + getOperator().name() + "' must be a boolean", getSpan());
  125. }
  126. return !(Boolean)operand;
  127. } else {
  128. return operand;
  129. }
  130. }
  131. }
  132. /** A binary operation represents arithmetic operators, like addition or division, comparison operators, like less than or
  133. * equals, logical operators, like and, or an assignment. **/
  134. public static class BinaryOperation extends Expression {
  135. public static enum BinaryOperator {
  136. Addition, Subtraction, Multiplication, Division, Modulo, Equal, NotEqual, Less, LessEqual, Greater, GreaterEqual, And, Or, Xor, Assignment;
  137. public static BinaryOperator getOperator (Token op) {
  138. if (op.getType() == TokenType.Plus) {
  139. return BinaryOperator.Addition;
  140. }
  141. if (op.getType() == TokenType.Minus) {
  142. return BinaryOperator.Subtraction;
  143. }
  144. if (op.getType() == TokenType.Asterisk) {
  145. return BinaryOperator.Multiplication;
  146. }
  147. if (op.getType() == TokenType.ForwardSlash) {
  148. return BinaryOperator.Division;
  149. }
  150. if (op.getType() == TokenType.Percentage) {
  151. return BinaryOperator.Modulo;
  152. }
  153. if (op.getType() == TokenType.Equal) {
  154. return BinaryOperator.Equal;
  155. }
  156. if (op.getType() == TokenType.NotEqual) {
  157. return BinaryOperator.NotEqual;
  158. }
  159. if (op.getType() == TokenType.Less) {
  160. return BinaryOperator.Less;
  161. }
  162. if (op.getType() == TokenType.LessEqual) {
  163. return BinaryOperator.LessEqual;
  164. }
  165. if (op.getType() == TokenType.Greater) {
  166. return BinaryOperator.Greater;
  167. }
  168. if (op.getType() == TokenType.GreaterEqual) {
  169. return BinaryOperator.GreaterEqual;
  170. }
  171. if (op.getType() == TokenType.And) {
  172. return BinaryOperator.And;
  173. }
  174. if (op.getType() == TokenType.Or) {
  175. return BinaryOperator.Or;
  176. }
  177. if (op.getType() == TokenType.Xor) {
  178. return BinaryOperator.Xor;
  179. }
  180. if (op.getType() == TokenType.Assignment) {
  181. return BinaryOperator.Assignment;
  182. }
  183. ExpressionError.error("Unknown binary operator " + op + ".", op.getSpan());
  184. return null; // not reached
  185. }
  186. }
  187. private final Expression leftOperand;
  188. private final BinaryOperator operator;
  189. private final Expression rightOperand;
  190. public BinaryOperation (Expression leftOperand, Token operator, Expression rightOperand) {
  191. super(operator.getSpan());
  192. this.leftOperand = leftOperand;
  193. this.operator = BinaryOperator.getOperator(operator);
  194. this.rightOperand = rightOperand;
  195. }
  196. public Expression getLeftOperand () {
  197. return leftOperand;
  198. }
  199. public BinaryOperator getOperator () {
  200. return operator;
  201. }
  202. public Expression getRightOperand () {
  203. return rightOperand;
  204. }
  205. private Object evaluateAddition (Object left, Object right) {
  206. if (left instanceof String || right instanceof String) {
  207. return left.toString() + right.toString();
  208. }
  209. if (left instanceof Double || right instanceof Double) {
  210. return ((Number)left).doubleValue() + ((Number)right).doubleValue();
  211. }
  212. if (left instanceof Float || right instanceof Float) {
  213. return ((Number)left).floatValue() + ((Number)right).floatValue();
  214. }
  215. if (left instanceof Long || right instanceof Long) {
  216. return ((Number)left).longValue() + ((Number)right).longValue();
  217. }
  218. if (left instanceof Integer || right instanceof Integer) {
  219. return ((Number)left).intValue() + ((Number)right).intValue();
  220. }
  221. if (left instanceof Short || right instanceof Short) {
  222. return ((Number)left).shortValue() + ((Number)right).shortValue();
  223. }
  224. if (left instanceof Byte || right instanceof Byte) {
  225. return ((Number)left).byteValue() + ((Number)right).byteValue();
  226. }
  227. ExpressionError.error("Operands for addition operator must be numbers or strings, got " + left + ", " + right + ".", getSpan());
  228. return null; // never reached
  229. }
  230. private Object evaluateSubtraction (Object left, Object right) {
  231. if (left instanceof Double || right instanceof Double) {
  232. return ((Number)left).doubleValue() - ((Number)right).doubleValue();
  233. } else if (left instanceof Float || right instanceof Float) {
  234. return ((Number)left).floatValue() - ((Number)right).floatValue();
  235. } else if (left instanceof Long || right instanceof Long) {
  236. return ((Number)left).longValue() - ((Number)right).longValue();
  237. } else if (left instanceof Integer || right instanceof Integer) {
  238. return ((Number)left).intValue() - ((Number)right).intValue();
  239. } else if (left instanceof Short || right instanceof Short) {
  240. return ((Number)left).shortValue() - ((Number)right).shortValue();
  241. } else if (left instanceof Byte || right instanceof Byte) {
  242. return ((Number)left).byteValue() - ((Number)right).byteValue();
  243. } else {
  244. ExpressionError.error("Operands for subtraction operator must be numbers" + left + ", " + right + ".", getSpan());
  245. return null; // never reached
  246. }
  247. }
  248. private Object evaluateMultiplication (Object left, Object right) {
  249. if (left instanceof Double || right instanceof Double) {
  250. return ((Number)left).doubleValue() * ((Number)right).doubleValue();
  251. } else if (left instanceof Float || right instanceof Float) {
  252. return ((Number)left).floatValue() * ((Number)right).floatValue();
  253. } else if (left instanceof Long || right instanceof Long) {
  254. return ((Number)left).longValue() * ((Number)right).longValue();
  255. } else if (left instanceof Integer || right instanceof Integer) {
  256. return ((Number)left).intValue() * ((Number)right).intValue();
  257. } else if (left instanceof Short || right instanceof Short) {
  258. return ((Number)left).shortValue() * ((Number)right).shortValue();
  259. } else if (left instanceof Byte || right instanceof Byte) {
  260. return ((Number)left).byteValue() * ((Number)right).byteValue();
  261. } else {
  262. ExpressionError.error("Operands for multiplication operator must be numbers" + left + ", " + right + ".", getSpan());
  263. return null; // never reached
  264. }
  265. }
  266. private Object evaluateDivision (Object left, Object right) {
  267. if (left instanceof Double || right instanceof Double) {
  268. return ((Number)left).doubleValue() / ((Number)right).doubleValue();
  269. } else if (left instanceof Float || right instanceof Float) {
  270. return ((Number)left).floatValue() / ((Number)right).floatValue();
  271. } else if (left instanceof Long || right instanceof Long) {
  272. return ((Number)left).longValue() / ((Number)right).longValue();
  273. } else if (left instanceof Integer || right instanceof Integer) {
  274. return ((Number)left).intValue() / ((Number)right).intValue();
  275. } else if (left instanceof Short || right instanceof Short) {
  276. return ((Number)left).shortValue() / ((Number)right).shortValue();
  277. } else if (left instanceof Byte || right instanceof Byte) {
  278. return ((Number)left).byteValue() / ((Number)right).byteValue();
  279. } else {
  280. ExpressionError.error("Operands for division operator must be numbers" + left + ", " + right + ".", getSpan());
  281. return null; // never reached
  282. }
  283. }
  284. private Object evaluateModulo (Object left, Object right) {
  285. if (left instanceof Double || right instanceof Double) {
  286. return ((Number)left).doubleValue() % ((Number)right).doubleValue();
  287. } else if (left instanceof Float || right instanceof Float) {
  288. return ((Number)left).floatValue() % ((Number)right).floatValue();
  289. } else if (left instanceof Long || right instanceof Long) {
  290. return ((Number)left).longValue() % ((Number)right).longValue();
  291. } else if (left instanceof Integer || right instanceof Integer) {
  292. return ((Number)left).intValue() % ((Number)right).intValue();
  293. } else if (left instanceof Short || right instanceof Short) {
  294. return ((Number)left).shortValue() % ((Number)right).shortValue();
  295. } else if (left instanceof Byte || right instanceof Byte) {
  296. return ((Number)left).byteValue() % ((Number)right).byteValue();
  297. } else {
  298. ExpressionError.error("Operands for modulo operator must be numbers" + left + ", " + right + ".", getSpan());
  299. return null; // never reached
  300. }
  301. }
  302. private boolean evaluateLess (Object left, Object right) {
  303. if (left instanceof Double || right instanceof Double) {
  304. return ((Number)left).doubleValue() < ((Number)right).doubleValue();
  305. } else if (left instanceof Float || right instanceof Float) {
  306. return ((Number)left).floatValue() < ((Number)right).floatValue();
  307. } else if (left instanceof Long || right instanceof Long) {
  308. return ((Number)left).longValue() < ((Number)right).longValue();
  309. } else if (left instanceof Integer || right instanceof Integer) {
  310. return ((Number)left).intValue() < ((Number)right).intValue();
  311. } else if (left instanceof Short || right instanceof Short) {
  312. return ((Number)left).shortValue() < ((Number)right).shortValue();
  313. } else if (left instanceof Byte || right instanceof Byte) {
  314. return ((Number)left).byteValue() < ((Number)right).byteValue();
  315. } else {
  316. ExpressionError.error("Operands for less operator must be numbers" + left + ", " + right + ".", getSpan());
  317. return false; // never reached
  318. }
  319. }
  320. private Object evaluateLessEqual (Object left, Object right) {
  321. if (left instanceof Double || right instanceof Double) {
  322. return ((Number)left).doubleValue() <= ((Number)right).doubleValue();
  323. } else if (left instanceof Float || right instanceof Float) {
  324. return ((Number)left).floatValue() <= ((Number)right).floatValue();
  325. } else if (left instanceof Long || right instanceof Long) {
  326. return ((Number)left).longValue() <= ((Number)right).longValue();
  327. } else if (left instanceof Integer || right instanceof Integer) {
  328. return ((Number)left).intValue() <= ((Number)right).intValue();
  329. } else if (left instanceof Short || right instanceof Short) {
  330. return ((Number)left).shortValue() <= ((Number)right).shortValue();
  331. } else if (left instanceof Byte || right instanceof Byte) {
  332. return ((Number)left).byteValue() <= ((Number)right).byteValue();
  333. } else {
  334. ExpressionError.error("Operands for less/equal operator must be numbers" + left + ", " + right + ".", getSpan());
  335. return null; // never reached
  336. }
  337. }
  338. private Object evaluateGreater (Object left, Object right) {
  339. if(left == null || right == null){
  340. return false;
  341. }
  342. if (left instanceof Double || right instanceof Double) {
  343. return ((Number)left).doubleValue() > ((Number)right).doubleValue();
  344. } else if (left instanceof Float || right instanceof Float) {
  345. return ((Number)left).floatValue() > ((Number)right).floatValue();
  346. } else if (left instanceof Long || right instanceof Long) {
  347. return ((Number)left).longValue() > ((Number)right).longValue();
  348. } else if (left instanceof Integer || right instanceof Integer) {
  349. return ((Number)left).intValue() > ((Number)right).intValue();
  350. } else if (left instanceof Short || right instanceof Short) {
  351. return ((Number)left).shortValue() > ((Number)right).shortValue();
  352. } else if (left instanceof Byte || right instanceof Byte) {
  353. return ((Number)left).byteValue() > ((Number)right).byteValue();
  354. } else {
  355. ExpressionError.error("Operands for greater operator must be numbers" + left + ", " + right + ".", getSpan());
  356. return null; // never reached
  357. }
  358. }
  359. private Object evaluateGreaterEqual (Object left, Object right) {
  360. if (left instanceof Double || right instanceof Double) {
  361. return ((Number)left).doubleValue() >= ((Number)right).doubleValue();
  362. } else if (left instanceof Float || right instanceof Float) {
  363. return ((Number)left).floatValue() >= ((Number)right).floatValue();
  364. } else if (left instanceof Long || right instanceof Long) {
  365. return ((Number)left).longValue() >= ((Number)right).longValue();
  366. } else if (left instanceof Integer || right instanceof Integer) {
  367. return ((Number)left).intValue() >= ((Number)right).intValue();
  368. } else if (left instanceof Short || right instanceof Short) {
  369. return ((Number)left).shortValue() >= ((Number)right).shortValue();
  370. } else if (left instanceof Byte || right instanceof Byte) {
  371. return ((Number)left).byteValue() >= ((Number)right).byteValue();
  372. } else {
  373. ExpressionError.error("Operands for greater/equal operator must be numbers" + left + ", " + right + ".", getSpan());
  374. return null; // never reached
  375. }
  376. }
  377. private Object evaluateAnd (Object left, ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  378. if (!(left instanceof Boolean)) {
  379. ExpressionError.error("Left operand must be a boolean, got " + left + ".", getLeftOperand().getSpan());
  380. }
  381. if (!(Boolean)left) {
  382. return false;
  383. }
  384. Object right = getRightOperand().evaluate(template, context);
  385. if (!(right instanceof Boolean)) {
  386. ExpressionError.error("Right operand must be a boolean, got " + right + ".", getRightOperand().getSpan());
  387. }
  388. return (Boolean)left && (Boolean)right;
  389. }
  390. private Object evaluateOr (Object left, ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  391. if (!(left instanceof Boolean)) {
  392. ExpressionError.error("Left operand must be a boolean, got " + left + ".", getLeftOperand().getSpan());
  393. }
  394. if ((Boolean)left) {
  395. return true;
  396. }
  397. Object right = getRightOperand().evaluate(template, context);
  398. if (!(right instanceof Boolean)) {
  399. ExpressionError.error("Right operand must be a boolean, got " + right + ".", getRightOperand().getSpan());
  400. }
  401. return (Boolean)left || (Boolean)right;
  402. }
  403. private Object evaluateXor (Object left, Object right) {
  404. if (!(left instanceof Boolean)) {
  405. ExpressionError.error("Left operand must be a boolean, got " + left + ".", getLeftOperand().getSpan());
  406. }
  407. if (!(right instanceof Boolean)) {
  408. ExpressionError.error("Right operand must be a boolean, got " + right + ".", getRightOperand().getSpan());
  409. }
  410. return (Boolean)left ^ (Boolean)right;
  411. }
  412. private Object evaluateEqual (Object left, Object right) {
  413. if (left != null) {
  414. return left.equals(right);
  415. }
  416. if (right != null) {
  417. return right.equals(left);
  418. }
  419. return true;
  420. }
  421. private Object evaluateNotEqual (Object left, Object right) {
  422. return !(Boolean)evaluateEqual(left, right);
  423. }
  424. @Override
  425. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  426. if (getOperator() == BinaryOperator.Assignment) {
  427. if (!(getLeftOperand() instanceof VariableAccess)) {
  428. ExpressionError.error("Can only assign to top-level variables in context.", getLeftOperand().getSpan());
  429. }
  430. Object value = getRightOperand().evaluate(template, context);
  431. context.set(((VariableAccess)getLeftOperand()).getVariableName().getText(), value);
  432. return null;
  433. }
  434. Object left = getLeftOperand().evaluate(template, context);
  435. Object right = getOperator() == BinaryOperator.And || getOperator() == BinaryOperator.Or ? null : getRightOperand().evaluate(template, context);
  436. switch (getOperator()) {
  437. case Addition:
  438. return evaluateAddition(left, right);
  439. case Subtraction:
  440. return evaluateSubtraction(left, right);
  441. case Multiplication:
  442. return evaluateMultiplication(left, right);
  443. case Division:
  444. return evaluateDivision(left, right);
  445. case Modulo:
  446. return evaluateModulo(left, right);
  447. case Less:
  448. return evaluateLess(left, right);
  449. case LessEqual:
  450. return evaluateLessEqual(left, right);
  451. case Greater:
  452. return evaluateGreater(left, right);
  453. case GreaterEqual:
  454. return evaluateGreaterEqual(left, right);
  455. case Equal:
  456. return evaluateEqual(left, right);
  457. case NotEqual:
  458. return evaluateNotEqual(left, right);
  459. case And:
  460. return evaluateAnd(left, template, context);
  461. case Or:
  462. return evaluateOr(left, template, context);
  463. case Xor:
  464. return evaluateXor(left, right);
  465. default:
  466. ExpressionError.error("Binary operator " + getOperator().name() + " not implemented", getSpan());
  467. return null;
  468. }
  469. }
  470. }
  471. /** A ternary operation is an abbreviated if/then/else operation, and equivalent to the the ternary operator in Java. **/
  472. public static class TernaryOperation extends Expression {
  473. private final Expression condition;
  474. private final Expression trueExpression;
  475. private final Expression falseExpression;
  476. public TernaryOperation (Expression condition, Expression trueExpression, Expression falseExpression) {
  477. super(new Span(condition.getSpan(), falseExpression.getSpan()));
  478. this.condition = condition;
  479. this.trueExpression = trueExpression;
  480. this.falseExpression = falseExpression;
  481. }
  482. public Expression getCondition () {
  483. return condition;
  484. }
  485. public Expression getTrueExpression () {
  486. return trueExpression;
  487. }
  488. public Expression getFalseExpression () {
  489. return falseExpression;
  490. }
  491. @Override
  492. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  493. Object condition = getCondition().evaluate(template, context);
  494. if (!(condition instanceof Boolean)) {
  495. ExpressionError.error("Condition of ternary operator must be a boolean, got " + condition + ".", getSpan());
  496. }
  497. return ((Boolean)condition) ? getTrueExpression().evaluate(template, context) : getFalseExpression().evaluate(template, context);
  498. }
  499. }
  500. /** A null literal, with the single value <code>null</code> **/
  501. public static class NullLiteral extends Expression {
  502. public NullLiteral (Span span) {
  503. super(span);
  504. }
  505. @Override
  506. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  507. return null;
  508. }
  509. }
  510. /** A boolean literal, with the values <code>true</code> and <code>false</code> **/
  511. public static class BooleanLiteral extends Expression {
  512. private final Boolean value;
  513. public BooleanLiteral (Span literal) {
  514. super(literal);
  515. this.value = Boolean.parseBoolean(literal.getText());
  516. }
  517. public Boolean getValue () {
  518. return value;
  519. }
  520. @Override
  521. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  522. return value;
  523. }
  524. }
  525. /** A double precision floating point literal. Must be marked with the <code>d</code> suffix, e.g. "1.0d". **/
  526. public static class DoubleLiteral extends Expression {
  527. private final Double value;
  528. public DoubleLiteral (Span literal) {
  529. super(literal);
  530. this.value = Double.parseDouble(literal.getText().substring(0, literal.getText().length() - 1));
  531. }
  532. public Double getValue () {
  533. return value;
  534. }
  535. @Override
  536. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  537. return value;
  538. }
  539. }
  540. /** A single precision floating point literla. May be optionally marked with the <code>f</code> suffix, e.g. "1.0f". **/
  541. public static class FloatLiteral extends Expression {
  542. private final Float value;
  543. public FloatLiteral (Span literal) {
  544. super(literal);
  545. String text = literal.getText();
  546. if (text.charAt(text.length() - 1) == 'f') {
  547. text = text.substring(0, text.length() - 1);
  548. }
  549. this.value = Float.parseFloat(text);
  550. }
  551. public Float getValue () {
  552. return value;
  553. }
  554. @Override
  555. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  556. return value;
  557. }
  558. }
  559. /** A byte literal. Must be marked with the <code>b</code> suffix, e.g. "123b". **/
  560. public static class ByteLiteral extends Expression {
  561. private final Byte value;
  562. public ByteLiteral (Span literal) {
  563. super(literal);
  564. this.value = Byte.parseByte(literal.getText().substring(0, literal.getText().length() - 1));
  565. }
  566. public Byte getValue () {
  567. return value;
  568. }
  569. @Override
  570. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  571. return value;
  572. }
  573. }
  574. /** A short literal. Must be marked with the <code>s</code> suffix, e.g. "123s". **/
  575. public static class ShortLiteral extends Expression {
  576. private final Short value;
  577. public ShortLiteral (Span literal) {
  578. super(literal);
  579. this.value = Short.parseShort(literal.getText().substring(0, literal.getText().length() - 1));
  580. }
  581. public Short getValue () {
  582. return value;
  583. }
  584. @Override
  585. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  586. return value;
  587. }
  588. }
  589. /** An integer literal. **/
  590. public static class IntegerLiteral extends Expression {
  591. private final Integer value;
  592. public IntegerLiteral (Span literal) {
  593. super(literal);
  594. this.value = Integer.parseInt(literal.getText());
  595. }
  596. public Integer getValue () {
  597. return value;
  598. }
  599. @Override
  600. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  601. return value;
  602. }
  603. }
  604. /** A long integer literal. Must be marked with the <code>l</code> suffix, e.g. "123l". **/
  605. public static class LongLiteral extends Expression {
  606. private final Long value;
  607. public LongLiteral (Span literal) {
  608. super(literal);
  609. this.value = Long.parseLong(literal.getText().substring(0, literal.getText().length() - 1));
  610. }
  611. public Long getValue () {
  612. return value;
  613. }
  614. @Override
  615. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  616. return value;
  617. }
  618. }
  619. /** A character literal, enclosed in single quotes. Supports escape sequences \n, \r,\t, \' and \\. **/
  620. public static class CharacterLiteral extends Expression {
  621. private final Character value;
  622. public CharacterLiteral (Span literal) {
  623. super(literal);
  624. String text = literal.getText();
  625. if (text.length() > 3) {
  626. if (text.charAt(2) == 'n') {
  627. value = '\n';
  628. } else if (text.charAt(2) == 'r') {
  629. value = '\r';
  630. } else if (text.charAt(2) == 't') {
  631. value = '\t';
  632. } else if (text.charAt(2) == '\\') {
  633. value = '\\';
  634. } else if (text.charAt(2) == '\'') {
  635. value = '\'';
  636. } else {
  637. ExpressionError.error("Unknown escape sequence '" + literal.getText() + "'.", literal);
  638. value = 0; // never reached
  639. }
  640. } else {
  641. this.value = literal.getText().charAt(1);
  642. }
  643. }
  644. public Character getValue () {
  645. return value;
  646. }
  647. @Override
  648. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  649. return value;
  650. }
  651. }
  652. /** A string literal, enclosed in double quotes. Supports escape sequences \n, \r, \t, \" and \\. **/
  653. public static class StringLiteral extends Expression {
  654. private final String value;
  655. public StringLiteral (Span literal) {
  656. super(literal);
  657. String text = getSpan().getText();
  658. String unescapedValue = text.substring(1, text.length() - 1);
  659. StringBuilder builder = new StringBuilder();
  660. CharacterStream stream = new CharacterStream(unescapedValue);
  661. while (stream.hasMore()) {
  662. if (stream.match("\\\\", true)) {
  663. builder.append('\\');
  664. } else if (stream.match("\\n", true)) {
  665. builder.append('\n');
  666. } else if (stream.match("\\r", true)) {
  667. builder.append('\r');
  668. } else if (stream.match("\\t", true)) {
  669. builder.append('\t');
  670. } else if (stream.match("\\\"", true)) {
  671. builder.append('"');
  672. } else {
  673. builder.append(stream.consume());
  674. }
  675. }
  676. value = builder.toString();
  677. }
  678. /** Returns the literal without quotes **/
  679. public String getValue () {
  680. return value;
  681. }
  682. @Override
  683. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  684. return value;
  685. }
  686. }
  687. /** Represents a top-level variable access by name. E.g. in the expression "a + 1", <code>a</code> would be encoded as a
  688. * VariableAccess node. Variables can be both read (in expressions) and written to (in assignments). Variable values are looked
  689. * up and written to a {@link ExpressionTemplateContext}. **/
  690. public static class VariableAccess extends Expression {
  691. public VariableAccess (Span name) {
  692. super(name);
  693. }
  694. public Span getVariableName () {
  695. return getSpan();
  696. }
  697. @Override
  698. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  699. Object value = context.get(getSpan().getText());
  700. //if (value == null) ExpressionError.error("找不到变量'" + getSpan().getText() + "'或变量值为null", getSpan());
  701. return value;
  702. }
  703. }
  704. /** Represents a map or array element access of the form <code>mapOrArray[keyOrIndex]</code>. Maps and arrays may only be read
  705. * from. **/
  706. public static class MapOrArrayAccess extends Expression {
  707. private final Expression mapOrArray;
  708. private final Expression keyOrIndex;
  709. public MapOrArrayAccess (Span span, Expression mapOrArray, Expression keyOrIndex) {
  710. super(span);
  711. this.mapOrArray = mapOrArray;
  712. this.keyOrIndex = keyOrIndex;
  713. }
  714. /** Returns an expression that must evaluate to a map or array. **/
  715. public Expression getMapOrArray () {
  716. return mapOrArray;
  717. }
  718. /** Returns an expression that is used as the key or index to fetch a map or array element. **/
  719. public Expression getKeyOrIndex () {
  720. return keyOrIndex;
  721. }
  722. @SuppressWarnings("rawtypes")
  723. @Override
  724. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  725. Object mapOrArray = getMapOrArray().evaluate(template, context);
  726. if (mapOrArray == null) {
  727. return null;
  728. }
  729. Object keyOrIndex = getKeyOrIndex().evaluate(template, context);
  730. if (keyOrIndex == null) {
  731. return null;
  732. }
  733. if (mapOrArray instanceof Map) {
  734. return ((Map)mapOrArray).get(keyOrIndex);
  735. } else if (mapOrArray instanceof List) {
  736. if (!(keyOrIndex instanceof Number)) {
  737. ExpressionError.error("List index must be an integer, but was " + keyOrIndex.getClass().getSimpleName(), getKeyOrIndex().getSpan());
  738. }
  739. int index = ((Number)keyOrIndex).intValue();
  740. return ((List)mapOrArray).get(index);
  741. } else {
  742. if (!(keyOrIndex instanceof Number)) {
  743. ExpressionError.error("Array index must be an integer, but was " + keyOrIndex.getClass().getSimpleName(), getKeyOrIndex().getSpan());
  744. }
  745. int index = ((Number)keyOrIndex).intValue();
  746. if (mapOrArray instanceof int[]) {
  747. return ((int[])mapOrArray)[index];
  748. } else if (mapOrArray instanceof float[]) {
  749. return ((float[])mapOrArray)[index];
  750. } else if (mapOrArray instanceof double[]) {
  751. return ((double[])mapOrArray)[index];
  752. } else if (mapOrArray instanceof boolean[]) {
  753. return ((boolean[])mapOrArray)[index];
  754. } else if (mapOrArray instanceof char[]) {
  755. return ((char[])mapOrArray)[index];
  756. } else if (mapOrArray instanceof short[]) {
  757. return ((short[])mapOrArray)[index];
  758. } else if (mapOrArray instanceof long[]) {
  759. return ((long[])mapOrArray)[index];
  760. } else if (mapOrArray instanceof byte[]) {
  761. return ((byte[])mapOrArray)[index];
  762. } else if (mapOrArray instanceof String) {
  763. return Character.toString(((String)mapOrArray).charAt(index));
  764. } else {
  765. return ((Object[])mapOrArray)[index];
  766. }
  767. }
  768. }
  769. }
  770. /** Represents an access of a member (field or method or entry in a map) of the form <code>object.member</code>. Members may
  771. * only be read from. **/
  772. public static class MemberAccess extends Expression {
  773. private final Expression object;
  774. private final Span name;
  775. private Object cachedMember;
  776. public MemberAccess (Expression object, Span name) {
  777. super(name);
  778. this.object = object;
  779. this.name = name;
  780. }
  781. /** Returns the object on which to access the member. **/
  782. public Expression getObject () {
  783. return object;
  784. }
  785. /** The name of the member. **/
  786. public Span getName () {
  787. return name;
  788. }
  789. /** Returns the cached member descriptor as returned by {@link AbstractReflection#getField(Object, String)} or
  790. * {@link AbstractReflection#getMethod(Object, String, Object...)}. See {@link #setCachedMember(Object)}. **/
  791. public Object getCachedMember () {
  792. return cachedMember;
  793. }
  794. /** Sets the member descriptor as returned by {@link AbstractReflection#getField(Object, String)} or
  795. * {@link AbstractReflection#getMethod(Object, String, Object...)} for faster member lookups. Called by {@link AstInterpreter} the
  796. * first time this node is evaluated. Subsequent evaluations can use the cached descriptor, avoiding a costly reflective
  797. * lookup. **/
  798. public void setCachedMember (Object cachedMember) {
  799. this.cachedMember = cachedMember;
  800. }
  801. @SuppressWarnings("rawtypes")
  802. @Override
  803. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  804. Object object = getObject().evaluate(template, context);
  805. if (object == null) {
  806. return null;
  807. }
  808. // special case for array.length
  809. if (object.getClass().isArray() && "length".equals(getName().getText())) {
  810. return Array.getLength(object);
  811. }
  812. // special case for map, allows to do map.key instead of map[key]
  813. if (object instanceof Map) {
  814. Map map = (Map)object;
  815. return map.get(getName().getText());
  816. }
  817. Object field = getCachedMember();
  818. if (field != null) {
  819. try {
  820. return AbstractReflection.getInstance().getFieldValue(object, field);
  821. } catch (Throwable t) {
  822. // fall through
  823. }
  824. }
  825. String text = getName().getText();
  826. field = AbstractReflection.getInstance().getField(object, text);
  827. if (field == null) {
  828. String methodName = null;
  829. if(text.length() > 1){
  830. methodName = text.substring(0,1).toUpperCase() + text.substring(1);
  831. }else{
  832. methodName = text.toUpperCase();
  833. }
  834. MemberAccess access = new MemberAccess(this.object, new Span("get" + methodName));
  835. MethodCall methodCall = new MethodCall(getName(),access, Collections.emptyList());
  836. try {
  837. return methodCall.evaluate(template, context);
  838. } catch (TemplateException e) {
  839. if(ExceptionUtils.indexOfThrowable(e, InvocationTargetException.class) > -1){
  840. ExpressionError.error(String.format("在%s中调用方法get%s发生异常"
  841. ,object.getClass()
  842. ,methodName), getSpan(),e);
  843. return null;
  844. }
  845. access = new MemberAccess(this.object, new Span("is" + methodName));
  846. methodCall = new MethodCall(getName(),access, Collections.emptyList());
  847. try {
  848. return methodCall.evaluate(template, context);
  849. } catch (TemplateException e1) {
  850. if(ExceptionUtils.indexOfThrowable(e1, InvocationTargetException.class) > -1){
  851. ExpressionError.error(String.format("在%s中调用方法is%s发生异常"
  852. ,object.getClass()
  853. ,methodName), getSpan(),e);
  854. return null;
  855. }
  856. ExpressionError.error(String.format("在%s中找不到属性%s或者方法get%s、方法is%s"
  857. ,object.getClass()
  858. ,getName().getText()
  859. ,methodName
  860. ,methodName), getSpan());
  861. }
  862. }
  863. }
  864. setCachedMember(field);
  865. return AbstractReflection.getInstance().getFieldValue(object, field);
  866. }
  867. }
  868. public static class LambdaAccess extends Expression {
  869. private final List<Expression> elements = new ArrayList<>();
  870. private final Expression function;
  871. private MemberAccess arrayLike;
  872. public LambdaAccess (Span span, Expression function, List<Expression> elements) {
  873. super(span);
  874. this.elements.addAll(elements);
  875. this.function = function;
  876. }
  877. public LambdaAccess (Span span, Expression function, Expression... elements) {
  878. super(span);
  879. this.elements.addAll(Arrays.asList(elements));
  880. this.function = function;
  881. }
  882. public List<Expression> getElements() {
  883. return elements;
  884. }
  885. /** Returns an expression that is used as the key or index to fetch a map or array element. **/
  886. public Expression getFunction() {
  887. return function;
  888. }
  889. @SuppressWarnings("rawtypes")
  890. @Override
  891. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  892. if (ArrayLikeLambdaExecutor.SUPPORT_METHOD.contains(arrayLike.getName().getText())) {
  893. return oneArgumentParser(template, context);
  894. } else {
  895. ExpressionError.error("只支持 "+ String.join(",", ArrayLikeLambdaExecutor.SUPPORT_METHOD) +"。不支持的lambda函数: " + arrayLike.getName().getText(), arrayLike.getSpan());
  896. }
  897. return null;
  898. }
  899. private <T,R> Object oneArgumentParser(ExpressionTemplate template, ExpressionTemplateContext context) {
  900. Expression object = arrayLike.getObject();
  901. if (object instanceof VariableAccess) {
  902. VariableAccess arrLike = (VariableAccess) object;
  903. String parName = arrLike.getVariableName().getText();
  904. Object arrLikeObj = context.get(parName);
  905. if (arrLikeObj.getClass().isArray()) {
  906. try {
  907. // Integer size = (Integer) arrLikeObj.getClass().getDeclaredField("length").get(arrLikeObj);
  908. int size = Array.getLength(arrLikeObj);
  909. List<Object> list = new ArrayList<>(size);
  910. for (int i = 0; i < size; i++) {
  911. list.add(Array.get(arrLikeObj, i));
  912. }
  913. arrLikeObj = list;
  914. } catch (Exception e) {
  915. e.printStackTrace();
  916. }
  917. } else if (arrLikeObj instanceof Iterator) {
  918. Iterator<?> it = (Iterator<?>) arrLikeObj;
  919. List<Object> list = new ArrayList<>();
  920. it.forEachRemaining(list::add);
  921. arrLikeObj = list;
  922. } else if (arrLikeObj instanceof Enumeration) {
  923. Enumeration<?> en = (Enumeration<?>) arrLikeObj;
  924. arrLikeObj = Collections.list(en);
  925. }
  926. if (arrLikeObj instanceof Collection) {
  927. Collection<?> coll = (Collection<?>) arrLikeObj;
  928. AtomicInteger ai = new AtomicInteger();
  929. return new ArrayLikeLambdaExecutor.MultipleArgumentsLambda(elements, lambdaArgumentsValues -> {
  930. try {
  931. context.push();
  932. for (int i = 0; i < elements.size() && i < lambdaArgumentsValues.length; i++) {
  933. Expression expression = elements.get(i);
  934. context.setOnCurrentScope(expression.getSpan().getText(), lambdaArgumentsValues[i]);
  935. }
  936. return function.evaluate(template, context);
  937. } catch (IOException e) {
  938. e.printStackTrace();
  939. throw new RuntimeException(e);
  940. } finally {
  941. context.pop();
  942. }
  943. });
  944. }
  945. }
  946. return null;
  947. }
  948. public void setArrayLike(MemberAccess arrayLike) {
  949. this.arrayLike = arrayLike;
  950. }
  951. public MemberAccess getArrayLike() {
  952. return arrayLike;
  953. }
  954. }
  955. /** Represents a call to a top-level function. A function may either be a {@link FunctionalInterface} stored in a
  956. * {@link ExpressionTemplateContext}, or a {@link Macro} defined in a template. */
  957. public static class FunctionCall extends Expression {
  958. private final Expression function;
  959. private final List<Expression> arguments;
  960. private Object cachedFunction;
  961. private final ThreadLocal<Object[]> cachedArguments;
  962. public FunctionCall (Span span, Expression function, List<Expression> arguments) {
  963. super(span);
  964. this.function = function;
  965. this.arguments = arguments;
  966. this.cachedArguments = new ThreadLocal<Object[]>();
  967. }
  968. /** Return the expression that must evaluate to a {@link FunctionalInterface} or a {@link Macro}. **/
  969. public Expression getFunction () {
  970. return function;
  971. }
  972. /** Returns the list of expressions to be passed to the function as arguments. **/
  973. public List<Expression> getArguments () {
  974. return arguments;
  975. }
  976. /** Returns the cached "function" descriptor as returned by {@link AbstractReflection#getMethod(Object, String, Object...)} or the
  977. * {@link Macro}. See {@link #setCachedFunction(Object)}. **/
  978. public Object getCachedFunction () {
  979. return cachedFunction;
  980. }
  981. /** Sets the "function" descriptor as returned by {@link AbstractReflection#getMethod(Object, String, Object...)} for faster
  982. * lookups, or the {@link Macro} to be called. Called by {@link AstInterpreter} the first time this node is evaluated.
  983. * Subsequent evaluations can use the cached descriptor, avoiding a costly reflective lookup. **/
  984. public void setCachedFunction (Object cachedFunction) {
  985. this.cachedFunction = cachedFunction;
  986. }
  987. /** Returns a scratch buffer to store arguments in when calling the function in {@link AstInterpreter}. Avoids generating
  988. * garbage. **/
  989. public Object[] getCachedArguments () {
  990. Object[] args = cachedArguments.get();
  991. if (args == null) {
  992. args = new Object[arguments.size()];
  993. cachedArguments.set(args);
  994. }
  995. return args;
  996. }
  997. /** Must be invoked when this node is done evaluating so we don't leak memory **/
  998. public void clearCachedArguments () {
  999. Object[] args = getCachedArguments();
  1000. for (int i = 0; i < args.length; i++) {
  1001. args[i] = null;
  1002. }
  1003. }
  1004. @Override
  1005. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  1006. try {
  1007. Object[] argumentValues = getCachedArguments();
  1008. List<Expression> arguments = getArguments();
  1009. for (int i = 0, n = argumentValues.length; i < n; i++) {
  1010. Expression expr = arguments.get(i);
  1011. argumentValues[i] = expr.evaluate(template, context);
  1012. }
  1013. // This is a special case to handle template level macros. If a call to a macro is
  1014. // made, evaluating the function expression will result in an exception, as the
  1015. // function name can't be found in the context. Instead we need to manually check
  1016. // if the function expression is a VariableAccess and if so, if it can be found
  1017. // in the context.
  1018. Object function = null;
  1019. if (getFunction() instanceof VariableAccess) {
  1020. VariableAccess varAccess = (VariableAccess)getFunction();
  1021. function = context.get(varAccess.getVariableName().getText());
  1022. } else {
  1023. function = getFunction().evaluate(template, context);
  1024. }
  1025. if (function != null) {
  1026. Object method = getCachedFunction();
  1027. if (method != null) {
  1028. try {
  1029. return AbstractReflection.getInstance().callMethod(function, method, argumentValues);
  1030. } catch (Throwable t) {
  1031. // fall through
  1032. }
  1033. }
  1034. method = AbstractReflection.getInstance().getMethod(function, null, argumentValues);
  1035. if (method == null) {
  1036. ExpressionError.error("Couldn't find function.", getSpan());
  1037. }
  1038. setCachedFunction(method);
  1039. try {
  1040. return AbstractReflection.getInstance().callMethod(function, method, argumentValues);
  1041. } catch (Throwable t) {
  1042. ExpressionError.error(t.getMessage(), getSpan(), t);
  1043. return null; // never reached
  1044. }
  1045. } else {
  1046. ExpressionError.error("Couldn't find function " + getFunction(), getSpan());
  1047. return null; // never reached
  1048. }
  1049. } finally {
  1050. clearCachedArguments();
  1051. }
  1052. }
  1053. }
  1054. /** Represents a call to a method of the form <code>object.method(a, b, c)</code>. **/
  1055. public static class MethodCall extends Expression {
  1056. private final MemberAccess method;
  1057. private final List<Expression> arguments;
  1058. private Object cachedMethod;
  1059. private final ThreadLocal<Object[]> cachedArguments;
  1060. private boolean cachedMethodStatic;
  1061. public MethodCall (Span span, MemberAccess method, List<Expression> arguments) {
  1062. super(span);
  1063. this.method = method;
  1064. this.arguments = arguments;
  1065. this.cachedArguments = new ThreadLocal<Object[]>();
  1066. }
  1067. /** Returns the object on which to call the method. **/
  1068. public Expression getObject () {
  1069. return method.getObject();
  1070. }
  1071. /** Returns the method to call. **/
  1072. public MemberAccess getMethod () {
  1073. return method;
  1074. }
  1075. /** Returns the list of expressions to be passed to the function as arguments. **/
  1076. public List<Expression> getArguments () {
  1077. return arguments;
  1078. }
  1079. /** Returns the cached member descriptor as returned by {@link AbstractReflection#getMethod(Object, String, Object...)}. See
  1080. * {@link #setCachedMember(Object)}. **/
  1081. public Object getCachedMethod () {
  1082. return cachedMethod;
  1083. }
  1084. /** Sets the method descriptor as returned by {@link AbstractReflection#getMethod(Object, String, Object...)} for faster lookups.
  1085. * Called by {@link AstInterpreter} the first time this node is evaluated. Subsequent evaluations can use the cached
  1086. * descriptor, avoiding a costly reflective lookup. **/
  1087. public void setCachedMethod (Object cachedMethod) {
  1088. this.cachedMethod = cachedMethod;
  1089. }
  1090. /** Returns a scratch buffer to store arguments in when calling the function in {@link AstInterpreter}. Avoids generating
  1091. * garbage. **/
  1092. public Object[] getCachedArguments () {
  1093. Object[] args = cachedArguments.get();
  1094. if (args == null) {
  1095. args = new Object[arguments.size()];
  1096. cachedArguments.set(args);
  1097. }
  1098. return args;
  1099. }
  1100. /** Must be invoked when this node is done evaluating so we don't leak memory **/
  1101. public void clearCachedArguments () {
  1102. Object[] args = getCachedArguments();
  1103. for (int i = 0; i < args.length; i++) {
  1104. args[i] = null;
  1105. }
  1106. }
  1107. @Override
  1108. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  1109. try {
  1110. Object object = getObject().evaluate(template, context);
  1111. if (object == null) {
  1112. return null;
  1113. }
  1114. Object[] argumentValues = getCachedArguments();
  1115. List<Expression> arguments = getArguments();
  1116. for (int i = 0, n = argumentValues.length; i < n; i++) {
  1117. Expression expr = arguments.get(i);
  1118. argumentValues[i] = expr.evaluate(template, context);
  1119. }
  1120. // Otherwise try to find a corresponding method or field pointing to a lambda.
  1121. Object method = getCachedMethod();
  1122. if (method != null) {
  1123. try {
  1124. if (isCachedMethodStatic()) {
  1125. return AbstractReflection.getInstance().callMethod(null, method, object, argumentValues);
  1126. }
  1127. return AbstractReflection.getInstance().callMethod(object, method, argumentValues);
  1128. } catch (Throwable t) {
  1129. t.printStackTrace();
  1130. // fall through
  1131. }
  1132. }
  1133. method = AbstractReflection.getInstance().getMethod(object, getMethod().getName().getText(), argumentValues);
  1134. if (method != null) {
  1135. // found the method on the object, call it
  1136. setCachedMethod(method);
  1137. try {
  1138. return AbstractReflection.getInstance().callMethod(object, method, argumentValues);
  1139. } catch (Throwable t) {
  1140. ExpressionError.error(t.getMessage(), getSpan(), t);
  1141. return null; // never reached
  1142. }
  1143. }
  1144. method = AbstractReflection.getInstance().getExtensionMethod(object, getMethod().getName().getText(), argumentValues);
  1145. if(method != null){
  1146. try {
  1147. int argumentLength = argumentValues == null ? 0 : argumentValues.length;
  1148. Object[] parameters = new Object[argumentLength + 1];
  1149. if(argumentLength > 0){
  1150. for (int i = 0; i < argumentLength; i++) {
  1151. parameters[i + 1] = argumentValues[i];
  1152. }
  1153. }
  1154. parameters[0] = object;
  1155. if(object.getClass().isArray()){
  1156. Object[] objs = new Object[Array.getLength(object)];
  1157. for (int i = 0,len = objs.length; i < len; i++) {
  1158. Array.set(objs, i, Array.get(object, i));
  1159. }
  1160. parameters[0] = objs;
  1161. }
  1162. return AbstractReflection.getInstance().callMethod(object, method, parameters);
  1163. } catch (Throwable t) {
  1164. ExpressionError.error(t.getMessage(), getSpan(), t);
  1165. // fall through
  1166. return null;
  1167. }
  1168. }else {
  1169. // didn't find the method on the object, try to find a field pointing to a lambda
  1170. Object field = AbstractReflection.getInstance().getField(object, getMethod().getName().getText());
  1171. if (field == null){
  1172. ExpressionError.error("在'" + object.getClass() + "'中找不到方法 " + getMethod().getName().getText() + "(" + StringUtils.join(JavaReflection.getStringTypes(argumentValues),",") + ")",
  1173. getSpan());
  1174. }
  1175. Object function = AbstractReflection.getInstance().getFieldValue(object, field);
  1176. method = AbstractReflection.getInstance().getMethod(function, null, argumentValues);
  1177. if (method == null){
  1178. ExpressionError.error("在'" + object.getClass() + "'中找不到方法 " + getMethod().getName().getText() + "("+ StringUtils.join(JavaReflection.getStringTypes(argumentValues),",") +")",
  1179. getSpan());
  1180. }
  1181. try {
  1182. return AbstractReflection.getInstance().callMethod(function, method, argumentValues);
  1183. } catch (Throwable t) {
  1184. ExpressionError.error(t.getMessage(), getSpan(), t);
  1185. return null; // never reached
  1186. }
  1187. }
  1188. } finally {
  1189. clearCachedArguments();
  1190. }
  1191. }
  1192. public void setCachedMethodStatic(boolean cachedMethodStatic) {
  1193. this.cachedMethodStatic = cachedMethodStatic;
  1194. }
  1195. public boolean isCachedMethodStatic() {
  1196. return cachedMethodStatic;
  1197. }
  1198. }
  1199. /** Represents a map literal of the form <code>{ key: value, key2: value, ... }</code> which can be nested. */
  1200. public static class MapLiteral extends Expression {
  1201. private final List<Token> keys;
  1202. private final List<Expression> values;
  1203. public MapLiteral (Span span, List<Token> keys, List<Expression> values) {
  1204. super(span);
  1205. this.keys = keys;
  1206. this.values = values;
  1207. }
  1208. public List<Token> getKeys () {
  1209. return keys;
  1210. }
  1211. public List<Expression> getValues () {
  1212. return values;
  1213. }
  1214. @Override
  1215. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  1216. Map<String, Object> map = new HashMap<>();
  1217. for (int i = 0, n = keys.size(); i < n; i++) {
  1218. Object value = values.get(i).evaluate(template, context);
  1219. Token tokenKey = keys.get(i);
  1220. String key = tokenKey.getSpan().getText();
  1221. if(tokenKey.getType() == TokenType.StringLiteral){
  1222. key = (String) new StringLiteral(tokenKey.getSpan()).evaluate(template, context);
  1223. }else if(key != null && key.startsWith("$")){
  1224. Object objKey = context.get(key.substring(1));
  1225. if(objKey != null){
  1226. key = objKey.toString();
  1227. }else{
  1228. key = null;
  1229. }
  1230. }
  1231. map.put(key, value);
  1232. }
  1233. return map;
  1234. }
  1235. }
  1236. /** Represents a list literal of the form <code>[ value, value2, value3, ...]</code> which can be nested. */
  1237. public static class ListLiteral extends Expression {
  1238. public final List<Expression> values;
  1239. public ListLiteral (Span span, List<Expression> values) {
  1240. super(span);
  1241. this.values = values;
  1242. }
  1243. public List<Expression> getValues () {
  1244. return values;
  1245. }
  1246. @Override
  1247. public Object evaluate (ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
  1248. List<Object> list = new ArrayList<>();
  1249. for (int i = 0, n = values.size(); i < n; i++) {
  1250. list.add(values.get(i).evaluate(template, context));
  1251. }
  1252. return list;
  1253. }
  1254. }
  1255. }