mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-22 12:56:53 +00:00
Implement reading from null safe dereferences
Null safe dereferences make handling null or missing values shorter. Compare without: ``` if (ctx._source.missing != null && ctx._source.missing.foo != null) { ctx._source.foo_length = ctx.source.missing.foo.length() } ``` To with: ``` Integer length = ctx._source.missing?.foo?.length(); if (length != null) { ctx._source.foo_length = length } ``` Combining this with the as of yet unimplemented elvis operator allows for very concise defaults for nulls: ``` ctx._source.foo_length = ctx._source.missing?.foo?.length() ?: 0; ``` Since you have to start somewhere, we started with null safe dereferenes. Anyway, this is a feature borrowed from groovy. Groovy allows writing to null values like: ``` def v = null v?.field = 'cat' ``` And the writes are simply ignored. Painless doesn't support this at this point because it'd be complex to implement and maybe not all that useful. There is no runtime cost for this feature if it is not used. When it is used we implement it fairly efficiently, adding a jump rather than a temporary variable. This should also work fairly well with doc values.
This commit is contained in:
parent
b743ab0b07
commit
d03b8e4abb
@ -130,6 +130,37 @@ using these characters:
|
||||
|`x` | COMMENTS (aka extended) | `'a' ==~ /a #comment/x`
|
||||
|=======================================================================
|
||||
|
||||
[float]
|
||||
[[painless-deref]]
|
||||
=== Dereferences
|
||||
|
||||
Like lots of languages, Painless uses `.` to reference fields and call methods:
|
||||
|
||||
[source,painless]
|
||||
---------------------------------------------------------
|
||||
String foo = 'foo';
|
||||
TypeWithGetterOrPublicField bar = new TypeWithGetterOrPublicField()
|
||||
return foo.length() + bar.x
|
||||
---------------------------------------------------------
|
||||
|
||||
Like Groovy, Painless uses `?.` to perform null-safe references, with the
|
||||
result being `null` if the left hand side is null:
|
||||
|
||||
[source,painless]
|
||||
---------------------------------------------------------
|
||||
String foo = null;
|
||||
return foo?.length() // Returns null
|
||||
---------------------------------------------------------
|
||||
|
||||
Unlike Groovy, Painless doesn't support writing to null values with this
|
||||
operator:
|
||||
|
||||
[source,painless]
|
||||
---------------------------------------------------------
|
||||
TypeWithSetterOrPublicField foo = null;
|
||||
foo?.x = 'bar' // Compile error
|
||||
---------------------------------------------------------
|
||||
|
||||
[float]
|
||||
[[painless-operators]]
|
||||
=== Operators
|
||||
|
@ -156,11 +156,11 @@ postdot
|
||||
;
|
||||
|
||||
callinvoke
|
||||
: DOT DOTID arguments
|
||||
: COND? DOT DOTID arguments
|
||||
;
|
||||
|
||||
fieldaccess
|
||||
: DOT ( DOTID | DOTINTEGER )
|
||||
: COND? DOT ( DOTID | DOTINTEGER )
|
||||
;
|
||||
|
||||
braceaccess
|
||||
|
@ -30,6 +30,9 @@ import org.elasticsearch.painless.Definition.Type;
|
||||
public final class AnalyzerCaster {
|
||||
|
||||
public static Cast getLegalCast(Location location, Type actual, Type expected, boolean explicit, boolean internal) {
|
||||
if (actual == null || expected == null) {
|
||||
throw new IllegalStateException("Neither actual [" + actual + "] nor expected [" + expected + "] can be null");
|
||||
}
|
||||
if (actual.equals(expected)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -2558,6 +2558,7 @@ class PainlessParser extends Parser {
|
||||
public ArgumentsContext arguments() {
|
||||
return getRuleContext(ArgumentsContext.class,0);
|
||||
}
|
||||
public TerminalNode COND() { return getToken(PainlessParser.COND, 0); }
|
||||
public CallinvokeContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@ -2572,14 +2573,24 @@ class PainlessParser extends Parser {
|
||||
public final CallinvokeContext callinvoke() throws RecognitionException {
|
||||
CallinvokeContext _localctx = new CallinvokeContext(_ctx, getState());
|
||||
enterRule(_localctx, 40, RULE_callinvoke);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(354);
|
||||
match(DOT);
|
||||
setState(355);
|
||||
_la = _input.LA(1);
|
||||
if (_la==COND) {
|
||||
{
|
||||
setState(354);
|
||||
match(COND);
|
||||
}
|
||||
}
|
||||
|
||||
setState(357);
|
||||
match(DOT);
|
||||
setState(358);
|
||||
match(DOTID);
|
||||
setState(356);
|
||||
setState(359);
|
||||
arguments();
|
||||
}
|
||||
}
|
||||
@ -2598,6 +2609,7 @@ class PainlessParser extends Parser {
|
||||
public TerminalNode DOT() { return getToken(PainlessParser.DOT, 0); }
|
||||
public TerminalNode DOTID() { return getToken(PainlessParser.DOTID, 0); }
|
||||
public TerminalNode DOTINTEGER() { return getToken(PainlessParser.DOTINTEGER, 0); }
|
||||
public TerminalNode COND() { return getToken(PainlessParser.COND, 0); }
|
||||
public FieldaccessContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@ -2616,9 +2628,18 @@ class PainlessParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(358);
|
||||
setState(362);
|
||||
_la = _input.LA(1);
|
||||
if (_la==COND) {
|
||||
{
|
||||
setState(361);
|
||||
match(COND);
|
||||
}
|
||||
}
|
||||
|
||||
setState(364);
|
||||
match(DOT);
|
||||
setState(359);
|
||||
setState(365);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==DOTINTEGER || _la==DOTID) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
@ -2661,11 +2682,11 @@ class PainlessParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(361);
|
||||
setState(367);
|
||||
match(LBRACE);
|
||||
setState(362);
|
||||
setState(368);
|
||||
expression(0);
|
||||
setState(363);
|
||||
setState(369);
|
||||
match(RBRACE);
|
||||
}
|
||||
}
|
||||
@ -2762,17 +2783,17 @@ class PainlessParser extends Parser {
|
||||
int _la;
|
||||
try {
|
||||
int _alt;
|
||||
setState(409);
|
||||
switch ( getInterpreter().adaptivePredict(_input,34,_ctx) ) {
|
||||
setState(415);
|
||||
switch ( getInterpreter().adaptivePredict(_input,36,_ctx) ) {
|
||||
case 1:
|
||||
_localctx = new NewstandardarrayContext(_localctx);
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(365);
|
||||
setState(371);
|
||||
match(NEW);
|
||||
setState(366);
|
||||
setState(372);
|
||||
match(TYPE);
|
||||
setState(371);
|
||||
setState(377);
|
||||
_errHandler.sync(this);
|
||||
_alt = 1;
|
||||
do {
|
||||
@ -2780,11 +2801,11 @@ class PainlessParser extends Parser {
|
||||
case 1:
|
||||
{
|
||||
{
|
||||
setState(367);
|
||||
setState(373);
|
||||
match(LBRACE);
|
||||
setState(368);
|
||||
setState(374);
|
||||
expression(0);
|
||||
setState(369);
|
||||
setState(375);
|
||||
match(RBRACE);
|
||||
}
|
||||
}
|
||||
@ -2792,31 +2813,31 @@ class PainlessParser extends Parser {
|
||||
default:
|
||||
throw new NoViableAltException(this);
|
||||
}
|
||||
setState(373);
|
||||
setState(379);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,27,_ctx);
|
||||
_alt = getInterpreter().adaptivePredict(_input,29,_ctx);
|
||||
} while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER );
|
||||
setState(382);
|
||||
switch ( getInterpreter().adaptivePredict(_input,29,_ctx) ) {
|
||||
setState(388);
|
||||
switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) {
|
||||
case 1:
|
||||
{
|
||||
setState(375);
|
||||
setState(381);
|
||||
postdot();
|
||||
setState(379);
|
||||
setState(385);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,28,_ctx);
|
||||
_alt = getInterpreter().adaptivePredict(_input,30,_ctx);
|
||||
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
|
||||
if ( _alt==1 ) {
|
||||
{
|
||||
{
|
||||
setState(376);
|
||||
setState(382);
|
||||
postfix();
|
||||
}
|
||||
}
|
||||
}
|
||||
setState(381);
|
||||
setState(387);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,28,_ctx);
|
||||
_alt = getInterpreter().adaptivePredict(_input,30,_ctx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -2827,67 +2848,67 @@ class PainlessParser extends Parser {
|
||||
_localctx = new NewinitializedarrayContext(_localctx);
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(384);
|
||||
setState(390);
|
||||
match(NEW);
|
||||
setState(385);
|
||||
setState(391);
|
||||
match(TYPE);
|
||||
setState(386);
|
||||
setState(392);
|
||||
match(LBRACE);
|
||||
setState(387);
|
||||
setState(393);
|
||||
match(RBRACE);
|
||||
setState(388);
|
||||
setState(394);
|
||||
match(LBRACK);
|
||||
setState(397);
|
||||
setState(403);
|
||||
_la = _input.LA(1);
|
||||
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << NEW) | (1L << BOOLNOT) | (1L << BWNOT) | (1L << ADD) | (1L << SUB) | (1L << INCR) | (1L << DECR))) != 0) || ((((_la - 70)) & ~0x3f) == 0 && ((1L << (_la - 70)) & ((1L << (OCTAL - 70)) | (1L << (HEX - 70)) | (1L << (INTEGER - 70)) | (1L << (DECIMAL - 70)) | (1L << (STRING - 70)) | (1L << (REGEX - 70)) | (1L << (TRUE - 70)) | (1L << (FALSE - 70)) | (1L << (NULL - 70)) | (1L << (TYPE - 70)) | (1L << (ID - 70)))) != 0)) {
|
||||
{
|
||||
setState(389);
|
||||
setState(395);
|
||||
expression(0);
|
||||
setState(394);
|
||||
setState(400);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while (_la==COMMA) {
|
||||
{
|
||||
{
|
||||
setState(390);
|
||||
setState(396);
|
||||
match(COMMA);
|
||||
setState(391);
|
||||
setState(397);
|
||||
expression(0);
|
||||
}
|
||||
}
|
||||
setState(396);
|
||||
setState(402);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setState(400);
|
||||
setState(406);
|
||||
_la = _input.LA(1);
|
||||
if (_la==SEMICOLON) {
|
||||
{
|
||||
setState(399);
|
||||
setState(405);
|
||||
match(SEMICOLON);
|
||||
}
|
||||
}
|
||||
|
||||
setState(402);
|
||||
setState(408);
|
||||
match(RBRACK);
|
||||
setState(406);
|
||||
setState(412);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,33,_ctx);
|
||||
_alt = getInterpreter().adaptivePredict(_input,35,_ctx);
|
||||
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
|
||||
if ( _alt==1 ) {
|
||||
{
|
||||
{
|
||||
setState(403);
|
||||
setState(409);
|
||||
postfix();
|
||||
}
|
||||
}
|
||||
}
|
||||
setState(408);
|
||||
setState(414);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,33,_ctx);
|
||||
_alt = getInterpreter().adaptivePredict(_input,35,_ctx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -2933,41 +2954,41 @@ class PainlessParser extends Parser {
|
||||
enterRule(_localctx, 48, RULE_listinitializer);
|
||||
int _la;
|
||||
try {
|
||||
setState(424);
|
||||
switch ( getInterpreter().adaptivePredict(_input,36,_ctx) ) {
|
||||
setState(430);
|
||||
switch ( getInterpreter().adaptivePredict(_input,38,_ctx) ) {
|
||||
case 1:
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(411);
|
||||
match(LBRACE);
|
||||
setState(412);
|
||||
expression(0);
|
||||
setState(417);
|
||||
match(LBRACE);
|
||||
setState(418);
|
||||
expression(0);
|
||||
setState(423);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while (_la==COMMA) {
|
||||
{
|
||||
{
|
||||
setState(413);
|
||||
setState(419);
|
||||
match(COMMA);
|
||||
setState(414);
|
||||
setState(420);
|
||||
expression(0);
|
||||
}
|
||||
}
|
||||
setState(419);
|
||||
setState(425);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
setState(420);
|
||||
setState(426);
|
||||
match(RBRACE);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(422);
|
||||
setState(428);
|
||||
match(LBRACE);
|
||||
setState(423);
|
||||
setState(429);
|
||||
match(RBRACE);
|
||||
}
|
||||
break;
|
||||
@ -3014,43 +3035,43 @@ class PainlessParser extends Parser {
|
||||
enterRule(_localctx, 50, RULE_mapinitializer);
|
||||
int _la;
|
||||
try {
|
||||
setState(440);
|
||||
switch ( getInterpreter().adaptivePredict(_input,38,_ctx) ) {
|
||||
setState(446);
|
||||
switch ( getInterpreter().adaptivePredict(_input,40,_ctx) ) {
|
||||
case 1:
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(426);
|
||||
match(LBRACE);
|
||||
setState(427);
|
||||
maptoken();
|
||||
setState(432);
|
||||
match(LBRACE);
|
||||
setState(433);
|
||||
maptoken();
|
||||
setState(438);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while (_la==COMMA) {
|
||||
{
|
||||
{
|
||||
setState(428);
|
||||
setState(434);
|
||||
match(COMMA);
|
||||
setState(429);
|
||||
setState(435);
|
||||
maptoken();
|
||||
}
|
||||
}
|
||||
setState(434);
|
||||
setState(440);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
setState(435);
|
||||
setState(441);
|
||||
match(RBRACE);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(437);
|
||||
setState(443);
|
||||
match(LBRACE);
|
||||
setState(438);
|
||||
setState(444);
|
||||
match(COLON);
|
||||
setState(439);
|
||||
setState(445);
|
||||
match(RBRACE);
|
||||
}
|
||||
break;
|
||||
@ -3092,11 +3113,11 @@ class PainlessParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(442);
|
||||
setState(448);
|
||||
expression(0);
|
||||
setState(443);
|
||||
setState(449);
|
||||
match(COLON);
|
||||
setState(444);
|
||||
setState(450);
|
||||
expression(0);
|
||||
}
|
||||
}
|
||||
@ -3143,34 +3164,34 @@ class PainlessParser extends Parser {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
{
|
||||
setState(446);
|
||||
setState(452);
|
||||
match(LP);
|
||||
setState(455);
|
||||
setState(461);
|
||||
_la = _input.LA(1);
|
||||
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << NEW) | (1L << THIS) | (1L << BOOLNOT) | (1L << BWNOT) | (1L << ADD) | (1L << SUB) | (1L << INCR) | (1L << DECR))) != 0) || ((((_la - 70)) & ~0x3f) == 0 && ((1L << (_la - 70)) & ((1L << (OCTAL - 70)) | (1L << (HEX - 70)) | (1L << (INTEGER - 70)) | (1L << (DECIMAL - 70)) | (1L << (STRING - 70)) | (1L << (REGEX - 70)) | (1L << (TRUE - 70)) | (1L << (FALSE - 70)) | (1L << (NULL - 70)) | (1L << (TYPE - 70)) | (1L << (ID - 70)))) != 0)) {
|
||||
{
|
||||
setState(447);
|
||||
setState(453);
|
||||
argument();
|
||||
setState(452);
|
||||
setState(458);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while (_la==COMMA) {
|
||||
{
|
||||
{
|
||||
setState(448);
|
||||
setState(454);
|
||||
match(COMMA);
|
||||
setState(449);
|
||||
setState(455);
|
||||
argument();
|
||||
}
|
||||
}
|
||||
setState(454);
|
||||
setState(460);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setState(457);
|
||||
setState(463);
|
||||
match(RP);
|
||||
}
|
||||
}
|
||||
@ -3211,26 +3232,26 @@ class PainlessParser extends Parser {
|
||||
ArgumentContext _localctx = new ArgumentContext(_ctx, getState());
|
||||
enterRule(_localctx, 56, RULE_argument);
|
||||
try {
|
||||
setState(462);
|
||||
switch ( getInterpreter().adaptivePredict(_input,41,_ctx) ) {
|
||||
setState(468);
|
||||
switch ( getInterpreter().adaptivePredict(_input,43,_ctx) ) {
|
||||
case 1:
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(459);
|
||||
setState(465);
|
||||
expression(0);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(460);
|
||||
setState(466);
|
||||
lambda();
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
enterOuterAlt(_localctx, 3);
|
||||
{
|
||||
setState(461);
|
||||
setState(467);
|
||||
funcref();
|
||||
}
|
||||
break;
|
||||
@ -3285,58 +3306,58 @@ class PainlessParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(477);
|
||||
setState(483);
|
||||
switch (_input.LA(1)) {
|
||||
case TYPE:
|
||||
case ID:
|
||||
{
|
||||
setState(464);
|
||||
setState(470);
|
||||
lamtype();
|
||||
}
|
||||
break;
|
||||
case LP:
|
||||
{
|
||||
setState(465);
|
||||
setState(471);
|
||||
match(LP);
|
||||
setState(474);
|
||||
setState(480);
|
||||
_la = _input.LA(1);
|
||||
if (_la==TYPE || _la==ID) {
|
||||
{
|
||||
setState(466);
|
||||
setState(472);
|
||||
lamtype();
|
||||
setState(471);
|
||||
setState(477);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while (_la==COMMA) {
|
||||
{
|
||||
{
|
||||
setState(467);
|
||||
setState(473);
|
||||
match(COMMA);
|
||||
setState(468);
|
||||
setState(474);
|
||||
lamtype();
|
||||
}
|
||||
}
|
||||
setState(473);
|
||||
setState(479);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setState(476);
|
||||
setState(482);
|
||||
match(RP);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NoViableAltException(this);
|
||||
}
|
||||
setState(479);
|
||||
setState(485);
|
||||
match(ARROW);
|
||||
setState(482);
|
||||
setState(488);
|
||||
switch (_input.LA(1)) {
|
||||
case LBRACK:
|
||||
{
|
||||
setState(480);
|
||||
setState(486);
|
||||
block();
|
||||
}
|
||||
break;
|
||||
@ -3361,7 +3382,7 @@ class PainlessParser extends Parser {
|
||||
case TYPE:
|
||||
case ID:
|
||||
{
|
||||
setState(481);
|
||||
setState(487);
|
||||
expression(0);
|
||||
}
|
||||
break;
|
||||
@ -3404,16 +3425,16 @@ class PainlessParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(485);
|
||||
setState(491);
|
||||
_la = _input.LA(1);
|
||||
if (_la==TYPE) {
|
||||
{
|
||||
setState(484);
|
||||
setState(490);
|
||||
decltype();
|
||||
}
|
||||
}
|
||||
|
||||
setState(487);
|
||||
setState(493);
|
||||
match(ID);
|
||||
}
|
||||
}
|
||||
@ -3492,17 +3513,17 @@ class PainlessParser extends Parser {
|
||||
FuncrefContext _localctx = new FuncrefContext(_ctx, getState());
|
||||
enterRule(_localctx, 62, RULE_funcref);
|
||||
try {
|
||||
setState(502);
|
||||
switch ( getInterpreter().adaptivePredict(_input,47,_ctx) ) {
|
||||
setState(508);
|
||||
switch ( getInterpreter().adaptivePredict(_input,49,_ctx) ) {
|
||||
case 1:
|
||||
_localctx = new ClassfuncrefContext(_localctx);
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(489);
|
||||
setState(495);
|
||||
match(TYPE);
|
||||
setState(490);
|
||||
setState(496);
|
||||
match(REF);
|
||||
setState(491);
|
||||
setState(497);
|
||||
match(ID);
|
||||
}
|
||||
break;
|
||||
@ -3510,11 +3531,11 @@ class PainlessParser extends Parser {
|
||||
_localctx = new ConstructorfuncrefContext(_localctx);
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(492);
|
||||
setState(498);
|
||||
decltype();
|
||||
setState(493);
|
||||
setState(499);
|
||||
match(REF);
|
||||
setState(494);
|
||||
setState(500);
|
||||
match(NEW);
|
||||
}
|
||||
break;
|
||||
@ -3522,11 +3543,11 @@ class PainlessParser extends Parser {
|
||||
_localctx = new CapturingfuncrefContext(_localctx);
|
||||
enterOuterAlt(_localctx, 3);
|
||||
{
|
||||
setState(496);
|
||||
setState(502);
|
||||
match(ID);
|
||||
setState(497);
|
||||
setState(503);
|
||||
match(REF);
|
||||
setState(498);
|
||||
setState(504);
|
||||
match(ID);
|
||||
}
|
||||
break;
|
||||
@ -3534,11 +3555,11 @@ class PainlessParser extends Parser {
|
||||
_localctx = new LocalfuncrefContext(_localctx);
|
||||
enterOuterAlt(_localctx, 4);
|
||||
{
|
||||
setState(499);
|
||||
setState(505);
|
||||
match(THIS);
|
||||
setState(500);
|
||||
setState(506);
|
||||
match(REF);
|
||||
setState(501);
|
||||
setState(507);
|
||||
match(ID);
|
||||
}
|
||||
break;
|
||||
@ -3606,7 +3627,7 @@ class PainlessParser extends Parser {
|
||||
}
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3T\u01fb\4\2\t\2\4"+
|
||||
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3T\u0201\4\2\t\2\4"+
|
||||
"\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+
|
||||
"\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
|
||||
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
|
||||
@ -3632,173 +3653,176 @@ class PainlessParser extends Parser {
|
||||
"\3\22\7\22\u0140\n\22\f\22\16\22\u0143\13\22\3\22\5\22\u0146\n\22\3\23"+
|
||||
"\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23"+
|
||||
"\3\23\3\23\3\23\5\23\u015a\n\23\3\24\3\24\3\24\5\24\u015f\n\24\3\25\3"+
|
||||
"\25\5\25\u0163\n\25\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\30\3\30\3\30"+
|
||||
"\3\30\3\31\3\31\3\31\3\31\3\31\3\31\6\31\u0176\n\31\r\31\16\31\u0177\3"+
|
||||
"\31\3\31\7\31\u017c\n\31\f\31\16\31\u017f\13\31\5\31\u0181\n\31\3\31\3"+
|
||||
"\31\3\31\3\31\3\31\3\31\3\31\3\31\7\31\u018b\n\31\f\31\16\31\u018e\13"+
|
||||
"\31\5\31\u0190\n\31\3\31\5\31\u0193\n\31\3\31\3\31\7\31\u0197\n\31\f\31"+
|
||||
"\16\31\u019a\13\31\5\31\u019c\n\31\3\32\3\32\3\32\3\32\7\32\u01a2\n\32"+
|
||||
"\f\32\16\32\u01a5\13\32\3\32\3\32\3\32\3\32\5\32\u01ab\n\32\3\33\3\33"+
|
||||
"\3\33\3\33\7\33\u01b1\n\33\f\33\16\33\u01b4\13\33\3\33\3\33\3\33\3\33"+
|
||||
"\3\33\5\33\u01bb\n\33\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\7\35\u01c5"+
|
||||
"\n\35\f\35\16\35\u01c8\13\35\5\35\u01ca\n\35\3\35\3\35\3\36\3\36\3\36"+
|
||||
"\5\36\u01d1\n\36\3\37\3\37\3\37\3\37\3\37\7\37\u01d8\n\37\f\37\16\37\u01db"+
|
||||
"\13\37\5\37\u01dd\n\37\3\37\5\37\u01e0\n\37\3\37\3\37\3\37\5\37\u01e5"+
|
||||
"\n\37\3 \5 \u01e8\n \3 \3 \3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\5!\u01f9"+
|
||||
"\n!\3!\2\3\36\"\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62"+
|
||||
"\64\668:<>@\2\16\3\3\r\r\3\2\37!\3\2\"#\3\289\3\2$&\3\2\'*\3\2+.\3\2<"+
|
||||
"G\3\2:;\4\2\35\36\"#\3\2HK\3\2ST\u0233\2E\3\2\2\2\4P\3\2\2\2\6U\3\2\2"+
|
||||
"\2\b\u00bb\3\2\2\2\n\u00bf\3\2\2\2\f\u00c1\3\2\2\2\16\u00ca\3\2\2\2\20"+
|
||||
"\u00ce\3\2\2\2\22\u00d0\3\2\2\2\24\u00d2\3\2\2\2\26\u00db\3\2\2\2\30\u00e3"+
|
||||
"\3\2\2\2\32\u00e8\3\2\2\2\34\u00ef\3\2\2\2\36\u00f1\3\2\2\2 \u0133\3\2"+
|
||||
"\2\2\"\u0145\3\2\2\2$\u0159\3\2\2\2&\u015e\3\2\2\2(\u0162\3\2\2\2*\u0164"+
|
||||
"\3\2\2\2,\u0168\3\2\2\2.\u016b\3\2\2\2\60\u019b\3\2\2\2\62\u01aa\3\2\2"+
|
||||
"\2\64\u01ba\3\2\2\2\66\u01bc\3\2\2\28\u01c0\3\2\2\2:\u01d0\3\2\2\2<\u01df"+
|
||||
"\3\2\2\2>\u01e7\3\2\2\2@\u01f8\3\2\2\2BD\5\4\3\2CB\3\2\2\2DG\3\2\2\2E"+
|
||||
"C\3\2\2\2EF\3\2\2\2FK\3\2\2\2GE\3\2\2\2HJ\5\b\5\2IH\3\2\2\2JM\3\2\2\2"+
|
||||
"KI\3\2\2\2KL\3\2\2\2LN\3\2\2\2MK\3\2\2\2NO\7\2\2\3O\3\3\2\2\2PQ\5\26\f"+
|
||||
"\2QR\7R\2\2RS\5\6\4\2ST\5\f\7\2T\5\3\2\2\2Ua\7\t\2\2VW\5\26\f\2W^\7R\2"+
|
||||
"\2XY\7\f\2\2YZ\5\26\f\2Z[\7R\2\2[]\3\2\2\2\\X\3\2\2\2]`\3\2\2\2^\\\3\2"+
|
||||
"\2\2^_\3\2\2\2_b\3\2\2\2`^\3\2\2\2aV\3\2\2\2ab\3\2\2\2bc\3\2\2\2cd\7\n"+
|
||||
"\2\2d\7\3\2\2\2ef\7\16\2\2fg\7\t\2\2gh\5\36\20\2hi\7\n\2\2im\5\n\6\2j"+
|
||||
"k\7\20\2\2kn\5\n\6\2ln\6\5\2\2mj\3\2\2\2ml\3\2\2\2n\u00bc\3\2\2\2op\7"+
|
||||
"\21\2\2pq\7\t\2\2qr\5\36\20\2ru\7\n\2\2sv\5\n\6\2tv\5\16\b\2us\3\2\2\2"+
|
||||
"ut\3\2\2\2v\u00bc\3\2\2\2wx\7\22\2\2xy\5\f\7\2yz\7\21\2\2z{\7\t\2\2{|"+
|
||||
"\5\36\20\2|}\7\n\2\2}~\5\34\17\2~\u00bc\3\2\2\2\177\u0080\7\23\2\2\u0080"+
|
||||
"\u0082\7\t\2\2\u0081\u0083\5\20\t\2\u0082\u0081\3\2\2\2\u0082\u0083\3"+
|
||||
"\2\2\2\u0083\u0084\3\2\2\2\u0084\u0086\7\r\2\2\u0085\u0087\5\36\20\2\u0086"+
|
||||
"\u0085\3\2\2\2\u0086\u0087\3\2\2\2\u0087\u0088\3\2\2\2\u0088\u008a\7\r"+
|
||||
"\2\2\u0089\u008b\5\22\n\2\u008a\u0089\3\2\2\2\u008a\u008b\3\2\2\2\u008b"+
|
||||
"\u008c\3\2\2\2\u008c\u008f\7\n\2\2\u008d\u0090\5\n\6\2\u008e\u0090\5\16"+
|
||||
"\b\2\u008f\u008d\3\2\2\2\u008f\u008e\3\2\2\2\u0090\u00bc\3\2\2\2\u0091"+
|
||||
"\u0092\7\23\2\2\u0092\u0093\7\t\2\2\u0093\u0094\5\26\f\2\u0094\u0095\7"+
|
||||
"R\2\2\u0095\u0096\7\65\2\2\u0096\u0097\5\36\20\2\u0097\u0098\7\n\2\2\u0098"+
|
||||
"\u0099\5\n\6\2\u0099\u00bc\3\2\2\2\u009a\u009b\7\23\2\2\u009b\u009c\7"+
|
||||
"\t\2\2\u009c\u009d\7R\2\2\u009d\u009e\7\17\2\2\u009e\u009f\5\36\20\2\u009f"+
|
||||
"\u00a0\7\n\2\2\u00a0\u00a1\5\n\6\2\u00a1\u00bc\3\2\2\2\u00a2\u00a3\5\24"+
|
||||
"\13\2\u00a3\u00a4\5\34\17\2\u00a4\u00bc\3\2\2\2\u00a5\u00a6\7\24\2\2\u00a6"+
|
||||
"\u00bc\5\34\17\2\u00a7\u00a8\7\25\2\2\u00a8\u00bc\5\34\17\2\u00a9\u00aa"+
|
||||
"\7\26\2\2\u00aa\u00ab\5\36\20\2\u00ab\u00ac\5\34\17\2\u00ac\u00bc\3\2"+
|
||||
"\2\2\u00ad\u00ae\7\30\2\2\u00ae\u00b0\5\f\7\2\u00af\u00b1\5\32\16\2\u00b0"+
|
||||
"\u00af\3\2\2\2\u00b1\u00b2\3\2\2\2\u00b2\u00b0\3\2\2\2\u00b2\u00b3\3\2"+
|
||||
"\2\2\u00b3\u00bc\3\2\2\2\u00b4\u00b5\7\32\2\2\u00b5\u00b6\5\36\20\2\u00b6"+
|
||||
"\u00b7\5\34\17\2\u00b7\u00bc\3\2\2\2\u00b8\u00b9\5\36\20\2\u00b9\u00ba"+
|
||||
"\5\34\17\2\u00ba\u00bc\3\2\2\2\u00bbe\3\2\2\2\u00bbo\3\2\2\2\u00bbw\3"+
|
||||
"\2\2\2\u00bb\177\3\2\2\2\u00bb\u0091\3\2\2\2\u00bb\u009a\3\2\2\2\u00bb"+
|
||||
"\u00a2\3\2\2\2\u00bb\u00a5\3\2\2\2\u00bb\u00a7\3\2\2\2\u00bb\u00a9\3\2"+
|
||||
"\2\2\u00bb\u00ad\3\2\2\2\u00bb\u00b4\3\2\2\2\u00bb\u00b8\3\2\2\2\u00bc"+
|
||||
"\t\3\2\2\2\u00bd\u00c0\5\f\7\2\u00be\u00c0\5\b\5\2\u00bf\u00bd\3\2\2\2"+
|
||||
"\u00bf\u00be\3\2\2\2\u00c0\13\3\2\2\2\u00c1\u00c5\7\5\2\2\u00c2\u00c4"+
|
||||
"\5\b\5\2\u00c3\u00c2\3\2\2\2\u00c4\u00c7\3\2\2\2\u00c5\u00c3\3\2\2\2\u00c5"+
|
||||
"\u00c6\3\2\2\2\u00c6\u00c8\3\2\2\2\u00c7\u00c5\3\2\2\2\u00c8\u00c9\7\6"+
|
||||
"\2\2\u00c9\r\3\2\2\2\u00ca\u00cb\7\r\2\2\u00cb\17\3\2\2\2\u00cc\u00cf"+
|
||||
"\5\24\13\2\u00cd\u00cf\5\36\20\2\u00ce\u00cc\3\2\2\2\u00ce\u00cd\3\2\2"+
|
||||
"\2\u00cf\21\3\2\2\2\u00d0\u00d1\5\36\20\2\u00d1\23\3\2\2\2\u00d2\u00d3"+
|
||||
"\5\26\f\2\u00d3\u00d8\5\30\r\2\u00d4\u00d5\7\f\2\2\u00d5\u00d7\5\30\r"+
|
||||
"\2\u00d6\u00d4\3\2\2\2\u00d7\u00da\3\2\2\2\u00d8\u00d6\3\2\2\2\u00d8\u00d9"+
|
||||
"\3\2\2\2\u00d9\25\3\2\2\2\u00da\u00d8\3\2\2\2\u00db\u00e0\7Q\2\2\u00dc"+
|
||||
"\u00dd\7\7\2\2\u00dd\u00df\7\b\2\2\u00de\u00dc\3\2\2\2\u00df\u00e2\3\2"+
|
||||
"\2\2\u00e0\u00de\3\2\2\2\u00e0\u00e1\3\2\2\2\u00e1\27\3\2\2\2\u00e2\u00e0"+
|
||||
"\3\2\2\2\u00e3\u00e6\7R\2\2\u00e4\u00e5\7<\2\2\u00e5\u00e7\5\36\20\2\u00e6"+
|
||||
"\u00e4\3\2\2\2\u00e6\u00e7\3\2\2\2\u00e7\31\3\2\2\2\u00e8\u00e9\7\31\2"+
|
||||
"\2\u00e9\u00ea\7\t\2\2\u00ea\u00eb\7Q\2\2\u00eb\u00ec\7R\2\2\u00ec\u00ed"+
|
||||
"\7\n\2\2\u00ed\u00ee\5\f\7\2\u00ee\33\3\2\2\2\u00ef\u00f0\t\2\2\2\u00f0"+
|
||||
"\35\3\2\2\2\u00f1\u00f2\b\20\1\2\u00f2\u00f3\5 \21\2\u00f3\u0123\3\2\2"+
|
||||
"\2\u00f4\u00f5\f\20\2\2\u00f5\u00f6\t\3\2\2\u00f6\u0122\5\36\20\21\u00f7"+
|
||||
"\u00f8\f\17\2\2\u00f8\u00f9\t\4\2\2\u00f9\u0122\5\36\20\20\u00fa\u00fb"+
|
||||
"\f\16\2\2\u00fb\u00fc\t\5\2\2\u00fc\u0122\5\36\20\17\u00fd\u00fe\f\r\2"+
|
||||
"\2\u00fe\u00ff\t\6\2\2\u00ff\u0122\5\36\20\16\u0100\u0101\f\f\2\2\u0101"+
|
||||
"\u0102\t\7\2\2\u0102\u0122\5\36\20\r\u0103\u0104\f\n\2\2\u0104\u0105\t"+
|
||||
"\b\2\2\u0105\u0122\5\36\20\13\u0106\u0107\f\t\2\2\u0107\u0108\7/\2\2\u0108"+
|
||||
"\u0122\5\36\20\n\u0109\u010a\f\b\2\2\u010a\u010b\7\60\2\2\u010b\u0122"+
|
||||
"\5\36\20\t\u010c\u010d\f\7\2\2\u010d\u010e\7\61\2\2\u010e\u0122\5\36\20"+
|
||||
"\b\u010f\u0110\f\6\2\2\u0110\u0111\7\62\2\2\u0111\u0122\5\36\20\7\u0112"+
|
||||
"\u0113\f\5\2\2\u0113\u0114\7\63\2\2\u0114\u0122\5\36\20\6\u0115\u0116"+
|
||||
"\f\4\2\2\u0116\u0117\7\64\2\2\u0117\u0118\5\36\20\2\u0118\u0119\7\65\2"+
|
||||
"\2\u0119\u011a\5\36\20\4\u011a\u0122\3\2\2\2\u011b\u011c\f\3\2\2\u011c"+
|
||||
"\u011d\t\t\2\2\u011d\u0122\5\36\20\3\u011e\u011f\f\13\2\2\u011f\u0120"+
|
||||
"\7\34\2\2\u0120\u0122\5\26\f\2\u0121\u00f4\3\2\2\2\u0121\u00f7\3\2\2\2"+
|
||||
"\u0121\u00fa\3\2\2\2\u0121\u00fd\3\2\2\2\u0121\u0100\3\2\2\2\u0121\u0103"+
|
||||
"\3\2\2\2\u0121\u0106\3\2\2\2\u0121\u0109\3\2\2\2\u0121\u010c\3\2\2\2\u0121"+
|
||||
"\u010f\3\2\2\2\u0121\u0112\3\2\2\2\u0121\u0115\3\2\2\2\u0121\u011b\3\2"+
|
||||
"\2\2\u0121\u011e\3\2\2\2\u0122\u0125\3\2\2\2\u0123\u0121\3\2\2\2\u0123"+
|
||||
"\u0124\3\2\2\2\u0124\37\3\2\2\2\u0125\u0123\3\2\2\2\u0126\u0127\t\n\2"+
|
||||
"\2\u0127\u0134\5\"\22\2\u0128\u0129\5\"\22\2\u0129\u012a\t\n\2\2\u012a"+
|
||||
"\u0134\3\2\2\2\u012b\u0134\5\"\22\2\u012c\u012d\t\13\2\2\u012d\u0134\5"+
|
||||
" \21\2\u012e\u012f\7\t\2\2\u012f\u0130\5\26\f\2\u0130\u0131\7\n\2\2\u0131"+
|
||||
"\u0132\5 \21\2\u0132\u0134\3\2\2\2\u0133\u0126\3\2\2\2\u0133\u0128\3\2"+
|
||||
"\2\2\u0133\u012b\3\2\2\2\u0133\u012c\3\2\2\2\u0133\u012e\3\2\2\2\u0134"+
|
||||
"!\3\2\2\2\u0135\u0139\5$\23\2\u0136\u0138\5&\24\2\u0137\u0136\3\2\2\2"+
|
||||
"\u0138\u013b\3\2\2\2\u0139\u0137\3\2\2\2\u0139\u013a\3\2\2\2\u013a\u0146"+
|
||||
"\3\2\2\2\u013b\u0139\3\2\2\2\u013c\u013d\5\26\f\2\u013d\u0141\5(\25\2"+
|
||||
"\u013e\u0140\5&\24\2\u013f\u013e\3\2\2\2\u0140\u0143\3\2\2\2\u0141\u013f"+
|
||||
"\3\2\2\2\u0141\u0142\3\2\2\2\u0142\u0146\3\2\2\2\u0143\u0141\3\2\2\2\u0144"+
|
||||
"\u0146\5\60\31\2\u0145\u0135\3\2\2\2\u0145\u013c\3\2\2\2\u0145\u0144\3"+
|
||||
"\2\2\2\u0146#\3\2\2\2\u0147\u0148\7\t\2\2\u0148\u0149\5\36\20\2\u0149"+
|
||||
"\u014a\7\n\2\2\u014a\u015a\3\2\2\2\u014b\u015a\t\f\2\2\u014c\u015a\7N"+
|
||||
"\2\2\u014d\u015a\7O\2\2\u014e\u015a\7P\2\2\u014f\u015a\7L\2\2\u0150\u015a"+
|
||||
"\7M\2\2\u0151\u015a\5\62\32\2\u0152\u015a\5\64\33\2\u0153\u015a\7R\2\2"+
|
||||
"\u0154\u0155\7R\2\2\u0155\u015a\58\35\2\u0156\u0157\7\27\2\2\u0157\u0158"+
|
||||
"\7Q\2\2\u0158\u015a\58\35\2\u0159\u0147\3\2\2\2\u0159\u014b\3\2\2\2\u0159"+
|
||||
"\u014c\3\2\2\2\u0159\u014d\3\2\2\2\u0159\u014e\3\2\2\2\u0159\u014f\3\2"+
|
||||
"\2\2\u0159\u0150\3\2\2\2\u0159\u0151\3\2\2\2\u0159\u0152\3\2\2\2\u0159"+
|
||||
"\u0153\3\2\2\2\u0159\u0154\3\2\2\2\u0159\u0156\3\2\2\2\u015a%\3\2\2\2"+
|
||||
"\u015b\u015f\5*\26\2\u015c\u015f\5,\27\2\u015d\u015f\5.\30\2\u015e\u015b"+
|
||||
"\3\2\2\2\u015e\u015c\3\2\2\2\u015e\u015d\3\2\2\2\u015f\'\3\2\2\2\u0160"+
|
||||
"\u0163\5*\26\2\u0161\u0163\5,\27\2\u0162\u0160\3\2\2\2\u0162\u0161\3\2"+
|
||||
"\2\2\u0163)\3\2\2\2\u0164\u0165\7\13\2\2\u0165\u0166\7T\2\2\u0166\u0167"+
|
||||
"\58\35\2\u0167+\3\2\2\2\u0168\u0169\7\13\2\2\u0169\u016a\t\r\2\2\u016a"+
|
||||
"-\3\2\2\2\u016b\u016c\7\7\2\2\u016c\u016d\5\36\20\2\u016d\u016e\7\b\2"+
|
||||
"\2\u016e/\3\2\2\2\u016f\u0170\7\27\2\2\u0170\u0175\7Q\2\2\u0171\u0172"+
|
||||
"\7\7\2\2\u0172\u0173\5\36\20\2\u0173\u0174\7\b\2\2\u0174\u0176\3\2\2\2"+
|
||||
"\u0175\u0171\3\2\2\2\u0176\u0177\3\2\2\2\u0177\u0175\3\2\2\2\u0177\u0178"+
|
||||
"\3\2\2\2\u0178\u0180\3\2\2\2\u0179\u017d\5(\25\2\u017a\u017c\5&\24\2\u017b"+
|
||||
"\u017a\3\2\2\2\u017c\u017f\3\2\2\2\u017d\u017b\3\2\2\2\u017d\u017e\3\2"+
|
||||
"\2\2\u017e\u0181\3\2\2\2\u017f\u017d\3\2\2\2\u0180\u0179\3\2\2\2\u0180"+
|
||||
"\u0181\3\2\2\2\u0181\u019c\3\2\2\2\u0182\u0183\7\27\2\2\u0183\u0184\7"+
|
||||
"Q\2\2\u0184\u0185\7\7\2\2\u0185\u0186\7\b\2\2\u0186\u018f\7\5\2\2\u0187"+
|
||||
"\u018c\5\36\20\2\u0188\u0189\7\f\2\2\u0189\u018b\5\36\20\2\u018a\u0188"+
|
||||
"\3\2\2\2\u018b\u018e\3\2\2\2\u018c\u018a\3\2\2\2\u018c\u018d\3\2\2\2\u018d"+
|
||||
"\u0190\3\2\2\2\u018e\u018c\3\2\2\2\u018f\u0187\3\2\2\2\u018f\u0190\3\2"+
|
||||
"\2\2\u0190\u0192\3\2\2\2\u0191\u0193\7\r\2\2\u0192\u0191\3\2\2\2\u0192"+
|
||||
"\u0193\3\2\2\2\u0193\u0194\3\2\2\2\u0194\u0198\7\6\2\2\u0195\u0197\5&"+
|
||||
"\24\2\u0196\u0195\3\2\2\2\u0197\u019a\3\2\2\2\u0198\u0196\3\2\2\2\u0198"+
|
||||
"\u0199\3\2\2\2\u0199\u019c\3\2\2\2\u019a\u0198\3\2\2\2\u019b\u016f\3\2"+
|
||||
"\2\2\u019b\u0182\3\2\2\2\u019c\61\3\2\2\2\u019d\u019e\7\7\2\2\u019e\u01a3"+
|
||||
"\5\36\20\2\u019f\u01a0\7\f\2\2\u01a0\u01a2\5\36\20\2\u01a1\u019f\3\2\2"+
|
||||
"\2\u01a2\u01a5\3\2\2\2\u01a3\u01a1\3\2\2\2\u01a3\u01a4\3\2\2\2\u01a4\u01a6"+
|
||||
"\3\2\2\2\u01a5\u01a3\3\2\2\2\u01a6\u01a7\7\b\2\2\u01a7\u01ab\3\2\2\2\u01a8"+
|
||||
"\u01a9\7\7\2\2\u01a9\u01ab\7\b\2\2\u01aa\u019d\3\2\2\2\u01aa\u01a8\3\2"+
|
||||
"\2\2\u01ab\63\3\2\2\2\u01ac\u01ad\7\7\2\2\u01ad\u01b2\5\66\34\2\u01ae"+
|
||||
"\u01af\7\f\2\2\u01af\u01b1\5\66\34\2\u01b0\u01ae\3\2\2\2\u01b1\u01b4\3"+
|
||||
"\2\2\2\u01b2\u01b0\3\2\2\2\u01b2\u01b3\3\2\2\2\u01b3\u01b5\3\2\2\2\u01b4"+
|
||||
"\u01b2\3\2\2\2\u01b5\u01b6\7\b\2\2\u01b6\u01bb\3\2\2\2\u01b7\u01b8\7\7"+
|
||||
"\2\2\u01b8\u01b9\7\65\2\2\u01b9\u01bb\7\b\2\2\u01ba\u01ac\3\2\2\2\u01ba"+
|
||||
"\u01b7\3\2\2\2\u01bb\65\3\2\2\2\u01bc\u01bd\5\36\20\2\u01bd\u01be\7\65"+
|
||||
"\2\2\u01be\u01bf\5\36\20\2\u01bf\67\3\2\2\2\u01c0\u01c9\7\t\2\2\u01c1"+
|
||||
"\u01c6\5:\36\2\u01c2\u01c3\7\f\2\2\u01c3\u01c5\5:\36\2\u01c4\u01c2\3\2"+
|
||||
"\2\2\u01c5\u01c8\3\2\2\2\u01c6\u01c4\3\2\2\2\u01c6\u01c7\3\2\2\2\u01c7"+
|
||||
"\u01ca\3\2\2\2\u01c8\u01c6\3\2\2\2\u01c9\u01c1\3\2\2\2\u01c9\u01ca\3\2"+
|
||||
"\2\2\u01ca\u01cb\3\2\2\2\u01cb\u01cc\7\n\2\2\u01cc9\3\2\2\2\u01cd\u01d1"+
|
||||
"\5\36\20\2\u01ce\u01d1\5<\37\2\u01cf\u01d1\5@!\2\u01d0\u01cd\3\2\2\2\u01d0"+
|
||||
"\u01ce\3\2\2\2\u01d0\u01cf\3\2\2\2\u01d1;\3\2\2\2\u01d2\u01e0\5> \2\u01d3"+
|
||||
"\u01dc\7\t\2\2\u01d4\u01d9\5> \2\u01d5\u01d6\7\f\2\2\u01d6\u01d8\5> \2"+
|
||||
"\u01d7\u01d5\3\2\2\2\u01d8\u01db\3\2\2\2\u01d9\u01d7\3\2\2\2\u01d9\u01da"+
|
||||
"\3\2\2\2\u01da\u01dd\3\2\2\2\u01db\u01d9\3\2\2\2\u01dc\u01d4\3\2\2\2\u01dc"+
|
||||
"\u01dd\3\2\2\2\u01dd\u01de\3\2\2\2\u01de\u01e0\7\n\2\2\u01df\u01d2\3\2"+
|
||||
"\2\2\u01df\u01d3\3\2\2\2\u01e0\u01e1\3\2\2\2\u01e1\u01e4\7\67\2\2\u01e2"+
|
||||
"\u01e5\5\f\7\2\u01e3\u01e5\5\36\20\2\u01e4\u01e2\3\2\2\2\u01e4\u01e3\3"+
|
||||
"\2\2\2\u01e5=\3\2\2\2\u01e6\u01e8\5\26\f\2\u01e7\u01e6\3\2\2\2\u01e7\u01e8"+
|
||||
"\3\2\2\2\u01e8\u01e9\3\2\2\2\u01e9\u01ea\7R\2\2\u01ea?\3\2\2\2\u01eb\u01ec"+
|
||||
"\7Q\2\2\u01ec\u01ed\7\66\2\2\u01ed\u01f9\7R\2\2\u01ee\u01ef\5\26\f\2\u01ef"+
|
||||
"\u01f0\7\66\2\2\u01f0\u01f1\7\27\2\2\u01f1\u01f9\3\2\2\2\u01f2\u01f3\7"+
|
||||
"R\2\2\u01f3\u01f4\7\66\2\2\u01f4\u01f9\7R\2\2\u01f5\u01f6\7\33\2\2\u01f6"+
|
||||
"\u01f7\7\66\2\2\u01f7\u01f9\7R\2\2\u01f8\u01eb\3\2\2\2\u01f8\u01ee\3\2"+
|
||||
"\2\2\u01f8\u01f2\3\2\2\2\u01f8\u01f5\3\2\2\2\u01f9A\3\2\2\2\62EK^amu\u0082"+
|
||||
"\u0086\u008a\u008f\u00b2\u00bb\u00bf\u00c5\u00ce\u00d8\u00e0\u00e6\u0121"+
|
||||
"\u0123\u0133\u0139\u0141\u0145\u0159\u015e\u0162\u0177\u017d\u0180\u018c"+
|
||||
"\u018f\u0192\u0198\u019b\u01a3\u01aa\u01b2\u01ba\u01c6\u01c9\u01d0\u01d9"+
|
||||
"\u01dc\u01df\u01e4\u01e7\u01f8";
|
||||
"\25\5\25\u0163\n\25\3\26\5\26\u0166\n\26\3\26\3\26\3\26\3\26\3\27\5\27"+
|
||||
"\u016d\n\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31"+
|
||||
"\3\31\6\31\u017c\n\31\r\31\16\31\u017d\3\31\3\31\7\31\u0182\n\31\f\31"+
|
||||
"\16\31\u0185\13\31\5\31\u0187\n\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31"+
|
||||
"\3\31\7\31\u0191\n\31\f\31\16\31\u0194\13\31\5\31\u0196\n\31\3\31\5\31"+
|
||||
"\u0199\n\31\3\31\3\31\7\31\u019d\n\31\f\31\16\31\u01a0\13\31\5\31\u01a2"+
|
||||
"\n\31\3\32\3\32\3\32\3\32\7\32\u01a8\n\32\f\32\16\32\u01ab\13\32\3\32"+
|
||||
"\3\32\3\32\3\32\5\32\u01b1\n\32\3\33\3\33\3\33\3\33\7\33\u01b7\n\33\f"+
|
||||
"\33\16\33\u01ba\13\33\3\33\3\33\3\33\3\33\3\33\5\33\u01c1\n\33\3\34\3"+
|
||||
"\34\3\34\3\34\3\35\3\35\3\35\3\35\7\35\u01cb\n\35\f\35\16\35\u01ce\13"+
|
||||
"\35\5\35\u01d0\n\35\3\35\3\35\3\36\3\36\3\36\5\36\u01d7\n\36\3\37\3\37"+
|
||||
"\3\37\3\37\3\37\7\37\u01de\n\37\f\37\16\37\u01e1\13\37\5\37\u01e3\n\37"+
|
||||
"\3\37\5\37\u01e6\n\37\3\37\3\37\3\37\5\37\u01eb\n\37\3 \5 \u01ee\n \3"+
|
||||
" \3 \3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\5!\u01ff\n!\3!\2\3\36\"\2"+
|
||||
"\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@\2\16\3"+
|
||||
"\3\r\r\3\2\37!\3\2\"#\3\289\3\2$&\3\2\'*\3\2+.\3\2<G\3\2:;\4\2\35\36\""+
|
||||
"#\3\2HK\3\2ST\u023b\2E\3\2\2\2\4P\3\2\2\2\6U\3\2\2\2\b\u00bb\3\2\2\2\n"+
|
||||
"\u00bf\3\2\2\2\f\u00c1\3\2\2\2\16\u00ca\3\2\2\2\20\u00ce\3\2\2\2\22\u00d0"+
|
||||
"\3\2\2\2\24\u00d2\3\2\2\2\26\u00db\3\2\2\2\30\u00e3\3\2\2\2\32\u00e8\3"+
|
||||
"\2\2\2\34\u00ef\3\2\2\2\36\u00f1\3\2\2\2 \u0133\3\2\2\2\"\u0145\3\2\2"+
|
||||
"\2$\u0159\3\2\2\2&\u015e\3\2\2\2(\u0162\3\2\2\2*\u0165\3\2\2\2,\u016c"+
|
||||
"\3\2\2\2.\u0171\3\2\2\2\60\u01a1\3\2\2\2\62\u01b0\3\2\2\2\64\u01c0\3\2"+
|
||||
"\2\2\66\u01c2\3\2\2\28\u01c6\3\2\2\2:\u01d6\3\2\2\2<\u01e5\3\2\2\2>\u01ed"+
|
||||
"\3\2\2\2@\u01fe\3\2\2\2BD\5\4\3\2CB\3\2\2\2DG\3\2\2\2EC\3\2\2\2EF\3\2"+
|
||||
"\2\2FK\3\2\2\2GE\3\2\2\2HJ\5\b\5\2IH\3\2\2\2JM\3\2\2\2KI\3\2\2\2KL\3\2"+
|
||||
"\2\2LN\3\2\2\2MK\3\2\2\2NO\7\2\2\3O\3\3\2\2\2PQ\5\26\f\2QR\7R\2\2RS\5"+
|
||||
"\6\4\2ST\5\f\7\2T\5\3\2\2\2Ua\7\t\2\2VW\5\26\f\2W^\7R\2\2XY\7\f\2\2YZ"+
|
||||
"\5\26\f\2Z[\7R\2\2[]\3\2\2\2\\X\3\2\2\2]`\3\2\2\2^\\\3\2\2\2^_\3\2\2\2"+
|
||||
"_b\3\2\2\2`^\3\2\2\2aV\3\2\2\2ab\3\2\2\2bc\3\2\2\2cd\7\n\2\2d\7\3\2\2"+
|
||||
"\2ef\7\16\2\2fg\7\t\2\2gh\5\36\20\2hi\7\n\2\2im\5\n\6\2jk\7\20\2\2kn\5"+
|
||||
"\n\6\2ln\6\5\2\2mj\3\2\2\2ml\3\2\2\2n\u00bc\3\2\2\2op\7\21\2\2pq\7\t\2"+
|
||||
"\2qr\5\36\20\2ru\7\n\2\2sv\5\n\6\2tv\5\16\b\2us\3\2\2\2ut\3\2\2\2v\u00bc"+
|
||||
"\3\2\2\2wx\7\22\2\2xy\5\f\7\2yz\7\21\2\2z{\7\t\2\2{|\5\36\20\2|}\7\n\2"+
|
||||
"\2}~\5\34\17\2~\u00bc\3\2\2\2\177\u0080\7\23\2\2\u0080\u0082\7\t\2\2\u0081"+
|
||||
"\u0083\5\20\t\2\u0082\u0081\3\2\2\2\u0082\u0083\3\2\2\2\u0083\u0084\3"+
|
||||
"\2\2\2\u0084\u0086\7\r\2\2\u0085\u0087\5\36\20\2\u0086\u0085\3\2\2\2\u0086"+
|
||||
"\u0087\3\2\2\2\u0087\u0088\3\2\2\2\u0088\u008a\7\r\2\2\u0089\u008b\5\22"+
|
||||
"\n\2\u008a\u0089\3\2\2\2\u008a\u008b\3\2\2\2\u008b\u008c\3\2\2\2\u008c"+
|
||||
"\u008f\7\n\2\2\u008d\u0090\5\n\6\2\u008e\u0090\5\16\b\2\u008f\u008d\3"+
|
||||
"\2\2\2\u008f\u008e\3\2\2\2\u0090\u00bc\3\2\2\2\u0091\u0092\7\23\2\2\u0092"+
|
||||
"\u0093\7\t\2\2\u0093\u0094\5\26\f\2\u0094\u0095\7R\2\2\u0095\u0096\7\65"+
|
||||
"\2\2\u0096\u0097\5\36\20\2\u0097\u0098\7\n\2\2\u0098\u0099\5\n\6\2\u0099"+
|
||||
"\u00bc\3\2\2\2\u009a\u009b\7\23\2\2\u009b\u009c\7\t\2\2\u009c\u009d\7"+
|
||||
"R\2\2\u009d\u009e\7\17\2\2\u009e\u009f\5\36\20\2\u009f\u00a0\7\n\2\2\u00a0"+
|
||||
"\u00a1\5\n\6\2\u00a1\u00bc\3\2\2\2\u00a2\u00a3\5\24\13\2\u00a3\u00a4\5"+
|
||||
"\34\17\2\u00a4\u00bc\3\2\2\2\u00a5\u00a6\7\24\2\2\u00a6\u00bc\5\34\17"+
|
||||
"\2\u00a7\u00a8\7\25\2\2\u00a8\u00bc\5\34\17\2\u00a9\u00aa\7\26\2\2\u00aa"+
|
||||
"\u00ab\5\36\20\2\u00ab\u00ac\5\34\17\2\u00ac\u00bc\3\2\2\2\u00ad\u00ae"+
|
||||
"\7\30\2\2\u00ae\u00b0\5\f\7\2\u00af\u00b1\5\32\16\2\u00b0\u00af\3\2\2"+
|
||||
"\2\u00b1\u00b2\3\2\2\2\u00b2\u00b0\3\2\2\2\u00b2\u00b3\3\2\2\2\u00b3\u00bc"+
|
||||
"\3\2\2\2\u00b4\u00b5\7\32\2\2\u00b5\u00b6\5\36\20\2\u00b6\u00b7\5\34\17"+
|
||||
"\2\u00b7\u00bc\3\2\2\2\u00b8\u00b9\5\36\20\2\u00b9\u00ba\5\34\17\2\u00ba"+
|
||||
"\u00bc\3\2\2\2\u00bbe\3\2\2\2\u00bbo\3\2\2\2\u00bbw\3\2\2\2\u00bb\177"+
|
||||
"\3\2\2\2\u00bb\u0091\3\2\2\2\u00bb\u009a\3\2\2\2\u00bb\u00a2\3\2\2\2\u00bb"+
|
||||
"\u00a5\3\2\2\2\u00bb\u00a7\3\2\2\2\u00bb\u00a9\3\2\2\2\u00bb\u00ad\3\2"+
|
||||
"\2\2\u00bb\u00b4\3\2\2\2\u00bb\u00b8\3\2\2\2\u00bc\t\3\2\2\2\u00bd\u00c0"+
|
||||
"\5\f\7\2\u00be\u00c0\5\b\5\2\u00bf\u00bd\3\2\2\2\u00bf\u00be\3\2\2\2\u00c0"+
|
||||
"\13\3\2\2\2\u00c1\u00c5\7\5\2\2\u00c2\u00c4\5\b\5\2\u00c3\u00c2\3\2\2"+
|
||||
"\2\u00c4\u00c7\3\2\2\2\u00c5\u00c3\3\2\2\2\u00c5\u00c6\3\2\2\2\u00c6\u00c8"+
|
||||
"\3\2\2\2\u00c7\u00c5\3\2\2\2\u00c8\u00c9\7\6\2\2\u00c9\r\3\2\2\2\u00ca"+
|
||||
"\u00cb\7\r\2\2\u00cb\17\3\2\2\2\u00cc\u00cf\5\24\13\2\u00cd\u00cf\5\36"+
|
||||
"\20\2\u00ce\u00cc\3\2\2\2\u00ce\u00cd\3\2\2\2\u00cf\21\3\2\2\2\u00d0\u00d1"+
|
||||
"\5\36\20\2\u00d1\23\3\2\2\2\u00d2\u00d3\5\26\f\2\u00d3\u00d8\5\30\r\2"+
|
||||
"\u00d4\u00d5\7\f\2\2\u00d5\u00d7\5\30\r\2\u00d6\u00d4\3\2\2\2\u00d7\u00da"+
|
||||
"\3\2\2\2\u00d8\u00d6\3\2\2\2\u00d8\u00d9\3\2\2\2\u00d9\25\3\2\2\2\u00da"+
|
||||
"\u00d8\3\2\2\2\u00db\u00e0\7Q\2\2\u00dc\u00dd\7\7\2\2\u00dd\u00df\7\b"+
|
||||
"\2\2\u00de\u00dc\3\2\2\2\u00df\u00e2\3\2\2\2\u00e0\u00de\3\2\2\2\u00e0"+
|
||||
"\u00e1\3\2\2\2\u00e1\27\3\2\2\2\u00e2\u00e0\3\2\2\2\u00e3\u00e6\7R\2\2"+
|
||||
"\u00e4\u00e5\7<\2\2\u00e5\u00e7\5\36\20\2\u00e6\u00e4\3\2\2\2\u00e6\u00e7"+
|
||||
"\3\2\2\2\u00e7\31\3\2\2\2\u00e8\u00e9\7\31\2\2\u00e9\u00ea\7\t\2\2\u00ea"+
|
||||
"\u00eb\7Q\2\2\u00eb\u00ec\7R\2\2\u00ec\u00ed\7\n\2\2\u00ed\u00ee\5\f\7"+
|
||||
"\2\u00ee\33\3\2\2\2\u00ef\u00f0\t\2\2\2\u00f0\35\3\2\2\2\u00f1\u00f2\b"+
|
||||
"\20\1\2\u00f2\u00f3\5 \21\2\u00f3\u0123\3\2\2\2\u00f4\u00f5\f\20\2\2\u00f5"+
|
||||
"\u00f6\t\3\2\2\u00f6\u0122\5\36\20\21\u00f7\u00f8\f\17\2\2\u00f8\u00f9"+
|
||||
"\t\4\2\2\u00f9\u0122\5\36\20\20\u00fa\u00fb\f\16\2\2\u00fb\u00fc\t\5\2"+
|
||||
"\2\u00fc\u0122\5\36\20\17\u00fd\u00fe\f\r\2\2\u00fe\u00ff\t\6\2\2\u00ff"+
|
||||
"\u0122\5\36\20\16\u0100\u0101\f\f\2\2\u0101\u0102\t\7\2\2\u0102\u0122"+
|
||||
"\5\36\20\r\u0103\u0104\f\n\2\2\u0104\u0105\t\b\2\2\u0105\u0122\5\36\20"+
|
||||
"\13\u0106\u0107\f\t\2\2\u0107\u0108\7/\2\2\u0108\u0122\5\36\20\n\u0109"+
|
||||
"\u010a\f\b\2\2\u010a\u010b\7\60\2\2\u010b\u0122\5\36\20\t\u010c\u010d"+
|
||||
"\f\7\2\2\u010d\u010e\7\61\2\2\u010e\u0122\5\36\20\b\u010f\u0110\f\6\2"+
|
||||
"\2\u0110\u0111\7\62\2\2\u0111\u0122\5\36\20\7\u0112\u0113\f\5\2\2\u0113"+
|
||||
"\u0114\7\63\2\2\u0114\u0122\5\36\20\6\u0115\u0116\f\4\2\2\u0116\u0117"+
|
||||
"\7\64\2\2\u0117\u0118\5\36\20\2\u0118\u0119\7\65\2\2\u0119\u011a\5\36"+
|
||||
"\20\4\u011a\u0122\3\2\2\2\u011b\u011c\f\3\2\2\u011c\u011d\t\t\2\2\u011d"+
|
||||
"\u0122\5\36\20\3\u011e\u011f\f\13\2\2\u011f\u0120\7\34\2\2\u0120\u0122"+
|
||||
"\5\26\f\2\u0121\u00f4\3\2\2\2\u0121\u00f7\3\2\2\2\u0121\u00fa\3\2\2\2"+
|
||||
"\u0121\u00fd\3\2\2\2\u0121\u0100\3\2\2\2\u0121\u0103\3\2\2\2\u0121\u0106"+
|
||||
"\3\2\2\2\u0121\u0109\3\2\2\2\u0121\u010c\3\2\2\2\u0121\u010f\3\2\2\2\u0121"+
|
||||
"\u0112\3\2\2\2\u0121\u0115\3\2\2\2\u0121\u011b\3\2\2\2\u0121\u011e\3\2"+
|
||||
"\2\2\u0122\u0125\3\2\2\2\u0123\u0121\3\2\2\2\u0123\u0124\3\2\2\2\u0124"+
|
||||
"\37\3\2\2\2\u0125\u0123\3\2\2\2\u0126\u0127\t\n\2\2\u0127\u0134\5\"\22"+
|
||||
"\2\u0128\u0129\5\"\22\2\u0129\u012a\t\n\2\2\u012a\u0134\3\2\2\2\u012b"+
|
||||
"\u0134\5\"\22\2\u012c\u012d\t\13\2\2\u012d\u0134\5 \21\2\u012e\u012f\7"+
|
||||
"\t\2\2\u012f\u0130\5\26\f\2\u0130\u0131\7\n\2\2\u0131\u0132\5 \21\2\u0132"+
|
||||
"\u0134\3\2\2\2\u0133\u0126\3\2\2\2\u0133\u0128\3\2\2\2\u0133\u012b\3\2"+
|
||||
"\2\2\u0133\u012c\3\2\2\2\u0133\u012e\3\2\2\2\u0134!\3\2\2\2\u0135\u0139"+
|
||||
"\5$\23\2\u0136\u0138\5&\24\2\u0137\u0136\3\2\2\2\u0138\u013b\3\2\2\2\u0139"+
|
||||
"\u0137\3\2\2\2\u0139\u013a\3\2\2\2\u013a\u0146\3\2\2\2\u013b\u0139\3\2"+
|
||||
"\2\2\u013c\u013d\5\26\f\2\u013d\u0141\5(\25\2\u013e\u0140\5&\24\2\u013f"+
|
||||
"\u013e\3\2\2\2\u0140\u0143\3\2\2\2\u0141\u013f\3\2\2\2\u0141\u0142\3\2"+
|
||||
"\2\2\u0142\u0146\3\2\2\2\u0143\u0141\3\2\2\2\u0144\u0146\5\60\31\2\u0145"+
|
||||
"\u0135\3\2\2\2\u0145\u013c\3\2\2\2\u0145\u0144\3\2\2\2\u0146#\3\2\2\2"+
|
||||
"\u0147\u0148\7\t\2\2\u0148\u0149\5\36\20\2\u0149\u014a\7\n\2\2\u014a\u015a"+
|
||||
"\3\2\2\2\u014b\u015a\t\f\2\2\u014c\u015a\7N\2\2\u014d\u015a\7O\2\2\u014e"+
|
||||
"\u015a\7P\2\2\u014f\u015a\7L\2\2\u0150\u015a\7M\2\2\u0151\u015a\5\62\32"+
|
||||
"\2\u0152\u015a\5\64\33\2\u0153\u015a\7R\2\2\u0154\u0155\7R\2\2\u0155\u015a"+
|
||||
"\58\35\2\u0156\u0157\7\27\2\2\u0157\u0158\7Q\2\2\u0158\u015a\58\35\2\u0159"+
|
||||
"\u0147\3\2\2\2\u0159\u014b\3\2\2\2\u0159\u014c\3\2\2\2\u0159\u014d\3\2"+
|
||||
"\2\2\u0159\u014e\3\2\2\2\u0159\u014f\3\2\2\2\u0159\u0150\3\2\2\2\u0159"+
|
||||
"\u0151\3\2\2\2\u0159\u0152\3\2\2\2\u0159\u0153\3\2\2\2\u0159\u0154\3\2"+
|
||||
"\2\2\u0159\u0156\3\2\2\2\u015a%\3\2\2\2\u015b\u015f\5*\26\2\u015c\u015f"+
|
||||
"\5,\27\2\u015d\u015f\5.\30\2\u015e\u015b\3\2\2\2\u015e\u015c\3\2\2\2\u015e"+
|
||||
"\u015d\3\2\2\2\u015f\'\3\2\2\2\u0160\u0163\5*\26\2\u0161\u0163\5,\27\2"+
|
||||
"\u0162\u0160\3\2\2\2\u0162\u0161\3\2\2\2\u0163)\3\2\2\2\u0164\u0166\7"+
|
||||
"\64\2\2\u0165\u0164\3\2\2\2\u0165\u0166\3\2\2\2\u0166\u0167\3\2\2\2\u0167"+
|
||||
"\u0168\7\13\2\2\u0168\u0169\7T\2\2\u0169\u016a\58\35\2\u016a+\3\2\2\2"+
|
||||
"\u016b\u016d\7\64\2\2\u016c\u016b\3\2\2\2\u016c\u016d\3\2\2\2\u016d\u016e"+
|
||||
"\3\2\2\2\u016e\u016f\7\13\2\2\u016f\u0170\t\r\2\2\u0170-\3\2\2\2\u0171"+
|
||||
"\u0172\7\7\2\2\u0172\u0173\5\36\20\2\u0173\u0174\7\b\2\2\u0174/\3\2\2"+
|
||||
"\2\u0175\u0176\7\27\2\2\u0176\u017b\7Q\2\2\u0177\u0178\7\7\2\2\u0178\u0179"+
|
||||
"\5\36\20\2\u0179\u017a\7\b\2\2\u017a\u017c\3\2\2\2\u017b\u0177\3\2\2\2"+
|
||||
"\u017c\u017d\3\2\2\2\u017d\u017b\3\2\2\2\u017d\u017e\3\2\2\2\u017e\u0186"+
|
||||
"\3\2\2\2\u017f\u0183\5(\25\2\u0180\u0182\5&\24\2\u0181\u0180\3\2\2\2\u0182"+
|
||||
"\u0185\3\2\2\2\u0183\u0181\3\2\2\2\u0183\u0184\3\2\2\2\u0184\u0187\3\2"+
|
||||
"\2\2\u0185\u0183\3\2\2\2\u0186\u017f\3\2\2\2\u0186\u0187\3\2\2\2\u0187"+
|
||||
"\u01a2\3\2\2\2\u0188\u0189\7\27\2\2\u0189\u018a\7Q\2\2\u018a\u018b\7\7"+
|
||||
"\2\2\u018b\u018c\7\b\2\2\u018c\u0195\7\5\2\2\u018d\u0192\5\36\20\2\u018e"+
|
||||
"\u018f\7\f\2\2\u018f\u0191\5\36\20\2\u0190\u018e\3\2\2\2\u0191\u0194\3"+
|
||||
"\2\2\2\u0192\u0190\3\2\2\2\u0192\u0193\3\2\2\2\u0193\u0196\3\2\2\2\u0194"+
|
||||
"\u0192\3\2\2\2\u0195\u018d\3\2\2\2\u0195\u0196\3\2\2\2\u0196\u0198\3\2"+
|
||||
"\2\2\u0197\u0199\7\r\2\2\u0198\u0197\3\2\2\2\u0198\u0199\3\2\2\2\u0199"+
|
||||
"\u019a\3\2\2\2\u019a\u019e\7\6\2\2\u019b\u019d\5&\24\2\u019c\u019b\3\2"+
|
||||
"\2\2\u019d\u01a0\3\2\2\2\u019e\u019c\3\2\2\2\u019e\u019f\3\2\2\2\u019f"+
|
||||
"\u01a2\3\2\2\2\u01a0\u019e\3\2\2\2\u01a1\u0175\3\2\2\2\u01a1\u0188\3\2"+
|
||||
"\2\2\u01a2\61\3\2\2\2\u01a3\u01a4\7\7\2\2\u01a4\u01a9\5\36\20\2\u01a5"+
|
||||
"\u01a6\7\f\2\2\u01a6\u01a8\5\36\20\2\u01a7\u01a5\3\2\2\2\u01a8\u01ab\3"+
|
||||
"\2\2\2\u01a9\u01a7\3\2\2\2\u01a9\u01aa\3\2\2\2\u01aa\u01ac\3\2\2\2\u01ab"+
|
||||
"\u01a9\3\2\2\2\u01ac\u01ad\7\b\2\2\u01ad\u01b1\3\2\2\2\u01ae\u01af\7\7"+
|
||||
"\2\2\u01af\u01b1\7\b\2\2\u01b0\u01a3\3\2\2\2\u01b0\u01ae\3\2\2\2\u01b1"+
|
||||
"\63\3\2\2\2\u01b2\u01b3\7\7\2\2\u01b3\u01b8\5\66\34\2\u01b4\u01b5\7\f"+
|
||||
"\2\2\u01b5\u01b7\5\66\34\2\u01b6\u01b4\3\2\2\2\u01b7\u01ba\3\2\2\2\u01b8"+
|
||||
"\u01b6\3\2\2\2\u01b8\u01b9\3\2\2\2\u01b9\u01bb\3\2\2\2\u01ba\u01b8\3\2"+
|
||||
"\2\2\u01bb\u01bc\7\b\2\2\u01bc\u01c1\3\2\2\2\u01bd\u01be\7\7\2\2\u01be"+
|
||||
"\u01bf\7\65\2\2\u01bf\u01c1\7\b\2\2\u01c0\u01b2\3\2\2\2\u01c0\u01bd\3"+
|
||||
"\2\2\2\u01c1\65\3\2\2\2\u01c2\u01c3\5\36\20\2\u01c3\u01c4\7\65\2\2\u01c4"+
|
||||
"\u01c5\5\36\20\2\u01c5\67\3\2\2\2\u01c6\u01cf\7\t\2\2\u01c7\u01cc\5:\36"+
|
||||
"\2\u01c8\u01c9\7\f\2\2\u01c9\u01cb\5:\36\2\u01ca\u01c8\3\2\2\2\u01cb\u01ce"+
|
||||
"\3\2\2\2\u01cc\u01ca\3\2\2\2\u01cc\u01cd\3\2\2\2\u01cd\u01d0\3\2\2\2\u01ce"+
|
||||
"\u01cc\3\2\2\2\u01cf\u01c7\3\2\2\2\u01cf\u01d0\3\2\2\2\u01d0\u01d1\3\2"+
|
||||
"\2\2\u01d1\u01d2\7\n\2\2\u01d29\3\2\2\2\u01d3\u01d7\5\36\20\2\u01d4\u01d7"+
|
||||
"\5<\37\2\u01d5\u01d7\5@!\2\u01d6\u01d3\3\2\2\2\u01d6\u01d4\3\2\2\2\u01d6"+
|
||||
"\u01d5\3\2\2\2\u01d7;\3\2\2\2\u01d8\u01e6\5> \2\u01d9\u01e2\7\t\2\2\u01da"+
|
||||
"\u01df\5> \2\u01db\u01dc\7\f\2\2\u01dc\u01de\5> \2\u01dd\u01db\3\2\2\2"+
|
||||
"\u01de\u01e1\3\2\2\2\u01df\u01dd\3\2\2\2\u01df\u01e0\3\2\2\2\u01e0\u01e3"+
|
||||
"\3\2\2\2\u01e1\u01df\3\2\2\2\u01e2\u01da\3\2\2\2\u01e2\u01e3\3\2\2\2\u01e3"+
|
||||
"\u01e4\3\2\2\2\u01e4\u01e6\7\n\2\2\u01e5\u01d8\3\2\2\2\u01e5\u01d9\3\2"+
|
||||
"\2\2\u01e6\u01e7\3\2\2\2\u01e7\u01ea\7\67\2\2\u01e8\u01eb\5\f\7\2\u01e9"+
|
||||
"\u01eb\5\36\20\2\u01ea\u01e8\3\2\2\2\u01ea\u01e9\3\2\2\2\u01eb=\3\2\2"+
|
||||
"\2\u01ec\u01ee\5\26\f\2\u01ed\u01ec\3\2\2\2\u01ed\u01ee\3\2\2\2\u01ee"+
|
||||
"\u01ef\3\2\2\2\u01ef\u01f0\7R\2\2\u01f0?\3\2\2\2\u01f1\u01f2\7Q\2\2\u01f2"+
|
||||
"\u01f3\7\66\2\2\u01f3\u01ff\7R\2\2\u01f4\u01f5\5\26\f\2\u01f5\u01f6\7"+
|
||||
"\66\2\2\u01f6\u01f7\7\27\2\2\u01f7\u01ff\3\2\2\2\u01f8\u01f9\7R\2\2\u01f9"+
|
||||
"\u01fa\7\66\2\2\u01fa\u01ff\7R\2\2\u01fb\u01fc\7\33\2\2\u01fc\u01fd\7"+
|
||||
"\66\2\2\u01fd\u01ff\7R\2\2\u01fe\u01f1\3\2\2\2\u01fe\u01f4\3\2\2\2\u01fe"+
|
||||
"\u01f8\3\2\2\2\u01fe\u01fb\3\2\2\2\u01ffA\3\2\2\2\64EK^amu\u0082\u0086"+
|
||||
"\u008a\u008f\u00b2\u00bb\u00bf\u00c5\u00ce\u00d8\u00e0\u00e6\u0121\u0123"+
|
||||
"\u0133\u0139\u0141\u0145\u0159\u015e\u0162\u0165\u016c\u017d\u0183\u0186"+
|
||||
"\u0192\u0195\u0198\u019e\u01a1\u01a9\u01b0\u01b8\u01c0\u01cc\u01cf\u01d6"+
|
||||
"\u01df\u01e2\u01e5\u01ea\u01ed\u01fe";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
|
@ -898,7 +898,7 @@ public final class Walker extends PainlessParserBaseVisitor<ANode> {
|
||||
String name = ctx.DOTID().getText();
|
||||
List<AExpression> arguments = collectArguments(ctx.arguments());
|
||||
|
||||
return new PCallInvoke(location(ctx), prefix, name, arguments);
|
||||
return new PCallInvoke(location(ctx), prefix, name, ctx.COND() != null, arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -917,7 +917,7 @@ public final class Walker extends PainlessParserBaseVisitor<ANode> {
|
||||
throw location(ctx).createError(new IllegalStateException("Illegal tree structure."));
|
||||
}
|
||||
|
||||
return new PField(location(ctx), prefix, value);
|
||||
return new PField(location(ctx), prefix, ctx.COND() != null, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -34,7 +34,7 @@ import org.elasticsearch.painless.MethodWriter;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
/**
|
||||
* Respresents a conditional expression.
|
||||
* Represents a conditional expression.
|
||||
*/
|
||||
public final class EConditional extends AExpression {
|
||||
|
||||
|
@ -39,14 +39,16 @@ import java.util.Set;
|
||||
public final class PCallInvoke extends AExpression {
|
||||
|
||||
private final String name;
|
||||
private final boolean nullSafe;
|
||||
private final List<AExpression> arguments;
|
||||
|
||||
private AExpression sub = null;
|
||||
|
||||
public PCallInvoke(Location location, AExpression prefix, String name, List<AExpression> arguments) {
|
||||
public PCallInvoke(Location location, AExpression prefix, String name, boolean nullSafe, List<AExpression> arguments) {
|
||||
super(location, prefix);
|
||||
|
||||
this.name = Objects.requireNonNull(name);
|
||||
this.nullSafe = nullSafe;
|
||||
this.arguments = Objects.requireNonNull(arguments);
|
||||
}
|
||||
|
||||
@ -87,6 +89,10 @@ public final class PCallInvoke extends AExpression {
|
||||
"Unknown call [" + name + "] with [" + arguments.size() + "] arguments on type [" + struct.name + "]."));
|
||||
}
|
||||
|
||||
if (nullSafe) {
|
||||
sub = new PSubNullSafeCallInvoke(location, sub);
|
||||
}
|
||||
|
||||
sub.expected = expected;
|
||||
sub.explicit = explicit;
|
||||
sub.analyze(locals);
|
||||
|
@ -40,13 +40,15 @@ import java.util.Set;
|
||||
*/
|
||||
public final class PField extends AStoreable {
|
||||
|
||||
private final boolean nullSafe;
|
||||
private final String value;
|
||||
|
||||
private AStoreable sub = null;
|
||||
|
||||
public PField(Location location, AExpression prefix, String value) {
|
||||
public PField(Location location, AExpression prefix, boolean nullSafe, String value) {
|
||||
super(location, prefix);
|
||||
|
||||
this.nullSafe = nullSafe;
|
||||
this.value = Objects.requireNonNull(value);
|
||||
}
|
||||
|
||||
@ -106,6 +108,10 @@ public final class PField extends AStoreable {
|
||||
throw createError(new IllegalArgumentException("Unknown field [" + value + "] for type [" + prefix.actual.name + "]."));
|
||||
}
|
||||
|
||||
if (nullSafe) {
|
||||
sub = new PSubNullSafeField(location, sub);
|
||||
}
|
||||
|
||||
sub.write = write;
|
||||
sub.read = read;
|
||||
sub.expected = expected;
|
||||
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.painless.node;
|
||||
|
||||
import org.elasticsearch.painless.Definition;
|
||||
import org.elasticsearch.painless.Globals;
|
||||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.objectweb.asm.Label;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Implements a call who's value is null if the prefix is null rather than throwing an NPE.
|
||||
*/
|
||||
public class PSubNullSafeCallInvoke extends AExpression {
|
||||
/**
|
||||
* The expression gaurded by the null check. Required at construction time and replaced at analysis time.
|
||||
*/
|
||||
private AExpression guarded;
|
||||
|
||||
public PSubNullSafeCallInvoke(Location location, AExpression guarded) {
|
||||
super(location);
|
||||
this.guarded = requireNonNull(guarded);
|
||||
}
|
||||
|
||||
@Override
|
||||
void extractVariables(Set<String> variables) {
|
||||
guarded.extractVariables(variables);
|
||||
}
|
||||
|
||||
@Override
|
||||
void analyze(Locals locals) {
|
||||
guarded.analyze(locals);
|
||||
actual = guarded.actual;
|
||||
if (actual.sort.primitive) {
|
||||
// Result must be nullable. We emit boxing instructions if needed.
|
||||
actual = Definition.getType(actual.sort.boxed.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void write(MethodWriter writer, Globals globals) {
|
||||
writer.writeDebugInfo(location);
|
||||
|
||||
Label end = new Label();
|
||||
writer.dup();
|
||||
writer.ifNull(end);
|
||||
guarded.write(writer, globals);
|
||||
if (guarded.actual.sort.primitive) {
|
||||
// Box primitives so they are nullable
|
||||
writer.box(guarded.actual.type);
|
||||
}
|
||||
writer.mark(end);
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.painless.node;
|
||||
|
||||
import org.elasticsearch.painless.Definition.Type;
|
||||
import org.elasticsearch.painless.Definition;
|
||||
import org.elasticsearch.painless.Globals;
|
||||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.objectweb.asm.Label;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Implements a field who's value is null if the prefix is null rather than throwing an NPE.
|
||||
*/
|
||||
public class PSubNullSafeField extends AStoreable {
|
||||
private AStoreable guarded;
|
||||
|
||||
public PSubNullSafeField(Location location, AStoreable guarded) {
|
||||
super(location);
|
||||
this.guarded = guarded;
|
||||
}
|
||||
|
||||
@Override
|
||||
void extractVariables(Set<String> variables) {
|
||||
guarded.extractVariables(variables);
|
||||
}
|
||||
|
||||
@Override
|
||||
void analyze(Locals locals) {
|
||||
if (write) {
|
||||
throw createError(new IllegalArgumentException("Can't write to null safe reference"));
|
||||
}
|
||||
guarded.read = read;
|
||||
guarded.analyze(locals);
|
||||
actual = guarded.actual;
|
||||
if (actual.sort.primitive) {
|
||||
// Result must be nullable. We emit boxing instructions if needed.
|
||||
actual = Definition.getType(actual.sort.boxed.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
int accessElementCount() {
|
||||
return guarded.accessElementCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isDefOptimized() {
|
||||
return guarded.isDefOptimized();
|
||||
}
|
||||
|
||||
@Override
|
||||
void updateActual(Type actual) {
|
||||
guarded.updateActual(actual);
|
||||
}
|
||||
|
||||
@Override
|
||||
void write(MethodWriter writer, Globals globals) {
|
||||
Label end = new Label();
|
||||
writer.dup();
|
||||
writer.ifNull(end);
|
||||
guarded.write(writer, globals);
|
||||
if (guarded.actual.sort.primitive) {
|
||||
// Box primitives so they are nullable
|
||||
writer.box(guarded.actual.type);
|
||||
}
|
||||
writer.mark(end);
|
||||
}
|
||||
|
||||
@Override
|
||||
void setup(MethodWriter writer, Globals globals) {
|
||||
throw createError(new IllegalArgumentException("Can't write to null safe field"));
|
||||
}
|
||||
|
||||
@Override
|
||||
void load(MethodWriter writer, Globals globals) {
|
||||
throw createError(new IllegalArgumentException("Can't write to null safe field"));
|
||||
}
|
||||
|
||||
@Override
|
||||
void store(MethodWriter writer, Globals globals) {
|
||||
throw createError(new IllegalArgumentException("Can't write to null safe field"));
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@ package org.elasticsearch.painless;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static java.util.Collections.singletonMap;
|
||||
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
@ -135,4 +137,73 @@ public class BasicExpressionTests extends ScriptTestCase {
|
||||
assertEquals(2, exec("int x = 5; return (x+x)/x;"));
|
||||
assertEquals(true, exec("boolean t = true, f = false; return t && (f || t);"));
|
||||
}
|
||||
|
||||
public void testNullSafeDeref() {
|
||||
// Objects in general
|
||||
assertNull( exec("String a = null; return a?.toString()")); // Call
|
||||
assertNull( exec("String a = null; return a?.length()")); // Call and box
|
||||
assertEquals("foo", exec("String a = 'foo'; return a?.toString()")); // Call
|
||||
assertEquals(Integer.valueOf(3), exec("String a = 'foo'; return a?.length()")); // Call and box
|
||||
|
||||
// Maps
|
||||
assertNull( exec("Map a = null; return a?.toString()")); // Call
|
||||
assertNull( exec("Map a = null; return a?.size()")); // Call and box
|
||||
assertNull( exec("Map a = null; return a?.other")); // Read shortcut
|
||||
assertEquals("{}", exec("Map a = [:]; return a?.toString()")); // Call
|
||||
assertEquals(0, exec("Map a = [:]; return a?.size()")); // Call and box
|
||||
assertEquals(1, exec("Map a = ['other':1]; return a?.other")); // Read shortcut
|
||||
|
||||
// Array
|
||||
// Since you can't invoke methods on arrays we skip the toString and hashCode tests
|
||||
assertNull( exec("int[] a = null; return a?.length")); // Length (boxed)
|
||||
assertEquals(2, exec("int[] a = new int[] {2, 3}; return a?.length")); // Length (boxed)
|
||||
|
||||
// Def
|
||||
assertNull( exec("def a = null; return a?.getX()")); // Invoke
|
||||
assertNull( exec("def a = null; return a?.x")); // Read shortcut
|
||||
assertEquals(0, exec("def a = new org.elasticsearch.painless.FeatureTest(); return a?.getX()")); // Invoke
|
||||
assertEquals(0, exec("def a = new org.elasticsearch.painless.FeatureTest(); return a?.x")); // Read shortcut
|
||||
|
||||
// Results from maps (should just work but let's test anyway)
|
||||
FeatureTest t = new FeatureTest();
|
||||
assertNull( exec("Map a = ['thing': params.t]; return a.other?.getX()", singletonMap("t", t), true));
|
||||
assertNull( exec("Map a = ['thing': params.t]; return a.other?.x", singletonMap("t", t), true));
|
||||
assertNull( exec("def a = ['thing': params.t]; return a.other?.getX()", singletonMap("t", t), true));
|
||||
assertNull( exec("def a = ['thing': params.t]; return a.other?.x", singletonMap("t", t), true));
|
||||
assertEquals(0, exec("Map a = ['other': params.t]; return a.other?.getX()", singletonMap("t", t), true));
|
||||
assertEquals(0, exec("Map a = ['other': params.t]; return a.other?.x", singletonMap("t", t), true));
|
||||
assertEquals(0, exec("def a = ['other': params.t]; return a.other?.getX()", singletonMap("t", t), true));
|
||||
assertEquals(0, exec("def a = ['other': params.t]; return a.other?.x", singletonMap("t", t), true));
|
||||
|
||||
// Chains
|
||||
assertNull( exec("Map a = ['thing': ['cat': params.t]]; return a.other?.cat?.getX()", singletonMap("t", t), true));
|
||||
assertNull( exec("Map a = ['thing': ['cat': params.t]]; return a.other?.cat?.x", singletonMap("t", t), true));
|
||||
assertNull( exec("def a = ['thing': ['cat': params.t]]; return a.other?.cat?.getX()", singletonMap("t", t), true));
|
||||
assertNull( exec("def a = ['thing': ['cat': params.t]]; return a.other?.cat?.x", singletonMap("t", t), true));
|
||||
assertEquals(0, exec("Map a = ['other': ['cat': params.t]]; return a.other?.cat?.getX()", singletonMap("t", t), true));
|
||||
assertEquals(0, exec("Map a = ['other': ['cat': params.t]]; return a.other?.cat?.x", singletonMap("t", t), true));
|
||||
assertEquals(0, exec("def a = ['other': ['cat': params.t]]; return a.other?.cat?.getX()", singletonMap("t", t), true));
|
||||
assertEquals(0, exec("def a = ['other': ['cat': params.t]]; return a.other?.cat?.x", singletonMap("t", t), true));
|
||||
|
||||
// Check that we don't try to cast when the LHS doesn't provide an "expected" value
|
||||
assertNull(exec(
|
||||
"def a = [:];\n"
|
||||
+ "a.missing_length = a.missing?.length();\n"
|
||||
+ "return a.missing_length", true));
|
||||
assertEquals(3, exec(
|
||||
"def a = [:];\n"
|
||||
+ "a.missing = 'foo';\n"
|
||||
+ "a.missing_length = a.missing?.length();\n"
|
||||
+ "return a.missing_length", true));
|
||||
|
||||
// Writes, all unsupported at this point
|
||||
// assertEquals(null, exec("org.elasticsearch.painless.FeatureTest a = null; return a?.x")); // Read field
|
||||
// assertEquals(null, exec("org.elasticsearch.painless.FeatureTest a = null; a?.x = 7; return a?.x")); // Write field
|
||||
// assertEquals(null, exec("Map a = null; a?.other = 'wow'; return a?.other")); // Write shortcut
|
||||
// assertEquals(null, exec("def a = null; a?.other = 'cat'; return a?.other")); // Write shortcut
|
||||
// assertEquals(null, exec("Map a = ['thing': 'bar']; a.other?.cat = 'no'; return a.other?.cat"));
|
||||
// assertEquals(null, exec("def a = ['thing': 'bar']; a.other?.cat = 'no'; return a.other?.cat"));
|
||||
// assertEquals(null, exec("Map a = ['thing': 'bar']; a.other?.cat?.dog = 'wombat'; return a.other?.cat?.dog"));
|
||||
// assertEquals(null, exec("def a = ['thing': 'bar']; a.other?.cat?.dog = 'wombat'; return a.other?.cat?.dog"));
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,59 @@
|
||||
- match: { _source.foo: yyy }
|
||||
- match: { _source.count: 1 }
|
||||
|
||||
- do:
|
||||
update:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body:
|
||||
script:
|
||||
lang: painless
|
||||
inline: "ctx._source.missing_length = ctx._source.missing?.length()"
|
||||
|
||||
- match: { _index: test_1 }
|
||||
- match: { _type: test }
|
||||
- match: { _id: "1" }
|
||||
- match: { _version: 4 }
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
|
||||
- match: { _source.foo: yyy }
|
||||
- match: { _source.count: 1 }
|
||||
- is_false: _source.missing
|
||||
- is_false: _source.missing_length
|
||||
|
||||
- do:
|
||||
update:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body:
|
||||
script:
|
||||
lang: painless
|
||||
inline: "ctx._source.foo_length = ctx._source.foo?.length()"
|
||||
|
||||
- match: { _index: test_1 }
|
||||
- match: { _type: test }
|
||||
- match: { _id: "1" }
|
||||
- match: { _version: 5 }
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
|
||||
- match: { _source.foo: yyy }
|
||||
- match: { _source.foo_length: 3 }
|
||||
- match: { _source.count: 1 }
|
||||
- is_false: _source.missing
|
||||
- is_false: _source.missing_length
|
||||
|
||||
---
|
||||
"Update Script with script error":
|
||||
- do:
|
||||
|
@ -10,6 +10,8 @@ setup:
|
||||
properties:
|
||||
foo:
|
||||
type: keyword
|
||||
missing:
|
||||
type: keyword
|
||||
- do:
|
||||
index:
|
||||
index: test
|
||||
@ -26,14 +28,42 @@ setup:
|
||||
body:
|
||||
script_fields:
|
||||
bar:
|
||||
script:
|
||||
script:
|
||||
inline: "doc['foo'].value + params.x;"
|
||||
lang: painless
|
||||
params:
|
||||
x: "bbb"
|
||||
|
||||
- match: { hits.hits.0.fields.bar.0: "aaabbb"}
|
||||
|
||||
---
|
||||
"Scripted Field with a null safe dereference (non-null)":
|
||||
- do:
|
||||
search:
|
||||
body:
|
||||
script_fields:
|
||||
bar:
|
||||
script:
|
||||
inline: "doc['foo'].value?.length() + params.x;"
|
||||
params:
|
||||
x: 5
|
||||
|
||||
- match: { hits.hits.0.fields.bar.0: 8}
|
||||
|
||||
---
|
||||
"Scripted Field with a null safe dereference (null)":
|
||||
# Change this to ?: once we have it implemented
|
||||
- do:
|
||||
search:
|
||||
body:
|
||||
script_fields:
|
||||
bar:
|
||||
script:
|
||||
inline: "(doc['missing'].value?.length() == null ? 0 : doc['missing'].value?.length()) + params.x;"
|
||||
params:
|
||||
x: 5
|
||||
|
||||
- match: { hits.hits.0.fields.bar.0: 5}
|
||||
|
||||
---
|
||||
"Scripted Field with script error":
|
||||
- do:
|
||||
@ -43,7 +73,6 @@ setup:
|
||||
script_fields:
|
||||
bar:
|
||||
script:
|
||||
lang: painless
|
||||
inline: "while (true) {}"
|
||||
|
||||
- match: { error.root_cause.0.type: "script_exception" }
|
||||
|
Loading…
x
Reference in New Issue
Block a user