painless-operators-reference.asciidoc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. [[painless-operators-reference]]
  2. === Operators: Reference
  3. [[method-call-operator]]
  4. ==== Method Call
  5. Use the `method call operator '()'` to call a member method on a
  6. <<reference-types, reference type>> value. Implicit
  7. <<boxing-unboxing, boxing/unboxing>> is evaluated as necessary per argument
  8. during the method call. When a method call is made on a target `def` type value,
  9. the parameters and return type value are considered to also be of the `def` type
  10. and are evaluated at run-time.
  11. An overloaded method is one that shares the same name with two or more methods.
  12. A method is overloaded based on arity where the same name is re-used for
  13. multiple methods as long as the number of parameters differs.
  14. *Errors*
  15. * If the reference type value is `null`.
  16. * If the member method name doesn't exist for a given reference type value.
  17. * If the number of arguments passed in is different from the number of specified
  18. parameters.
  19. * If the arguments cannot be implicitly cast or implicitly boxed/unboxed to the
  20. correct type values for the parameters.
  21. *Grammar*
  22. [source,ANTLR4]
  23. ----
  24. method_call: '.' ID arguments;
  25. arguments: '(' (expression (',' expression)*)? ')';
  26. ----
  27. *Examples*
  28. * Method calls on different reference types.
  29. +
  30. [source,Painless]
  31. ----
  32. <1> Map m = new HashMap();
  33. <2> m.put(1, 2);
  34. <3> int z = m.get(1);
  35. <4> def d = new ArrayList();
  36. <5> d.add(1);
  37. <6> int i = Integer.parseInt(d.get(0).toString());
  38. ----
  39. +
  40. <1> declare `Map m`;
  41. allocate `HashMap` instance -> `HashMap reference`;
  42. store `HashMap reference` to `m`
  43. <2> load from `m` -> `Map reference`;
  44. implicit cast `int 1` to `def` -> `def`;
  45. implicit cast `int 2` to `def` -> `def`;
  46. call `put` on `Map reference` with arguments (`int 1`, `int 2`)
  47. <3> declare `int z`;
  48. load from `m` -> `Map reference`;
  49. call `get` on `Map reference` with arguments (`int 1`) -> `def`;
  50. implicit cast `def` to `int 2` -> `int 2`;
  51. store `int 2` to `z`
  52. <4> declare `def d`;
  53. allocate `ArrayList` instance -> `ArrayList reference`;
  54. implicit cast `ArrayList` to `def` -> `def`;
  55. store `def` to `d`
  56. <5> load from `d` -> `def`;
  57. implicit cast `def` to `ArrayList reference` -> `ArrayList reference`
  58. call `add` on `ArrayList reference` with arguments (`int 1`);
  59. <6> declare `int i`;
  60. load from `d` -> `def`;
  61. implicit cast `def` to `ArrayList reference` -> `ArrayList reference`
  62. call `get` on `ArrayList reference` with arguments (`int 1`) -> `def`;
  63. implicit cast `def` to `Integer 1 reference` -> `Integer 1 reference`;
  64. call `toString` on `Integer 1 reference` -> `String '1'`;
  65. call `parseInt` on `Integer` with arguments (`String '1'`) -> `int 1`;
  66. store `int 1` in `i`;
  67. [[field-access-operator]]
  68. ==== Field Access
  69. Use the `field access operator '.'` to store a value to or load a value from a
  70. <<reference-types, reference type>> member field.
  71. *Errors*
  72. * If the reference type value is `null`.
  73. * If the member field name doesn't exist for a given reference type value.
  74. *Grammar*
  75. [source,ANTLR4]
  76. ----
  77. field_access: '.' ID;
  78. ----
  79. *Examples*
  80. The examples use the following reference type definition:
  81. [source,Painless]
  82. ----
  83. name:
  84. Example
  85. non-static member fields:
  86. * int x
  87. * def y
  88. * List z
  89. ----
  90. * Field access with the `Example` type.
  91. +
  92. [source,Painless]
  93. ----
  94. <1> Example example = new Example();
  95. <2> example.x = 1;
  96. <3> example.y = example.x;
  97. <4> example.z = new ArrayList();
  98. <5> example.z.add(1);
  99. <6> example.x = example.z.get(0);
  100. ----
  101. +
  102. <1> declare `Example example`;
  103. allocate `Example` instance -> `Example reference`;
  104. store `Example reference` to `example`
  105. <2> load from `example` -> `Example reference`;
  106. store `int 1` to `x` of `Example reference`
  107. <3> load from `example` -> `Example reference @0`;
  108. load from `example` -> `Example reference @1`;
  109. load from `x` of `Example reference @1` -> `int 1`;
  110. implicit cast `int 1` to `def` -> `def`;
  111. store `def` to `y` of `Example reference @0`;
  112. (note `Example reference @0` and `Example reference @1` are the same)
  113. <4> load from `example` -> `Example reference`;
  114. allocate `ArrayList` instance -> `ArrayList reference`;
  115. implicit cast `ArrayList reference` to `List reference` -> `List reference`;
  116. store `List reference` to `z` of `Example reference`
  117. <5> load from `example` -> `Example reference`;
  118. load from `z` of `Example reference` -> `List reference`;
  119. call `add` on `List reference` with arguments (`int 1`)
  120. <6> load from `example` -> `Example reference @0`;
  121. load from `example` -> `Example reference @1`;
  122. load from `z` of `Example reference @1` -> `List reference`;
  123. call `get` on `List reference` with arguments (`int 0`) -> `int 1`;
  124. store `int 1` in `x` of `List reference @0`;
  125. (note `Example reference @0` and `Example reference @1` are the same)
  126. [[null-safe-operator]]
  127. ==== Null Safe
  128. Use the `null safe operator '?.'` instead of the method call operator or field
  129. access operator to ensure a reference type value is `non-null` before
  130. a method call or field access. A `null` value will be returned if the reference
  131. type value is `null`, otherwise the method call or field access is evaluated.
  132. *Errors*
  133. * If the method call return type value or the field access type value is not
  134. a reference type value and is not implicitly castable to a reference type
  135. value.
  136. *Grammar*
  137. [source,ANTLR4]
  138. ----
  139. null_safe: null_safe_method_call
  140. | null_safe_field_access
  141. ;
  142. null_safe_method_call: '?.' ID arguments;
  143. arguments: '(' (expression (',' expression)*)? ')';
  144. null_safe_field_access: '?.' ID;
  145. ----
  146. *Examples*
  147. The examples use the following reference type definition:
  148. [source,Painless]
  149. ----
  150. name:
  151. Example
  152. non-static member methods:
  153. * List factory()
  154. non-static member fields:
  155. * List x
  156. ----
  157. * Null safe without a `null` value.
  158. +
  159. [source,Painless]
  160. ----
  161. <1> Example example = new Example();
  162. <2> List x = example?.factory();
  163. ----
  164. +
  165. <1> declare `Example example`;
  166. allocate `Example` instance -> `Example reference`;
  167. store `Example reference` to `example`
  168. <2> declare `List x`;
  169. load from `example` -> `Example reference`;
  170. null safe call `factory` on `Example reference` -> `List reference`;
  171. store `List reference` to `x`;
  172. +
  173. * Null safe with a `null` value;
  174. +
  175. [source,Painless]
  176. ----
  177. <1> Example example = null;
  178. <2> List x = example?.x;
  179. ----
  180. <1> declare `Example example`;
  181. store `null` to `example`
  182. <2> declare `List x`;
  183. load from `example` -> `Example reference`;
  184. null safe access `x` on `Example reference` -> `null`;
  185. store `null` to `x`;
  186. (note the *null safe operator* returned `null` because `example` is `null`)
  187. [[list-initialization-operator]]
  188. ==== List Initialization
  189. Use the `list initialization operator '[]'` to allocate an `List` type instance
  190. to the heap with a set of pre-defined values. Each value used to initialize the
  191. `List` type instance is cast to a `def` type value upon insertion into the
  192. `List` type instance using the `add` method. The order of the specified values
  193. is maintained.
  194. *Grammar*
  195. [source,ANTLR4]
  196. ----
  197. list_initialization: '[' expression (',' expression)* ']'
  198. | '[' ']';
  199. ----
  200. *Examples*
  201. * List initialization of an empty `List` type value.
  202. +
  203. [source,Painless]
  204. ----
  205. <1> List empty = [];
  206. ----
  207. +
  208. <1> declare `List empty`;
  209. allocate `ArrayList` instance -> `ArrayList reference`;
  210. implicit cast `ArrayList reference` to `List reference` -> `List reference`;
  211. store `List reference` to `empty`
  212. +
  213. * List initialization with static values.
  214. +
  215. [source,Painless]
  216. ----
  217. <1> List list = [1, 2, 3];
  218. ----
  219. +
  220. <1> declare `List list`;
  221. allocate `ArrayList` instance -> `ArrayList reference`;
  222. call `add` on `ArrayList reference` with arguments(`int 1`);
  223. call `add` on `ArrayList reference` with arguments(`int 2`);
  224. call `add` on `ArrayList reference` with arguments(`int 3`);
  225. implicit cast `ArrayList reference` to `List reference` -> `List reference`;
  226. store `List reference` to `list`
  227. +
  228. * List initialization with non-static values.
  229. +
  230. [source,Painless]
  231. ----
  232. <1> int i = 1;
  233. <2> long l = 2L;
  234. <3> float f = 3.0F;
  235. <4> double d = 4.0;
  236. <5> String s = "5";
  237. <6> List list = [i, l, f*d, s];
  238. ----
  239. +
  240. <1> declare `int i`;
  241. store `int 1` to `i`
  242. <2> declare `long l`;
  243. store `long 2` to `l`
  244. <3> declare `float f`;
  245. store `float 3.0` to `f`
  246. <4> declare `double d`;
  247. store `double 4.0` to `d`
  248. <5> declare `String s`;
  249. store `String "5"` to `s`
  250. <6> declare `List list`;
  251. allocate `ArrayList` instance -> `ArrayList reference`;
  252. load from `i` -> `int 1`;
  253. call `add` on `ArrayList reference` with arguments(`int 1`);
  254. load from `l` -> `long 2`;
  255. call `add` on `ArrayList reference` with arguments(`long 2`);
  256. load from `f` -> `float 3.0`;
  257. load from `d` -> `double 4.0`;
  258. promote `float 3.0` and `double 4.0`: result `double`;
  259. implicit cast `float 3.0` to `double 3.0` -> `double 3.0`;
  260. multiply `double 3.0` and `double 4.0` -> `double 12.0`;
  261. call `add` on `ArrayList reference` with arguments(`double 12.0`);
  262. load from `s` -> `String "5"`;
  263. call `add` on `ArrayList reference` with arguments(`String "5"`);
  264. implicit cast `ArrayList reference` to `List reference` -> `List reference`;
  265. store `List reference` to `list`
  266. [[list-access-operator]]
  267. ==== List Access
  268. Use the `list access operator '[]'` as a shortcut for a `set` method call or
  269. `get` method call made on a `List` type value.
  270. *Errors*
  271. * If a value other than a `List` type value is accessed.
  272. * If a non-integer type value is used as an index for a `set` method call or
  273. `get` method call.
  274. *Grammar*
  275. [source,ANTLR4]
  276. ----
  277. list_access: '[' expression ']'
  278. ----
  279. *Examples*
  280. * List access with the `List` type.
  281. +
  282. [source,Painless]
  283. ----
  284. <1> List list = new ArrayList();
  285. <2> list.add(1);
  286. <3> list.add(2);
  287. <4> list.add(3);
  288. <5> list[0] = 2;
  289. <6> list[1] = 5;
  290. <7> int x = list[0] + list[1];
  291. <8> int y = 1;
  292. <9> int z = list[y];
  293. ----
  294. +
  295. <1> declare `List list`;
  296. allocate `ArrayList` instance -> `ArrayList reference`;
  297. implicit cast `ArrayList reference` to `List reference` -> `List reference`;
  298. store `List reference` to `list`
  299. <2> load from `list` -> `List reference`;
  300. call `add` on `List reference` with arguments(`int 1`)
  301. <3> load from `list` -> `List reference`;
  302. call `add` on `List reference` with arguments(`int 2`)
  303. <4> load from `list` -> `List reference`;
  304. call `add` on `List reference` with arguments(`int 3`)
  305. <5> load from `list` -> `List reference`;
  306. call `set` on `List reference` with arguments(`int 0`, `int 2`)
  307. <6> load from `list` -> `List reference`;
  308. call `set` on `List reference` with arguments(`int 1`, `int 5`)
  309. <7> declare `int x`;
  310. load from `list` -> `List reference`;
  311. call `get` on `List reference` with arguments(`int 0`) -> `def`;
  312. implicit cast `def` to `int 2` -> `int 2`;
  313. load from `list` -> `List reference`;
  314. call `get` on `List reference` with arguments(`int 1`) -> `def`;
  315. implicit cast `def` to `int 5` -> `int 5`;
  316. add `int 2` and `int 5` -> `int 7`;
  317. store `int 7` to `x`
  318. <8> declare `int y`;
  319. store `int 1` int `y`
  320. <9> declare `int z`;
  321. load from `list` -> `List reference`;
  322. load from `y` -> `int 1`;
  323. call `get` on `List reference` with arguments(`int 1`) -> `def`;
  324. implicit cast `def` to `int 5` -> `int 5`;
  325. store `int 5` to `z`
  326. +
  327. * List access with the `def` type.
  328. +
  329. [source,Painless]
  330. ----
  331. <1> def d = new ArrayList();
  332. <2> d.add(1);
  333. <3> d.add(2);
  334. <4> d.add(3);
  335. <5> d[0] = 2;
  336. <6> d[1] = 5;
  337. <7> def x = d[0] + d[1];
  338. <8> def y = 1;
  339. <9> def z = d[y];
  340. ----
  341. +
  342. <1> declare `List d`;
  343. allocate `ArrayList` instance -> `ArrayList reference`;
  344. implicit cast `ArrayList reference` to `def` -> `def`;
  345. store `def` to `d`
  346. <2> load from `d` -> `def`;
  347. implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
  348. call `add` on `ArrayList reference` with arguments(`int 1`)
  349. <3> load from `d` -> `def`;
  350. implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
  351. call `add` on `ArrayList reference` with arguments(`int 2`)
  352. <4> load from `d` -> `def`;
  353. implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
  354. call `add` on `ArrayList reference` with arguments(`int 3`)
  355. <5> load from `d` -> `def`;
  356. implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
  357. call `set` on `ArrayList reference` with arguments(`int 0`, `int 2`)
  358. <6> load from `d` -> `def`;
  359. implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
  360. call `set` on `ArrayList reference` with arguments(`int 1`, `int 5`)
  361. <7> declare `def x`;
  362. load from `d` -> `def`;
  363. implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
  364. call `get` on `ArrayList reference` with arguments(`int 0`) -> `def`;
  365. implicit cast `def` to `int 2` -> `int 2`;
  366. load from `d` -> `def`;
  367. implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
  368. call `get` on `ArrayList reference` with arguments(`int 1`) -> `def`;
  369. implicit cast `def` to `int 2` -> `int 2`;
  370. add `int 2` and `int 5` -> `int 7`;
  371. store `int 7` to `x`
  372. <8> declare `int y`;
  373. store `int 1` int `y`
  374. <9> declare `int z`;
  375. load from `d` -> `ArrayList reference`;
  376. load from `y` -> `def`;
  377. implicit cast `def` to `int 1` -> `int 1`;
  378. call `get` on `ArrayList reference` with arguments(`int 1`) -> `def`;
  379. store `def` to `z`
  380. [[map-initialization-operator]]
  381. ==== Map Initialization
  382. Use the `map initialization operator '[:]'` to allocate a `Map` type instance to
  383. the heap with a set of pre-defined values. Each pair of values used to
  384. initialize the `Map` type instance are cast to `def` type values upon insertion
  385. into the `Map` type instance using the `put` method.
  386. *Grammar*
  387. [source,ANTLR4]
  388. ----
  389. map_initialization: '[' key_pair (',' key_pair)* ']'
  390. | '[' ':' ']';
  391. key_pair: expression ':' expression
  392. ----
  393. *Examples*
  394. * Map initialization of an empty `Map` type value.
  395. +
  396. [source,Painless]
  397. ----
  398. <1> Map empty = [:];
  399. ----
  400. +
  401. <1> declare `Map empty`;
  402. allocate `HashMap` instance -> `HashMap reference`;
  403. implicit cast `HashMap reference` to `Map reference` -> `Map reference`;
  404. store `Map reference` to `empty`
  405. +
  406. * Map initialization with static values.
  407. +
  408. [source,Painless]
  409. ----
  410. <1> Map map = [1:2, 3:4, 5:6];
  411. ----
  412. +
  413. <1> declare `Map map`;
  414. allocate `HashMap` instance -> `HashMap reference`;
  415. call `put` on `HashMap reference` with arguments(`int 1`, `int 2`);
  416. call `put` on `HashMap reference` with arguments(`int 3`, `int 4`);
  417. call `put` on `HashMap reference` with arguments(`int 5`, `int 6`);
  418. implicit cast `HashMap reference` to `Map reference` -> `Map reference`;
  419. store `Map reference` to `map`
  420. +
  421. * Map initialization with non-static values.
  422. +
  423. [source,Painless]
  424. ----
  425. <1> byte b = 0;
  426. <2> int i = 1;
  427. <3> long l = 2L;
  428. <4> float f = 3.0F;
  429. <5> double d = 4.0;
  430. <6> String s = "5";
  431. <7> Map map = [b:i, l:f*d, d:s];
  432. ----
  433. +
  434. <1> declare `byte b`;
  435. store `byte 0` to `b`
  436. <2> declare `int i`;
  437. store `int 1` to `i`
  438. <3> declare `long l`;
  439. store `long 2` to `l`
  440. <4> declare `float f`;
  441. store `float 3.0` to `f`
  442. <5> declare `double d`;
  443. store `double 4.0` to `d`
  444. <6> declare `String s`;
  445. store `String "5"` to `s`
  446. <7> declare `Map map`;
  447. allocate `HashMap` instance -> `HashMap reference`;
  448. load from `b` -> `byte 0`;
  449. load from `i` -> `int 1`;
  450. call `put` on `HashMap reference` with arguments(`byte 0`, `int 1`);
  451. load from `l` -> `long 2`;
  452. load from `f` -> `float 3.0`;
  453. load from `d` -> `double 4.0`;
  454. promote `float 3.0` and `double 4.0`: result `double`;
  455. implicit cast `float 3.0` to `double 3.0` -> `double 3.0`;
  456. multiply `double 3.0` and `double 4.0` -> `double 12.0`;
  457. call `put` on `HashMap reference` with arguments(`long 2`, `double 12.0`);
  458. load from `d` -> `double 4.0`;
  459. load from `s` -> `String "5"`;
  460. call `put` on `HashMap reference` with
  461. arguments(`double 4.0`, `String "5"`);
  462. implicit cast `HashMap reference` to `Map reference` -> `Map reference`;
  463. store `Map reference` to `map`
  464. [[map-access-operator]]
  465. ==== Map Access
  466. Use the `map access operator '[]'` as a shortcut for a `put` method call or
  467. `get` method call made on a `Map` type value.
  468. *Errors*
  469. * If a value other than a `Map` type value is accessed.
  470. *Grammar*
  471. [source,ANTLR4]
  472. ----
  473. map_access: '[' expression ']'
  474. ----
  475. *Examples*
  476. * Map access with the `Map` type.
  477. +
  478. [source,Painless]
  479. ----
  480. <1> Map map = new HashMap();
  481. <2> map['value2'] = 2;
  482. <3> map['value5'] = 5;
  483. <4> int x = map['value2'] + map['value5'];
  484. <5> String y = 'value5';
  485. <6> int z = x[z];
  486. ----
  487. +
  488. <1> declare `Map map`;
  489. allocate `HashMap` instance -> `HashMap reference`;
  490. implicit cast `HashMap reference` to `Map reference` -> `Map reference`;
  491. store `Map reference` to `map`
  492. <2> load from `map` -> `Map reference`;
  493. call `put` on `Map reference` with arguments(`String 'value2'`, `int 2`)
  494. <3> load from `map` -> `Map reference`;
  495. call `put` on `Map reference` with arguments(`String 'value5'`, `int 5`)
  496. <4> declare `int x`;
  497. load from `map` -> `Map reference`;
  498. call `get` on `Map reference` with arguments(`String 'value2'`) -> `def`;
  499. implicit cast `def` to `int 2` -> `int 2`;
  500. load from `map` -> `Map reference`;
  501. call `get` on `Map reference` with arguments(`String 'value5'`) -> `def`;
  502. implicit cast `def` to `int 5` -> `int 5`;
  503. add `int 2` and `int 5` -> `int 7`;
  504. store `int 7` to `x`
  505. <5> declare `String y`;
  506. store `String 'value5'` to `y`
  507. <6> declare `int z`;
  508. load from `map` -> `Map reference`;
  509. load from `y` -> `String 'value5'`;
  510. call `get` on `Map reference` with arguments(`String 'value5'`) -> `def`;
  511. implicit cast `def` to `int 5` -> `int 5`;
  512. store `int 5` to `z`
  513. +
  514. * Map access with the `def` type.
  515. +
  516. [source,Painless]
  517. ----
  518. <1> def d = new HashMap();
  519. <2> d['value2'] = 2;
  520. <3> d['value5'] = 5;
  521. <4> int x = d['value2'] + d['value5'];
  522. <5> String y = 'value5';
  523. <6> def z = d[y];
  524. ----
  525. +
  526. <1> declare `def d`;
  527. allocate `HashMap` instance -> `HashMap reference`;
  528. implicit cast `HashMap reference` to `def` -> `def`;
  529. store `def` to `d`
  530. <2> load from `d` -> `def`;
  531. implicit cast `def` to `HashMap reference` -> `HashMap reference`;
  532. call `put` on `HashMap reference` with arguments(`String 'value2'`, `int 2`)
  533. <3> load from `d` -> `def`;
  534. implicit cast `def` to `HashMap reference` -> `HashMap reference`;
  535. call `put` on `HashMap reference` with arguments(`String 'value5'`, `int 5`)
  536. <4> declare `int x`;
  537. load from `d` -> `def`;
  538. implicit cast `def` to `HashMap reference` -> `HashMap reference`;
  539. call `get` on `HashMap reference` with arguments(`String 'value2'`)
  540. -> `def`;
  541. implicit cast `def` to `int 2` -> `int 2`;
  542. load from `d` -> `def`;
  543. call `get` on `HashMap reference` with arguments(`String 'value5'`)
  544. -> `def`;
  545. implicit cast `def` to `int 5` -> `int 5`;
  546. add `int 2` and `int 5` -> `int 7`;
  547. store `int 7` to `x`
  548. <5> declare `String y`;
  549. store `String 'value5'` to `y`
  550. <6> declare `def z`;
  551. load from `d` -> `def`;
  552. load from `y` -> `String 'value5'`;
  553. call `get` on `HashMap reference` with arguments(`String 'value5'`)
  554. -> `def`;
  555. store `def` to `z`
  556. [[new-instance-operator]]
  557. ==== New Instance
  558. Use the `new instance operator 'new ()'` to allocate a
  559. <<reference-types, reference type>> instance to the heap and call a specified
  560. constructor. Implicit <<boxing-unboxing, boxing/unboxing>> is evaluated as
  561. necessary per argument during the constructor call.
  562. An overloaded constructor is one that shares the same name with two or more
  563. constructors. A constructor is overloaded based on arity where the same
  564. reference type name is re-used for multiple constructors as long as the number
  565. of parameters differs.
  566. *Errors*
  567. * If the reference type name doesn't exist for instance allocation.
  568. * If the number of arguments passed in is different from the number of specified
  569. parameters.
  570. * If the arguments cannot be implicitly cast or implicitly boxed/unboxed to the
  571. correct type values for the parameters.
  572. *Grammar*
  573. [source,ANTLR4]
  574. ----
  575. new_instance: 'new' TYPE '(' (expression (',' expression)*)? ')';
  576. ----
  577. *Examples*
  578. * Allocation of new instances with different types.
  579. [source,Painless]
  580. ----
  581. <1> Map m = new HashMap();
  582. <2> def d = new ArrayList();
  583. <3> def e = new HashMap(m);
  584. ----
  585. <1> declare `Map m`;
  586. allocate `HashMap` instance -> `HashMap reference`;
  587. implicit cast `HashMap reference` to `Map reference` -> `Map reference`;
  588. store `Map reference` to `m`;
  589. <2> declare `def d`;
  590. allocate `ArrayList` instance -> `ArrayList reference`;
  591. implicit cast `ArrayList reference` to `def` -> `def`;
  592. store `def` to `d`;
  593. <3> declare `def e`;
  594. load from `m` -> `Map reference`;
  595. allocate `HashMap` instance with arguments (`Map reference`)
  596. -> `HashMap reference`;
  597. implicit cast `HashMap reference` to `def` -> `def`;
  598. store `def` to `e`;
  599. [[string-concatenation-operator]]
  600. ==== String Concatenation
  601. Use the `string concatenation operator '+'` to concatenate two values together
  602. where at least one of the values is a <<string-type, `String` type>>.
  603. *Grammar*
  604. [source,ANTLR4]
  605. ----
  606. concatenate: expression '+' expression;
  607. ----
  608. *Examples*
  609. * String concatenation with different primitive types.
  610. +
  611. [source,Painless]
  612. ----
  613. <1> String x = "con";
  614. <2> String y = x + "cat";
  615. <3> String z = 4 + 5 + x;
  616. ----
  617. +
  618. <1> declare `String x`;
  619. store `String "con"` to `x`;
  620. <2> declare `String y`;
  621. load from `x` -> `String "con"`;
  622. concat `String "con"` and `String "cat"` -> `String "concat"`;
  623. store `String "concat"` to `y`
  624. <3> declare `String z`;
  625. add `int 4` and `int 5` -> `int 9`;
  626. concat `int 9` and `String "9concat"`;
  627. store `String "9concat"` to `z`;
  628. (note the addition is done prior to the concatenation due to precedence and
  629. associativity of the specific operations)
  630. +
  631. * String concatenation with the `def` type.
  632. +
  633. [source,Painless]
  634. ----
  635. <1> def d = 2;
  636. <2> d = "con" + d + "cat";
  637. ----
  638. +
  639. <1> declare `def`;
  640. implicit cast `int 2` to `def` -> `def`;
  641. store `def` in `d`;
  642. <2> concat `String "con"` and `int 9` -> `String "con9"`;
  643. concat `String "con9"` and `String "con"` -> `String "con9cat"`
  644. implicit cast `String "con9cat"` to `def` -> `def`;
  645. store `def` to `d`;
  646. (note the switch in type of `d` from `int` to `String`)
  647. [[elvis-operator]]
  648. ==== Elvis
  649. An elvis consists of two expressions. The first expression is evaluated
  650. with to check for a `null` value. If the first expression evaluates to
  651. `null` then the second expression is evaluated and its value used. If the first
  652. expression evaluates to `non-null` then the resultant value of the first
  653. expression is used. Use the `elvis operator '?:'` as a shortcut for the
  654. conditional operator.
  655. *Errors*
  656. * If the first expression or second expression cannot produce a `null` value.
  657. *Grammar*
  658. [source,ANTLR4]
  659. ----
  660. elvis: expression '?:' expression;
  661. ----
  662. *Examples*
  663. * Elvis with different reference types.
  664. +
  665. [source,Painless]
  666. ----
  667. <1> List x = new ArrayList();
  668. <2> List y = x ?: new ArrayList();
  669. <3> y = null;
  670. <4> List z = y ?: new ArrayList();
  671. ----
  672. +
  673. <1> declare `List x`;
  674. allocate `ArrayList` instance -> `ArrayList reference`;
  675. implicit cast `ArrayList reference` to `List reference` -> `List reference`;
  676. store `List reference` to `x`;
  677. <2> declare `List y`;
  678. load `x` -> `List reference`;
  679. `List reference` equals `null` -> `false`;
  680. evaluate 1st expression: `List reference` -> `List reference`;
  681. store `List reference` to `y`
  682. <3> store `null` to `y`;
  683. <4> declare `List z`;
  684. load `y` -> `List reference`;
  685. `List reference` equals `null` -> `true`;
  686. evaluate 2nd expression:
  687. allocate `ArrayList` instance -> `ArrayList reference`;
  688. implicit cast `ArrayList reference` to `List reference` -> `List reference`;
  689. store `List reference` to `z`;