From 688854d89cadfe2cb7c98d7be531c71218899330 Mon Sep 17 00:00:00 2001
From: Dimitris Athanasiou
Date: Tue, 17 Apr 2018 18:46:49 +0100
Subject: [PATCH 01/15] Add versions 5.6.10 and 6.2.5
---
server/src/main/java/org/elasticsearch/Version.java | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/server/src/main/java/org/elasticsearch/Version.java b/server/src/main/java/org/elasticsearch/Version.java
index 5128dbf30a01c..490a230976047 100644
--- a/server/src/main/java/org/elasticsearch/Version.java
+++ b/server/src/main/java/org/elasticsearch/Version.java
@@ -117,6 +117,8 @@ public class Version implements Comparable, ToXContentFragment {
public static final Version V_5_6_8 = new Version(V_5_6_8_ID, org.apache.lucene.util.Version.LUCENE_6_6_1);
public static final int V_5_6_9_ID = 5060999;
public static final Version V_5_6_9 = new Version(V_5_6_9_ID, org.apache.lucene.util.Version.LUCENE_6_6_1);
+ public static final int V_5_6_10_ID = 50601099;
+ public static final Version V_5_6_10 = new Version(V_5_6_10_ID, org.apache.lucene.util.Version.LUCENE_6_6_1);
public static final int V_6_0_0_alpha1_ID = 6000001;
public static final Version V_6_0_0_alpha1 = new Version(V_6_0_0_alpha1_ID, org.apache.lucene.util.Version.LUCENE_7_0_0);
public static final int V_6_0_0_alpha2_ID = 6000002;
@@ -159,6 +161,8 @@ public class Version implements Comparable, ToXContentFragment {
public static final Version V_6_2_3 = new Version(V_6_2_3_ID, LUCENE_7_2_1);
public static final int V_6_2_4_ID = 6020499;
public static final Version V_6_2_4 = new Version(V_6_2_4_ID, LUCENE_7_2_1);
+ public static final int V_6_2_5_ID = 6020599;
+ public static final Version V_6_2_5 = new Version(V_6_2_5_ID, LUCENE_7_2_1);
public static final int V_6_3_0_ID = 6030099;
public static final Version V_6_3_0 = new Version(V_6_3_0_ID, org.apache.lucene.util.Version.LUCENE_7_3_0);
public static final Version CURRENT = V_6_3_0;
@@ -176,6 +180,8 @@ public static Version fromId(int id) {
switch (id) {
case V_6_3_0_ID:
return V_6_3_0;
+ case V_6_2_5_ID:
+ return V_6_2_5;
case V_6_2_4_ID:
return V_6_2_4;
case V_6_2_3_ID:
@@ -212,6 +218,8 @@ public static Version fromId(int id) {
return V_6_0_0_alpha2;
case V_6_0_0_alpha1_ID:
return V_6_0_0_alpha1;
+ case V_5_6_10_ID:
+ return V_5_6_10;
case V_5_6_9_ID:
return V_5_6_9;
case V_5_6_8_ID:
From acfc91fe975c9e1b96373abe3f3d776d79bf1e7c Mon Sep 17 00:00:00 2001
From: Luca Cavanna
Date: Tue, 17 Apr 2018 18:18:21 +0200
Subject: [PATCH 02/15] Remove `flatSettings` support from request classes
(#29560)
As part of adding support for new API to the high-level REST client,
we added support for the `flat_settings` parameter to some of our
request classes. We added documentation that such flag is only ever
read by the high-level REST client, but the truth is that it doesn't
do anything given that settings are always parsed back into a `Settings`
object, no matter whether they are returned in a flat format or not.
It was a mistake to add support for this flag in the context of the
high-level REST client, hence this commit removes it.
---
.../org/elasticsearch/client/Request.java | 3 ---
.../elasticsearch/client/RequestTests.java | 13 ----------
.../ClusterClientDocumentationIT.java | 4 ----
.../IndicesClientDocumentationIT.java | 7 +-----
.../high-level/cluster/put_settings.asciidoc | 7 ------
.../indices/indices_exists.asciidoc | 3 +--
.../high-level/indices/put_settings.asciidoc | 7 ------
.../ClusterUpdateSettingsRequest.java | 24 -------------------
.../admin/indices/get/GetIndexRequest.java | 23 ------------------
.../settings/put/UpdateSettingsRequest.java | 24 -------------------
.../UpdateSettingsRequestStreamableTests.java | 2 --
11 files changed, 2 insertions(+), 115 deletions(-)
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java
index 98bca928b6718..2a029e797d158 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java
@@ -581,7 +581,6 @@ private static Request resize(ResizeRequest resizeRequest) throws IOException {
static Request clusterPutSettings(ClusterUpdateSettingsRequest clusterUpdateSettingsRequest) throws IOException {
Params parameters = Params.builder();
- parameters.withFlatSettings(clusterUpdateSettingsRequest.flatSettings());
parameters.withTimeout(clusterUpdateSettingsRequest.timeout());
parameters.withMasterTimeout(clusterUpdateSettingsRequest.masterNodeTimeout());
HttpEntity entity = createEntity(clusterUpdateSettingsRequest, REQUEST_BODY_CONTENT_TYPE);
@@ -612,7 +611,6 @@ static Request indicesExist(GetIndexRequest request) {
params.withLocal(request.local());
params.withHuman(request.humanReadable());
params.withIndicesOptions(request.indicesOptions());
- params.withFlatSettings(request.flatSettings());
params.withIncludeDefaults(request.includeDefaults());
return new Request(HttpHead.METHOD_NAME, endpoint, params.getParams(), null);
}
@@ -622,7 +620,6 @@ static Request indexPutSettings(UpdateSettingsRequest updateSettingsRequest) thr
parameters.withTimeout(updateSettingsRequest.timeout());
parameters.withMasterTimeout(updateSettingsRequest.masterNodeTimeout());
parameters.withIndicesOptions(updateSettingsRequest.indicesOptions());
- parameters.withFlatSettings(updateSettingsRequest.flatSettings());
parameters.withPreserveExisting(updateSettingsRequest.isPreserveExisting());
String[] indices = updateSettingsRequest.indices() == null ? Strings.EMPTY_ARRAY : updateSettingsRequest.indices();
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java
index 3959ccb465d81..a5db1cdf7b3cc 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java
@@ -280,7 +280,6 @@ public void testIndicesExist() {
Map expectedParams = new HashMap<>();
setRandomIndicesOptions(getIndexRequest::indicesOptions, getIndexRequest::indicesOptions, expectedParams);
setRandomLocal(getIndexRequest, expectedParams);
- setRandomFlatSettings(getIndexRequest::flatSettings, expectedParams);
setRandomHumanReadable(getIndexRequest, expectedParams);
setRandomIncludeDefaults(getIndexRequest, expectedParams);
@@ -1322,7 +1321,6 @@ private static void resizeTest(ResizeType resizeType, CheckedFunction expectedParams = new HashMap<>();
- setRandomFlatSettings(request::flatSettings, expectedParams);
setRandomMasterTimeout(request, expectedParams);
setRandomTimeout(request::timeout, AcknowledgedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);
@@ -1375,7 +1373,6 @@ public void testIndexPutSettings() throws IOException {
String[] indices = randomBoolean() ? null : randomIndicesNames(0, 2);
UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest(indices);
Map expectedParams = new HashMap<>();
- setRandomFlatSettings(updateSettingsRequest::flatSettings, expectedParams);
setRandomMasterTimeout(updateSettingsRequest, expectedParams);
setRandomTimeout(updateSettingsRequest::timeout, AcknowledgedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);
setRandomIndicesOptions(updateSettingsRequest::indicesOptions, updateSettingsRequest::indicesOptions, expectedParams);
@@ -1658,16 +1655,6 @@ private static void setRandomTimeout(Consumer setter, TimeValue defaultT
}
}
- private static void setRandomFlatSettings(Consumer setter, Map expectedParams) {
- if (randomBoolean()) {
- boolean flatSettings = randomBoolean();
- setter.accept(flatSettings);
- if (flatSettings) {
- expectedParams.put("flat_settings", String.valueOf(flatSettings));
- }
- }
- }
-
private static void setRandomMasterTimeout(MasterNodeRequest> request, Map expectedParams) {
if (randomBoolean()) {
String masterTimeout = randomTimeValue();
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/ClusterClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/ClusterClientDocumentationIT.java
index 0747ca757c4b9..2e7ea1650f424 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/ClusterClientDocumentationIT.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/ClusterClientDocumentationIT.java
@@ -124,10 +124,6 @@ public void testClusterPutSettings() throws IOException {
request.masterNodeTimeout("1m"); // <2>
// end::put-settings-request-masterTimeout
- // tag::put-settings-request-flat-settings
- request.flatSettings(true); // <1>
- // end::put-settings-request-flat-settings
-
// tag::put-settings-execute
ClusterUpdateSettingsResponse response = client.cluster().putSettings(request);
// end::put-settings-execute
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java
index a2aa1eb718a0c..c3004a01c9bd0 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java
@@ -58,7 +58,6 @@
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
import org.elasticsearch.client.RestHighLevelClient;
-import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
@@ -114,8 +113,7 @@ public void testIndicesExist() throws IOException {
request.local(false); // <1>
request.humanReadable(true); // <2>
request.includeDefaults(false); // <3>
- request.flatSettings(false); // <4>
- request.indicesOptions(indicesOptions); // <5>
+ request.indicesOptions(indicesOptions); // <4>
// end::indices-exists-request-optionals
// tag::indices-exists-response
@@ -1433,9 +1431,6 @@ public void testIndexPutSettings() throws Exception {
// end::put-settings-settings-source
}
- // tag::put-settings-request-flat-settings
- request.flatSettings(true); // <1>
- // end::put-settings-request-flat-settings
// tag::put-settings-request-preserveExisting
request.setPreserveExisting(false); // <1>
// end::put-settings-request-preserveExisting
diff --git a/docs/java-rest/high-level/cluster/put_settings.asciidoc b/docs/java-rest/high-level/cluster/put_settings.asciidoc
index 74b479faa0501..dc9b1679d4717 100644
--- a/docs/java-rest/high-level/cluster/put_settings.asciidoc
+++ b/docs/java-rest/high-level/cluster/put_settings.asciidoc
@@ -54,13 +54,6 @@ include-tagged::{doc-tests}/ClusterClientDocumentationIT.java[put-settings-setti
==== Optional Arguments
The following arguments can optionally be provided:
-["source","java",subs="attributes,callouts,macros"]
---------------------------------------------------
-include-tagged::{doc-tests}/ClusterClientDocumentationIT.java[put-settings-request-flat-settings]
---------------------------------------------------
-<1> Whether the updated settings returned in the `ClusterUpdateSettings` should
-be in a flat format
-
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/ClusterClientDocumentationIT.java[put-settings-request-timeout]
diff --git a/docs/java-rest/high-level/indices/indices_exists.asciidoc b/docs/java-rest/high-level/indices/indices_exists.asciidoc
index 4a227db49ed8c..ee744e97ce8bd 100644
--- a/docs/java-rest/high-level/indices/indices_exists.asciidoc
+++ b/docs/java-rest/high-level/indices/indices_exists.asciidoc
@@ -23,8 +23,7 @@ include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[indices-exists-req
<1> Whether to return local information or retrieve the state from master node
<2> Return result in a format suitable for humans
<3> Whether to return all default setting for each of the indices
-<4> Return settings in flat format
-<5> Controls how unavailable indices are resolved and how wildcard expressions are expanded
+<4> Controls how unavailable indices are resolved and how wildcard expressions are expanded
[[java-rest-high-indices-sync]]
==== Synchronous Execution
diff --git a/docs/java-rest/high-level/indices/put_settings.asciidoc b/docs/java-rest/high-level/indices/put_settings.asciidoc
index 49312da82a400..c305eeaa0965b 100644
--- a/docs/java-rest/high-level/indices/put_settings.asciidoc
+++ b/docs/java-rest/high-level/indices/put_settings.asciidoc
@@ -55,13 +55,6 @@ include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[put-settings-setti
==== Optional Arguments
The following arguments can optionally be provided:
-["source","java",subs="attributes,callouts,macros"]
---------------------------------------------------
-include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[put-settings-request-flat-settings]
---------------------------------------------------
-<1> Whether the updated settings returned in the `UpdateSettings` should
-be in a flat format
-
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[put-settings-request-preserveExisting]
diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/settings/ClusterUpdateSettingsRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/settings/ClusterUpdateSettingsRequest.java
index 38d3a9d5caf54..f13c30c53503b 100644
--- a/server/src/main/java/org/elasticsearch/action/admin/cluster/settings/ClusterUpdateSettingsRequest.java
+++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/settings/ClusterUpdateSettingsRequest.java
@@ -58,7 +58,6 @@ public class ClusterUpdateSettingsRequest extends AcknowledgedRequest r.transientSettings = t, (p, c) -> Settings.fromXContent(p), TRANSIENT);
}
- private boolean flatSettings = false;
private Settings transientSettings = EMPTY_SETTINGS;
private Settings persistentSettings = EMPTY_SETTINGS;
@@ -74,29 +73,6 @@ public ActionRequestValidationException validate() {
return validationException;
}
- /**
- * Sets the value of "flat_settings".
- * Used only by the high-level REST client.
- *
- * @param flatSettings
- * value of "flat_settings" flag to be set
- * @return this request
- */
- public ClusterUpdateSettingsRequest flatSettings(boolean flatSettings) {
- this.flatSettings = flatSettings;
- return this;
- }
-
- /**
- * Return settings in flat format.
- * Used only by the high-level REST client.
- *
- * @return true
if settings need to be returned in flat format; false
otherwise.
- */
- public boolean flatSettings() {
- return flatSettings;
- }
-
public Settings transientSettings() {
return transientSettings;
}
diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/get/GetIndexRequest.java b/server/src/main/java/org/elasticsearch/action/admin/indices/get/GetIndexRequest.java
index 333d339979263..1f1a7595ed46b 100644
--- a/server/src/main/java/org/elasticsearch/action/admin/indices/get/GetIndexRequest.java
+++ b/server/src/main/java/org/elasticsearch/action/admin/indices/get/GetIndexRequest.java
@@ -66,7 +66,6 @@ public static Feature fromId(byte id) {
private static final Feature[] DEFAULT_FEATURES = new Feature[] { Feature.ALIASES, Feature.MAPPINGS, Feature.SETTINGS };
private Feature[] features = DEFAULT_FEATURES;
private boolean humanReadable = false;
- private transient boolean flatSettings = false;
private transient boolean includeDefaults = false;
public GetIndexRequest features(Feature... features) {
@@ -104,28 +103,6 @@ public boolean humanReadable() {
return humanReadable;
}
- /**
- * Sets the value of "flat_settings".
- * Used only by the high-level REST client.
- *
- * @param flatSettings value of "flat_settings" flag to be set
- * @return this request
- */
- public GetIndexRequest flatSettings(boolean flatSettings) {
- this.flatSettings = flatSettings;
- return this;
- }
-
- /**
- * Return settings in flat format.
- * Used only by the high-level REST client.
- *
- * @return true
if settings need to be returned in flat format; false
otherwise.
- */
- public boolean flatSettings() {
- return flatSettings;
- }
-
/**
* Sets the value of "include_defaults".
* Used only by the high-level REST client.
diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/settings/put/UpdateSettingsRequest.java b/server/src/main/java/org/elasticsearch/action/admin/indices/settings/put/UpdateSettingsRequest.java
index 594564b681562..18c7d506c7275 100644
--- a/server/src/main/java/org/elasticsearch/action/admin/indices/settings/put/UpdateSettingsRequest.java
+++ b/server/src/main/java/org/elasticsearch/action/admin/indices/settings/put/UpdateSettingsRequest.java
@@ -55,7 +55,6 @@ public class UpdateSettingsRequest extends AcknowledgedRequesttrue if settings need to be returned in flat format; false
otherwise.
- */
- public boolean flatSettings() {
- return flatSettings;
- }
-
@Override
public ActionRequestValidationException validate() {
ActionRequestValidationException validationException = null;
diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/settings/put/UpdateSettingsRequestStreamableTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/settings/put/UpdateSettingsRequestStreamableTests.java
index 463049a8c3c1f..114af3c13e707 100644
--- a/server/src/test/java/org/elasticsearch/action/admin/indices/settings/put/UpdateSettingsRequestStreamableTests.java
+++ b/server/src/test/java/org/elasticsearch/action/admin/indices/settings/put/UpdateSettingsRequestStreamableTests.java
@@ -67,7 +67,6 @@ public static UpdateSettingsRequest createTestItem() {
request.timeout(randomTimeValue());
request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean()));
request.setPreserveExisting(randomBoolean());
- request.flatSettings(randomBoolean());
return request;
}
@@ -77,7 +76,6 @@ private static UpdateSettingsRequest copyRequest(UpdateSettingsRequest request)
result.timeout(request.timeout());
result.indicesOptions(request.indicesOptions());
result.setPreserveExisting(request.isPreserveExisting());
- result.flatSettings(request.flatSettings());
return result;
}
From bdb69a054c025be24ea9ef9359bbe55d333a7fec Mon Sep 17 00:00:00 2001
From: Zachary Tong
Date: Tue, 17 Apr 2018 17:33:18 +0000
Subject: [PATCH 03/15] [TEST] test against scaled value instead of fixed
epsilon in MovAvgIT
When comparing doubles, fixed epsilons can fail because the absolute
difference in values may be quite large, even though the relative
difference is tiny (e.g. with two very large numbers).
Instead, we can scale epsilon by the absolute value of the expected
value. This means we are looking for a diff that is epsilon-percent
away from the value, rather than just epsilon.
This is basically checking the relative error using junit's assertEqual.
This commit is a backport of the changes in #29409 (removing the c/p
snippet) and the test fix in cfc9d12acc3ffc6748108d3ce2749d4f5bf4ed41
---
.../pipeline/moving/avg/MovAvgIT.java | 29 +++----------------
1 file changed, 4 insertions(+), 25 deletions(-)
diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgIT.java b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgIT.java
index bbe6ecc3a4e68..a476f2a714552 100644
--- a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgIT.java
+++ b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgIT.java
@@ -1292,8 +1292,8 @@ private void assertBucketContents(Histogram.Bucket actual, Double expectedCount,
assertThat("[_count] movavg should be NaN, but is ["+countMovAvg.value()+"] instead", countMovAvg.value(), equalTo(Double.NaN));
} else {
assertThat("[_count] movavg is null", countMovAvg, notNullValue());
- assertTrue("[_count] movavg does not match expected [" + countMovAvg.value() + " vs " + expectedCount + "]",
- nearlyEqual(countMovAvg.value(), expectedCount, 0.1));
+ assertEquals("[_count] movavg does not match expected [" + countMovAvg.value() + " vs " + expectedCount + "]",
+ countMovAvg.value(), expectedCount, 0.1 * Math.abs(countMovAvg.value()));
}
// This is a gap bucket
@@ -1304,29 +1304,8 @@ private void assertBucketContents(Histogram.Bucket actual, Double expectedCount,
assertThat("[value] movavg should be NaN, but is ["+valuesMovAvg.value()+"] instead", valuesMovAvg.value(), equalTo(Double.NaN));
} else {
assertThat("[value] movavg is null", valuesMovAvg, notNullValue());
- assertTrue("[value] movavg does not match expected [" + valuesMovAvg.value() + " vs " + expectedValue + "]",
- nearlyEqual(valuesMovAvg.value(), expectedValue, 0.1));
- }
- }
-
- /**
- * Better floating point comparisons courtesy of https://github.com/brazzy/floating-point-gui.de
- *
- * Snippet adapted to use doubles instead of floats
- */
- private static boolean nearlyEqual(double a, double b, double epsilon) {
- final double absA = Math.abs(a);
- final double absB = Math.abs(b);
- final double diff = Math.abs(a - b);
-
- if (a == b) { // shortcut, handles infinities
- return true;
- } else if (a == 0 || b == 0 || diff < Double.MIN_NORMAL) {
- // a or b is zero or both are extremely close to it
- // relative error is less meaningful here
- return diff < (epsilon * Double.MIN_NORMAL);
- } else { // use relative error
- return diff / Math.min((absA + absB), Double.MAX_VALUE) < epsilon;
+ assertEquals("[value] movavg does not match expected [" + valuesMovAvg.value() + " vs " + expectedValue + "]",
+ valuesMovAvg.value(), expectedValue, 0.1 * Math.abs(countMovAvg.value()));
}
}
From 36740f66b70f5b4397fa693d7fbf71eea59cbae4 Mon Sep 17 00:00:00 2001
From: Julie Tibshirani
Date: Tue, 17 Apr 2018 14:27:30 -0700
Subject: [PATCH 04/15] Fix the version ID for v5.6.10.
(cherry picked from commit 64a98cd575fa6013c5d22c9155f4240d7ea71a77)
---
server/src/main/java/org/elasticsearch/Version.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/server/src/main/java/org/elasticsearch/Version.java b/server/src/main/java/org/elasticsearch/Version.java
index 490a230976047..a2be7de6ff3e5 100644
--- a/server/src/main/java/org/elasticsearch/Version.java
+++ b/server/src/main/java/org/elasticsearch/Version.java
@@ -117,7 +117,7 @@ public class Version implements Comparable, ToXContentFragment {
public static final Version V_5_6_8 = new Version(V_5_6_8_ID, org.apache.lucene.util.Version.LUCENE_6_6_1);
public static final int V_5_6_9_ID = 5060999;
public static final Version V_5_6_9 = new Version(V_5_6_9_ID, org.apache.lucene.util.Version.LUCENE_6_6_1);
- public static final int V_5_6_10_ID = 50601099;
+ public static final int V_5_6_10_ID = 5061099;
public static final Version V_5_6_10 = new Version(V_5_6_10_ID, org.apache.lucene.util.Version.LUCENE_6_6_1);
public static final int V_6_0_0_alpha1_ID = 6000001;
public static final Version V_6_0_0_alpha1 = new Version(V_6_0_0_alpha1_ID, org.apache.lucene.util.Version.LUCENE_7_0_0);
From afad63406dd9cede2a07329022c0c0fc2a5ccb36 Mon Sep 17 00:00:00 2001
From: Jim Ferenczi
Date: Wed, 18 Apr 2018 10:54:45 +0200
Subject: [PATCH 05/15] Mutes failing MovAvgIT tests
Relates #29456
---
.../search/aggregations/pipeline/moving/avg/MovAvgIT.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgIT.java b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgIT.java
index a476f2a714552..93e2b26834286 100644
--- a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgIT.java
+++ b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgIT.java
@@ -68,6 +68,7 @@
import static org.hamcrest.core.IsNull.nullValue;
@ESIntegTestCase.SuiteScopeTestCase
+@LuceneTestCase.AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/29456")
public class MovAvgIT extends ESIntegTestCase {
private static final String INTERVAL_FIELD = "l_value";
private static final String VALUE_FIELD = "v_value";
From f1579423c77c168c87a3485f4bf5bd5543a7d7d5 Mon Sep 17 00:00:00 2001
From: Jim Ferenczi
Date: Wed, 18 Apr 2018 11:45:13 +0200
Subject: [PATCH 06/15] Add missing import in MovAvgIT
Relates #29456
---
.../search/aggregations/pipeline/moving/avg/MovAvgIT.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgIT.java b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgIT.java
index 93e2b26834286..76646c62a5eb2 100644
--- a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgIT.java
+++ b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgIT.java
@@ -19,6 +19,7 @@
package org.elasticsearch.search.aggregations.pipeline.moving.avg;
+import org.apache.lucene.util.LuceneTestCase;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
From 8b0b74d3519c0e35cab47556f778336c8fcb5627 Mon Sep 17 00:00:00 2001
From: Clinton Gormley
Date: Wed, 18 Apr 2018 12:40:44 +0200
Subject: [PATCH 07/15] Added release notes for 6.2.4
---
docs/reference/release-notes.asciidoc | 1 +
docs/reference/release-notes/6.2.4.asciidoc | 41 +++++++++++++++++++++
2 files changed, 42 insertions(+)
create mode 100644 docs/reference/release-notes/6.2.4.asciidoc
diff --git a/docs/reference/release-notes.asciidoc b/docs/reference/release-notes.asciidoc
index 95171f989396d..1902ced7356c5 100644
--- a/docs/reference/release-notes.asciidoc
+++ b/docs/reference/release-notes.asciidoc
@@ -5,6 +5,7 @@
--
This section summarizes the changes in each release.
+* <>
* <>
* <>
* <>
diff --git a/docs/reference/release-notes/6.2.4.asciidoc b/docs/reference/release-notes/6.2.4.asciidoc
new file mode 100644
index 0000000000000..38d796a00d63f
--- /dev/null
+++ b/docs/reference/release-notes/6.2.4.asciidoc
@@ -0,0 +1,41 @@
+[[release-notes-6.2.4]]
+== 6.2.4 Release Notes
+
+Also see <>.
+
+[[bug-6.2.4]]
+[float]
+=== Bug fixes
+
+Engine::
+* Harden periodically check to avoid endless flush loop {pull}29125[#29125] (issues: {issue}28350[#28350], {issue}29097[#29097])
+
+Ingest::
+* Don't allow referencing the pattern bank name in the pattern bank {pull}29295[#29295] (issue: {issue}29257[#29257])
+
+Java High Level REST Client::
+* Bulk processor#awaitClose to close scheduler {pull}29263[#29263]
+
+Java Low Level REST Client::
+* REST client: hosts marked dead for the first time should not be immediately retried {pull}29230[#29230]
+
+Network::
+* Cross-cluster search and default connections can get crossed [OPEN] [ISSUE] {pull}29321[#29321]
+
+Percolator::
+* Fixed bug when non percolator docs end up in the search hits {pull}29447[#29447] (issue: {issue}29429[#29429])
+* Fixed a msm accounting error that can occur during analyzing a percolator query {pull}29415[#29415] (issue: {issue}29393[#29393])
+* Fix more query extraction bugs. {pull}29388[#29388] (issues: {issue}28353[#28353], {issue}29376[#29376])
+* Fix some query extraction bugs. {pull}29283[#29283]
+
+Plugins::
+* Plugins: Fix native controller confirmation for non-meta plugin {pull}29434[#29434]
+
+Search::
+* Propagate ignore_unmapped to inner_hits {pull}29261[#29261] (issue: {issue}29071[#29071])
+
+Settings::
+* Archive unknown or invalid settings on updates {pull}28888[#28888] (issue: {issue}28609[#28609])
+
+
+
From 303efdee4836b874b81b1cd7b67548acc152e100 Mon Sep 17 00:00:00 2001
From: Clinton Gormley
Date: Wed, 18 Apr 2018 12:47:55 +0200
Subject: [PATCH 08/15] Added missing include for release notes
---
docs/reference/release-notes.asciidoc | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/reference/release-notes.asciidoc b/docs/reference/release-notes.asciidoc
index 1902ced7356c5..af65ba177cb10 100644
--- a/docs/reference/release-notes.asciidoc
+++ b/docs/reference/release-notes.asciidoc
@@ -19,6 +19,7 @@ This section summarizes the changes in each release.
* <>
--
+include::release-notes/6.2.4.asciidoc[]
include::release-notes/6.2.3.asciidoc[]
include::release-notes/6.2.2.asciidoc[]
include::release-notes/6.2.1.asciidoc[]
From 98a5019d3c4ae54437c4e765d766ce3e848c2584 Mon Sep 17 00:00:00 2001
From: Jason Tedor
Date: Wed, 18 Apr 2018 08:43:43 -0400
Subject: [PATCH 09/15] Fix full cluster restart test recovery (#29545)
The test was using a parameter on GET /_cluster/health that older nodes
do not understand. Yet, we do no even need to make this call here, we
can use ensure green for the index.
---
.../org/elasticsearch/upgrades/FullClusterRestartIT.java | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/qa/full-cluster-restart/src/test/java/org/elasticsearch/upgrades/FullClusterRestartIT.java b/qa/full-cluster-restart/src/test/java/org/elasticsearch/upgrades/FullClusterRestartIT.java
index 1f6abd90a441e..54e2d88dde769 100644
--- a/qa/full-cluster-restart/src/test/java/org/elasticsearch/upgrades/FullClusterRestartIT.java
+++ b/qa/full-cluster-restart/src/test/java/org/elasticsearch/upgrades/FullClusterRestartIT.java
@@ -699,8 +699,7 @@ public void testEmptyShard() throws IOException {
* Tests recovery of an index with or without a translog and the
* statistics we gather about that.
*/
- @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/29544")
- public void testRecovery() throws IOException {
+ public void testRecovery() throws Exception {
int count;
boolean shouldHaveTranslog;
if (runningAgainstOldCluster) {
@@ -713,7 +712,7 @@ public void testRecovery() throws IOException {
indexRandomDocuments(count, true, true, i -> jsonBuilder().startObject().field("field", "value").endObject());
// make sure all recoveries are done
- ensureNoInitializingShards();
+ ensureGreen(index);
// Explicitly flush so we're sure to have a bunch of documents in the Lucene index
client().performRequest("POST", "/_flush");
if (shouldHaveTranslog) {
From 24674777acbb59bbdb5f000542a3f5acf585dd0c Mon Sep 17 00:00:00 2001
From: Jim Ferenczi
Date: Wed, 18 Apr 2018 13:01:06 +0200
Subject: [PATCH 10/15] Fix binary doc values fetching in _search (#29567)
Binary doc values are retrieved during the DocValueFetchSubPhase through an instance of ScriptDocValues.
Since 6.0 ScriptDocValues instances are not allowed to reuse the object that they return (https://github.com/elastic/elasticsearch/issues/26775) but BinaryScriptDocValues doesn't follow this restriction and reuses instances of BytesRefBuilder among different documents.
This results in `field` values assigned to the wrong document in the response.
This commit fixes this issue by recreating the BytesRef for each value that needs to be returned.
Fixes #29565
---
.../index/fielddata/ScriptDocValues.java | 16 ++++++--
.../fielddata/BinaryDVFieldDataTests.java | 37 ++++++++++---------
2 files changed, 33 insertions(+), 20 deletions(-)
diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java b/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java
index 552ddbf9d616d..01f6bc192988c 100644
--- a/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java
+++ b/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java
@@ -633,7 +633,12 @@ public String get(int index) {
public BytesRef getBytesValue() {
if (size() > 0) {
- return values[0].get();
+ /**
+ * We need to make a copy here because {@link BinaryScriptDocValues} might reuse the
+ * returned value and the same instance might be used to
+ * return values from multiple documents.
+ **/
+ return values[0].toBytesRef();
} else {
return null;
}
@@ -658,14 +663,19 @@ public BytesRefs(SortedBinaryDocValues in) {
@Override
public BytesRef get(int index) {
- return values[index].get();
+ /**
+ * We need to make a copy here because {@link BinaryScriptDocValues} might reuse the
+ * returned value and the same instance might be used to
+ * return values from multiple documents.
+ **/
+ return values[index].toBytesRef();
}
public BytesRef getValue() {
if (count == 0) {
return new BytesRef();
}
- return values[0].get();
+ return values[0].toBytesRef();
}
}
diff --git a/server/src/test/java/org/elasticsearch/index/fielddata/BinaryDVFieldDataTests.java b/server/src/test/java/org/elasticsearch/index/fielddata/BinaryDVFieldDataTests.java
index 7f407dd1c01d1..3b29d15bf3fb2 100644
--- a/server/src/test/java/org/elasticsearch/index/fielddata/BinaryDVFieldDataTests.java
+++ b/server/src/test/java/org/elasticsearch/index/fielddata/BinaryDVFieldDataTests.java
@@ -52,7 +52,6 @@ public void testDocValue() throws Exception {
final DocumentMapper mapper = mapperService.documentMapperParser().parse("test", new CompressedXContent(mapping));
-
List bytesList1 = new ArrayList<>(2);
bytesList1.add(randomBytes());
bytesList1.add(randomBytes());
@@ -123,22 +122,26 @@ public void testDocValue() throws Exception {
// Test whether ScriptDocValues.BytesRefs makes a deepcopy
fieldData = indexFieldData.load(reader);
ScriptDocValues> scriptValues = fieldData.getScriptValues();
- scriptValues.setNextDocId(0);
- assertEquals(2, scriptValues.size());
- assertEquals(bytesList1.get(0), scriptValues.get(0));
- assertEquals(bytesList1.get(1), scriptValues.get(1));
-
- scriptValues.setNextDocId(1);
- assertEquals(1, scriptValues.size());
- assertEquals(bytes1, scriptValues.get(0));
-
- scriptValues.setNextDocId(2);
- assertEquals(0, scriptValues.size());
-
- scriptValues.setNextDocId(3);
- assertEquals(2, scriptValues.size());
- assertEquals(bytesList2.get(0), scriptValues.get(0));
- assertEquals(bytesList2.get(1), scriptValues.get(1));
+ Object[][] retValues = new BytesRef[4][0];
+ for (int i = 0; i < 4; i++) {
+ scriptValues.setNextDocId(i);
+ retValues[i] = new BytesRef[scriptValues.size()];
+ for (int j = 0; j < retValues[i].length; j++) {
+ retValues[i][j] = scriptValues.get(j);
+ }
+ }
+ assertEquals(2, retValues[0].length);
+ assertEquals(bytesList1.get(0), retValues[0][0]);
+ assertEquals(bytesList1.get(1), retValues[0][1]);
+
+ assertEquals(1, retValues[1].length);
+ assertEquals(bytes1, retValues[1][0]);
+
+ assertEquals(0, retValues[2].length);
+
+ assertEquals(2, retValues[3].length);
+ assertEquals(bytesList2.get(0), retValues[3][0]);
+ assertEquals(bytesList2.get(1), retValues[3][1]);
}
private static BytesRef randomBytes() {
From 79425ec76d88f389a7674f9181f664c79ff6d7e2 Mon Sep 17 00:00:00 2001
From: Jim Ferenczi
Date: Wed, 18 Apr 2018 15:13:24 +0200
Subject: [PATCH 11/15] Remove extra copy in ScriptDocValues.Strings
This commit removes a BytesRef copy introduced in #29567 and not
required.
Relates #29567
---
.../index/fielddata/ScriptDocValues.java | 26 ++-----------------
1 file changed, 2 insertions(+), 24 deletions(-)
diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java b/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java
index 01f6bc192988c..3d07a0f87aa5e 100644
--- a/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java
+++ b/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java
@@ -631,28 +631,9 @@ public String get(int index) {
return values[index].get().utf8ToString();
}
- public BytesRef getBytesValue() {
- if (size() > 0) {
- /**
- * We need to make a copy here because {@link BinaryScriptDocValues} might reuse the
- * returned value and the same instance might be used to
- * return values from multiple documents.
- **/
- return values[0].toBytesRef();
- } else {
- return null;
- }
- }
-
public String getValue() {
- BytesRef value = getBytesValue();
- if (value == null) {
- return null;
- } else {
- return value.utf8ToString();
- }
+ return count == 0 ? null : get(0);
}
-
}
public static final class BytesRefs extends BinaryScriptDocValues {
@@ -672,10 +653,7 @@ public BytesRef get(int index) {
}
public BytesRef getValue() {
- if (count == 0) {
- return new BytesRef();
- }
- return values[0].toBytesRef();
+ return count == 0 ? new BytesRef() : get(0);
}
}
From 6c3e16c8b7d40c553ffbee6a5dc077e205ed610c Mon Sep 17 00:00:00 2001
From: Paul Sanwald
Date: Wed, 18 Apr 2018 07:42:05 -0700
Subject: [PATCH 12/15] Add a CHANGELOG file for release notes. (#29450)
* Add a CHANGELOG file for 7.x release notes.
* update file to include 6.x
* remove confusing comment and small edit to section title
* moving CHANGELOG file under docs directory, as it pertains to release notes.
---
.gitattributes | 1 +
docs/CHANGELOG.asciidoc | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+)
create mode 100644 .gitattributes
create mode 100644 docs/CHANGELOG.asciidoc
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000000..0c4d2c9b20b63
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+CHANGELOG.asciidoc merge=union
diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc
new file mode 100644
index 0000000000000..9c6e36a2e1d0d
--- /dev/null
+++ b/docs/CHANGELOG.asciidoc
@@ -0,0 +1,38 @@
+// Use these for links to issue and pulls. Note issues and pulls redirect one to
+// each other on Github, so don't worry too much on using the right prefix.
+// :issue: https://github.com/elastic/elasticsearch/issues/
+// :pull: https://github.com/elastic/elasticsearch/pull/
+
+= Elasticsearch Release Notes
+
+== Elasticsearch 7.0.0
+
+=== Breaking Changes
+
+=== Breaking Java Changes
+
+=== Deprecations
+
+=== New Features
+
+=== Enhancements
+
+=== Bug Fixes
+
+=== Regressions
+
+=== Known Issues
+
+== Elasticsearch version 6.3.0
+
+=== New Features
+
+=== Enhancements
+
+=== Bug Fixes
+
+=== Regressions
+
+=== Known Issues
+
+
From 771a0399f0a6eb0ea6b6d4b876cc06f416982c20 Mon Sep 17 00:00:00 2001
From: Nhat Nguyen
Date: Tue, 17 Apr 2018 08:03:41 -0400
Subject: [PATCH 13/15] Enforce translog access via engine (#29542)
Today the translog of an engine is exposed and can be accessed directly.
While this exposure offers much flexibility, it also causes these troubles:
- Inconsistent behavior between translog method and engine method.
For example, rolling a translog generation via an engine also trims
unreferenced files, but translog's method does not.
- An engine does not get notified when critical errors happen in translog
as the access is direct.
This change isolates translog of an engine and enforces all accesses to
translog via the engine.
---
.../org/elasticsearch/index/IndexService.java | 3 +-
.../elasticsearch/index/engine/Engine.java | 62 ++++++++++++++++++-
.../index/engine/InternalEngine.java | 2 +-
.../seqno/GlobalCheckpointSyncAction.java | 2 +-
.../elasticsearch/index/shard/IndexShard.java | 46 +++++++++++---
.../index/shard/PrimaryReplicaSyncer.java | 2 +-
.../index/shard/RefreshListeners.java | 10 +--
.../recovery/RecoverySourceHandler.java | 13 ++--
.../index/IndexServiceTests.java | 6 +-
.../ESIndexLevelReplicationTestCase.java | 2 +-
.../IndexLevelReplicationTests.java | 8 +--
.../RecoveryDuringReplicationTests.java | 6 +-
.../GlobalCheckpointSyncActionTests.java | 5 +-
.../index/shard/IndexShardIT.java | 11 ++--
.../index/shard/IndexShardTests.java | 25 ++++----
.../index/shard/RefreshListenersTests.java | 2 +-
.../PeerRecoveryTargetServiceTests.java | 4 +-
.../indices/recovery/RecoveryTests.java | 22 +++----
.../index/engine/EngineTestCase.java | 7 +++
.../index/shard/IndexShardTestCase.java | 6 ++
.../test/InternalTestCluster.java | 3 +-
21 files changed, 169 insertions(+), 78 deletions(-)
diff --git a/server/src/main/java/org/elasticsearch/index/IndexService.java b/server/src/main/java/org/elasticsearch/index/IndexService.java
index b46374a383681..256376eec2a11 100644
--- a/server/src/main/java/org/elasticsearch/index/IndexService.java
+++ b/server/src/main/java/org/elasticsearch/index/IndexService.java
@@ -675,8 +675,7 @@ private void maybeFSyncTranslogs() {
if (indexSettings.getTranslogDurability() == Translog.Durability.ASYNC) {
for (IndexShard shard : this.shards.values()) {
try {
- Translog translog = shard.getTranslog();
- if (translog.syncNeeded()) {
+ if (shard.isSyncNeeded()) {
shard.sync();
}
} catch (AlreadyClosedException ex) {
diff --git a/server/src/main/java/org/elasticsearch/index/engine/Engine.java b/server/src/main/java/org/elasticsearch/index/engine/Engine.java
index d6d62465d3f9b..a3265c866e793 100644
--- a/server/src/main/java/org/elasticsearch/index/engine/Engine.java
+++ b/server/src/main/java/org/elasticsearch/index/engine/Engine.java
@@ -66,6 +66,7 @@
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.store.Store;
import org.elasticsearch.index.translog.Translog;
+import org.elasticsearch.index.translog.TranslogStats;
import java.io.Closeable;
import java.io.FileNotFoundException;
@@ -510,8 +511,18 @@ public enum SearcherScope {
EXTERNAL, INTERNAL
}
- /** returns the translog for this engine */
- public abstract Translog getTranslog();
+ /**
+ * Returns the translog associated with this engine.
+ * Prefer to keep the translog package-private, so that an engine can control all accesses to the translog.
+ */
+ abstract Translog getTranslog();
+
+ /**
+ * Checks if the underlying storage sync is required.
+ */
+ public boolean isTranslogSyncNeeded() {
+ return getTranslog().syncNeeded();
+ }
/**
* Ensures that all locations in the given stream have been written to the underlying storage.
@@ -520,6 +531,36 @@ public enum SearcherScope {
public abstract void syncTranslog() throws IOException;
+ public Closeable acquireTranslogRetentionLock() {
+ return getTranslog().acquireRetentionLock();
+ }
+
+ /**
+ * Creates a new translog snapshot from this engine for reading translog operations whose seq# at least the provided seq#.
+ * The caller has to close the returned snapshot after finishing the reading.
+ */
+ public Translog.Snapshot newTranslogSnapshotFromMinSeqNo(long minSeqNo) throws IOException {
+ return getTranslog().newSnapshotFromMinSeqNo(minSeqNo);
+ }
+
+ /**
+ * Returns the estimated number of translog operations in this engine whose seq# at least the provided seq#.
+ */
+ public int estimateTranslogOperationsFromMinSeq(long minSeqNo) {
+ return getTranslog().estimateTotalOperationsFromMinSeq(minSeqNo);
+ }
+
+ public TranslogStats getTranslogStats() {
+ return getTranslog().stats();
+ }
+
+ /**
+ * Returns the last location that the translog of this engine has written into.
+ */
+ public Translog.Location getTranslogLastWriteLocation() {
+ return getTranslog().getLastWriteLocation();
+ }
+
protected final void ensureOpen(Exception suppressed) {
if (isClosed.get()) {
AlreadyClosedException ace = new AlreadyClosedException(shardId + " engine is closed", failedEngine.get());
@@ -546,6 +587,13 @@ public CommitStats commitStats() {
*/
public abstract LocalCheckpointTracker getLocalCheckpointTracker();
+ /**
+ * Returns the latest global checkpoint value that has been persisted in the underlying storage (i.e. translog's checkpoint)
+ */
+ public long getLastSyncedGlobalCheckpoint() {
+ return getTranslog().getLastSyncedGlobalCheckpoint();
+ }
+
/**
* Global stats on segments.
*/
@@ -810,6 +858,16 @@ public final boolean refreshNeeded() {
*/
public abstract void trimTranslog() throws EngineException;
+ /**
+ * Tests whether or not the translog generation should be rolled to a new generation.
+ * This test is based on the size of the current generation compared to the configured generation threshold size.
+ *
+ * @return {@code true} if the current generation should be rolled to a new generation
+ */
+ public boolean shouldRollTranslogGeneration() {
+ return getTranslog().shouldRollGeneration();
+ }
+
/**
* Rolls the translog generation and cleans unneeded.
*/
diff --git a/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java b/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java
index 5839aafab9983..b5a1ec49b55e5 100644
--- a/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java
+++ b/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java
@@ -435,7 +435,7 @@ private Translog openTranslog(EngineConfig engineConfig, TranslogDeletionPolicy
}
@Override
- public Translog getTranslog() {
+ Translog getTranslog() {
ensureOpen();
return translog;
}
diff --git a/server/src/main/java/org/elasticsearch/index/seqno/GlobalCheckpointSyncAction.java b/server/src/main/java/org/elasticsearch/index/seqno/GlobalCheckpointSyncAction.java
index 0ec03cb7a8f5e..9b55cff8cff9a 100644
--- a/server/src/main/java/org/elasticsearch/index/seqno/GlobalCheckpointSyncAction.java
+++ b/server/src/main/java/org/elasticsearch/index/seqno/GlobalCheckpointSyncAction.java
@@ -131,7 +131,7 @@ protected ReplicaResult shardOperationOnReplica(final Request request, final Ind
private void maybeSyncTranslog(final IndexShard indexShard) throws IOException {
if (indexShard.getTranslogDurability() == Translog.Durability.REQUEST &&
- indexShard.getTranslog().getLastSyncedGlobalCheckpoint() < indexShard.getGlobalCheckpoint()) {
+ indexShard.getLastSyncedGlobalCheckpoint() < indexShard.getGlobalCheckpoint()) {
indexShard.sync();
}
}
diff --git a/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java b/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java
index d6422e7c693bd..44fc0938d390b 100644
--- a/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java
+++ b/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java
@@ -966,7 +966,7 @@ public FieldDataStats fieldDataStats(String... fields) {
}
public TranslogStats translogStats() {
- return getEngine().getTranslog().stats();
+ return getEngine().getTranslogStats();
}
public CompletionStats completionStats(String... fields) {
@@ -1366,7 +1366,7 @@ private boolean assertMaxUnsafeAutoIdInCommit() throws IOException {
}
protected void onNewEngine(Engine newEngine) {
- refreshListeners.setTranslog(newEngine.getTranslog());
+ refreshListeners.setCurrentRefreshLocationSupplier(newEngine::getTranslogLastWriteLocation);
}
/**
@@ -1598,8 +1598,7 @@ boolean shouldRollTranslogGeneration() {
final Engine engine = getEngineOrNull();
if (engine != null) {
try {
- final Translog translog = engine.getTranslog();
- return translog.shouldRollGeneration();
+ return engine.shouldRollTranslogGeneration();
} catch (final AlreadyClosedException e) {
// we are already closed, no need to flush or roll
}
@@ -1614,9 +1613,26 @@ public void onSettingsChanged() {
}
}
+ /**
+ * Acquires a lock on the translog files, preventing them from being trimmed.
+ */
public Closeable acquireTranslogRetentionLock() {
- Engine engine = getEngine();
- return engine.getTranslog().acquireRetentionLock();
+ return getEngine().acquireTranslogRetentionLock();
+ }
+
+ /**
+ * Creates a new translog snapshot for reading translog operations whose seq# at least the provided seq#.
+ * The caller has to close the returned snapshot after finishing the reading.
+ */
+ public Translog.Snapshot newTranslogSnapshotFromMinSeqNo(long minSeqNo) throws IOException {
+ return getEngine().newTranslogSnapshotFromMinSeqNo(minSeqNo);
+ }
+
+ /**
+ * Returns the estimated number of operations in translog whose seq# at least the provided seq#.
+ */
+ public int estimateTranslogOperationsFromMinSeq(long minSeqNo) {
+ return getEngine().estimateTranslogOperationsFromMinSeq(minSeqNo);
}
public List segments(boolean verbose) {
@@ -1627,10 +1643,6 @@ public void flushAndCloseEngine() throws IOException {
getEngine().flushAndClose();
}
- public Translog getTranslog() {
- return getEngine().getTranslog();
- }
-
public String getHistoryUUID() {
return getEngine().getHistoryUUID();
}
@@ -1768,6 +1780,13 @@ public long getGlobalCheckpoint() {
return replicationTracker.getGlobalCheckpoint();
}
+ /**
+ * Returns the latest global checkpoint value that has been persisted in the underlying storage (i.e. translog's checkpoint)
+ */
+ public long getLastSyncedGlobalCheckpoint() {
+ return getEngine().getLastSyncedGlobalCheckpoint();
+ }
+
/**
* Get the local knowledge of the global checkpoints for all in-sync allocation IDs.
*
@@ -2343,6 +2362,13 @@ public void sync() throws IOException {
getEngine().syncTranslog();
}
+ /**
+ * Checks if the underlying storage sync is required.
+ */
+ public boolean isSyncNeeded() {
+ return getEngine().isTranslogSyncNeeded();
+ }
+
/**
* Returns the current translog durability mode
*/
diff --git a/server/src/main/java/org/elasticsearch/index/shard/PrimaryReplicaSyncer.java b/server/src/main/java/org/elasticsearch/index/shard/PrimaryReplicaSyncer.java
index 1e31eae7d417f..af8c9bdd0272f 100644
--- a/server/src/main/java/org/elasticsearch/index/shard/PrimaryReplicaSyncer.java
+++ b/server/src/main/java/org/elasticsearch/index/shard/PrimaryReplicaSyncer.java
@@ -83,7 +83,7 @@ public void resync(final IndexShard indexShard, final ActionListener
ActionListener resyncListener = null;
try {
final long startingSeqNo = indexShard.getGlobalCheckpoint() + 1;
- Translog.Snapshot snapshot = indexShard.getTranslog().newSnapshotFromMinSeqNo(startingSeqNo);
+ Translog.Snapshot snapshot = indexShard.newTranslogSnapshotFromMinSeqNo(startingSeqNo);
resyncListener = new ActionListener() {
@Override
public void onResponse(final ResyncTask resyncTask) {
diff --git a/server/src/main/java/org/elasticsearch/index/shard/RefreshListeners.java b/server/src/main/java/org/elasticsearch/index/shard/RefreshListeners.java
index 17e824eb046c7..d8a51d58ad956 100644
--- a/server/src/main/java/org/elasticsearch/index/shard/RefreshListeners.java
+++ b/server/src/main/java/org/elasticsearch/index/shard/RefreshListeners.java
@@ -32,6 +32,7 @@
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.IntSupplier;
+import java.util.function.Supplier;
import static java.util.Objects.requireNonNull;
@@ -153,21 +154,20 @@ public int pendingCount() {
/**
* Setup the translog used to find the last refreshed location.
*/
- public void setTranslog(Translog translog) {
- this.translog = translog;
+ public void setCurrentRefreshLocationSupplier(Supplier currentRefreshLocationSupplier) {
+ this.currentRefreshLocationSupplier = currentRefreshLocationSupplier;
}
- // Implementation of ReferenceManager.RefreshListener that adapts Lucene's RefreshListener into Elasticsearch's refresh listeners.
- private Translog translog;
/**
* Snapshot of the translog location before the current refresh if there is a refresh going on or null. Doesn't have to be volatile
* because when it is used by the refreshing thread.
*/
private Translog.Location currentRefreshLocation;
+ private Supplier currentRefreshLocationSupplier;
@Override
public void beforeRefresh() throws IOException {
- currentRefreshLocation = translog.getLastWriteLocation();
+ currentRefreshLocation = currentRefreshLocationSupplier.get();
}
@Override
diff --git a/server/src/main/java/org/elasticsearch/indices/recovery/RecoverySourceHandler.java b/server/src/main/java/org/elasticsearch/indices/recovery/RecoverySourceHandler.java
index 710b4bc46e235..78f44ee723114 100644
--- a/server/src/main/java/org/elasticsearch/indices/recovery/RecoverySourceHandler.java
+++ b/server/src/main/java/org/elasticsearch/indices/recovery/RecoverySourceHandler.java
@@ -145,9 +145,6 @@ public RecoveryResponse recoverToTarget() throws IOException {
}, shardId + " validating recovery target ["+ request.targetAllocationId() + "] registered ");
try (Closeable ignored = shard.acquireTranslogRetentionLock()) {
-
- final Translog translog = shard.getTranslog();
-
final long startingSeqNo;
final long requiredSeqNoRangeStart;
final boolean isSequenceNumberBasedRecovery = request.startingSeqNo() != SequenceNumbers.UNASSIGNED_SEQ_NO &&
@@ -170,7 +167,7 @@ public RecoveryResponse recoverToTarget() throws IOException {
requiredSeqNoRangeStart =
Long.parseLong(phase1Snapshot.getIndexCommit().getUserData().get(SequenceNumbers.LOCAL_CHECKPOINT_KEY)) + 1;
try {
- phase1(phase1Snapshot.getIndexCommit(), translog::totalOperations);
+ phase1(phase1Snapshot.getIndexCommit(), () -> shard.estimateTranslogOperationsFromMinSeq(startingSeqNo));
} catch (final Exception e) {
throw new RecoveryEngineException(shard.shardId(), 1, "phase1 failed", e);
} finally {
@@ -187,7 +184,7 @@ public RecoveryResponse recoverToTarget() throws IOException {
try {
// For a sequence based recovery, the target can keep its local translog
- prepareTargetForTranslog(isSequenceNumberBasedRecovery == false, translog.estimateTotalOperationsFromMinSeq(startingSeqNo));
+ prepareTargetForTranslog(isSequenceNumberBasedRecovery == false, shard.estimateTranslogOperationsFromMinSeq(startingSeqNo));
} catch (final Exception e) {
throw new RecoveryEngineException(shard.shardId(), 1, "prepare target for translog failed", e);
}
@@ -210,9 +207,9 @@ public RecoveryResponse recoverToTarget() throws IOException {
logger.trace("all operations up to [{}] completed, which will be used as an ending sequence number", endingSeqNo);
- logger.trace("snapshot translog for recovery; current size is [{}]", translog.estimateTotalOperationsFromMinSeq(startingSeqNo));
+ logger.trace("snapshot translog for recovery; current size is [{}]", shard.estimateTranslogOperationsFromMinSeq(startingSeqNo));
final long targetLocalCheckpoint;
- try(Translog.Snapshot snapshot = translog.newSnapshotFromMinSeqNo(startingSeqNo)) {
+ try(Translog.Snapshot snapshot = shard.newTranslogSnapshotFromMinSeqNo(startingSeqNo)) {
targetLocalCheckpoint = phase2(startingSeqNo, requiredSeqNoRangeStart, endingSeqNo, snapshot);
} catch (Exception e) {
throw new RecoveryEngineException(shard.shardId(), 2, "phase2 failed", e);
@@ -261,7 +258,7 @@ boolean isTranslogReadyForSequenceNumberBasedRecovery() throws IOException {
// the start recovery request is initialized with the starting sequence number set to the target shard's local checkpoint plus one
if (startingSeqNo - 1 <= localCheckpoint) {
final LocalCheckpointTracker tracker = new LocalCheckpointTracker(startingSeqNo, startingSeqNo - 1);
- try (Translog.Snapshot snapshot = shard.getTranslog().newSnapshotFromMinSeqNo(startingSeqNo)) {
+ try (Translog.Snapshot snapshot = shard.newTranslogSnapshotFromMinSeqNo(startingSeqNo)) {
Translog.Operation operation;
while ((operation = snapshot.next()) != null) {
if (operation.seqNo() != SequenceNumbers.UNASSIGNED_SEQ_NO) {
diff --git a/server/src/test/java/org/elasticsearch/index/IndexServiceTests.java b/server/src/test/java/org/elasticsearch/index/IndexServiceTests.java
index 74d2a0961030e..7f798f7bb875a 100644
--- a/server/src/test/java/org/elasticsearch/index/IndexServiceTests.java
+++ b/server/src/test/java/org/elasticsearch/index/IndexServiceTests.java
@@ -229,7 +229,7 @@ public void testAsyncFsyncActuallyWorks() throws Exception {
client().prepareIndex("test", "test", "1").setSource("{\"foo\": \"bar\"}", XContentType.JSON).get();
IndexShard shard = indexService.getShard(0);
assertBusy(() -> {
- assertFalse(shard.getTranslog().syncNeeded());
+ assertFalse(shard.isSyncNeeded());
});
}
@@ -254,7 +254,7 @@ public void testRescheduleAsyncFsync() throws Exception {
client().prepareIndex("test", "test", "1").setSource("{\"foo\": \"bar\"}", XContentType.JSON).get();
assertNotNull(indexService.getFsyncTask());
final IndexShard shard = indexService.getShard(0);
- assertBusy(() -> assertFalse(shard.getTranslog().syncNeeded()));
+ assertBusy(() -> assertFalse(shard.isSyncNeeded()));
client()
.admin()
@@ -290,7 +290,7 @@ public void testAsyncTranslogTrimActuallyWorks() throws Exception {
indexService.updateMetaData(metaData);
IndexShard shard = indexService.getShard(0);
- assertBusy(() -> assertThat(shard.getTranslog().totalOperations(), equalTo(0)));
+ assertBusy(() -> assertThat(shard.estimateTranslogOperationsFromMinSeq(0L), equalTo(0)));
}
public void testIllegalFsyncInterval() {
diff --git a/server/src/test/java/org/elasticsearch/index/replication/ESIndexLevelReplicationTestCase.java b/server/src/test/java/org/elasticsearch/index/replication/ESIndexLevelReplicationTestCase.java
index 97fc1b528acf3..fd62318f96c3a 100644
--- a/server/src/test/java/org/elasticsearch/index/replication/ESIndexLevelReplicationTestCase.java
+++ b/server/src/test/java/org/elasticsearch/index/replication/ESIndexLevelReplicationTestCase.java
@@ -681,7 +681,7 @@ class GlobalCheckpointSync extends ReplicationAction<
@Override
protected PrimaryResult performOnPrimary(
final IndexShard primary, final GlobalCheckpointSyncAction.Request request) throws Exception {
- primary.getTranslog().sync();
+ primary.sync();
return new PrimaryResult(request, new ReplicationResponse());
}
diff --git a/server/src/test/java/org/elasticsearch/index/replication/IndexLevelReplicationTests.java b/server/src/test/java/org/elasticsearch/index/replication/IndexLevelReplicationTests.java
index baa56ee9585f6..2d2aaac7bbd26 100644
--- a/server/src/test/java/org/elasticsearch/index/replication/IndexLevelReplicationTests.java
+++ b/server/src/test/java/org/elasticsearch/index/replication/IndexLevelReplicationTests.java
@@ -330,7 +330,7 @@ public void testSeqNoCollision() throws Exception {
final Translog.Operation op1;
final List initOperations = new ArrayList<>(initDocs);
- try (Translog.Snapshot snapshot = replica2.getTranslog().newSnapshot()) {
+ try (Translog.Snapshot snapshot = getTranslog(replica2).newSnapshot()) {
assertThat(snapshot.totalOperations(), equalTo(initDocs + 1));
for (int i = 0; i < initDocs; i++) {
Translog.Operation op = snapshot.next();
@@ -347,7 +347,7 @@ public void testSeqNoCollision() throws Exception {
shards.promoteReplicaToPrimary(replica1).get(); // wait until resync completed.
shards.index(new IndexRequest(index.getName(), "type", "d2").source("{}", XContentType.JSON));
final Translog.Operation op2;
- try (Translog.Snapshot snapshot = replica2.getTranslog().newSnapshot()) {
+ try (Translog.Snapshot snapshot = getTranslog(replica2).newSnapshot()) {
assertThat(snapshot.totalOperations(), equalTo(initDocs + 2));
op2 = snapshot.next();
assertThat(op2.seqNo(), equalTo(op1.seqNo()));
@@ -362,7 +362,7 @@ public void testSeqNoCollision() throws Exception {
shards.promoteReplicaToPrimary(replica2);
logger.info("--> Recover replica3 from replica2");
recoverReplica(replica3, replica2);
- try (Translog.Snapshot snapshot = replica3.getTranslog().newSnapshot()) {
+ try (Translog.Snapshot snapshot = getTranslog(replica3).newSnapshot()) {
assertThat(snapshot.totalOperations(), equalTo(initDocs + 1));
assertThat(snapshot.next(), equalTo(op2));
assertThat("Remaining of snapshot should contain init operations", snapshot, containsOperationsInAnyOrder(initOperations));
@@ -468,7 +468,7 @@ private static void assertNoOpTranslogOperationForDocumentFailure(
long expectedPrimaryTerm,
String failureMessage) throws IOException {
for (IndexShard indexShard : replicationGroup) {
- try(Translog.Snapshot snapshot = indexShard.getTranslog().newSnapshot()) {
+ try(Translog.Snapshot snapshot = getTranslog(indexShard).newSnapshot()) {
assertThat(snapshot.totalOperations(), equalTo(expectedOperation));
long expectedSeqNo = 0L;
Translog.Operation op = snapshot.next();
diff --git a/server/src/test/java/org/elasticsearch/index/replication/RecoveryDuringReplicationTests.java b/server/src/test/java/org/elasticsearch/index/replication/RecoveryDuringReplicationTests.java
index c7469f2432ad3..323b0364dfb93 100644
--- a/server/src/test/java/org/elasticsearch/index/replication/RecoveryDuringReplicationTests.java
+++ b/server/src/test/java/org/elasticsearch/index/replication/RecoveryDuringReplicationTests.java
@@ -128,7 +128,7 @@ public void testRecoveryOfDisconnectedReplica() throws Exception {
shards.flush();
translogTrimmed = randomBoolean();
if (translogTrimmed) {
- final Translog translog = shards.getPrimary().getTranslog();
+ final Translog translog = getTranslog(shards.getPrimary());
translog.getDeletionPolicy().setRetentionAgeInMillis(0);
translog.trimUnreferencedReaders();
}
@@ -271,7 +271,7 @@ public void testRecoveryAfterPrimaryPromotion() throws Exception {
// otherwise the deletion policy won't trim translog
assertBusy(() -> {
shards.syncGlobalCheckpoint();
- assertThat(newPrimary.getTranslog().getLastSyncedGlobalCheckpoint(), equalTo(newPrimary.seqNoStats().getMaxSeqNo()));
+ assertThat(newPrimary.getLastSyncedGlobalCheckpoint(), equalTo(newPrimary.seqNoStats().getMaxSeqNo()));
});
newPrimary.flush(new FlushRequest());
uncommittedOpsOnPrimary = shards.indexDocs(randomIntBetween(0, 10));
@@ -340,7 +340,7 @@ public void testReplicaRollbackStaleDocumentsInPeerRecovery() throws Exception {
// Index more docs - move the global checkpoint >= seqno of the stale operations.
goodDocs += shards.indexDocs(scaledRandomIntBetween(staleDocs, staleDocs * 5));
shards.syncGlobalCheckpoint();
- assertThat(replica.getTranslog().getLastSyncedGlobalCheckpoint(), equalTo(replica.seqNoStats().getMaxSeqNo()));
+ assertThat(replica.getLastSyncedGlobalCheckpoint(), equalTo(replica.seqNoStats().getMaxSeqNo()));
// Recover a replica again should also rollback the stale documents.
shards.removeReplica(replica);
replica.close("recover replica - second time", false);
diff --git a/server/src/test/java/org/elasticsearch/index/seqno/GlobalCheckpointSyncActionTests.java b/server/src/test/java/org/elasticsearch/index/seqno/GlobalCheckpointSyncActionTests.java
index 70813531aeb0e..596575abc3025 100644
--- a/server/src/test/java/org/elasticsearch/index/seqno/GlobalCheckpointSyncActionTests.java
+++ b/server/src/test/java/org/elasticsearch/index/seqno/GlobalCheckpointSyncActionTests.java
@@ -90,9 +90,6 @@ public void testTranslogSyncAfterGlobalCheckpointSync() throws Exception {
final Translog.Durability durability = randomFrom(Translog.Durability.ASYNC, Translog.Durability.REQUEST);
when(indexShard.getTranslogDurability()).thenReturn(durability);
- final Translog translog = mock(Translog.class);
- when(indexShard.getTranslog()).thenReturn(translog);
-
final long globalCheckpoint = randomIntBetween(Math.toIntExact(SequenceNumbers.NO_OPS_PERFORMED), Integer.MAX_VALUE);
final long lastSyncedGlobalCheckpoint;
if (randomBoolean() && globalCheckpoint != SequenceNumbers.NO_OPS_PERFORMED) {
@@ -104,7 +101,7 @@ public void testTranslogSyncAfterGlobalCheckpointSync() throws Exception {
}
when(indexShard.getGlobalCheckpoint()).thenReturn(globalCheckpoint);
- when(translog.getLastSyncedGlobalCheckpoint()).thenReturn(lastSyncedGlobalCheckpoint);
+ when(indexShard.getLastSyncedGlobalCheckpoint()).thenReturn(lastSyncedGlobalCheckpoint);
final GlobalCheckpointSyncAction action = new GlobalCheckpointSyncAction(
Settings.EMPTY,
diff --git a/server/src/test/java/org/elasticsearch/index/shard/IndexShardIT.java b/server/src/test/java/org/elasticsearch/index/shard/IndexShardIT.java
index de071563f4d00..e2e79368b2355 100644
--- a/server/src/test/java/org/elasticsearch/index/shard/IndexShardIT.java
+++ b/server/src/test/java/org/elasticsearch/index/shard/IndexShardIT.java
@@ -101,6 +101,7 @@
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
+import static org.elasticsearch.index.shard.IndexShardTestCase.getTranslog;
public class IndexShardIT extends ESSingleNodeTestCase {
@@ -161,7 +162,7 @@ public void testDurableFlagHasEffect() throws Exception {
IndicesService indicesService = getInstanceFromNode(IndicesService.class);
IndexService test = indicesService.indexService(resolveIndex("test"));
IndexShard shard = test.getShardOrNull(0);
- Translog translog = ShardUtilsTests.getShardEngine(shard).getTranslog();
+ Translog translog = getTranslog(shard);
Predicate needsSync = (tlog) -> {
// we can't use tlog.needsSync() here since it also takes the global checkpoint into account
// we explicitly want to check here if our durability checks are taken into account so we only
@@ -337,7 +338,7 @@ public void testMaybeFlush() throws Exception {
SourceToParse.source("test", "test", "1", new BytesArray("{}"), XContentType.JSON),
IndexRequest.UNSET_AUTO_GENERATED_TIMESTAMP, false, update -> {});
assertTrue(shard.shouldPeriodicallyFlush());
- final Translog translog = shard.getEngine().getTranslog();
+ final Translog translog = getTranslog(shard);
assertEquals(2, translog.stats().getUncommittedOperations());
client().prepareIndex("test", "test", "2").setSource("{}", XContentType.JSON)
.setRefreshPolicy(randomBoolean() ? IMMEDIATE : NONE).get();
@@ -378,7 +379,7 @@ public void testMaybeRollTranslogGeneration() throws Exception {
final IndexService test = indicesService.indexService(resolveIndex("test"));
final IndexShard shard = test.getShardOrNull(0);
int rolls = 0;
- final Translog translog = shard.getEngine().getTranslog();
+ final Translog translog = getTranslog(shard);
final long generation = translog.currentFileGeneration();
final int numberOfDocuments = randomIntBetween(32, 128);
for (int i = 0; i < numberOfDocuments; i++) {
@@ -448,11 +449,11 @@ public void testStressMaybeFlushOrRollTranslogGeneration() throws Exception {
assertThat(shard.flushStats().getPeriodic(), equalTo(periodic + 1));
};
} else {
- final long generation = shard.getEngine().getTranslog().currentFileGeneration();
+ final long generation = getTranslog(shard).currentFileGeneration();
client().prepareIndex("test", "test", "1").setSource("{}", XContentType.JSON).get();
check = () -> assertEquals(
generation + 1,
- shard.getEngine().getTranslog().currentFileGeneration());
+ getTranslog(shard).currentFileGeneration());
}
assertBusy(check);
running.set(false);
diff --git a/server/src/test/java/org/elasticsearch/index/shard/IndexShardTests.java b/server/src/test/java/org/elasticsearch/index/shard/IndexShardTests.java
index ac3349d6bf9ef..d7e3e75ffff52 100644
--- a/server/src/test/java/org/elasticsearch/index/shard/IndexShardTests.java
+++ b/server/src/test/java/org/elasticsearch/index/shard/IndexShardTests.java
@@ -70,7 +70,6 @@
import org.elasticsearch.core.internal.io.IOUtils;
import org.elasticsearch.env.NodeEnvironment;
import org.elasticsearch.index.IndexSettings;
-import org.elasticsearch.index.MergePolicyConfig;
import org.elasticsearch.index.VersionType;
import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.engine.EngineException;
@@ -516,7 +515,7 @@ public void onFailure(Exception e) {
public void testPrimaryPromotionRollsGeneration() throws Exception {
final IndexShard indexShard = newStartedShard(false);
- final long currentTranslogGeneration = indexShard.getTranslog().getGeneration().translogFileGeneration;
+ final long currentTranslogGeneration = getTranslog(indexShard).getGeneration().translogFileGeneration;
// promote the replica
final ShardRouting replicaRouting = indexShard.routingEntry();
@@ -554,8 +553,8 @@ public void onFailure(Exception e) {
ThreadPool.Names.GENERIC, "");
latch.await();
- assertThat(indexShard.getTranslog().getGeneration().translogFileGeneration, equalTo(currentTranslogGeneration + 1));
- assertThat(TestTranslog.getCurrentTerm(indexShard.getTranslog()), equalTo(newPrimaryTerm));
+ assertThat(getTranslog(indexShard).getGeneration().translogFileGeneration, equalTo(currentTranslogGeneration + 1));
+ assertThat(TestTranslog.getCurrentTerm(getTranslog(indexShard)), equalTo(newPrimaryTerm));
closeShards(indexShard);
}
@@ -576,7 +575,7 @@ public void testOperationPermitsOnPrimaryShards() throws InterruptedException, E
true, ShardRoutingState.STARTED, replicaRouting.allocationId());
final long newPrimaryTerm = indexShard.getPrimaryTerm() + between(1, 1000);
indexShard.updateShardState(primaryRouting, newPrimaryTerm, (shard, listener) -> {
- assertThat(TestTranslog.getCurrentTerm(indexShard.getTranslog()), equalTo(newPrimaryTerm));
+ assertThat(TestTranslog.getCurrentTerm(getTranslog(indexShard)), equalTo(newPrimaryTerm));
}, 0L,
Collections.singleton(indexShard.routingEntry().allocationId().getId()),
new IndexShardRoutingTable.Builder(indexShard.shardId()).addShard(primaryRouting).build(),
@@ -667,7 +666,7 @@ public void testOperationPermitOnReplicaShards() throws Exception {
}
final long primaryTerm = indexShard.getPrimaryTerm();
- final long translogGen = engineClosed ? -1 : indexShard.getTranslog().getGeneration().translogFileGeneration;
+ final long translogGen = engineClosed ? -1 : getTranslog(indexShard).getGeneration().translogFileGeneration;
final Releasable operation1;
final Releasable operation2;
@@ -745,7 +744,7 @@ public void onFailure(Exception e) {
@Override
public void onResponse(Releasable releasable) {
assertThat(indexShard.getPrimaryTerm(), equalTo(newPrimaryTerm));
- assertThat(TestTranslog.getCurrentTerm(indexShard.getTranslog()), equalTo(newPrimaryTerm));
+ assertThat(TestTranslog.getCurrentTerm(getTranslog(indexShard)), equalTo(newPrimaryTerm));
assertThat(indexShard.getLocalCheckpoint(), equalTo(expectedLocalCheckpoint));
assertThat(indexShard.getGlobalCheckpoint(), equalTo(newGlobalCheckPoint));
onResponse.set(true);
@@ -791,25 +790,25 @@ private void finish() {
assertFalse(onResponse.get());
assertNull(onFailure.get());
assertThat(indexShard.getPrimaryTerm(), equalTo(primaryTerm));
- assertThat(TestTranslog.getCurrentTerm(indexShard.getTranslog()), equalTo(primaryTerm));
+ assertThat(TestTranslog.getCurrentTerm(getTranslog(indexShard)), equalTo(primaryTerm));
Releasables.close(operation1);
// our operation should still be blocked
assertFalse(onResponse.get());
assertNull(onFailure.get());
assertThat(indexShard.getPrimaryTerm(), equalTo(primaryTerm));
- assertThat(TestTranslog.getCurrentTerm(indexShard.getTranslog()), equalTo(primaryTerm));
+ assertThat(TestTranslog.getCurrentTerm(getTranslog(indexShard)), equalTo(primaryTerm));
Releasables.close(operation2);
barrier.await();
// now lock acquisition should have succeeded
assertThat(indexShard.getPrimaryTerm(), equalTo(newPrimaryTerm));
- assertThat(TestTranslog.getCurrentTerm(indexShard.getTranslog()), equalTo(newPrimaryTerm));
+ assertThat(TestTranslog.getCurrentTerm(getTranslog(indexShard)), equalTo(newPrimaryTerm));
if (engineClosed) {
assertFalse(onResponse.get());
assertThat(onFailure.get(), instanceOf(AlreadyClosedException.class));
} else {
assertTrue(onResponse.get());
assertNull(onFailure.get());
- assertThat(indexShard.getTranslog().getGeneration().translogFileGeneration, equalTo(translogGen + 1));
+ assertThat(getTranslog(indexShard).getGeneration().translogFileGeneration, equalTo(translogGen + 1));
assertThat(indexShard.getLocalCheckpoint(), equalTo(expectedLocalCheckpoint));
assertThat(indexShard.getGlobalCheckpoint(), equalTo(newGlobalCheckPoint));
}
@@ -1645,7 +1644,7 @@ public void testRecoverFromStoreWithNoOps() throws IOException {
assertEquals(1, newShard.recoveryState().getTranslog().totalOperations());
assertEquals(1, newShard.recoveryState().getTranslog().totalOperationsOnStart());
assertEquals(100.0f, newShard.recoveryState().getTranslog().recoveredPercent(), 0.01f);
- try (Translog.Snapshot snapshot = newShard.getTranslog().newSnapshot()) {
+ try (Translog.Snapshot snapshot = getTranslog(newShard).newSnapshot()) {
Translog.Operation operation;
int numNoops = 0;
while ((operation = snapshot.next()) != null) {
@@ -2046,7 +2045,7 @@ public void testTranslogRecoverySyncsTranslog() throws IOException {
@Override
public long indexTranslogOperations(List operations, int totalTranslogOps) throws IOException {
final long localCheckpoint = super.indexTranslogOperations(operations, totalTranslogOps);
- assertFalse(replica.getTranslog().syncNeeded());
+ assertFalse(replica.isSyncNeeded());
return localCheckpoint;
}
}, true);
diff --git a/server/src/test/java/org/elasticsearch/index/shard/RefreshListenersTests.java b/server/src/test/java/org/elasticsearch/index/shard/RefreshListenersTests.java
index 5803bf263633d..2d1c1d4e15af8 100644
--- a/server/src/test/java/org/elasticsearch/index/shard/RefreshListenersTests.java
+++ b/server/src/test/java/org/elasticsearch/index/shard/RefreshListenersTests.java
@@ -133,7 +133,7 @@ indexSettings, null, store, newMergePolicy(), iwc.getAnalyzer(), iwc.getSimilari
(e, s) -> 0, new NoneCircuitBreakerService(), () -> SequenceNumbers.NO_OPS_PERFORMED, () -> primaryTerm);
engine = new InternalEngine(config);
engine.recoverFromTranslog();
- listeners.setTranslog(engine.getTranslog());
+ listeners.setCurrentRefreshLocationSupplier(engine::getTranslogLastWriteLocation);
}
@After
diff --git a/server/src/test/java/org/elasticsearch/indices/recovery/PeerRecoveryTargetServiceTests.java b/server/src/test/java/org/elasticsearch/indices/recovery/PeerRecoveryTargetServiceTests.java
index d65d40e5bcdaa..91b35594772cf 100644
--- a/server/src/test/java/org/elasticsearch/indices/recovery/PeerRecoveryTargetServiceTests.java
+++ b/server/src/test/java/org/elasticsearch/indices/recovery/PeerRecoveryTargetServiceTests.java
@@ -59,7 +59,7 @@ public void testGetStartingSeqNo() throws Exception {
}
flushShard(replica);
replica.updateGlobalCheckpointOnReplica(initDocs - 1, "test");
- replica.getTranslog().sync();
+ replica.sync();
final RecoveryTarget recoveryTarget = new RecoveryTarget(replica, null, null, null);
assertThat(PeerRecoveryTargetService.getStartingSeqNo(logger, recoveryTarget), equalTo(initDocs));
recoveryTarget.decRef();
@@ -81,7 +81,7 @@ public void testGetStartingSeqNo() throws Exception {
// Advances the global checkpoint, a safe commit also advances
{
replica.updateGlobalCheckpointOnReplica(initDocs + moreDocs - 1, "test");
- replica.getTranslog().sync();
+ replica.sync();
final RecoveryTarget recoveryTarget = new RecoveryTarget(replica, null, null, null);
assertThat(PeerRecoveryTargetService.getStartingSeqNo(logger, recoveryTarget), equalTo(initDocs + moreDocs));
recoveryTarget.decRef();
diff --git a/server/src/test/java/org/elasticsearch/indices/recovery/RecoveryTests.java b/server/src/test/java/org/elasticsearch/indices/recovery/RecoveryTests.java
index f46ab7ebbd603..4e9d0ccb22e11 100644
--- a/server/src/test/java/org/elasticsearch/indices/recovery/RecoveryTests.java
+++ b/server/src/test/java/org/elasticsearch/indices/recovery/RecoveryTests.java
@@ -61,7 +61,7 @@ public void testTranslogHistoryTransferred() throws Exception {
try (ReplicationGroup shards = createGroup(0)) {
shards.startPrimary();
int docs = shards.indexDocs(10);
- shards.getPrimary().getTranslog().rollGeneration();
+ getTranslog(shards.getPrimary()).rollGeneration();
shards.flush();
if (randomBoolean()) {
docs += shards.indexDocs(10);
@@ -69,7 +69,7 @@ public void testTranslogHistoryTransferred() throws Exception {
shards.addReplica();
shards.startAll();
final IndexShard replica = shards.getReplicas().get(0);
- assertThat(replica.getTranslog().totalOperations(), equalTo(docs));
+ assertThat(replica.estimateTranslogOperationsFromMinSeq(0), equalTo(docs));
}
}
@@ -77,7 +77,7 @@ public void testRetentionPolicyChangeDuringRecovery() throws Exception {
try (ReplicationGroup shards = createGroup(0)) {
shards.startPrimary();
shards.indexDocs(10);
- shards.getPrimary().getTranslog().rollGeneration();
+ getTranslog(shards.getPrimary()).rollGeneration();
shards.flush();
shards.indexDocs(10);
final IndexShard replica = shards.addReplica();
@@ -99,7 +99,7 @@ public void testRetentionPolicyChangeDuringRecovery() throws Exception {
releaseRecovery.countDown();
future.get();
// rolling/flushing is async
- assertBusy(() -> assertThat(replica.getTranslog().totalOperations(), equalTo(0)));
+ assertBusy(() -> assertThat(replica.estimateTranslogOperationsFromMinSeq(0), equalTo(0)));
}
}
@@ -123,7 +123,7 @@ public void testRecoveryWithOutOfOrderDelete() throws Exception {
// delete #1
orgReplica.applyDeleteOperationOnReplica(1, 2, "type", "id", VersionType.EXTERNAL, u -> {});
- orgReplica.getTranslog().rollGeneration(); // isolate the delete in it's own generation
+ getTranslog(orgReplica).rollGeneration(); // isolate the delete in it's own generation
// index #0
orgReplica.applyIndexOperationOnReplica(0, 1, VersionType.EXTERNAL, IndexRequest.UNSET_AUTO_GENERATED_TIMESTAMP, false,
SourceToParse.source(indexName, "type", "id", new BytesArray("{}"), XContentType.JSON), u -> {});
@@ -167,7 +167,7 @@ public void testRecoveryWithOutOfOrderDelete() throws Exception {
shards.recoverReplica(newReplica);
shards.assertAllEqual(3);
- assertThat(newReplica.getTranslog().totalOperations(), equalTo(translogOps));
+ assertThat(newReplica.estimateTranslogOperationsFromMinSeq(0), equalTo(translogOps));
}
}
@@ -184,7 +184,7 @@ public void testDifferentHistoryUUIDDisablesOPsRecovery() throws Exception {
IndexShard replica = shards.getReplicas().get(0);
final String historyUUID = replica.getHistoryUUID();
- Translog.TranslogGeneration translogGeneration = replica.getTranslog().getGeneration();
+ Translog.TranslogGeneration translogGeneration = getTranslog(replica).getGeneration();
shards.removeReplica(replica);
replica.close("test", false);
IndexWriterConfig iwc = new IndexWriterConfig(null)
@@ -219,7 +219,7 @@ public void testDifferentHistoryUUIDDisablesOPsRecovery() throws Exception {
shards.recoverReplica(newReplica);
// file based recovery should be made
assertThat(newReplica.recoveryState().getIndex().fileDetails(), not(empty()));
- assertThat(newReplica.getTranslog().totalOperations(), equalTo(numDocs));
+ assertThat(newReplica.estimateTranslogOperationsFromMinSeq(0), equalTo(numDocs));
// history uuid was restored
assertThat(newReplica.getHistoryUUID(), equalTo(historyUUID));
@@ -238,7 +238,7 @@ public void testPeerRecoveryPersistGlobalCheckpoint() throws Exception {
}
final IndexShard replica = shards.addReplica();
shards.recoverReplica(replica);
- assertThat(replica.getTranslog().getLastSyncedGlobalCheckpoint(), equalTo(numDocs - 1));
+ assertThat(replica.getLastSyncedGlobalCheckpoint(), equalTo(numDocs - 1));
}
}
@@ -291,7 +291,7 @@ public void testSequenceBasedRecoveryKeepsTranslog() throws Exception {
final IndexShard newReplica = shards.addReplicaWithExistingPath(replica.shardPath(), replica.routingEntry().currentNodeId());
shards.recoverReplica(newReplica);
- try (Translog.Snapshot snapshot = newReplica.getTranslog().newSnapshot()) {
+ try (Translog.Snapshot snapshot = getTranslog(newReplica).newSnapshot()) {
assertThat("Sequence based recovery should keep existing translog", snapshot, SnapshotMatchers.size(initDocs + moreDocs));
}
assertThat(newReplica.recoveryState().getTranslog().recoveredOperations(), equalTo(uncommittedDocs + moreDocs));
@@ -321,7 +321,7 @@ public void testShouldFlushAfterPeerRecovery() throws Exception {
shards.recoverReplica(replica);
// Make sure the flushing will eventually be completed (eg. `shouldPeriodicallyFlush` is false)
assertBusy(() -> assertThat(getEngine(replica).shouldPeriodicallyFlush(), equalTo(false)));
- assertThat(replica.getTranslog().totalOperations(), equalTo(numDocs));
+ assertThat(replica.estimateTranslogOperationsFromMinSeq(0), equalTo(numDocs));
shards.assertAllEqual(numDocs);
}
}
diff --git a/test/framework/src/main/java/org/elasticsearch/index/engine/EngineTestCase.java b/test/framework/src/main/java/org/elasticsearch/index/engine/EngineTestCase.java
index dea92c2927d86..8fff17900b072 100644
--- a/test/framework/src/main/java/org/elasticsearch/index/engine/EngineTestCase.java
+++ b/test/framework/src/main/java/org/elasticsearch/index/engine/EngineTestCase.java
@@ -493,4 +493,11 @@ protected Engine.Delete replicaDeleteForDoc(String id, long version, long seqNo,
return new Engine.Delete("test", id, newUid(id), seqNo, 1, version, VersionType.EXTERNAL,
Engine.Operation.Origin.REPLICA, startTime);
}
+
+ /**
+ * Exposes a translog associated with the given engine for testing purpose.
+ */
+ public static Translog getTranslog(Engine engine) {
+ return engine.getTranslog();
+ }
}
diff --git a/test/framework/src/main/java/org/elasticsearch/index/shard/IndexShardTestCase.java b/test/framework/src/main/java/org/elasticsearch/index/shard/IndexShardTestCase.java
index 9a1378ae4830c..095962701b8d3 100644
--- a/test/framework/src/main/java/org/elasticsearch/index/shard/IndexShardTestCase.java
+++ b/test/framework/src/main/java/org/elasticsearch/index/shard/IndexShardTestCase.java
@@ -55,6 +55,7 @@
import org.elasticsearch.index.cache.query.DisabledQueryCache;
import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.engine.EngineFactory;
+import org.elasticsearch.index.engine.EngineTestCase;
import org.elasticsearch.index.mapper.IdFieldMapper;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.Mapping;
@@ -66,6 +67,7 @@
import org.elasticsearch.index.snapshots.IndexShardSnapshotStatus;
import org.elasticsearch.index.store.DirectoryService;
import org.elasticsearch.index.store.Store;
+import org.elasticsearch.index.translog.Translog;
import org.elasticsearch.indices.breaker.CircuitBreakerService;
import org.elasticsearch.indices.breaker.HierarchyCircuitBreakerService;
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
@@ -645,6 +647,10 @@ public static Engine getEngine(IndexShard indexShard) {
return indexShard.getEngine();
}
+ public static Translog getTranslog(IndexShard shard) {
+ return EngineTestCase.getTranslog(getEngine(shard));
+ }
+
public static ReplicationTracker getReplicationTracker(IndexShard indexShard) {
return indexShard.getReplicationTracker();
}
diff --git a/test/framework/src/main/java/org/elasticsearch/test/InternalTestCluster.java b/test/framework/src/main/java/org/elasticsearch/test/InternalTestCluster.java
index d82b5052dbf54..12acd21903ec4 100644
--- a/test/framework/src/main/java/org/elasticsearch/test/InternalTestCluster.java
+++ b/test/framework/src/main/java/org/elasticsearch/test/InternalTestCluster.java
@@ -76,6 +76,7 @@
import org.elasticsearch.index.engine.CommitStats;
import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.shard.IndexShard;
+import org.elasticsearch.index.shard.IndexShardTestCase;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.indices.breaker.CircuitBreakerService;
@@ -1158,7 +1159,7 @@ private void assertOpenTranslogReferences() throws Exception {
for (IndexService indexService : indexServices) {
for (IndexShard indexShard : indexService) {
try {
- indexShard.getTranslog().getDeletionPolicy().assertNoOpenTranslogRefs();
+ IndexShardTestCase.getTranslog(indexShard).getDeletionPolicy().assertNoOpenTranslogRefs();
} catch (AlreadyClosedException ok) {
// all good
}
From 4ceb102ee403198d9bdaa5acf82d1189b8466561 Mon Sep 17 00:00:00 2001
From: Jack Conradson
Date: Tue, 17 Apr 2018 12:16:08 -0700
Subject: [PATCH 14/15] Painless Spec Documentation Clean Up (#29441)
Created a flatter structure for the different sections. Cleaned up comments, keywords, and literals. Used callouts for examples where it made sense.
---
docs/painless/index.asciidoc | 33 ----
docs/painless/painless-api-reference.asciidoc | 24 +--
docs/painless/painless-casting.asciidoc | 172 +++++++++++++++++
docs/painless/painless-comments.asciidoc | 51 +++++
docs/painless/painless-description.asciidoc | 2 +-
...iidoc => painless-general-syntax.asciidoc} | 40 +---
docs/painless/painless-keywords.asciidoc | 13 ++
docs/painless/painless-lang-spec.asciidoc | 73 ++------
docs/painless/painless-literals.asciidoc | 157 ++++++++++------
docs/painless/painless-operators.asciidoc | 1 +
docs/painless/painless-types.asciidoc | 177 +-----------------
docs/painless/painless-variables.asciidoc | 23 ++-
docs/reference/redirects.asciidoc | 2 +-
13 files changed, 384 insertions(+), 384 deletions(-)
create mode 100644 docs/painless/painless-casting.asciidoc
create mode 100644 docs/painless/painless-comments.asciidoc
rename docs/painless/{painless-syntax.asciidoc => painless-general-syntax.asciidoc} (72%)
create mode 100644 docs/painless/painless-keywords.asciidoc
diff --git a/docs/painless/index.asciidoc b/docs/painless/index.asciidoc
index 4898ed933363b..abfd4d4f00abe 100644
--- a/docs/painless/index.asciidoc
+++ b/docs/painless/index.asciidoc
@@ -5,39 +5,6 @@ include::../Versions.asciidoc[]
include::painless-getting-started.asciidoc[]
-// include::painless-examples.asciidoc[]
-
-// include::painless-design.asciidoc[]
-
include::painless-lang-spec.asciidoc[]
-include::painless-syntax.asciidoc[]
-
include::painless-api-reference.asciidoc[]
-
-////
-Proposed Outline (WIP)
-Getting Started with Painless
- Accessing Doc Values
- Updating Fields
- Working with Dates
- Using Regular Expressions
- Debugging Painless Scripts
-
-Example Scripts
- Using Painless in Script Fields
- Using Painless in Watches
- Using Painless in Function Score Queries
- Using Painless in Script Queries
- Using Painless When Updating Docs
- Using Painless When Reindexing
-
-How Painless Works
- Painless Architecture
- Dispatching Functions
-
-Painless Language Specification
-Painless API
-////
-
-Painless API Reference
diff --git a/docs/painless/painless-api-reference.asciidoc b/docs/painless/painless-api-reference.asciidoc
index 1bda6d890c859..54b1f20977b61 100644
--- a/docs/painless/painless-api-reference.asciidoc
+++ b/docs/painless/painless-api-reference.asciidoc
@@ -1,17 +1,13 @@
-["appendix",id="painless-api-reference"]
-= Painless API Reference
+[[painless-api-reference]]
+== Painless API Reference
-Painless has a strict whitelist for methods and
-classes to make sure that all painless scripts are secure and fast. Most of
-these methods are exposed directly from the JRE while others are part of
-Elasticsearch or Painless itself. Below is a list of all available methods
-grouped under the classes on which you can call them. Clicking on the method
-name takes you to the documentation for the method.
-
-NOTE: Methods defined in the JRE also have a `(java 9)` link which can be used
-to see the method's documentation in Java 9 while clicking on the method's name
-goes to the Java 8 documentation. Usually these aren't different but it is
-worth going to the version that matches the version of Java you are using to
-run Elasticsearch just in case.
+Painless has a strict whitelist for methods and classes to ensure all
+painless scripts are secure. Most of these methods are exposed directly
+from the Java Runtime Enviroment (JRE) while others are part of
+Elasticsearch or Painless itself. Below is a list of all available
+classes grouped with their respected methods. Clicking on the method
+name takes you to the documentation for that specific method. Methods
+defined in the JRE also have a `(java 9)` link which can be used to see
+the method's documentation in Java 9.
include::painless-api-reference/index.asciidoc[]
diff --git a/docs/painless/painless-casting.asciidoc b/docs/painless/painless-casting.asciidoc
new file mode 100644
index 0000000000000..ec4f9919bd043
--- /dev/null
+++ b/docs/painless/painless-casting.asciidoc
@@ -0,0 +1,172 @@
+[[painless-casting]]
+=== Casting
+
+Casting is the conversion of one type to another. Implicit casts are casts that
+occur automatically, such as during an assignment operation. Explicit casts are
+casts where you use the casting operator to explicitly convert one type to
+another. This is necessary during operations where the cast cannot be inferred.
+
+To cast to a new type, precede the expression by the new type enclosed in
+parentheses, for example
+`(int)x`.
+
+The following sections specify the implicit casts that can be performed and the
+explicit casts that are allowed. The only other permitted cast is casting
+a single character `String` to a `char`.
+
+*Grammar:*
+[source,ANTLR4]
+----
+cast: '(' TYPE ')' expression
+----
+
+[[numeric-casting]]
+==== Numeric Casting
+
+The following table shows the allowed implicit and explicit casts between
+numeric types. Read the table by row. To find out if you need to explicitly
+cast from type A to type B, find the row for type A and scan across to the
+column for type B.
+
+IMPORTANT: Explicit casts between numeric types can result in some data loss. A
+smaller numeric type cannot necessarily accommodate the value from a larger
+numeric type. You might also lose precision when casting from integer types
+to floating point types.
+
+|====
+| | byte | short | char | int | long | float | double
+| byte | | implicit | implicit | implicit | implicit | implicit | implicit
+| short | explicit | | explicit | implicit | implicit | implicit | implicit
+| char | explicit | explicit | | implicit | implicit | implicit | implicit
+| int | explicit | explicit | explicit | | implicit | implicit | implicit
+| long | explicit | explicit | explicit | explicit | | implicit | implicit
+| float | explicit | explicit | explicit | explicit | explicit | | implicit
+| double | explicit | explicit | explicit | explicit | explicit | explicit |
+|====
+
+
+Example(s)
+[source,Java]
+----
+int a = 1; // Declare int variable a and set it to the literal
+ // value 1
+long b = a; // Declare long variable b and set it to int variable
+ // a with an implicit cast to convert from int to long
+short c = (short)b; // Declare short variable c, explicitly cast b to a
+ // short, and assign b to c
+byte d = a; // ERROR: Casting an int to a byte requires an explicit
+ // cast
+double e = (double)a; // Explicitly cast int variable a to a double and assign
+ // it to the double variable e. The explicit cast is
+ // allowed, but it is not necessary.
+----
+
+[[reference-casting]]
+==== Reference Casting
+
+A reference type can be implicitly cast to another reference type as long as
+the type being cast _from_ is a descendant of the type being cast _to_. A
+reference type can be explicitly cast _to_ if the type being cast to is a
+descendant of the type being cast _from_.
+
+*Examples:*
+[source,Java]
+----
+List x; // Declare List variable x
+ArrayList y = new ArrayList(); // Declare ArrayList variable y and assign it a
+ // newly allocated ArrayList [1]
+x = y; // Assign Arraylist y to List x using an
+ // implicit cast
+y = (ArrayList)x; // Explicitly cast List x to an ArrayList and
+ // assign it to ArrayList y
+x = (List)y; // Set List x to ArrayList y using an explicit
+ // cast (the explicit cast is not necessary)
+y = x; // ERROR: List x cannot be implicitly cast to
+ // an ArrayList, an explicit cast is required
+Map m = y; // ERROR: Cannot implicitly or explicitly cast [2]
+ // an ArrayList to a Map, no relationship
+ // exists between the two types.
+----
+[1] `ArrayList` is a descendant of the `List` type.
+[2] `Map` is unrelated to the `List` and `ArrayList` types.
+
+[[def-type-casting]]
+==== def Type Casting
+All primitive and reference types can always be implicitly cast to
+`def`. While it is possible to explicitly cast to `def`, it is not necessary.
+
+However, it is not always possible to implicitly cast a `def` to other
+primitive and reference types. An explicit cast is required if an explicit
+cast would normally be required between the non-def types.
+
+
+*Examples:*
+[source,Java]
+----
+def x; // Declare def variable x and set it to null
+x = 3; // Set the def variable x to the literal 3 with an implicit
+ // cast from int to def
+double a = x; // Declare double variable a and set it to def variable x,
+ // which contains a double
+int b = x; // ERROR: Results in a run-time error because an explicit cast is
+ // required to cast from a double to an int
+int c = (int)x; // Declare int variable c, explicitly cast def variable x to an
+ // int, and assign x to c
+----
+
+[[boxing-unboxing]]
+==== Boxing and Unboxing
+
+Boxing is where a cast is used to convert a primitive type to its corresponding
+reference type. Unboxing is the reverse, converting a reference type to the
+corresponding primitive type.
+
+There are two places Painless performs implicit boxing and unboxing:
+
+* When you call methods, Painless automatically boxes and unboxes arguments
+so you can specify either primitive types or their corresponding reference
+types.
+* When you use the `def` type, Painless automatically boxes and unboxes as
+needed when converting to and from `def`.
+
+The casting operator does not support any way to explicitly box a primitive
+type or unbox a reference type.
+
+If a primitive type needs to be converted to a reference type, the Painless
+reference type API supports methods that can do that. However, under normal
+circumstances this should not be necessary.
+
+*Examples:*
+[source,Java]
+----
+Integer x = 1; // ERROR: not a legal implicit cast
+Integer y = (Integer)1; // ERROR: not a legal explicit cast
+int a = new Integer(1); // ERROR: not a legal implicit cast
+int b = (int)new Integer(1); // ERROR: not a legal explicit cast
+----
+
+[[promotion]]
+==== Promotion
+
+Promotion is where certain operations require types to be either a minimum
+numerical type or for two (or more) types to be equivalent.
+The documentation for each operation that has these requirements
+includes promotion tables that describe how this is handled.
+
+When an operation promotes a type or types, the resultant type
+of the operation is the promoted type. Types can be promoted to def
+at compile-time; however, at run-time, the resultant type will be the
+promotion of the types the `def` is representing.
+
+*Examples:*
+[source,Java]
+----
+2 + 2.0 // Add the literal int 2 and the literal double 2.0. The literal
+ // 2 is promoted to a double and the resulting value is a double.
+
+def x = 1; // Declare def variable x and set it to the literal int 1 through
+ // an implicit cast
+x + 2.0F // Add def variable x and the literal float 2.0.
+ // At compile-time the types are promoted to def.
+ // At run-time the types are promoted to float.
+----
diff --git a/docs/painless/painless-comments.asciidoc b/docs/painless/painless-comments.asciidoc
new file mode 100644
index 0000000000000..d1d2e47a143a6
--- /dev/null
+++ b/docs/painless/painless-comments.asciidoc
@@ -0,0 +1,51 @@
+[[painless-comments]]
+=== Comments
+
+Painless supports both single-line and multi-line comments. Comments can be
+included anywhere within a script. Use the `//` token anywhere on a line to
+specify a single-line comment. All characters from the `//` token to the end
+of the line are ignored. Use an opening `/*` token and a closing `*/` token
+to specify a multi-line comment. Multi-line comments can start anywhere on a
+line, and all characters in between the `/*` token and `*/` token are ignored.
+
+*Grammar*
+[source,ANTLR4]
+----
+SINGLE_LINE_COMMENT: '//' .*? [\n\r];
+MULTI_LINE_COMMENT: '/*' .*? '*/';
+----
+
+*Examples*
+
+Single-line comments.
+
+[source,Painless]
+----
+// single-line comment
+
+int value; // single-line comment
+----
+
+Multi-line comments.
+
+[source,Painless]
+----
+/* multi-
+ line
+ comment */
+
+int value; /* multi-
+ line
+ comment */ value = 0;
+
+int value; /* multi-line
+ comment */
+
+/* multi-line
+ comment */ int value;
+
+int value; /* multi-line
+ comment */ value = 0;
+
+int value; /* multi-line comment */ value = 0;
+----
diff --git a/docs/painless/painless-description.asciidoc b/docs/painless/painless-description.asciidoc
index 874eab5632cfb..dfaf66ca26d4b 100644
--- a/docs/painless/painless-description.asciidoc
+++ b/docs/painless/painless-description.asciidoc
@@ -2,7 +2,7 @@ _Painless_ is a simple, secure scripting language designed specifically for use
with Elasticsearch. It is the default scripting language for Elasticsearch and
can safely be used for inline and stored scripts. For a detailed description of
the Painless syntax and language features, see the
-{painless}/painless-specification.html[Painless Language Specification].
+{painless}/painless-lang-spec.html[Painless Language Specification].
[[painless-features]]
You can use Painless anywhere scripts can be used in Elasticsearch. Painless
diff --git a/docs/painless/painless-syntax.asciidoc b/docs/painless/painless-general-syntax.asciidoc
similarity index 72%
rename from docs/painless/painless-syntax.asciidoc
rename to docs/painless/painless-general-syntax.asciidoc
index c68ed5168c01b..114bff80bfa70 100644
--- a/docs/painless/painless-syntax.asciidoc
+++ b/docs/painless/painless-general-syntax.asciidoc
@@ -1,7 +1,6 @@
-[[painless-syntax]]
-=== Painless Syntax
+[[painless-general-syntax]]
+=== General Syntax
-[float]
[[control-flow]]
==== Control flow
@@ -17,7 +16,6 @@ for (item : list) {
}
---------------------------------------------------------
-[float]
[[functions]]
==== Functions
@@ -32,7 +30,6 @@ if (isNegative(someVar)) {
}
---------------------------------------------------------
-[float]
[[lambda-expressions]]
==== Lambda expressions
Lambda expressions and method references work the same as in https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html[Java].
@@ -49,7 +46,6 @@ list.sort(Integer::compare);
You can make method references to functions within the script with `this`,
for example `list.sort(this::mycompare)`.
-[float]
[[patterns]]
==== Patterns
@@ -62,7 +58,6 @@ are always constants and compiled efficiently a single time.
Pattern p = /[aeiou]/
---------------------------------------------------------
-[float]
[[pattern-flags]]
===== Pattern flags
@@ -84,34 +79,3 @@ Pattern class] using these characters:
|`u` | UNICODE_CASE | `'Ɛ' ==~ /ɛ/iu`
|`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
----------------------------------------------------------
diff --git a/docs/painless/painless-keywords.asciidoc b/docs/painless/painless-keywords.asciidoc
new file mode 100644
index 0000000000000..99b5b4060d24e
--- /dev/null
+++ b/docs/painless/painless-keywords.asciidoc
@@ -0,0 +1,13 @@
+[[painless-keywords]]
+=== Keywords
+
+The keywords in the table below are reserved for built-in language
+features. These keywords cannot be used as <> or
+<>.
+
+[cols="^1,^1,^1,^1,^1"]
+|====
+| if | else | while | do | for
+| in | continue | break | return | new
+| try | catch | throw | this | instanceof
+|====
diff --git a/docs/painless/painless-lang-spec.asciidoc b/docs/painless/painless-lang-spec.asciidoc
index 6544b0ad26495..b324ad301141c 100644
--- a/docs/painless/painless-lang-spec.asciidoc
+++ b/docs/painless/painless-lang-spec.asciidoc
@@ -1,73 +1,34 @@
-[[painless-specification]]
+[[painless-lang-spec]]
== Painless Language Specification
-Painless uses a Java-style syntax that is similar to Groovy. In fact, most
-Painless scripts are also valid Groovy, and simple Groovy scripts are typically
-valid Painless. This specification assumes you have at least a passing
-familiarity with Java and related languages.
-
-Painless is essentially a subset of Java with some additional scripting
-language features that make scripts easier to write. However, there are some
-important differences, particularly with the casting model. For more detailed
+Painless is a scripting language designed for security and performance.
+Painless syntax is similar to Java syntax along with some additional
+features such as dynamic typing, Map and List accessor shortcuts, and array
+initializers. As a direct comparison to Java, there are some important
+differences, especially related to the casting model. For more detailed
conceptual information about the basic constructs that Java and Painless share,
refer to the corresponding topics in the
https://docs.oracle.com/javase/specs/jls/se8/html/index.html[Java Language
Specification].
Painless scripts are parsed and compiled using the http://www.antlr.org/[ANTLR4]
-and http://asm.ow2.org/[ASM] libraries. Painless scripts are compiled directly
-into Java byte code and executed against a standard Java Virtual Machine. This
-specification uses ANTLR4 grammar notation to describe the allowed syntax.
+and http://asm.ow2.org/[ASM] libraries. Scripts are compiled directly
+into Java Virtual Machine (JVM) byte code and executed against a standard JVM.
+This specification uses ANTLR4 grammar notation to describe the allowed syntax.
However, the actual Painless grammar is more compact than what is shown here.
-[float]
-[[comments]]
-==== Comments
-
-Painless supports both single-line and multi-line comments. You can include
-comments anywhere within a script.
-
-Single-line comments are preceded by two slashes: `// comment`. They can be
-placed anywhere on a line. All characters from the two slashes to the end of
-the line are ignored.
-
-Multi-line comments are preceded by a slash-star `/*` and closed by
-star-slash `*/`. Multi-line comments can start anywhere on a line. All
-characters from the opening `/*` to the closing `*/` are ignored.
-
-*Examples:*
-
-[source,Java]
-----
-// single-line comment
-
- // single-line comment
-
-/* multi-
- line
- comment */
+include::painless-comments.asciidoc[]
- /* multi-line
- comment */
+include::painless-keywords.asciidoc[]
- /* multi-line comment */
-----
+include::painless-literals.asciidoc[]
-[float]
-[[keywords]]
-==== Keywords
+include::painless-variables.asciidoc[]
-Painless reserves the following keywords for built-in language features.
-These keywords cannot be used in other contexts, such as identifiers.
+include::painless-types.asciidoc[]
-[cols="^1,^1,^1,^1,^1"]
-|====
-| if | else | while | do | for
-| in | continue | break | return | new
-| try | catch | throw | this | instanceof
-|====
+include::painless-casting.asciidoc[]
-include::painless-literals.asciidoc[]
-include::painless-variables.asciidoc[]
-include::painless-types.asciidoc[]
include::painless-operators.asciidoc[]
+
+include::painless-general-syntax.asciidoc[]
diff --git a/docs/painless/painless-literals.asciidoc b/docs/painless/painless-literals.asciidoc
index 43c5eb82f96a2..3f91c9299c0ad 100644
--- a/docs/painless/painless-literals.asciidoc
+++ b/docs/painless/painless-literals.asciidoc
@@ -1,94 +1,143 @@
-[[literals]]
+[[painless-literals]]
=== Literals
-Literals are values that you can specify directly in Painless scripts.
+Use literals to specify different types of values directly in a script.
[[integers]]
==== Integers
-Specify integer literals in decimal, octal, or hex notation. Use the following
-single letter designations to specify the primitive type: `l` for `long`, `f`
-for `float`, and `d` for `double`. If not specified, the type defaults to
-`int` (with the exception of certain assignments described later).
+Use integer literals to specify an integer value in decimal, octal, or hex
+notation of the <> `int`, `long`, `float`,
+or `double`. Use the following single letter designations to specify the
+<>: `l` or `L` for `long`, `f` or `F` for
+`float`, and `d` or `D` for `double`. If not specified, the type defaults to
+`int`. Use `0` as a prefix to specify an integer literal as octal, and use
+`0x` or `0X` as a prefix to specify an integer literal as hex.
-*Grammar:*
+*Grammar*
[source,ANTLR4]
----
INTEGER: '-'? ( '0' | [1-9] [0-9]* ) [lLfFdD]?;
-OCTAL: '-'? '0' [0-7]+ [lL]?;
-HEX: '-'? '0' [xX] [0-9a-fA-F]+ [lL]?;
+OCTAL: '-'? '0' [0-7]+ [lL]?;
+HEX: '-'? '0' [xX] [0-9a-fA-F]+ [lL]?;
----
-*Examples:*
-[source,Java]
+*Examples*
+
+Integer literals.
+
+[source,Painless]
----
-0 // integer literal of 0
-0D // double literal of 0.0
-1234L // long literal of 1234
--90F // float literal of -90.0
--022 // integer literal of -18 specified in octal
-0xF2A // integer literal of 3882
+0 <1>
+0D <2>
+1234L <3>
+-90f <4>
+-022 <5>
+0xF2A <6>
----
-[[floating-point-values]]
-==== Floating Point Values
+<1> `int 0`
+<2> `double 0.0`
+<3> `long 1234`
+<4> `float -90.0`
+<5> `int -18` in octal
+<6> `int 3882` in hex
+
+[[floats]]
+==== Floats
-Specify floating point literals using the following single letter designations
-for the primitive type: `f` for `float` and `d` for `double`.
-If not specified, the type defaults to `double`.
+Use floating point literals to specify a floating point value of the
+<> `float` or `double`. Use the following
+single letter designations to specify the <>:
+`f` or `F` for `float` and `d` or `D` for `double`. If not specified, the type defaults
+to `double`.
-*Grammar:*
+*Grammar*
[source,ANTLR4]
----
-DECIMAL: '-'? ( '0' | [1-9] [0-9]* ) (DOT [0-9]+)? ( [eE] [+\-]? [0-9]+ )? [fFdD]?;
+DECIMAL: '-'? ( '0' | [1-9] [0-9]* ) (DOT [0-9]+)? EXPONENT? [fFdD]?;
+EXPONENT: ( [eE] [+\-]? [0-9]+ );
----
-*Examples:*
-[source,Java]
+*Examples*
+
+Floating point literals.
+
+[source,Painless]
----
-0.0 // double value of 0.0
-1E6 // double value of 1000000
-0.977777 // double value of 0.97777
--126.34 // double value of -126.34
-89.9F // float value of 89.9
+0.0 <1>
+1E6 <2>
+0.977777 <3>
+-126.34 <4>
+89.9F <5>
----
+<1> `double 0.0`
+<2> `double 1000000.0` in exponent notation
+<3> `double 0.977777`
+<4> `double -126.34`
+<5> `float 89.9`
+
[[strings]]
==== Strings
-Specify literal string with either single or double quotes. In double-quoted
-literal strings, you can escape double-quotes with a backslash to include them
-in the string. Similarly, you escape single quotes with a backslash in
-single-quoted literal strings. Backslashes themselves also need to be
-escaped with a backslash.
+Use string literals to specify string values of the
+<> with either single-quotes or double-quotes.
+Use a `\"` token to include a double-quote as part of a double-quoted string
+literal. Use a `\'` token to include a single-quote as part of a single-quoted
+string literal. Use a `\\` token to include a backslash as part of any string
+literal.
-*Grammar:*
+*Grammar*
[source,ANTLR4]
----
-STRING: ( '"' ( '\\"' | '\\\\' | ~[\\"] )*? '"' ) | ( '\'' ( '\\\'' | '\\\\' | ~[\\'] )*? '\'' );
+STRING: ( '"' ( '\\"' | '\\\\' | ~[\\"] )*? '"' )
+ | ( '\'' ( '\\\'' | '\\\\' | ~[\\'] )*? '\'' );
----
-*Examples:*
-[source,Java]
+*Examples*
+
+String literals using single-quotes.
+
+[source,Painless]
----
-"double-quoted String literal"
-'single-quoted String literal'
-"\"double-quoted String with escaped double-quotes\" and backslash: \\"
-'\'single-quoted String with escaped single-quotes\' and backslash \\'
-"double-quoted String with non-escaped 'single-quotes'"
-'single-quoted String with non-escaped "double-quotes"'
+'single-quoted string literal'
+'\'single-quoted string with escaped single-quotes\' and backslash \\'
+'single-quoted string with non-escaped "double-quotes"'
----
-[[char]]
-===== Char
+String literals using double-quotes.
-You cannot directly specify character literals in Painless. However, you can
-cast single-character strings to char. Attempting to cast a multi-character
-string to a char throws an error.
+[source,Painless]
+----
+"double-quoted string literal"
+"\"double-quoted string with escaped double-quotes\" and backslash: \\"
+"double-quoted string with non-escaped 'single-quotes'"
+----
-*Examples:*
-[source,Java]
+[[characters]]
+==== Characters
+
+Use the <> to convert string literals or
+<> values into <> values.
+<> values converted into
+<> values must be exactly one character in length
+or an error will occur.
+
+*Examples*
+
+Casting string literals into <> values.
+
+[source,Painless]
----
(char)"C"
(char)'c'
-----
\ No newline at end of file
+----
+
+Casting a <> value into a <> value.
+
+[source,Painless]
+----
+String s = "s";
+char c = (char)s;
+----
diff --git a/docs/painless/painless-operators.asciidoc b/docs/painless/painless-operators.asciidoc
index 7ba190b758e63..b2dab60796d55 100644
--- a/docs/painless/painless-operators.asciidoc
+++ b/docs/painless/painless-operators.asciidoc
@@ -1,3 +1,4 @@
+[[painless-operators]]
=== Operators
The following is a table of the available operators in Painless. Each operator will have further information and examples outside of the table. Many operators will have a promotion table as described by the documentation on promotion [MARK].
diff --git a/docs/painless/painless-types.asciidoc b/docs/painless/painless-types.asciidoc
index 9e5077503b4a8..9d575a2069ae3 100644
--- a/docs/painless/painless-types.asciidoc
+++ b/docs/painless/painless-types.asciidoc
@@ -1,5 +1,5 @@
-[[types]]
-=== Data Types
+[[painless-types]]
+=== Types
Painless supports both dynamic and static types. Static types are split into
_primitive types_ and _reference types_.
@@ -267,176 +267,3 @@ def[] da = new def[] {i, l, f*d, s}; // Declare def array da and set it to
// a def array with a size of 4 and the
// values i, l, f*d, and s
----
-
-[[casting]]
-=== Casting
-
-Casting is the conversion of one type to another. Implicit casts are casts that
-occur automatically, such as during an assignment operation. Explicit casts are
-casts where you use the casting operator to explicitly convert one type to
-another. This is necessary during operations where the cast cannot be inferred.
-
-To cast to a new type, precede the expression by the new type enclosed in
-parentheses, for example
-`(int)x`.
-
-The following sections specify the implicit casts that can be performed and the
-explicit casts that are allowed. The only other permitted cast is casting
-a single character `String` to a `char`.
-
-*Grammar:*
-[source,ANTLR4]
-----
-cast: '(' TYPE ')' expression
-----
-
-[[numeric-casting]]
-==== Numeric Casting
-
-The following table shows the allowed implicit and explicit casts between
-numeric types. Read the table by row. To find out if you need to explicitly
-cast from type A to type B, find the row for type A and scan across to the
-column for type B.
-
-IMPORTANT: Explicit casts between numeric types can result in some data loss. A
-smaller numeric type cannot necessarily accommodate the value from a larger
-numeric type. You might also lose precision when casting from integer types
-to floating point types.
-
-|====
-| | byte | short | char | int | long | float | double
-| byte | | implicit | implicit | implicit | implicit | implicit | implicit
-| short | explicit | | explicit | implicit | implicit | implicit | implicit
-| char | explicit | explicit | | implicit | implicit | implicit | implicit
-| int | explicit | explicit | explicit | | implicit | implicit | implicit
-| long | explicit | explicit | explicit | explicit | | implicit | implicit
-| float | explicit | explicit | explicit | explicit | explicit | | implicit
-| double | explicit | explicit | explicit | explicit | explicit | explicit |
-|====
-
-
-Example(s)
-[source,Java]
-----
-int a = 1; // Declare int variable a and set it to the literal
- // value 1
-long b = a; // Declare long variable b and set it to int variable
- // a with an implicit cast to convert from int to long
-short c = (short)b; // Declare short variable c, explicitly cast b to a
- // short, and assign b to c
-byte d = a; // ERROR: Casting an int to a byte requires an explicit
- // cast
-double e = (double)a; // Explicitly cast int variable a to a double and assign
- // it to the double variable e. The explicit cast is
- // allowed, but it is not necessary.
-----
-
-[[reference-casting]]
-==== Reference Casting
-
-A reference type can be implicitly cast to another reference type as long as
-the type being cast _from_ is a descendant of the type being cast _to_. A
-reference type can be explicitly cast _to_ if the type being cast to is a
-descendant of the type being cast _from_.
-
-*Examples:*
-[source,Java]
-----
-List x; // Declare List variable x
-ArrayList y = new ArrayList(); // Declare ArrayList variable y and assign it a
- // newly allocated ArrayList [1]
-x = y; // Assign Arraylist y to List x using an
- // implicit cast
-y = (ArrayList)x; // Explicitly cast List x to an ArrayList and
- // assign it to ArrayList y
-x = (List)y; // Set List x to ArrayList y using an explicit
- // cast (the explicit cast is not necessary)
-y = x; // ERROR: List x cannot be implicitly cast to
- // an ArrayList, an explicit cast is required
-Map m = y; // ERROR: Cannot implicitly or explicitly cast [2]
- // an ArrayList to a Map, no relationship
- // exists between the two types.
-----
-[1] `ArrayList` is a descendant of the `List` type.
-[2] `Map` is unrelated to the `List` and `ArrayList` types.
-
-[[def-type-casting]]
-==== def Type Casting
-All primitive and reference types can always be implicitly cast to
-`def`. While it is possible to explicitly cast to `def`, it is not necessary.
-
-However, it is not always possible to implicitly cast a `def` to other
-primitive and reference types. An explicit cast is required if an explicit
-cast would normally be required between the non-def types.
-
-
-*Examples:*
-[source,Java]
-----
-def x; // Declare def variable x and set it to null
-x = 3; // Set the def variable x to the literal 3 with an implicit
- // cast from int to def
-double a = x; // Declare double variable a and set it to def variable x,
- // which contains a double
-int b = x; // ERROR: Results in a run-time error because an explicit cast is
- // required to cast from a double to an int
-int c = (int)x; // Declare int variable c, explicitly cast def variable x to an
- // int, and assign x to c
-----
-
-[[boxing-unboxing]]
-==== Boxing and Unboxing
-
-Boxing is where a cast is used to convert a primitive type to its corresponding
-reference type. Unboxing is the reverse, converting a reference type to the
-corresponding primitive type.
-
-There are two places Painless performs implicit boxing and unboxing:
-
-* When you call methods, Painless automatically boxes and unboxes arguments
-so you can specify either primitive types or their corresponding reference
-types.
-* When you use the `def` type, Painless automatically boxes and unboxes as
-needed when converting to and from `def`.
-
-The casting operator does not support any way to explicitly box a primitive
-type or unbox a reference type.
-
-If a primitive type needs to be converted to a reference type, the Painless
-reference type API supports methods that can do that. However, under normal
-circumstances this should not be necessary.
-
-*Examples:*
-[source,Java]
-----
-Integer x = 1; // ERROR: not a legal implicit cast
-Integer y = (Integer)1; // ERROR: not a legal explicit cast
-int a = new Integer(1); // ERROR: not a legal implicit cast
-int b = (int)new Integer(1); // ERROR: not a legal explicit cast
-----
-
-[[promotion]]
-==== Promotion
-
-Promotion is where certain operations require types to be either a minimum
-numerical type or for two (or more) types to be equivalent.
-The documentation for each operation that has these requirements
-includes promotion tables that describe how this is handled.
-
-When an operation promotes a type or types, the resultant type
-of the operation is the promoted type. Types can be promoted to def
-at compile-time; however, at run-time, the resultant type will be the
-promotion of the types the `def` is representing.
-
-*Examples:*
-[source,Java]
-----
-2 + 2.0 // Add the literal int 2 and the literal double 2.0. The literal
- // 2 is promoted to a double and the resulting value is a double.
-
-def x = 1; // Declare def variable x and set it to the literal int 1 through
- // an implicit cast
-x + 2.0F // Add def variable x and the literal float 2.0.
- // At compile-time the types are promoted to def.
- // At run-time the types are promoted to float.
-----
diff --git a/docs/painless/painless-variables.asciidoc b/docs/painless/painless-variables.asciidoc
index 2177b0bb91ba8..08725b328a3c2 100644
--- a/docs/painless/painless-variables.asciidoc
+++ b/docs/painless/painless-variables.asciidoc
@@ -1,15 +1,15 @@
-[[variables]]
+[[painless-variables]]
=== Variables
-Variables in Painless must be declared and can be statically or <>.
+Variables in Painless must be declared and can be
+statically or <>.
-[[variable-identifiers]]
-==== Variable Identifiers
+[[identifiers]]
+==== Identifiers
Specify variable identifiers using the following grammar. Variable identifiers
-must start with a letter or underscore. You cannot use <> or
-<> as identifiers.
+must start with a letter or underscore. You cannot use
+<> or <> as identifiers.
*Grammar:*
[source,ANTLR4]
@@ -20,7 +20,6 @@ ID: [_a-zA-Z] [_a-zA-Z-0-9]*;
*Examples:*
[source,Java]
----
-_
a
Z
id
@@ -30,8 +29,8 @@ MAP25
_map25
----
-[[variable-declaration]]
-==== Variable Declaration
+[[declaration]]
+==== Declaration
Variables must be declared before you use them. The format is `type-name
identifier-name`. To declare multiple variables of the same type, specify a
@@ -56,7 +55,7 @@ int i = 10; // Declare the int variable i and set it to the int literal 10
----
[[variable-assignment]]
-==== Variable Assignment
+==== Assignment
Use the equals operator (`=`) to assign a value to a variable. The format is
`identifier-name = value`. Any value expression can be assigned to any variable
@@ -80,7 +79,7 @@ int i; // Declare an int i
i = 10; // Set the int i to the int literal 10
----
-Immediately assigning a value when declaring a variable.
+Immediately assigning a value when declaring a variable.
[source,Java]
----
diff --git a/docs/reference/redirects.asciidoc b/docs/reference/redirects.asciidoc
index 2e2967d4efab9..9ad3072e74903 100644
--- a/docs/reference/redirects.asciidoc
+++ b/docs/reference/redirects.asciidoc
@@ -484,7 +484,7 @@ Using `_index` in scripts has been replaced with writing `ScriptEngine` backends
=== Painless Syntax
See the
-{painless}/painless-specification.html[Painless Language Specification]
+{painless}/painless-lang-spec.html[Painless Language Specification]
in the guide to the {painless}/index.html[Painless Scripting Language].
[role="exclude",id="modules-scripting-painless-debugging"]
From 17302a00c293a331aadf3cc36aefb5331ff7bbfd Mon Sep 17 00:00:00 2001
From: Jack Conradson
Date: Wed, 18 Apr 2018 10:32:42 -0700
Subject: [PATCH 15/15] Painless: modify grammar to allow more statement
delimiters (#29566)
This allows the grammar to determine when and what delimiters statements will use by
splitting up the statements into regular statements and delimited statements, those that do
not require a delimiter versus those that do. This allows consumers of the statements to
determine what delimiters the statements will use so that in certain cases semicolons are
not necessary like when there's a closing right bracket.
This change removes the need for semicolon insertion in the lexer, simplifying the existing
lexer quite a bit. It also ensures that there isn't a need to track semicolons being inserted
into places that aren't necessary such as array initializers.
---
.../src/main/antlr/PainlessParser.g4 | 47 +-
.../painless/antlr/EnhancedPainlessLexer.java | 40 +-
.../painless/antlr/PainlessParser.java | 1607 +++++++++--------
.../antlr/PainlessParserBaseVisitor.java | 30 +-
.../painless/antlr/PainlessParserVisitor.java | 62 +-
.../elasticsearch/painless/antlr/Walker.java | 35 +-
.../elasticsearch/painless/RegexTests.java | 2 +-
.../painless/WhenThingsGoWrongTests.java | 2 +-
8 files changed, 936 insertions(+), 889 deletions(-)
diff --git a/modules/lang-painless/src/main/antlr/PainlessParser.g4 b/modules/lang-painless/src/main/antlr/PainlessParser.g4
index bfa4ee28dcc88..5292b4d195056 100644
--- a/modules/lang-painless/src/main/antlr/PainlessParser.g4
+++ b/modules/lang-painless/src/main/antlr/PainlessParser.g4
@@ -22,7 +22,7 @@ parser grammar PainlessParser;
options { tokenVocab=PainlessLexer; }
source
- : function* statement* EOF
+ : function* statement* dstatement? EOF
;
function
@@ -33,23 +33,31 @@ parameters
: LP ( decltype ID ( COMMA decltype ID )* )? RP
;
+statement
+ : rstatement
+ | dstatement SEMICOLON
+ ;
+
// Note we use a predicate on the if/else case here to prevent the
// "dangling-else" ambiguity by forcing the 'else' token to be consumed
// as soon as one is found. See (https://en.wikipedia.org/wiki/Dangling_else).
-statement
+rstatement
: IF LP expression RP trailer ( ELSE trailer | { _input.LA(1) != ELSE }? ) # if
| WHILE LP expression RP ( trailer | empty ) # while
- | DO block WHILE LP expression RP delimiter # do
| FOR LP initializer? SEMICOLON expression? SEMICOLON afterthought? RP ( trailer | empty ) # for
| FOR LP decltype ID COLON expression RP trailer # each
| FOR LP ID IN expression RP trailer # ineach
- | declaration delimiter # decl
- | CONTINUE delimiter # continue
- | BREAK delimiter # break
- | RETURN expression delimiter # return
| TRY block trap+ # try
- | THROW expression delimiter # throw
- | expression delimiter # expr
+ ;
+
+dstatement
+ : DO block WHILE LP expression RP # do
+ | declaration # decl
+ | CONTINUE # continue
+ | BREAK # break
+ | RETURN expression # return
+ | THROW expression # throw
+ | expression # expr
;
trailer
@@ -58,7 +66,7 @@ trailer
;
block
- : LBRACK statement* RBRACK
+ : LBRACK statement* dstatement? RBRACK
;
empty
@@ -90,11 +98,6 @@ trap
: CATCH LP TYPE ID RP block
;
-delimiter
- : SEMICOLON
- | EOF
- ;
-
expression
: unary # single
| expression ( MUL | DIV | REM ) expression # binary
@@ -169,8 +172,8 @@ braceaccess
;
arrayinitializer
- : NEW TYPE ( LBRACE expression RBRACE )+ ( postdot postfix* )? # newstandardarray
- | NEW TYPE LBRACE RBRACE LBRACK ( expression ( COMMA expression )* )? SEMICOLON? RBRACK postfix* # newinitializedarray
+ : NEW TYPE ( LBRACE expression RBRACE )+ ( postdot postfix* )? # newstandardarray
+ | NEW TYPE LBRACE RBRACE LBRACK ( expression ( COMMA expression )* )? RBRACK postfix* # newinitializedarray
;
listinitializer
@@ -206,10 +209,8 @@ lamtype
;
funcref
- : TYPE REF ID # classfuncref // reference to a static or instance method,
- // e.g. ArrayList::size or Integer::compare
- | decltype REF NEW # constructorfuncref // reference to a constructor, e.g. ArrayList::new
- | ID REF ID # capturingfuncref // reference to an instance method, e.g. object::toString
- // currently limited to capture of a simple variable (id).
- | THIS REF ID # localfuncref // reference to a local function, e.g. this::myfunc
+ : TYPE REF ID # classfuncref
+ | decltype REF NEW # constructorfuncref
+ | ID REF ID # capturingfuncref
+ | THIS REF ID # localfuncref
;
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/EnhancedPainlessLexer.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/EnhancedPainlessLexer.java
index 506ac8fcdecdb..adef4d3642571 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/EnhancedPainlessLexer.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/EnhancedPainlessLexer.java
@@ -44,8 +44,7 @@ final class EnhancedPainlessLexer extends PainlessLexer {
private final String sourceName;
private final Definition definition;
- private Token stashedNext = null;
- private Token previous = null;
+ private Token current = null;
EnhancedPainlessLexer(CharStream charStream, String sourceName, Definition definition) {
super(charStream);
@@ -53,27 +52,10 @@ final class EnhancedPainlessLexer extends PainlessLexer {
this.definition = definition;
}
- public Token getPreviousToken() {
- return previous;
- }
-
@Override
public Token nextToken() {
- if (stashedNext != null) {
- previous = stashedNext;
- stashedNext = null;
- return previous;
- }
- Token next = super.nextToken();
- if (insertSemicolon(previous, next)) {
- stashedNext = next;
- previous = _factory.create(new Pair(this, _input), PainlessLexer.SEMICOLON, ";",
- Lexer.DEFAULT_TOKEN_CHANNEL, next.getStartIndex(), next.getStopIndex(), next.getLine(), next.getCharPositionInLine());
- return previous;
- } else {
- previous = next;
- return next;
- }
+ current = super.nextToken();
+ return current;
}
@Override
@@ -101,7 +83,7 @@ protected boolean isSimpleType(String name) {
@Override
protected boolean slashIsRegex() {
- Token lastToken = getPreviousToken();
+ Token lastToken = current;
if (lastToken == null) {
return true;
}
@@ -120,18 +102,4 @@ protected boolean slashIsRegex() {
return true;
}
}
-
- private static boolean insertSemicolon(Token previous, Token next) {
- if (previous == null || next.getType() != PainlessLexer.RBRACK) {
- return false;
- }
- switch (previous.getType()) {
- case PainlessLexer.RBRACK: // };} would be weird!
- case PainlessLexer.SEMICOLON: // already have a semicolon, no need to add one
- case PainlessLexer.LBRACK: // empty blocks don't need a semicolon
- return false;
- default:
- return true;
- }
- }
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java
index 528a8a3d851c6..bba53d650ad32 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java
@@ -30,21 +30,21 @@ class PainlessParser extends Parser {
ID=82, DOTINTEGER=83, DOTID=84;
public static final int
RULE_source = 0, RULE_function = 1, RULE_parameters = 2, RULE_statement = 3,
- RULE_trailer = 4, RULE_block = 5, RULE_empty = 6, RULE_initializer = 7,
- RULE_afterthought = 8, RULE_declaration = 9, RULE_decltype = 10, RULE_declvar = 11,
- RULE_trap = 12, RULE_delimiter = 13, RULE_expression = 14, RULE_unary = 15,
- RULE_chain = 16, RULE_primary = 17, RULE_postfix = 18, RULE_postdot = 19,
- RULE_callinvoke = 20, RULE_fieldaccess = 21, RULE_braceaccess = 22, RULE_arrayinitializer = 23,
- RULE_listinitializer = 24, RULE_mapinitializer = 25, RULE_maptoken = 26,
- RULE_arguments = 27, RULE_argument = 28, RULE_lambda = 29, RULE_lamtype = 30,
- RULE_funcref = 31;
+ RULE_rstatement = 4, RULE_dstatement = 5, RULE_trailer = 6, RULE_block = 7,
+ RULE_empty = 8, RULE_initializer = 9, RULE_afterthought = 10, RULE_declaration = 11,
+ RULE_decltype = 12, RULE_declvar = 13, RULE_trap = 14, RULE_expression = 15,
+ RULE_unary = 16, RULE_chain = 17, RULE_primary = 18, RULE_postfix = 19,
+ RULE_postdot = 20, RULE_callinvoke = 21, RULE_fieldaccess = 22, RULE_braceaccess = 23,
+ RULE_arrayinitializer = 24, RULE_listinitializer = 25, RULE_mapinitializer = 26,
+ RULE_maptoken = 27, RULE_arguments = 28, RULE_argument = 29, RULE_lambda = 30,
+ RULE_lamtype = 31, RULE_funcref = 32;
public static final String[] ruleNames = {
- "source", "function", "parameters", "statement", "trailer", "block", "empty",
- "initializer", "afterthought", "declaration", "decltype", "declvar", "trap",
- "delimiter", "expression", "unary", "chain", "primary", "postfix", "postdot",
- "callinvoke", "fieldaccess", "braceaccess", "arrayinitializer", "listinitializer",
- "mapinitializer", "maptoken", "arguments", "argument", "lambda", "lamtype",
- "funcref"
+ "source", "function", "parameters", "statement", "rstatement", "dstatement",
+ "trailer", "block", "empty", "initializer", "afterthought", "declaration",
+ "decltype", "declvar", "trap", "expression", "unary", "chain", "primary",
+ "postfix", "postdot", "callinvoke", "fieldaccess", "braceaccess", "arrayinitializer",
+ "listinitializer", "mapinitializer", "maptoken", "arguments", "argument",
+ "lambda", "lamtype", "funcref"
};
private static final String[] _LITERAL_NAMES = {
@@ -133,6 +133,9 @@ public List statement() {
public StatementContext statement(int i) {
return getRuleContext(StatementContext.class,i);
}
+ public DstatementContext dstatement() {
+ return getRuleContext(DstatementContext.class,0);
+ }
public SourceContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@@ -152,37 +155,48 @@ public final SourceContext source() throws RecognitionException {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(67);
+ setState(69);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,0,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(64);
+ setState(66);
function();
}
}
}
- setState(69);
+ setState(71);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,0,_ctx);
}
- setState(73);
+ setState(75);
_errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,1,_ctx);
+ while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
+ if ( _alt==1 ) {
+ {
+ {
+ setState(72);
+ statement();
+ }
+ }
+ }
+ setState(77);
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,1,_ctx);
+ }
+ setState(79);
_la = _input.LA(1);
- while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << IF) | (1L << WHILE) | (1L << DO) | (1L << FOR) | (1L << CONTINUE) | (1L << BREAK) | (1L << RETURN) | (1L << NEW) | (1L << TRY) | (1L << THROW) | (1L << BOOLNOT) | (1L << BWNOT) | (1L << ADD) | (1L << SUB) | (1L << INCR) | (1L << DECR))) != 0) || ((((_la - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (OCTAL - 72)) | (1L << (HEX - 72)) | (1L << (INTEGER - 72)) | (1L << (DECIMAL - 72)) | (1L << (STRING - 72)) | (1L << (REGEX - 72)) | (1L << (TRUE - 72)) | (1L << (FALSE - 72)) | (1L << (NULL - 72)) | (1L << (TYPE - 72)) | (1L << (ID - 72)))) != 0)) {
+ if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << DO) | (1L << CONTINUE) | (1L << BREAK) | (1L << RETURN) | (1L << NEW) | (1L << THROW) | (1L << BOOLNOT) | (1L << BWNOT) | (1L << ADD) | (1L << SUB) | (1L << INCR) | (1L << DECR))) != 0) || ((((_la - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (OCTAL - 72)) | (1L << (HEX - 72)) | (1L << (INTEGER - 72)) | (1L << (DECIMAL - 72)) | (1L << (STRING - 72)) | (1L << (REGEX - 72)) | (1L << (TRUE - 72)) | (1L << (FALSE - 72)) | (1L << (NULL - 72)) | (1L << (TYPE - 72)) | (1L << (ID - 72)))) != 0)) {
{
- {
- setState(70);
- statement();
- }
+ setState(78);
+ dstatement();
}
- setState(75);
- _errHandler.sync(this);
- _la = _input.LA(1);
}
- setState(76);
+
+ setState(81);
match(EOF);
}
}
@@ -225,13 +239,13 @@ public final FunctionContext function() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(78);
+ setState(83);
decltype();
- setState(79);
+ setState(84);
match(ID);
- setState(80);
+ setState(85);
parameters();
- setState(81);
+ setState(86);
block();
}
}
@@ -281,38 +295,38 @@ public final ParametersContext parameters() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(83);
+ setState(88);
match(LP);
- setState(95);
+ setState(100);
_la = _input.LA(1);
if (_la==TYPE) {
{
- setState(84);
+ setState(89);
decltype();
- setState(85);
+ setState(90);
match(ID);
- setState(92);
+ setState(97);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==COMMA) {
{
{
- setState(86);
+ setState(91);
match(COMMA);
- setState(87);
+ setState(92);
decltype();
- setState(88);
+ setState(93);
match(ID);
}
}
- setState(94);
+ setState(99);
_errHandler.sync(this);
_la = _input.LA(1);
}
}
}
- setState(97);
+ setState(102);
match(RP);
}
}
@@ -328,43 +342,100 @@ public final ParametersContext parameters() throws RecognitionException {
}
public static class StatementContext extends ParserRuleContext {
+ public RstatementContext rstatement() {
+ return getRuleContext(RstatementContext.class,0);
+ }
+ public DstatementContext dstatement() {
+ return getRuleContext(DstatementContext.class,0);
+ }
+ public TerminalNode SEMICOLON() { return getToken(PainlessParser.SEMICOLON, 0); }
public StatementContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_statement; }
-
- public StatementContext() { }
- public void copyFrom(StatementContext ctx) {
- super.copyFrom(ctx);
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitStatement(this);
+ else return visitor.visitChildren(this);
}
}
- public static class DeclContext extends StatementContext {
- public DeclarationContext declaration() {
- return getRuleContext(DeclarationContext.class,0);
+
+ public final StatementContext statement() throws RecognitionException {
+ StatementContext _localctx = new StatementContext(_ctx, getState());
+ enterRule(_localctx, 6, RULE_statement);
+ try {
+ setState(108);
+ switch (_input.LA(1)) {
+ case IF:
+ case WHILE:
+ case FOR:
+ case TRY:
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(104);
+ rstatement();
+ }
+ break;
+ case LBRACE:
+ case LP:
+ case DO:
+ case CONTINUE:
+ case BREAK:
+ case RETURN:
+ case NEW:
+ case THROW:
+ case BOOLNOT:
+ case BWNOT:
+ case ADD:
+ case SUB:
+ case INCR:
+ case DECR:
+ case OCTAL:
+ case HEX:
+ case INTEGER:
+ case DECIMAL:
+ case STRING:
+ case REGEX:
+ case TRUE:
+ case FALSE:
+ case NULL:
+ case TYPE:
+ case ID:
+ enterOuterAlt(_localctx, 2);
+ {
+ setState(105);
+ dstatement();
+ setState(106);
+ match(SEMICOLON);
+ }
+ break;
+ default:
+ throw new NoViableAltException(this);
+ }
}
- public DelimiterContext delimiter() {
- return getRuleContext(DelimiterContext.class,0);
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
}
- public DeclContext(StatementContext ctx) { copyFrom(ctx); }
- @Override
- public T accept(ParseTreeVisitor extends T> visitor) {
- if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitDecl(this);
- else return visitor.visitChildren(this);
+ finally {
+ exitRule();
}
+ return _localctx;
}
- public static class BreakContext extends StatementContext {
- public TerminalNode BREAK() { return getToken(PainlessParser.BREAK, 0); }
- public DelimiterContext delimiter() {
- return getRuleContext(DelimiterContext.class,0);
+
+ public static class RstatementContext extends ParserRuleContext {
+ public RstatementContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
}
- public BreakContext(StatementContext ctx) { copyFrom(ctx); }
- @Override
- public T accept(ParseTreeVisitor extends T> visitor) {
- if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitBreak(this);
- else return visitor.visitChildren(this);
+ @Override public int getRuleIndex() { return RULE_rstatement; }
+
+ public RstatementContext() { }
+ public void copyFrom(RstatementContext ctx) {
+ super.copyFrom(ctx);
}
}
- public static class ForContext extends StatementContext {
+ public static class ForContext extends RstatementContext {
public TerminalNode FOR() { return getToken(PainlessParser.FOR, 0); }
public TerminalNode LP() { return getToken(PainlessParser.LP, 0); }
public List SEMICOLON() { return getTokens(PainlessParser.SEMICOLON); }
@@ -387,35 +458,32 @@ public ExpressionContext expression() {
public AfterthoughtContext afterthought() {
return getRuleContext(AfterthoughtContext.class,0);
}
- public ForContext(StatementContext ctx) { copyFrom(ctx); }
+ public ForContext(RstatementContext ctx) { copyFrom(ctx); }
@Override
public T accept(ParseTreeVisitor extends T> visitor) {
if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitFor(this);
else return visitor.visitChildren(this);
}
}
- public static class DoContext extends StatementContext {
- public TerminalNode DO() { return getToken(PainlessParser.DO, 0); }
+ public static class TryContext extends RstatementContext {
+ public TerminalNode TRY() { return getToken(PainlessParser.TRY, 0); }
public BlockContext block() {
return getRuleContext(BlockContext.class,0);
}
- public TerminalNode WHILE() { return getToken(PainlessParser.WHILE, 0); }
- public TerminalNode LP() { return getToken(PainlessParser.LP, 0); }
- public ExpressionContext expression() {
- return getRuleContext(ExpressionContext.class,0);
+ public List trap() {
+ return getRuleContexts(TrapContext.class);
}
- public TerminalNode RP() { return getToken(PainlessParser.RP, 0); }
- public DelimiterContext delimiter() {
- return getRuleContext(DelimiterContext.class,0);
+ public TrapContext trap(int i) {
+ return getRuleContext(TrapContext.class,i);
}
- public DoContext(StatementContext ctx) { copyFrom(ctx); }
+ public TryContext(RstatementContext ctx) { copyFrom(ctx); }
@Override
public T accept(ParseTreeVisitor extends T> visitor) {
- if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitDo(this);
+ if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitTry(this);
else return visitor.visitChildren(this);
}
}
- public static class WhileContext extends StatementContext {
+ public static class WhileContext extends RstatementContext {
public TerminalNode WHILE() { return getToken(PainlessParser.WHILE, 0); }
public TerminalNode LP() { return getToken(PainlessParser.LP, 0); }
public ExpressionContext expression() {
@@ -428,14 +496,14 @@ public TrailerContext trailer() {
public EmptyContext empty() {
return getRuleContext(EmptyContext.class,0);
}
- public WhileContext(StatementContext ctx) { copyFrom(ctx); }
+ public WhileContext(RstatementContext ctx) { copyFrom(ctx); }
@Override
public T accept(ParseTreeVisitor extends T> visitor) {
if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitWhile(this);
else return visitor.visitChildren(this);
}
}
- public static class IneachContext extends StatementContext {
+ public static class IneachContext extends RstatementContext {
public TerminalNode FOR() { return getToken(PainlessParser.FOR, 0); }
public TerminalNode LP() { return getToken(PainlessParser.LP, 0); }
public TerminalNode ID() { return getToken(PainlessParser.ID, 0); }
@@ -447,95 +515,14 @@ public ExpressionContext expression() {
public TrailerContext trailer() {
return getRuleContext(TrailerContext.class,0);
}
- public IneachContext(StatementContext ctx) { copyFrom(ctx); }
+ public IneachContext(RstatementContext ctx) { copyFrom(ctx); }
@Override
public T accept(ParseTreeVisitor extends T> visitor) {
if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitIneach(this);
else return visitor.visitChildren(this);
}
}
- public static class EachContext extends StatementContext {
- public TerminalNode FOR() { return getToken(PainlessParser.FOR, 0); }
- public TerminalNode LP() { return getToken(PainlessParser.LP, 0); }
- public DecltypeContext decltype() {
- return getRuleContext(DecltypeContext.class,0);
- }
- public TerminalNode ID() { return getToken(PainlessParser.ID, 0); }
- public TerminalNode COLON() { return getToken(PainlessParser.COLON, 0); }
- public ExpressionContext expression() {
- return getRuleContext(ExpressionContext.class,0);
- }
- public TerminalNode RP() { return getToken(PainlessParser.RP, 0); }
- public TrailerContext trailer() {
- return getRuleContext(TrailerContext.class,0);
- }
- public EachContext(StatementContext ctx) { copyFrom(ctx); }
- @Override
- public T accept(ParseTreeVisitor extends T> visitor) {
- if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitEach(this);
- else return visitor.visitChildren(this);
- }
- }
- public static class ThrowContext extends StatementContext {
- public TerminalNode THROW() { return getToken(PainlessParser.THROW, 0); }
- public ExpressionContext expression() {
- return getRuleContext(ExpressionContext.class,0);
- }
- public DelimiterContext delimiter() {
- return getRuleContext(DelimiterContext.class,0);
- }
- public ThrowContext(StatementContext ctx) { copyFrom(ctx); }
- @Override
- public T accept(ParseTreeVisitor extends T> visitor) {
- if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitThrow(this);
- else return visitor.visitChildren(this);
- }
- }
- public static class ContinueContext extends StatementContext {
- public TerminalNode CONTINUE() { return getToken(PainlessParser.CONTINUE, 0); }
- public DelimiterContext delimiter() {
- return getRuleContext(DelimiterContext.class,0);
- }
- public ContinueContext(StatementContext ctx) { copyFrom(ctx); }
- @Override
- public T accept(ParseTreeVisitor extends T> visitor) {
- if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitContinue(this);
- else return visitor.visitChildren(this);
- }
- }
- public static class TryContext extends StatementContext {
- public TerminalNode TRY() { return getToken(PainlessParser.TRY, 0); }
- public BlockContext block() {
- return getRuleContext(BlockContext.class,0);
- }
- public List trap() {
- return getRuleContexts(TrapContext.class);
- }
- public TrapContext trap(int i) {
- return getRuleContext(TrapContext.class,i);
- }
- public TryContext(StatementContext ctx) { copyFrom(ctx); }
- @Override
- public T accept(ParseTreeVisitor extends T> visitor) {
- if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitTry(this);
- else return visitor.visitChildren(this);
- }
- }
- public static class ExprContext extends StatementContext {
- public ExpressionContext expression() {
- return getRuleContext(ExpressionContext.class,0);
- }
- public DelimiterContext delimiter() {
- return getRuleContext(DelimiterContext.class,0);
- }
- public ExprContext(StatementContext ctx) { copyFrom(ctx); }
- @Override
- public T accept(ParseTreeVisitor extends T> visitor) {
- if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitExpr(this);
- else return visitor.visitChildren(this);
- }
- }
- public static class IfContext extends StatementContext {
+ public static class IfContext extends RstatementContext {
public TerminalNode IF() { return getToken(PainlessParser.IF, 0); }
public TerminalNode LP() { return getToken(PainlessParser.LP, 0); }
public ExpressionContext expression() {
@@ -549,66 +536,73 @@ public TrailerContext trailer(int i) {
return getRuleContext(TrailerContext.class,i);
}
public TerminalNode ELSE() { return getToken(PainlessParser.ELSE, 0); }
- public IfContext(StatementContext ctx) { copyFrom(ctx); }
+ public IfContext(RstatementContext ctx) { copyFrom(ctx); }
@Override
public T accept(ParseTreeVisitor extends T> visitor) {
if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitIf(this);
else return visitor.visitChildren(this);
}
}
- public static class ReturnContext extends StatementContext {
- public TerminalNode RETURN() { return getToken(PainlessParser.RETURN, 0); }
+ public static class EachContext extends RstatementContext {
+ public TerminalNode FOR() { return getToken(PainlessParser.FOR, 0); }
+ public TerminalNode LP() { return getToken(PainlessParser.LP, 0); }
+ public DecltypeContext decltype() {
+ return getRuleContext(DecltypeContext.class,0);
+ }
+ public TerminalNode ID() { return getToken(PainlessParser.ID, 0); }
+ public TerminalNode COLON() { return getToken(PainlessParser.COLON, 0); }
public ExpressionContext expression() {
return getRuleContext(ExpressionContext.class,0);
}
- public DelimiterContext delimiter() {
- return getRuleContext(DelimiterContext.class,0);
+ public TerminalNode RP() { return getToken(PainlessParser.RP, 0); }
+ public TrailerContext trailer() {
+ return getRuleContext(TrailerContext.class,0);
}
- public ReturnContext(StatementContext ctx) { copyFrom(ctx); }
+ public EachContext(RstatementContext ctx) { copyFrom(ctx); }
@Override
public T accept(ParseTreeVisitor extends T> visitor) {
- if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitReturn(this);
+ if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitEach(this);
else return visitor.visitChildren(this);
}
}
- public final StatementContext statement() throws RecognitionException {
- StatementContext _localctx = new StatementContext(_ctx, getState());
- enterRule(_localctx, 6, RULE_statement);
+ public final RstatementContext rstatement() throws RecognitionException {
+ RstatementContext _localctx = new RstatementContext(_ctx, getState());
+ enterRule(_localctx, 8, RULE_rstatement);
int _la;
try {
int _alt;
- setState(185);
+ setState(170);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) {
case 1:
_localctx = new IfContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(99);
+ setState(110);
match(IF);
- setState(100);
+ setState(111);
match(LP);
- setState(101);
+ setState(112);
expression(0);
- setState(102);
+ setState(113);
match(RP);
- setState(103);
+ setState(114);
trailer();
- setState(107);
+ setState(118);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) {
case 1:
{
- setState(104);
+ setState(115);
match(ELSE);
- setState(105);
+ setState(116);
trailer();
}
break;
case 2:
{
- setState(106);
+ setState(117);
if (!( _input.LA(1) != ELSE )) throw new FailedPredicateException(this, " _input.LA(1) != ELSE ");
}
break;
@@ -619,15 +613,15 @@ public final StatementContext statement() throws RecognitionException {
_localctx = new WhileContext(_localctx);
enterOuterAlt(_localctx, 2);
{
- setState(109);
+ setState(120);
match(WHILE);
- setState(110);
+ setState(121);
match(LP);
- setState(111);
+ setState(122);
expression(0);
- setState(112);
+ setState(123);
match(RP);
- setState(115);
+ setState(126);
switch (_input.LA(1)) {
case LBRACK:
case LBRACE:
@@ -660,13 +654,13 @@ public final StatementContext statement() throws RecognitionException {
case TYPE:
case ID:
{
- setState(113);
+ setState(124);
trailer();
}
break;
case SEMICOLON:
{
- setState(114);
+ setState(125);
empty();
}
break;
@@ -676,67 +670,47 @@ public final StatementContext statement() throws RecognitionException {
}
break;
case 3:
- _localctx = new DoContext(_localctx);
- enterOuterAlt(_localctx, 3);
- {
- setState(117);
- match(DO);
- setState(118);
- block();
- setState(119);
- match(WHILE);
- setState(120);
- match(LP);
- setState(121);
- expression(0);
- setState(122);
- match(RP);
- setState(123);
- delimiter();
- }
- break;
- case 4:
_localctx = new ForContext(_localctx);
- enterOuterAlt(_localctx, 4);
+ enterOuterAlt(_localctx, 3);
{
- setState(125);
+ setState(128);
match(FOR);
- setState(126);
+ setState(129);
match(LP);
- setState(128);
+ setState(131);
_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 - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (OCTAL - 72)) | (1L << (HEX - 72)) | (1L << (INTEGER - 72)) | (1L << (DECIMAL - 72)) | (1L << (STRING - 72)) | (1L << (REGEX - 72)) | (1L << (TRUE - 72)) | (1L << (FALSE - 72)) | (1L << (NULL - 72)) | (1L << (TYPE - 72)) | (1L << (ID - 72)))) != 0)) {
{
- setState(127);
+ setState(130);
initializer();
}
}
- setState(130);
+ setState(133);
match(SEMICOLON);
- setState(132);
+ setState(135);
_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 - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (OCTAL - 72)) | (1L << (HEX - 72)) | (1L << (INTEGER - 72)) | (1L << (DECIMAL - 72)) | (1L << (STRING - 72)) | (1L << (REGEX - 72)) | (1L << (TRUE - 72)) | (1L << (FALSE - 72)) | (1L << (NULL - 72)) | (1L << (TYPE - 72)) | (1L << (ID - 72)))) != 0)) {
{
- setState(131);
+ setState(134);
expression(0);
}
}
- setState(134);
+ setState(137);
match(SEMICOLON);
- setState(136);
+ setState(139);
_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 - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (OCTAL - 72)) | (1L << (HEX - 72)) | (1L << (INTEGER - 72)) | (1L << (DECIMAL - 72)) | (1L << (STRING - 72)) | (1L << (REGEX - 72)) | (1L << (TRUE - 72)) | (1L << (FALSE - 72)) | (1L << (NULL - 72)) | (1L << (TYPE - 72)) | (1L << (ID - 72)))) != 0)) {
{
- setState(135);
+ setState(138);
afterthought();
}
}
- setState(138);
- match(RP);
setState(141);
+ match(RP);
+ setState(144);
switch (_input.LA(1)) {
case LBRACK:
case LBRACE:
@@ -769,13 +743,13 @@ public final StatementContext statement() throws RecognitionException {
case TYPE:
case ID:
{
- setState(139);
+ setState(142);
trailer();
}
break;
case SEMICOLON:
{
- setState(140);
+ setState(143);
empty();
}
break;
@@ -784,99 +758,57 @@ public final StatementContext statement() throws RecognitionException {
}
}
break;
- case 5:
+ case 4:
_localctx = new EachContext(_localctx);
- enterOuterAlt(_localctx, 5);
+ enterOuterAlt(_localctx, 4);
{
- setState(143);
+ setState(146);
match(FOR);
- setState(144);
+ setState(147);
match(LP);
- setState(145);
+ setState(148);
decltype();
- setState(146);
+ setState(149);
match(ID);
- setState(147);
+ setState(150);
match(COLON);
- setState(148);
+ setState(151);
expression(0);
- setState(149);
+ setState(152);
match(RP);
- setState(150);
+ setState(153);
trailer();
}
break;
- case 6:
+ case 5:
_localctx = new IneachContext(_localctx);
- enterOuterAlt(_localctx, 6);
+ enterOuterAlt(_localctx, 5);
{
- setState(152);
+ setState(155);
match(FOR);
- setState(153);
+ setState(156);
match(LP);
- setState(154);
+ setState(157);
match(ID);
- setState(155);
+ setState(158);
match(IN);
- setState(156);
+ setState(159);
expression(0);
- setState(157);
- match(RP);
- setState(158);
- trailer();
- }
- break;
- case 7:
- _localctx = new DeclContext(_localctx);
- enterOuterAlt(_localctx, 7);
- {
setState(160);
- declaration();
+ match(RP);
setState(161);
- delimiter();
- }
- break;
- case 8:
- _localctx = new ContinueContext(_localctx);
- enterOuterAlt(_localctx, 8);
- {
- setState(163);
- match(CONTINUE);
- setState(164);
- delimiter();
- }
- break;
- case 9:
- _localctx = new BreakContext(_localctx);
- enterOuterAlt(_localctx, 9);
- {
- setState(165);
- match(BREAK);
- setState(166);
- delimiter();
- }
- break;
- case 10:
- _localctx = new ReturnContext(_localctx);
- enterOuterAlt(_localctx, 10);
- {
- setState(167);
- match(RETURN);
- setState(168);
- expression(0);
- setState(169);
- delimiter();
+ trailer();
}
break;
- case 11:
+ case 6:
_localctx = new TryContext(_localctx);
- enterOuterAlt(_localctx, 11);
+ enterOuterAlt(_localctx, 6);
{
- setState(171);
+ setState(163);
match(TRY);
- setState(172);
+ setState(164);
block();
- setState(174);
+ setState(166);
_errHandler.sync(this);
_alt = 1;
do {
@@ -884,7 +816,7 @@ public final StatementContext statement() throws RecognitionException {
case 1:
{
{
- setState(173);
+ setState(165);
trap();
}
}
@@ -892,32 +824,194 @@ public final StatementContext statement() throws RecognitionException {
default:
throw new NoViableAltException(this);
}
- setState(176);
+ setState(168);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,10,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,12,_ctx);
} while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER );
}
break;
- case 12:
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class DstatementContext extends ParserRuleContext {
+ public DstatementContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_dstatement; }
+
+ public DstatementContext() { }
+ public void copyFrom(DstatementContext ctx) {
+ super.copyFrom(ctx);
+ }
+ }
+ public static class DeclContext extends DstatementContext {
+ public DeclarationContext declaration() {
+ return getRuleContext(DeclarationContext.class,0);
+ }
+ public DeclContext(DstatementContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitDecl(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class BreakContext extends DstatementContext {
+ public TerminalNode BREAK() { return getToken(PainlessParser.BREAK, 0); }
+ public BreakContext(DstatementContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitBreak(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class ThrowContext extends DstatementContext {
+ public TerminalNode THROW() { return getToken(PainlessParser.THROW, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public ThrowContext(DstatementContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitThrow(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class ContinueContext extends DstatementContext {
+ public TerminalNode CONTINUE() { return getToken(PainlessParser.CONTINUE, 0); }
+ public ContinueContext(DstatementContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitContinue(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class ExprContext extends DstatementContext {
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public ExprContext(DstatementContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitExpr(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class DoContext extends DstatementContext {
+ public TerminalNode DO() { return getToken(PainlessParser.DO, 0); }
+ public BlockContext block() {
+ return getRuleContext(BlockContext.class,0);
+ }
+ public TerminalNode WHILE() { return getToken(PainlessParser.WHILE, 0); }
+ public TerminalNode LP() { return getToken(PainlessParser.LP, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public TerminalNode RP() { return getToken(PainlessParser.RP, 0); }
+ public DoContext(DstatementContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitDo(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class ReturnContext extends DstatementContext {
+ public TerminalNode RETURN() { return getToken(PainlessParser.RETURN, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public ReturnContext(DstatementContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitReturn(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final DstatementContext dstatement() throws RecognitionException {
+ DstatementContext _localctx = new DstatementContext(_ctx, getState());
+ enterRule(_localctx, 10, RULE_dstatement);
+ try {
+ setState(187);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) {
+ case 1:
+ _localctx = new DoContext(_localctx);
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(172);
+ match(DO);
+ setState(173);
+ block();
+ setState(174);
+ match(WHILE);
+ setState(175);
+ match(LP);
+ setState(176);
+ expression(0);
+ setState(177);
+ match(RP);
+ }
+ break;
+ case 2:
+ _localctx = new DeclContext(_localctx);
+ enterOuterAlt(_localctx, 2);
+ {
+ setState(179);
+ declaration();
+ }
+ break;
+ case 3:
+ _localctx = new ContinueContext(_localctx);
+ enterOuterAlt(_localctx, 3);
+ {
+ setState(180);
+ match(CONTINUE);
+ }
+ break;
+ case 4:
+ _localctx = new BreakContext(_localctx);
+ enterOuterAlt(_localctx, 4);
+ {
+ setState(181);
+ match(BREAK);
+ }
+ break;
+ case 5:
+ _localctx = new ReturnContext(_localctx);
+ enterOuterAlt(_localctx, 5);
+ {
+ setState(182);
+ match(RETURN);
+ setState(183);
+ expression(0);
+ }
+ break;
+ case 6:
_localctx = new ThrowContext(_localctx);
- enterOuterAlt(_localctx, 12);
+ enterOuterAlt(_localctx, 6);
{
- setState(178);
+ setState(184);
match(THROW);
- setState(179);
+ setState(185);
expression(0);
- setState(180);
- delimiter();
}
break;
- case 13:
+ case 7:
_localctx = new ExprContext(_localctx);
- enterOuterAlt(_localctx, 13);
+ enterOuterAlt(_localctx, 7);
{
- setState(182);
+ setState(186);
expression(0);
- setState(183);
- delimiter();
}
break;
}
@@ -953,14 +1047,14 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final TrailerContext trailer() throws RecognitionException {
TrailerContext _localctx = new TrailerContext(_ctx, getState());
- enterRule(_localctx, 8, RULE_trailer);
+ enterRule(_localctx, 12, RULE_trailer);
try {
- setState(189);
+ setState(191);
switch (_input.LA(1)) {
case LBRACK:
enterOuterAlt(_localctx, 1);
{
- setState(187);
+ setState(189);
block();
}
break;
@@ -995,7 +1089,7 @@ public final TrailerContext trailer() throws RecognitionException {
case ID:
enterOuterAlt(_localctx, 2);
{
- setState(188);
+ setState(190);
statement();
}
break;
@@ -1023,6 +1117,9 @@ public List statement() {
public StatementContext statement(int i) {
return getRuleContext(StatementContext.class,i);
}
+ public DstatementContext dstatement() {
+ return getRuleContext(DstatementContext.class,0);
+ }
public BlockContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@@ -1036,28 +1133,40 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final BlockContext block() throws RecognitionException {
BlockContext _localctx = new BlockContext(_ctx, getState());
- enterRule(_localctx, 10, RULE_block);
+ enterRule(_localctx, 14, RULE_block);
int _la;
try {
+ int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(191);
+ setState(193);
match(LBRACK);
- setState(195);
+ setState(197);
_errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,16,_ctx);
+ while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
+ if ( _alt==1 ) {
+ {
+ {
+ setState(194);
+ statement();
+ }
+ }
+ }
+ setState(199);
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,16,_ctx);
+ }
+ setState(201);
_la = _input.LA(1);
- while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << IF) | (1L << WHILE) | (1L << DO) | (1L << FOR) | (1L << CONTINUE) | (1L << BREAK) | (1L << RETURN) | (1L << NEW) | (1L << TRY) | (1L << THROW) | (1L << BOOLNOT) | (1L << BWNOT) | (1L << ADD) | (1L << SUB) | (1L << INCR) | (1L << DECR))) != 0) || ((((_la - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (OCTAL - 72)) | (1L << (HEX - 72)) | (1L << (INTEGER - 72)) | (1L << (DECIMAL - 72)) | (1L << (STRING - 72)) | (1L << (REGEX - 72)) | (1L << (TRUE - 72)) | (1L << (FALSE - 72)) | (1L << (NULL - 72)) | (1L << (TYPE - 72)) | (1L << (ID - 72)))) != 0)) {
- {
+ if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << DO) | (1L << CONTINUE) | (1L << BREAK) | (1L << RETURN) | (1L << NEW) | (1L << THROW) | (1L << BOOLNOT) | (1L << BWNOT) | (1L << ADD) | (1L << SUB) | (1L << INCR) | (1L << DECR))) != 0) || ((((_la - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (OCTAL - 72)) | (1L << (HEX - 72)) | (1L << (INTEGER - 72)) | (1L << (DECIMAL - 72)) | (1L << (STRING - 72)) | (1L << (REGEX - 72)) | (1L << (TRUE - 72)) | (1L << (FALSE - 72)) | (1L << (NULL - 72)) | (1L << (TYPE - 72)) | (1L << (ID - 72)))) != 0)) {
{
- setState(192);
- statement();
- }
+ setState(200);
+ dstatement();
}
- setState(197);
- _errHandler.sync(this);
- _la = _input.LA(1);
}
- setState(198);
+
+ setState(203);
match(RBRACK);
}
}
@@ -1087,11 +1196,11 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final EmptyContext empty() throws RecognitionException {
EmptyContext _localctx = new EmptyContext(_ctx, getState());
- enterRule(_localctx, 12, RULE_empty);
+ enterRule(_localctx, 16, RULE_empty);
try {
enterOuterAlt(_localctx, 1);
{
- setState(200);
+ setState(205);
match(SEMICOLON);
}
}
@@ -1126,22 +1235,22 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final InitializerContext initializer() throws RecognitionException {
InitializerContext _localctx = new InitializerContext(_ctx, getState());
- enterRule(_localctx, 14, RULE_initializer);
+ enterRule(_localctx, 18, RULE_initializer);
try {
- setState(204);
+ setState(209);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,18,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
- setState(202);
+ setState(207);
declaration();
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
- setState(203);
+ setState(208);
expression(0);
}
break;
@@ -1175,11 +1284,11 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final AfterthoughtContext afterthought() throws RecognitionException {
AfterthoughtContext _localctx = new AfterthoughtContext(_ctx, getState());
- enterRule(_localctx, 16, RULE_afterthought);
+ enterRule(_localctx, 20, RULE_afterthought);
try {
enterOuterAlt(_localctx, 1);
{
- setState(206);
+ setState(211);
expression(0);
}
}
@@ -1221,28 +1330,28 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final DeclarationContext declaration() throws RecognitionException {
DeclarationContext _localctx = new DeclarationContext(_ctx, getState());
- enterRule(_localctx, 18, RULE_declaration);
+ enterRule(_localctx, 22, RULE_declaration);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(208);
+ setState(213);
decltype();
- setState(209);
- declvar();
setState(214);
+ declvar();
+ setState(219);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==COMMA) {
{
{
- setState(210);
+ setState(215);
match(COMMA);
- setState(211);
+ setState(216);
declvar();
}
}
- setState(216);
+ setState(221);
_errHandler.sync(this);
_la = _input.LA(1);
}
@@ -1282,30 +1391,30 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final DecltypeContext decltype() throws RecognitionException {
DecltypeContext _localctx = new DecltypeContext(_ctx, getState());
- enterRule(_localctx, 20, RULE_decltype);
+ enterRule(_localctx, 24, RULE_decltype);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(217);
- match(TYPE);
setState(222);
+ match(TYPE);
+ setState(227);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,16,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,20,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(218);
+ setState(223);
match(LBRACE);
- setState(219);
+ setState(224);
match(RBRACE);
}
}
}
- setState(224);
+ setState(229);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,16,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,20,_ctx);
}
}
}
@@ -1339,20 +1448,20 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final DeclvarContext declvar() throws RecognitionException {
DeclvarContext _localctx = new DeclvarContext(_ctx, getState());
- enterRule(_localctx, 22, RULE_declvar);
+ enterRule(_localctx, 26, RULE_declvar);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(225);
+ setState(230);
match(ID);
- setState(228);
+ setState(233);
_la = _input.LA(1);
if (_la==ASSIGN) {
{
- setState(226);
+ setState(231);
match(ASSIGN);
- setState(227);
+ setState(232);
expression(0);
}
}
@@ -1392,21 +1501,21 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final TrapContext trap() throws RecognitionException {
TrapContext _localctx = new TrapContext(_ctx, getState());
- enterRule(_localctx, 24, RULE_trap);
+ enterRule(_localctx, 28, RULE_trap);
try {
enterOuterAlt(_localctx, 1);
{
- setState(230);
+ setState(235);
match(CATCH);
- setState(231);
+ setState(236);
match(LP);
- setState(232);
+ setState(237);
match(TYPE);
- setState(233);
+ setState(238);
match(ID);
- setState(234);
+ setState(239);
match(RP);
- setState(235);
+ setState(240);
block();
}
}
@@ -1421,47 +1530,6 @@ public final TrapContext trap() throws RecognitionException {
return _localctx;
}
- public static class DelimiterContext extends ParserRuleContext {
- public TerminalNode SEMICOLON() { return getToken(PainlessParser.SEMICOLON, 0); }
- public TerminalNode EOF() { return getToken(PainlessParser.EOF, 0); }
- public DelimiterContext(ParserRuleContext parent, int invokingState) {
- super(parent, invokingState);
- }
- @Override public int getRuleIndex() { return RULE_delimiter; }
- @Override
- public T accept(ParseTreeVisitor extends T> visitor) {
- if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor extends T>)visitor).visitDelimiter(this);
- else return visitor.visitChildren(this);
- }
- }
-
- public final DelimiterContext delimiter() throws RecognitionException {
- DelimiterContext _localctx = new DelimiterContext(_ctx, getState());
- enterRule(_localctx, 26, RULE_delimiter);
- int _la;
- try {
- enterOuterAlt(_localctx, 1);
- {
- setState(237);
- _la = _input.LA(1);
- if ( !(_la==EOF || _la==SEMICOLON) ) {
- _errHandler.recoverInline(this);
- } else {
- consume();
- }
- }
- }
- catch (RecognitionException re) {
- _localctx.exception = re;
- _errHandler.reportError(this, re);
- _errHandler.recover(this, re);
- }
- finally {
- exitRule();
- }
- return _localctx;
- }
-
public static class ExpressionContext extends ParserRuleContext {
public ExpressionContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
@@ -1631,8 +1699,8 @@ private ExpressionContext expression(int _p) throws RecognitionException {
int _parentState = getState();
ExpressionContext _localctx = new ExpressionContext(_ctx, _parentState);
ExpressionContext _prevctx = _localctx;
- int _startState = 28;
- enterRecursionRule(_localctx, 28, RULE_expression, _p);
+ int _startState = 30;
+ enterRecursionRule(_localctx, 30, RULE_expression, _p);
int _la;
try {
int _alt;
@@ -1643,35 +1711,35 @@ private ExpressionContext expression(int _p) throws RecognitionException {
_ctx = _localctx;
_prevctx = _localctx;
- setState(240);
+ setState(243);
unary();
}
_ctx.stop = _input.LT(-1);
- setState(292);
+ setState(295);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,19,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,23,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
if ( _parseListeners!=null ) triggerExitRuleEvent();
_prevctx = _localctx;
{
- setState(290);
+ setState(293);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,18,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) {
case 1:
{
_localctx = new BinaryContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(242);
+ setState(245);
if (!(precpred(_ctx, 15))) throw new FailedPredicateException(this, "precpred(_ctx, 15)");
- setState(243);
+ setState(246);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << MUL) | (1L << DIV) | (1L << REM))) != 0)) ) {
_errHandler.recoverInline(this);
} else {
consume();
}
- setState(244);
+ setState(247);
expression(16);
}
break;
@@ -1679,16 +1747,16 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new BinaryContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(245);
+ setState(248);
if (!(precpred(_ctx, 14))) throw new FailedPredicateException(this, "precpred(_ctx, 14)");
- setState(246);
+ setState(249);
_la = _input.LA(1);
if ( !(_la==ADD || _la==SUB) ) {
_errHandler.recoverInline(this);
} else {
consume();
}
- setState(247);
+ setState(250);
expression(15);
}
break;
@@ -1696,16 +1764,16 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new BinaryContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(248);
+ setState(251);
if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)");
- setState(249);
+ setState(252);
_la = _input.LA(1);
if ( !(_la==FIND || _la==MATCH) ) {
_errHandler.recoverInline(this);
} else {
consume();
}
- setState(250);
+ setState(253);
expression(14);
}
break;
@@ -1713,16 +1781,16 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new BinaryContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(251);
+ setState(254);
if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)");
- setState(252);
+ setState(255);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LSH) | (1L << RSH) | (1L << USH))) != 0)) ) {
_errHandler.recoverInline(this);
} else {
consume();
}
- setState(253);
+ setState(256);
expression(13);
}
break;
@@ -1730,16 +1798,16 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new CompContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(254);
+ setState(257);
if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)");
- setState(255);
+ setState(258);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LT) | (1L << LTE) | (1L << GT) | (1L << GTE))) != 0)) ) {
_errHandler.recoverInline(this);
} else {
consume();
}
- setState(256);
+ setState(259);
expression(12);
}
break;
@@ -1747,16 +1815,16 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new CompContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(257);
+ setState(260);
if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)");
- setState(258);
+ setState(261);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << EQ) | (1L << EQR) | (1L << NE) | (1L << NER))) != 0)) ) {
_errHandler.recoverInline(this);
} else {
consume();
}
- setState(259);
+ setState(262);
expression(10);
}
break;
@@ -1764,11 +1832,11 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new BinaryContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(260);
+ setState(263);
if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)");
- setState(261);
+ setState(264);
match(BWAND);
- setState(262);
+ setState(265);
expression(9);
}
break;
@@ -1776,11 +1844,11 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new BinaryContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(263);
+ setState(266);
if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
- setState(264);
+ setState(267);
match(XOR);
- setState(265);
+ setState(268);
expression(8);
}
break;
@@ -1788,11 +1856,11 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new BinaryContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(266);
+ setState(269);
if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)");
- setState(267);
+ setState(270);
match(BWOR);
- setState(268);
+ setState(271);
expression(7);
}
break;
@@ -1800,11 +1868,11 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new BoolContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(269);
+ setState(272);
if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)");
- setState(270);
+ setState(273);
match(BOOLAND);
- setState(271);
+ setState(274);
expression(6);
}
break;
@@ -1812,11 +1880,11 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new BoolContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(272);
+ setState(275);
if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)");
- setState(273);
+ setState(276);
match(BOOLOR);
- setState(274);
+ setState(277);
expression(5);
}
break;
@@ -1824,15 +1892,15 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new ConditionalContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(275);
+ setState(278);
if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)");
- setState(276);
+ setState(279);
match(COND);
- setState(277);
+ setState(280);
expression(0);
- setState(278);
+ setState(281);
match(COLON);
- setState(279);
+ setState(282);
expression(3);
}
break;
@@ -1840,11 +1908,11 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new ElvisContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(281);
+ setState(284);
if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
- setState(282);
+ setState(285);
match(ELVIS);
- setState(283);
+ setState(286);
expression(2);
}
break;
@@ -1852,16 +1920,16 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new AssignmentContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(284);
+ setState(287);
if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
- setState(285);
+ setState(288);
_la = _input.LA(1);
if ( !(((((_la - 60)) & ~0x3f) == 0 && ((1L << (_la - 60)) & ((1L << (ASSIGN - 60)) | (1L << (AADD - 60)) | (1L << (ASUB - 60)) | (1L << (AMUL - 60)) | (1L << (ADIV - 60)) | (1L << (AREM - 60)) | (1L << (AAND - 60)) | (1L << (AXOR - 60)) | (1L << (AOR - 60)) | (1L << (ALSH - 60)) | (1L << (ARSH - 60)) | (1L << (AUSH - 60)))) != 0)) ) {
_errHandler.recoverInline(this);
} else {
consume();
}
- setState(286);
+ setState(289);
expression(1);
}
break;
@@ -1869,20 +1937,20 @@ private ExpressionContext expression(int _p) throws RecognitionException {
{
_localctx = new InstanceofContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(287);
+ setState(290);
if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)");
- setState(288);
+ setState(291);
match(INSTANCEOF);
- setState(289);
+ setState(292);
decltype();
}
break;
}
}
}
- setState(294);
+ setState(297);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,19,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,23,_ctx);
}
}
}
@@ -1979,24 +2047,24 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final UnaryContext unary() throws RecognitionException {
UnaryContext _localctx = new UnaryContext(_ctx, getState());
- enterRule(_localctx, 30, RULE_unary);
+ enterRule(_localctx, 32, RULE_unary);
int _la;
try {
- setState(308);
+ setState(311);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,20,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,24,_ctx) ) {
case 1:
_localctx = new PreContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(295);
+ setState(298);
_la = _input.LA(1);
if ( !(_la==INCR || _la==DECR) ) {
_errHandler.recoverInline(this);
} else {
consume();
}
- setState(296);
+ setState(299);
chain();
}
break;
@@ -2004,9 +2072,9 @@ public final UnaryContext unary() throws RecognitionException {
_localctx = new PostContext(_localctx);
enterOuterAlt(_localctx, 2);
{
- setState(297);
+ setState(300);
chain();
- setState(298);
+ setState(301);
_la = _input.LA(1);
if ( !(_la==INCR || _la==DECR) ) {
_errHandler.recoverInline(this);
@@ -2019,7 +2087,7 @@ public final UnaryContext unary() throws RecognitionException {
_localctx = new ReadContext(_localctx);
enterOuterAlt(_localctx, 3);
{
- setState(300);
+ setState(303);
chain();
}
break;
@@ -2027,14 +2095,14 @@ public final UnaryContext unary() throws RecognitionException {
_localctx = new OperatorContext(_localctx);
enterOuterAlt(_localctx, 4);
{
- setState(301);
+ setState(304);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << BOOLNOT) | (1L << BWNOT) | (1L << ADD) | (1L << SUB))) != 0)) ) {
_errHandler.recoverInline(this);
} else {
consume();
}
- setState(302);
+ setState(305);
unary();
}
break;
@@ -2042,13 +2110,13 @@ public final UnaryContext unary() throws RecognitionException {
_localctx = new CastContext(_localctx);
enterOuterAlt(_localctx, 5);
{
- setState(303);
+ setState(306);
match(LP);
- setState(304);
+ setState(307);
decltype();
- setState(305);
+ setState(308);
match(RP);
- setState(306);
+ setState(309);
unary();
}
break;
@@ -2127,33 +2195,33 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final ChainContext chain() throws RecognitionException {
ChainContext _localctx = new ChainContext(_ctx, getState());
- enterRule(_localctx, 32, RULE_chain);
+ enterRule(_localctx, 34, RULE_chain);
try {
int _alt;
- setState(326);
+ setState(329);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,23,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,27,_ctx) ) {
case 1:
_localctx = new DynamicContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(310);
+ setState(313);
primary();
- setState(314);
+ setState(317);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,21,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,25,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(311);
+ setState(314);
postfix();
}
}
}
- setState(316);
+ setState(319);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,21,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,25,_ctx);
}
}
break;
@@ -2161,25 +2229,25 @@ public final ChainContext chain() throws RecognitionException {
_localctx = new StaticContext(_localctx);
enterOuterAlt(_localctx, 2);
{
- setState(317);
+ setState(320);
decltype();
- setState(318);
+ setState(321);
postdot();
- setState(322);
+ setState(325);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,22,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,26,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(319);
+ setState(322);
postfix();
}
}
}
- setState(324);
+ setState(327);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,22,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,26,_ctx);
}
}
break;
@@ -2187,7 +2255,7 @@ public final ChainContext chain() throws RecognitionException {
_localctx = new NewarrayContext(_localctx);
enterOuterAlt(_localctx, 3);
{
- setState(325);
+ setState(328);
arrayinitializer();
}
break;
@@ -2344,21 +2412,21 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final PrimaryContext primary() throws RecognitionException {
PrimaryContext _localctx = new PrimaryContext(_ctx, getState());
- enterRule(_localctx, 34, RULE_primary);
+ enterRule(_localctx, 36, RULE_primary);
int _la;
try {
- setState(346);
+ setState(349);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,24,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,28,_ctx) ) {
case 1:
_localctx = new PrecedenceContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(328);
+ setState(331);
match(LP);
- setState(329);
+ setState(332);
expression(0);
- setState(330);
+ setState(333);
match(RP);
}
break;
@@ -2366,7 +2434,7 @@ public final PrimaryContext primary() throws RecognitionException {
_localctx = new NumericContext(_localctx);
enterOuterAlt(_localctx, 2);
{
- setState(332);
+ setState(335);
_la = _input.LA(1);
if ( !(((((_la - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (OCTAL - 72)) | (1L << (HEX - 72)) | (1L << (INTEGER - 72)) | (1L << (DECIMAL - 72)))) != 0)) ) {
_errHandler.recoverInline(this);
@@ -2379,7 +2447,7 @@ public final PrimaryContext primary() throws RecognitionException {
_localctx = new TrueContext(_localctx);
enterOuterAlt(_localctx, 3);
{
- setState(333);
+ setState(336);
match(TRUE);
}
break;
@@ -2387,7 +2455,7 @@ public final PrimaryContext primary() throws RecognitionException {
_localctx = new FalseContext(_localctx);
enterOuterAlt(_localctx, 4);
{
- setState(334);
+ setState(337);
match(FALSE);
}
break;
@@ -2395,7 +2463,7 @@ public final PrimaryContext primary() throws RecognitionException {
_localctx = new NullContext(_localctx);
enterOuterAlt(_localctx, 5);
{
- setState(335);
+ setState(338);
match(NULL);
}
break;
@@ -2403,7 +2471,7 @@ public final PrimaryContext primary() throws RecognitionException {
_localctx = new StringContext(_localctx);
enterOuterAlt(_localctx, 6);
{
- setState(336);
+ setState(339);
match(STRING);
}
break;
@@ -2411,7 +2479,7 @@ public final PrimaryContext primary() throws RecognitionException {
_localctx = new RegexContext(_localctx);
enterOuterAlt(_localctx, 7);
{
- setState(337);
+ setState(340);
match(REGEX);
}
break;
@@ -2419,7 +2487,7 @@ public final PrimaryContext primary() throws RecognitionException {
_localctx = new ListinitContext(_localctx);
enterOuterAlt(_localctx, 8);
{
- setState(338);
+ setState(341);
listinitializer();
}
break;
@@ -2427,7 +2495,7 @@ public final PrimaryContext primary() throws RecognitionException {
_localctx = new MapinitContext(_localctx);
enterOuterAlt(_localctx, 9);
{
- setState(339);
+ setState(342);
mapinitializer();
}
break;
@@ -2435,7 +2503,7 @@ public final PrimaryContext primary() throws RecognitionException {
_localctx = new VariableContext(_localctx);
enterOuterAlt(_localctx, 10);
{
- setState(340);
+ setState(343);
match(ID);
}
break;
@@ -2443,9 +2511,9 @@ public final PrimaryContext primary() throws RecognitionException {
_localctx = new CalllocalContext(_localctx);
enterOuterAlt(_localctx, 11);
{
- setState(341);
+ setState(344);
match(ID);
- setState(342);
+ setState(345);
arguments();
}
break;
@@ -2453,11 +2521,11 @@ public final PrimaryContext primary() throws RecognitionException {
_localctx = new NewobjectContext(_localctx);
enterOuterAlt(_localctx, 12);
{
- setState(343);
+ setState(346);
match(NEW);
- setState(344);
+ setState(347);
match(TYPE);
- setState(345);
+ setState(348);
arguments();
}
break;
@@ -2497,29 +2565,29 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final PostfixContext postfix() throws RecognitionException {
PostfixContext _localctx = new PostfixContext(_ctx, getState());
- enterRule(_localctx, 36, RULE_postfix);
+ enterRule(_localctx, 38, RULE_postfix);
try {
- setState(351);
+ setState(354);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,29,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
- setState(348);
+ setState(351);
callinvoke();
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
- setState(349);
+ setState(352);
fieldaccess();
}
break;
case 3:
enterOuterAlt(_localctx, 3);
{
- setState(350);
+ setState(353);
braceaccess();
}
break;
@@ -2556,22 +2624,22 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final PostdotContext postdot() throws RecognitionException {
PostdotContext _localctx = new PostdotContext(_ctx, getState());
- enterRule(_localctx, 38, RULE_postdot);
+ enterRule(_localctx, 40, RULE_postdot);
try {
- setState(355);
+ setState(358);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,26,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,30,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
- setState(353);
+ setState(356);
callinvoke();
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
- setState(354);
+ setState(357);
fieldaccess();
}
break;
@@ -2608,21 +2676,21 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final CallinvokeContext callinvoke() throws RecognitionException {
CallinvokeContext _localctx = new CallinvokeContext(_ctx, getState());
- enterRule(_localctx, 40, RULE_callinvoke);
+ enterRule(_localctx, 42, RULE_callinvoke);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(357);
+ setState(360);
_la = _input.LA(1);
if ( !(_la==DOT || _la==NSDOT) ) {
_errHandler.recoverInline(this);
} else {
consume();
}
- setState(358);
+ setState(361);
match(DOTID);
- setState(359);
+ setState(362);
arguments();
}
}
@@ -2655,19 +2723,19 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final FieldaccessContext fieldaccess() throws RecognitionException {
FieldaccessContext _localctx = new FieldaccessContext(_ctx, getState());
- enterRule(_localctx, 42, RULE_fieldaccess);
+ enterRule(_localctx, 44, RULE_fieldaccess);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(361);
+ setState(364);
_la = _input.LA(1);
if ( !(_la==DOT || _la==NSDOT) ) {
_errHandler.recoverInline(this);
} else {
consume();
}
- setState(362);
+ setState(365);
_la = _input.LA(1);
if ( !(_la==DOTINTEGER || _la==DOTID) ) {
_errHandler.recoverInline(this);
@@ -2706,15 +2774,15 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final BraceaccessContext braceaccess() throws RecognitionException {
BraceaccessContext _localctx = new BraceaccessContext(_ctx, getState());
- enterRule(_localctx, 44, RULE_braceaccess);
+ enterRule(_localctx, 46, RULE_braceaccess);
try {
enterOuterAlt(_localctx, 1);
{
- setState(364);
+ setState(367);
match(LBRACE);
- setState(365);
+ setState(368);
expression(0);
- setState(366);
+ setState(369);
match(RBRACE);
}
}
@@ -2786,7 +2854,6 @@ public List expression() {
public ExpressionContext expression(int i) {
return getRuleContext(ExpressionContext.class,i);
}
- public TerminalNode SEMICOLON() { return getToken(PainlessParser.SEMICOLON, 0); }
public List postfix() {
return getRuleContexts(PostfixContext.class);
}
@@ -2807,22 +2874,22 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final ArrayinitializerContext arrayinitializer() throws RecognitionException {
ArrayinitializerContext _localctx = new ArrayinitializerContext(_ctx, getState());
- enterRule(_localctx, 46, RULE_arrayinitializer);
+ enterRule(_localctx, 48, RULE_arrayinitializer);
int _la;
try {
int _alt;
setState(412);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,34,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,37,_ctx) ) {
case 1:
_localctx = new NewstandardarrayContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(368);
+ setState(371);
match(NEW);
- setState(369);
+ setState(372);
match(TYPE);
- setState(374);
+ setState(377);
_errHandler.sync(this);
_alt = 1;
do {
@@ -2830,11 +2897,11 @@ public final ArrayinitializerContext arrayinitializer() throws RecognitionExcept
case 1:
{
{
- setState(370);
+ setState(373);
match(LBRACE);
- setState(371);
+ setState(374);
expression(0);
- setState(372);
+ setState(375);
match(RBRACE);
}
}
@@ -2842,32 +2909,32 @@ public final ArrayinitializerContext arrayinitializer() throws RecognitionExcept
default:
throw new NoViableAltException(this);
}
- setState(376);
+ setState(379);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,27,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,31,_ctx);
} while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER );
- setState(385);
+ setState(388);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,29,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,33,_ctx) ) {
case 1:
{
- setState(378);
+ setState(381);
postdot();
- setState(382);
+ setState(385);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,28,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,32,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(379);
+ setState(382);
postfix();
}
}
}
- setState(384);
+ setState(387);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,28,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,32,_ctx);
}
}
break;
@@ -2878,55 +2945,46 @@ public final ArrayinitializerContext arrayinitializer() throws RecognitionExcept
_localctx = new NewinitializedarrayContext(_localctx);
enterOuterAlt(_localctx, 2);
{
- setState(387);
+ setState(390);
match(NEW);
- setState(388);
+ setState(391);
match(TYPE);
- setState(389);
+ setState(392);
match(LBRACE);
- setState(390);
+ setState(393);
match(RBRACE);
- setState(391);
+ setState(394);
match(LBRACK);
- setState(400);
+ 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 - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (OCTAL - 72)) | (1L << (HEX - 72)) | (1L << (INTEGER - 72)) | (1L << (DECIMAL - 72)) | (1L << (STRING - 72)) | (1L << (REGEX - 72)) | (1L << (TRUE - 72)) | (1L << (FALSE - 72)) | (1L << (NULL - 72)) | (1L << (TYPE - 72)) | (1L << (ID - 72)))) != 0)) {
{
- setState(392);
+ setState(395);
expression(0);
- setState(397);
+ setState(400);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==COMMA) {
{
{
- setState(393);
+ setState(396);
match(COMMA);
- setState(394);
+ setState(397);
expression(0);
}
}
- setState(399);
+ setState(402);
_errHandler.sync(this);
_la = _input.LA(1);
}
}
}
- setState(403);
- _la = _input.LA(1);
- if (_la==SEMICOLON) {
- {
- setState(402);
- match(SEMICOLON);
- }
- }
-
setState(405);
match(RBRACK);
setState(409);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,33,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,36,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
@@ -2938,7 +2996,7 @@ public final ArrayinitializerContext arrayinitializer() throws RecognitionExcept
}
setState(411);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,33,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,36,_ctx);
}
}
break;
@@ -2981,12 +3039,12 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final ListinitializerContext listinitializer() throws RecognitionException {
ListinitializerContext _localctx = new ListinitializerContext(_ctx, getState());
- enterRule(_localctx, 48, RULE_listinitializer);
+ enterRule(_localctx, 50, RULE_listinitializer);
int _la;
try {
setState(427);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,36,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,39,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
@@ -3063,12 +3121,12 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final MapinitializerContext mapinitializer() throws RecognitionException {
MapinitializerContext _localctx = new MapinitializerContext(_ctx, getState());
- enterRule(_localctx, 50, RULE_mapinitializer);
+ enterRule(_localctx, 52, RULE_mapinitializer);
int _la;
try {
setState(443);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,38,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,41,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
@@ -3141,7 +3199,7 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final MaptokenContext maptoken() throws RecognitionException {
MaptokenContext _localctx = new MaptokenContext(_ctx, getState());
- enterRule(_localctx, 52, RULE_maptoken);
+ enterRule(_localctx, 54, RULE_maptoken);
try {
enterOuterAlt(_localctx, 1);
{
@@ -3190,7 +3248,7 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final ArgumentsContext arguments() throws RecognitionException {
ArgumentsContext _localctx = new ArgumentsContext(_ctx, getState());
- enterRule(_localctx, 54, RULE_arguments);
+ enterRule(_localctx, 56, RULE_arguments);
int _la;
try {
enterOuterAlt(_localctx, 1);
@@ -3262,11 +3320,11 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final ArgumentContext argument() throws RecognitionException {
ArgumentContext _localctx = new ArgumentContext(_ctx, getState());
- enterRule(_localctx, 56, RULE_argument);
+ enterRule(_localctx, 58, RULE_argument);
try {
setState(465);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,41,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,44,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
@@ -3334,7 +3392,7 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final LambdaContext lambda() throws RecognitionException {
LambdaContext _localctx = new LambdaContext(_ctx, getState());
- enterRule(_localctx, 58, RULE_lambda);
+ enterRule(_localctx, 60, RULE_lambda);
int _la;
try {
enterOuterAlt(_localctx, 1);
@@ -3453,7 +3511,7 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final LamtypeContext lamtype() throws RecognitionException {
LamtypeContext _localctx = new LamtypeContext(_ctx, getState());
- enterRule(_localctx, 60, RULE_lamtype);
+ enterRule(_localctx, 62, RULE_lamtype);
int _la;
try {
enterOuterAlt(_localctx, 1);
@@ -3544,11 +3602,11 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final FuncrefContext funcref() throws RecognitionException {
FuncrefContext _localctx = new FuncrefContext(_ctx, getState());
- enterRule(_localctx, 62, RULE_funcref);
+ enterRule(_localctx, 64, RULE_funcref);
try {
setState(505);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,47,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,50,_ctx) ) {
case 1:
_localctx = new ClassfuncrefContext(_localctx);
enterOuterAlt(_localctx, 1);
@@ -3612,14 +3670,14 @@ public final FuncrefContext funcref() throws RecognitionException {
public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
switch (ruleIndex) {
- case 3:
- return statement_sempred((StatementContext)_localctx, predIndex);
- case 14:
+ case 4:
+ return rstatement_sempred((RstatementContext)_localctx, predIndex);
+ case 15:
return expression_sempred((ExpressionContext)_localctx, predIndex);
}
return true;
}
- private boolean statement_sempred(StatementContext _localctx, int predIndex) {
+ private boolean rstatement_sempred(RstatementContext _localctx, int predIndex) {
switch (predIndex) {
case 0:
return _input.LA(1) != ELSE ;
@@ -3668,196 +3726,195 @@ private boolean expression_sempred(ExpressionContext _localctx, int predIndex) {
"\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"+
"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
- "\t!\3\2\7\2D\n\2\f\2\16\2G\13\2\3\2\7\2J\n\2\f\2\16\2M\13\2\3\2\3\2\3"+
- "\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\7\4]\n\4\f\4\16\4`\13\4"+
- "\5\4b\n\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5n\n\5\3\5\3\5\3\5"+
- "\3\5\3\5\3\5\5\5v\n\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5"+
- "\u0083\n\5\3\5\3\5\5\5\u0087\n\5\3\5\3\5\5\5\u008b\n\5\3\5\3\5\3\5\5\5"+
- "\u0090\n\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5"+
- "\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\6\5\u00b1"+
- "\n\5\r\5\16\5\u00b2\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5\u00bc\n\5\3\6\3\6"+
- "\5\6\u00c0\n\6\3\7\3\7\7\7\u00c4\n\7\f\7\16\7\u00c7\13\7\3\7\3\7\3\b\3"+
- "\b\3\t\3\t\5\t\u00cf\n\t\3\n\3\n\3\13\3\13\3\13\3\13\7\13\u00d7\n\13\f"+
- "\13\16\13\u00da\13\13\3\f\3\f\3\f\7\f\u00df\n\f\f\f\16\f\u00e2\13\f\3"+
- "\r\3\r\3\r\5\r\u00e7\n\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17"+
- "\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20"+
- "\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20"+
- "\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20"+
- "\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\7\20\u0125\n\20\f\20\16"+
- "\20\u0128\13\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21"+
- "\3\21\3\21\5\21\u0137\n\21\3\22\3\22\7\22\u013b\n\22\f\22\16\22\u013e"+
- "\13\22\3\22\3\22\3\22\7\22\u0143\n\22\f\22\16\22\u0146\13\22\3\22\5\22"+
- "\u0149\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\u015d\n\23\3\24\3\24\3\24\5\24\u0162"+
- "\n\24\3\25\3\25\5\25\u0166\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\u0179\n\31\r\31\16"+
- "\31\u017a\3\31\3\31\7\31\u017f\n\31\f\31\16\31\u0182\13\31\5\31\u0184"+
- "\n\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\7\31\u018e\n\31\f\31\16"+
- "\31\u0191\13\31\5\31\u0193\n\31\3\31\5\31\u0196\n\31\3\31\3\31\7\31\u019a"+
- "\n\31\f\31\16\31\u019d\13\31\5\31\u019f\n\31\3\32\3\32\3\32\3\32\7\32"+
- "\u01a5\n\32\f\32\16\32\u01a8\13\32\3\32\3\32\3\32\3\32\5\32\u01ae\n\32"+
- "\3\33\3\33\3\33\3\33\7\33\u01b4\n\33\f\33\16\33\u01b7\13\33\3\33\3\33"+
- "\3\33\3\33\3\33\5\33\u01be\n\33\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35"+
- "\7\35\u01c8\n\35\f\35\16\35\u01cb\13\35\5\35\u01cd\n\35\3\35\3\35\3\36"+
- "\3\36\3\36\5\36\u01d4\n\36\3\37\3\37\3\37\3\37\3\37\7\37\u01db\n\37\f"+
- "\37\16\37\u01de\13\37\5\37\u01e0\n\37\3\37\5\37\u01e3\n\37\3\37\3\37\3"+
- "\37\5\37\u01e8\n\37\3 \5 \u01eb\n \3 \3 \3!\3!\3!\3!\3!\3!\3!\3!\3!\3"+
- "!\3!\3!\3!\5!\u01fc\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\17\3\3\16\16\3\2 \"\3\2#$\3\2:;\3\2%\'"+
- "\3\2(+\3\2,/\3\2>I\3\2<=\4\2\36\37#$\3\2JM\3\2\13\f\3\2UV\u0237\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 \u0136\3\2\2\2\"\u0148\3\2\2\2$\u015c\3\2\2\2&\u0161"+
- "\3\2\2\2(\u0165\3\2\2\2*\u0167\3\2\2\2,\u016b\3\2\2\2.\u016e\3\2\2\2\60"+
- "\u019e\3\2\2\2\62\u01ad\3\2\2\2\64\u01bd\3\2\2\2\66\u01bf\3\2\2\28\u01c3"+
- "\3\2\2\2:\u01d3\3\2\2\2<\u01e2\3\2\2\2>\u01ea\3\2\2\2@\u01fb\3\2\2\2B"+
- "D\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\2"+
- "HJ\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\2"+
- "NO\7\2\2\3O\3\3\2\2\2PQ\5\26\f\2QR\7T\2\2RS\5\6\4\2ST\5\f\7\2T\5\3\2\2"+
- "\2Ua\7\t\2\2VW\5\26\f\2W^\7T\2\2XY\7\r\2\2YZ\5\26\f\2Z[\7T\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\17\2\2fg\7\t\2\2gh\5"+
- "\36\20\2hi\7\n\2\2im\5\n\6\2jk\7\21\2\2kn\5\n\6\2ln\6\5\2\2mj\3\2\2\2"+
- "ml\3\2\2\2n\u00bc\3\2\2\2op\7\22\2\2pq\7\t\2\2qr\5\36\20\2ru\7\n\2\2s"+
- "v\5\n\6\2tv\5\16\b\2us\3\2\2\2ut\3\2\2\2v\u00bc\3\2\2\2wx\7\23\2\2xy\5"+
- "\f\7\2yz\7\22\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\24\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\16"+
- "\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\16\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\24\2\2\u0092\u0093\7\t\2\2\u0093"+
- "\u0094\5\26\f\2\u0094\u0095\7T\2\2\u0095\u0096\7\66\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\24\2\2\u009b\u009c\7\t\2\2\u009c\u009d\7T\2\2\u009d\u009e\7\20"+
- "\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\25\2\2\u00a6\u00bc\5\34\17\2\u00a7\u00a8\7\26\2"+
- "\2\u00a8\u00bc\5\34\17\2\u00a9\u00aa\7\27\2\2\u00aa\u00ab\5\36\20\2\u00ab"+
- "\u00ac\5\34\17\2\u00ac\u00bc\3\2\2\2\u00ad\u00ae\7\31\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\33\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\u00bb"+
- "e\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\16\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\r\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\7S\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\7T\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\32\2\2\u00e9\u00ea\7\t\2\2\u00ea\u00eb"+
- "\7S\2\2\u00eb\u00ec\7T\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\u0126\3\2\2\2\u00f4\u00f5\f\21\2\2\u00f5\u00f6"+
- "\t\3\2\2\u00f6\u0125\5\36\20\22\u00f7\u00f8\f\20\2\2\u00f8\u00f9\t\4\2"+
- "\2\u00f9\u0125\5\36\20\21\u00fa\u00fb\f\17\2\2\u00fb\u00fc\t\5\2\2\u00fc"+
- "\u0125\5\36\20\20\u00fd\u00fe\f\16\2\2\u00fe\u00ff\t\6\2\2\u00ff\u0125"+
- "\5\36\20\17\u0100\u0101\f\r\2\2\u0101\u0102\t\7\2\2\u0102\u0125\5\36\20"+
- "\16\u0103\u0104\f\13\2\2\u0104\u0105\t\b\2\2\u0105\u0125\5\36\20\f\u0106"+
- "\u0107\f\n\2\2\u0107\u0108\7\60\2\2\u0108\u0125\5\36\20\13\u0109\u010a"+
- "\f\t\2\2\u010a\u010b\7\61\2\2\u010b\u0125\5\36\20\n\u010c\u010d\f\b\2"+
- "\2\u010d\u010e\7\62\2\2\u010e\u0125\5\36\20\t\u010f\u0110\f\7\2\2\u0110"+
- "\u0111\7\63\2\2\u0111\u0125\5\36\20\b\u0112\u0113\f\6\2\2\u0113\u0114"+
- "\7\64\2\2\u0114\u0125\5\36\20\7\u0115\u0116\f\5\2\2\u0116\u0117\7\65\2"+
- "\2\u0117\u0118\5\36\20\2\u0118\u0119\7\66\2\2\u0119\u011a\5\36\20\5\u011a"+
- "\u0125\3\2\2\2\u011b\u011c\f\4\2\2\u011c\u011d\7\67\2\2\u011d\u0125\5"+
- "\36\20\4\u011e\u011f\f\3\2\2\u011f\u0120\t\t\2\2\u0120\u0125\5\36\20\3"+
- "\u0121\u0122\f\f\2\2\u0122\u0123\7\35\2\2\u0123\u0125\5\26\f\2\u0124\u00f4"+
- "\3\2\2\2\u0124\u00f7\3\2\2\2\u0124\u00fa\3\2\2\2\u0124\u00fd\3\2\2\2\u0124"+
- "\u0100\3\2\2\2\u0124\u0103\3\2\2\2\u0124\u0106\3\2\2\2\u0124\u0109\3\2"+
- "\2\2\u0124\u010c\3\2\2\2\u0124\u010f\3\2\2\2\u0124\u0112\3\2\2\2\u0124"+
- "\u0115\3\2\2\2\u0124\u011b\3\2\2\2\u0124\u011e\3\2\2\2\u0124\u0121\3\2"+
- "\2\2\u0125\u0128\3\2\2\2\u0126\u0124\3\2\2\2\u0126\u0127\3\2\2\2\u0127"+
- "\37\3\2\2\2\u0128\u0126\3\2\2\2\u0129\u012a\t\n\2\2\u012a\u0137\5\"\22"+
- "\2\u012b\u012c\5\"\22\2\u012c\u012d\t\n\2\2\u012d\u0137\3\2\2\2\u012e"+
- "\u0137\5\"\22\2\u012f\u0130\t\13\2\2\u0130\u0137\5 \21\2\u0131\u0132\7"+
- "\t\2\2\u0132\u0133\5\26\f\2\u0133\u0134\7\n\2\2\u0134\u0135\5 \21\2\u0135"+
- "\u0137\3\2\2\2\u0136\u0129\3\2\2\2\u0136\u012b\3\2\2\2\u0136\u012e\3\2"+
- "\2\2\u0136\u012f\3\2\2\2\u0136\u0131\3\2\2\2\u0137!\3\2\2\2\u0138\u013c"+
- "\5$\23\2\u0139\u013b\5&\24\2\u013a\u0139\3\2\2\2\u013b\u013e\3\2\2\2\u013c"+
- "\u013a\3\2\2\2\u013c\u013d\3\2\2\2\u013d\u0149\3\2\2\2\u013e\u013c\3\2"+
- "\2\2\u013f\u0140\5\26\f\2\u0140\u0144\5(\25\2\u0141\u0143\5&\24\2\u0142"+
- "\u0141\3\2\2\2\u0143\u0146\3\2\2\2\u0144\u0142\3\2\2\2\u0144\u0145\3\2"+
- "\2\2\u0145\u0149\3\2\2\2\u0146\u0144\3\2\2\2\u0147\u0149\5\60\31\2\u0148"+
- "\u0138\3\2\2\2\u0148\u013f\3\2\2\2\u0148\u0147\3\2\2\2\u0149#\3\2\2\2"+
- "\u014a\u014b\7\t\2\2\u014b\u014c\5\36\20\2\u014c\u014d\7\n\2\2\u014d\u015d"+
- "\3\2\2\2\u014e\u015d\t\f\2\2\u014f\u015d\7P\2\2\u0150\u015d\7Q\2\2\u0151"+
- "\u015d\7R\2\2\u0152\u015d\7N\2\2\u0153\u015d\7O\2\2\u0154\u015d\5\62\32"+
- "\2\u0155\u015d\5\64\33\2\u0156\u015d\7T\2\2\u0157\u0158\7T\2\2\u0158\u015d"+
- "\58\35\2\u0159\u015a\7\30\2\2\u015a\u015b\7S\2\2\u015b\u015d\58\35\2\u015c"+
- "\u014a\3\2\2\2\u015c\u014e\3\2\2\2\u015c\u014f\3\2\2\2\u015c\u0150\3\2"+
- "\2\2\u015c\u0151\3\2\2\2\u015c\u0152\3\2\2\2\u015c\u0153\3\2\2\2\u015c"+
- "\u0154\3\2\2\2\u015c\u0155\3\2\2\2\u015c\u0156\3\2\2\2\u015c\u0157\3\2"+
- "\2\2\u015c\u0159\3\2\2\2\u015d%\3\2\2\2\u015e\u0162\5*\26\2\u015f\u0162"+
- "\5,\27\2\u0160\u0162\5.\30\2\u0161\u015e\3\2\2\2\u0161\u015f\3\2\2\2\u0161"+
- "\u0160\3\2\2\2\u0162\'\3\2\2\2\u0163\u0166\5*\26\2\u0164\u0166\5,\27\2"+
- "\u0165\u0163\3\2\2\2\u0165\u0164\3\2\2\2\u0166)\3\2\2\2\u0167\u0168\t"+
- "\r\2\2\u0168\u0169\7V\2\2\u0169\u016a\58\35\2\u016a+\3\2\2\2\u016b\u016c"+
- "\t\r\2\2\u016c\u016d\t\16\2\2\u016d-\3\2\2\2\u016e\u016f\7\7\2\2\u016f"+
- "\u0170\5\36\20\2\u0170\u0171\7\b\2\2\u0171/\3\2\2\2\u0172\u0173\7\30\2"+
- "\2\u0173\u0178\7S\2\2\u0174\u0175\7\7\2\2\u0175\u0176\5\36\20\2\u0176"+
- "\u0177\7\b\2\2\u0177\u0179\3\2\2\2\u0178\u0174\3\2\2\2\u0179\u017a\3\2"+
- "\2\2\u017a\u0178\3\2\2\2\u017a\u017b\3\2\2\2\u017b\u0183\3\2\2\2\u017c"+
- "\u0180\5(\25\2\u017d\u017f\5&\24\2\u017e\u017d\3\2\2\2\u017f\u0182\3\2"+
- "\2\2\u0180\u017e\3\2\2\2\u0180\u0181\3\2\2\2\u0181\u0184\3\2\2\2\u0182"+
- "\u0180\3\2\2\2\u0183\u017c\3\2\2\2\u0183\u0184\3\2\2\2\u0184\u019f\3\2"+
- "\2\2\u0185\u0186\7\30\2\2\u0186\u0187\7S\2\2\u0187\u0188\7\7\2\2\u0188"+
- "\u0189\7\b\2\2\u0189\u0192\7\5\2\2\u018a\u018f\5\36\20\2\u018b\u018c\7"+
- "\r\2\2\u018c\u018e\5\36\20\2\u018d\u018b\3\2\2\2\u018e\u0191\3\2\2\2\u018f"+
- "\u018d\3\2\2\2\u018f\u0190\3\2\2\2\u0190\u0193\3\2\2\2\u0191\u018f\3\2"+
- "\2\2\u0192\u018a\3\2\2\2\u0192\u0193\3\2\2\2\u0193\u0195\3\2\2\2\u0194"+
- "\u0196\7\16\2\2\u0195\u0194\3\2\2\2\u0195\u0196\3\2\2\2\u0196\u0197\3"+
- "\2\2\2\u0197\u019b\7\6\2\2\u0198\u019a\5&\24\2\u0199\u0198\3\2\2\2\u019a"+
+ "\t!\4\"\t\"\3\2\7\2F\n\2\f\2\16\2I\13\2\3\2\7\2L\n\2\f\2\16\2O\13\2\3"+
+ "\2\5\2R\n\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\7"+
+ "\4b\n\4\f\4\16\4e\13\4\5\4g\n\4\3\4\3\4\3\5\3\5\3\5\3\5\5\5o\n\5\3\6\3"+
+ "\6\3\6\3\6\3\6\3\6\3\6\3\6\5\6y\n\6\3\6\3\6\3\6\3\6\3\6\3\6\5\6\u0081"+
+ "\n\6\3\6\3\6\3\6\5\6\u0086\n\6\3\6\3\6\5\6\u008a\n\6\3\6\3\6\5\6\u008e"+
+ "\n\6\3\6\3\6\3\6\5\6\u0093\n\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6"+
+ "\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\6\6\u00a9\n\6\r\6\16\6\u00aa"+
+ "\5\6\u00ad\n\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7"+
+ "\3\7\5\7\u00be\n\7\3\b\3\b\5\b\u00c2\n\b\3\t\3\t\7\t\u00c6\n\t\f\t\16"+
+ "\t\u00c9\13\t\3\t\5\t\u00cc\n\t\3\t\3\t\3\n\3\n\3\13\3\13\5\13\u00d4\n"+
+ "\13\3\f\3\f\3\r\3\r\3\r\3\r\7\r\u00dc\n\r\f\r\16\r\u00df\13\r\3\16\3\16"+
+ "\3\16\7\16\u00e4\n\16\f\16\16\16\u00e7\13\16\3\17\3\17\3\17\5\17\u00ec"+
+ "\n\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21"+
+ "\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21"+
+ "\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21"+
+ "\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21"+
+ "\3\21\3\21\3\21\7\21\u0128\n\21\f\21\16\21\u012b\13\21\3\22\3\22\3\22"+
+ "\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\5\22\u013a\n\22\3\23"+
+ "\3\23\7\23\u013e\n\23\f\23\16\23\u0141\13\23\3\23\3\23\3\23\7\23\u0146"+
+ "\n\23\f\23\16\23\u0149\13\23\3\23\5\23\u014c\n\23\3\24\3\24\3\24\3\24"+
+ "\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24"+
+ "\5\24\u0160\n\24\3\25\3\25\3\25\5\25\u0165\n\25\3\26\3\26\5\26\u0169\n"+
+ "\26\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\32\3\32\3"+
+ "\32\3\32\3\32\3\32\6\32\u017c\n\32\r\32\16\32\u017d\3\32\3\32\7\32\u0182"+
+ "\n\32\f\32\16\32\u0185\13\32\5\32\u0187\n\32\3\32\3\32\3\32\3\32\3\32"+
+ "\3\32\3\32\3\32\7\32\u0191\n\32\f\32\16\32\u0194\13\32\5\32\u0196\n\32"+
+ "\3\32\3\32\7\32\u019a\n\32\f\32\16\32\u019d\13\32\5\32\u019f\n\32\3\33"+
+ "\3\33\3\33\3\33\7\33\u01a5\n\33\f\33\16\33\u01a8\13\33\3\33\3\33\3\33"+
+ "\3\33\5\33\u01ae\n\33\3\34\3\34\3\34\3\34\7\34\u01b4\n\34\f\34\16\34\u01b7"+
+ "\13\34\3\34\3\34\3\34\3\34\3\34\5\34\u01be\n\34\3\35\3\35\3\35\3\35\3"+
+ "\36\3\36\3\36\3\36\7\36\u01c8\n\36\f\36\16\36\u01cb\13\36\5\36\u01cd\n"+
+ "\36\3\36\3\36\3\37\3\37\3\37\5\37\u01d4\n\37\3 \3 \3 \3 \3 \7 \u01db\n"+
+ " \f \16 \u01de\13 \5 \u01e0\n \3 \5 \u01e3\n \3 \3 \3 \5 \u01e8\n \3!"+
+ "\5!\u01eb\n!\3!\3!\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\""+
+ "\5\"\u01fc\n\"\3\"\2\3 #\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&("+
+ "*,.\60\62\64\668:<>@B\2\16\3\2 \"\3\2#$\3\2:;\3\2%\'\3\2(+\3\2,/\3\2>"+
+ "I\3\2<=\4\2\36\37#$\3\2JM\3\2\13\f\3\2UV\u0237\2G\3\2\2\2\4U\3\2\2\2\6"+
+ "Z\3\2\2\2\bn\3\2\2\2\n\u00ac\3\2\2\2\f\u00bd\3\2\2\2\16\u00c1\3\2\2\2"+
+ "\20\u00c3\3\2\2\2\22\u00cf\3\2\2\2\24\u00d3\3\2\2\2\26\u00d5\3\2\2\2\30"+
+ "\u00d7\3\2\2\2\32\u00e0\3\2\2\2\34\u00e8\3\2\2\2\36\u00ed\3\2\2\2 \u00f4"+
+ "\3\2\2\2\"\u0139\3\2\2\2$\u014b\3\2\2\2&\u015f\3\2\2\2(\u0164\3\2\2\2"+
+ "*\u0168\3\2\2\2,\u016a\3\2\2\2.\u016e\3\2\2\2\60\u0171\3\2\2\2\62\u019e"+
+ "\3\2\2\2\64\u01ad\3\2\2\2\66\u01bd\3\2\2\28\u01bf\3\2\2\2:\u01c3\3\2\2"+
+ "\2<\u01d3\3\2\2\2>\u01e2\3\2\2\2@\u01ea\3\2\2\2B\u01fb\3\2\2\2DF\5\4\3"+
+ "\2ED\3\2\2\2FI\3\2\2\2GE\3\2\2\2GH\3\2\2\2HM\3\2\2\2IG\3\2\2\2JL\5\b\5"+
+ "\2KJ\3\2\2\2LO\3\2\2\2MK\3\2\2\2MN\3\2\2\2NQ\3\2\2\2OM\3\2\2\2PR\5\f\7"+
+ "\2QP\3\2\2\2QR\3\2\2\2RS\3\2\2\2ST\7\2\2\3T\3\3\2\2\2UV\5\32\16\2VW\7"+
+ "T\2\2WX\5\6\4\2XY\5\20\t\2Y\5\3\2\2\2Zf\7\t\2\2[\\\5\32\16\2\\c\7T\2\2"+
+ "]^\7\r\2\2^_\5\32\16\2_`\7T\2\2`b\3\2\2\2a]\3\2\2\2be\3\2\2\2ca\3\2\2"+
+ "\2cd\3\2\2\2dg\3\2\2\2ec\3\2\2\2f[\3\2\2\2fg\3\2\2\2gh\3\2\2\2hi\7\n\2"+
+ "\2i\7\3\2\2\2jo\5\n\6\2kl\5\f\7\2lm\7\16\2\2mo\3\2\2\2nj\3\2\2\2nk\3\2"+
+ "\2\2o\t\3\2\2\2pq\7\17\2\2qr\7\t\2\2rs\5 \21\2st\7\n\2\2tx\5\16\b\2uv"+
+ "\7\21\2\2vy\5\16\b\2wy\6\6\2\2xu\3\2\2\2xw\3\2\2\2y\u00ad\3\2\2\2z{\7"+
+ "\22\2\2{|\7\t\2\2|}\5 \21\2}\u0080\7\n\2\2~\u0081\5\16\b\2\177\u0081\5"+
+ "\22\n\2\u0080~\3\2\2\2\u0080\177\3\2\2\2\u0081\u00ad\3\2\2\2\u0082\u0083"+
+ "\7\24\2\2\u0083\u0085\7\t\2\2\u0084\u0086\5\24\13\2\u0085\u0084\3\2\2"+
+ "\2\u0085\u0086\3\2\2\2\u0086\u0087\3\2\2\2\u0087\u0089\7\16\2\2\u0088"+
+ "\u008a\5 \21\2\u0089\u0088\3\2\2\2\u0089\u008a\3\2\2\2\u008a\u008b\3\2"+
+ "\2\2\u008b\u008d\7\16\2\2\u008c\u008e\5\26\f\2\u008d\u008c\3\2\2\2\u008d"+
+ "\u008e\3\2\2\2\u008e\u008f\3\2\2\2\u008f\u0092\7\n\2\2\u0090\u0093\5\16"+
+ "\b\2\u0091\u0093\5\22\n\2\u0092\u0090\3\2\2\2\u0092\u0091\3\2\2\2\u0093"+
+ "\u00ad\3\2\2\2\u0094\u0095\7\24\2\2\u0095\u0096\7\t\2\2\u0096\u0097\5"+
+ "\32\16\2\u0097\u0098\7T\2\2\u0098\u0099\7\66\2\2\u0099\u009a\5 \21\2\u009a"+
+ "\u009b\7\n\2\2\u009b\u009c\5\16\b\2\u009c\u00ad\3\2\2\2\u009d\u009e\7"+
+ "\24\2\2\u009e\u009f\7\t\2\2\u009f\u00a0\7T\2\2\u00a0\u00a1\7\20\2\2\u00a1"+
+ "\u00a2\5 \21\2\u00a2\u00a3\7\n\2\2\u00a3\u00a4\5\16\b\2\u00a4\u00ad\3"+
+ "\2\2\2\u00a5\u00a6\7\31\2\2\u00a6\u00a8\5\20\t\2\u00a7\u00a9\5\36\20\2"+
+ "\u00a8\u00a7\3\2\2\2\u00a9\u00aa\3\2\2\2\u00aa\u00a8\3\2\2\2\u00aa\u00ab"+
+ "\3\2\2\2\u00ab\u00ad\3\2\2\2\u00acp\3\2\2\2\u00acz\3\2\2\2\u00ac\u0082"+
+ "\3\2\2\2\u00ac\u0094\3\2\2\2\u00ac\u009d\3\2\2\2\u00ac\u00a5\3\2\2\2\u00ad"+
+ "\13\3\2\2\2\u00ae\u00af\7\23\2\2\u00af\u00b0\5\20\t\2\u00b0\u00b1\7\22"+
+ "\2\2\u00b1\u00b2\7\t\2\2\u00b2\u00b3\5 \21\2\u00b3\u00b4\7\n\2\2\u00b4"+
+ "\u00be\3\2\2\2\u00b5\u00be\5\30\r\2\u00b6\u00be\7\25\2\2\u00b7\u00be\7"+
+ "\26\2\2\u00b8\u00b9\7\27\2\2\u00b9\u00be\5 \21\2\u00ba\u00bb\7\33\2\2"+
+ "\u00bb\u00be\5 \21\2\u00bc\u00be\5 \21\2\u00bd\u00ae\3\2\2\2\u00bd\u00b5"+
+ "\3\2\2\2\u00bd\u00b6\3\2\2\2\u00bd\u00b7\3\2\2\2\u00bd\u00b8\3\2\2\2\u00bd"+
+ "\u00ba\3\2\2\2\u00bd\u00bc\3\2\2\2\u00be\r\3\2\2\2\u00bf\u00c2\5\20\t"+
+ "\2\u00c0\u00c2\5\b\5\2\u00c1\u00bf\3\2\2\2\u00c1\u00c0\3\2\2\2\u00c2\17"+
+ "\3\2\2\2\u00c3\u00c7\7\5\2\2\u00c4\u00c6\5\b\5\2\u00c5\u00c4\3\2\2\2\u00c6"+
+ "\u00c9\3\2\2\2\u00c7\u00c5\3\2\2\2\u00c7\u00c8\3\2\2\2\u00c8\u00cb\3\2"+
+ "\2\2\u00c9\u00c7\3\2\2\2\u00ca\u00cc\5\f\7\2\u00cb\u00ca\3\2\2\2\u00cb"+
+ "\u00cc\3\2\2\2\u00cc\u00cd\3\2\2\2\u00cd\u00ce\7\6\2\2\u00ce\21\3\2\2"+
+ "\2\u00cf\u00d0\7\16\2\2\u00d0\23\3\2\2\2\u00d1\u00d4\5\30\r\2\u00d2\u00d4"+
+ "\5 \21\2\u00d3\u00d1\3\2\2\2\u00d3\u00d2\3\2\2\2\u00d4\25\3\2\2\2\u00d5"+
+ "\u00d6\5 \21\2\u00d6\27\3\2\2\2\u00d7\u00d8\5\32\16\2\u00d8\u00dd\5\34"+
+ "\17\2\u00d9\u00da\7\r\2\2\u00da\u00dc\5\34\17\2\u00db\u00d9\3\2\2\2\u00dc"+
+ "\u00df\3\2\2\2\u00dd\u00db\3\2\2\2\u00dd\u00de\3\2\2\2\u00de\31\3\2\2"+
+ "\2\u00df\u00dd\3\2\2\2\u00e0\u00e5\7S\2\2\u00e1\u00e2\7\7\2\2\u00e2\u00e4"+
+ "\7\b\2\2\u00e3\u00e1\3\2\2\2\u00e4\u00e7\3\2\2\2\u00e5\u00e3\3\2\2\2\u00e5"+
+ "\u00e6\3\2\2\2\u00e6\33\3\2\2\2\u00e7\u00e5\3\2\2\2\u00e8\u00eb\7T\2\2"+
+ "\u00e9\u00ea\7>\2\2\u00ea\u00ec\5 \21\2\u00eb\u00e9\3\2\2\2\u00eb\u00ec"+
+ "\3\2\2\2\u00ec\35\3\2\2\2\u00ed\u00ee\7\32\2\2\u00ee\u00ef\7\t\2\2\u00ef"+
+ "\u00f0\7S\2\2\u00f0\u00f1\7T\2\2\u00f1\u00f2\7\n\2\2\u00f2\u00f3\5\20"+
+ "\t\2\u00f3\37\3\2\2\2\u00f4\u00f5\b\21\1\2\u00f5\u00f6\5\"\22\2\u00f6"+
+ "\u0129\3\2\2\2\u00f7\u00f8\f\21\2\2\u00f8\u00f9\t\2\2\2\u00f9\u0128\5"+
+ " \21\22\u00fa\u00fb\f\20\2\2\u00fb\u00fc\t\3\2\2\u00fc\u0128\5 \21\21"+
+ "\u00fd\u00fe\f\17\2\2\u00fe\u00ff\t\4\2\2\u00ff\u0128\5 \21\20\u0100\u0101"+
+ "\f\16\2\2\u0101\u0102\t\5\2\2\u0102\u0128\5 \21\17\u0103\u0104\f\r\2\2"+
+ "\u0104\u0105\t\6\2\2\u0105\u0128\5 \21\16\u0106\u0107\f\13\2\2\u0107\u0108"+
+ "\t\7\2\2\u0108\u0128\5 \21\f\u0109\u010a\f\n\2\2\u010a\u010b\7\60\2\2"+
+ "\u010b\u0128\5 \21\13\u010c\u010d\f\t\2\2\u010d\u010e\7\61\2\2\u010e\u0128"+
+ "\5 \21\n\u010f\u0110\f\b\2\2\u0110\u0111\7\62\2\2\u0111\u0128\5 \21\t"+
+ "\u0112\u0113\f\7\2\2\u0113\u0114\7\63\2\2\u0114\u0128\5 \21\b\u0115\u0116"+
+ "\f\6\2\2\u0116\u0117\7\64\2\2\u0117\u0128\5 \21\7\u0118\u0119\f\5\2\2"+
+ "\u0119\u011a\7\65\2\2\u011a\u011b\5 \21\2\u011b\u011c\7\66\2\2\u011c\u011d"+
+ "\5 \21\5\u011d\u0128\3\2\2\2\u011e\u011f\f\4\2\2\u011f\u0120\7\67\2\2"+
+ "\u0120\u0128\5 \21\4\u0121\u0122\f\3\2\2\u0122\u0123\t\b\2\2\u0123\u0128"+
+ "\5 \21\3\u0124\u0125\f\f\2\2\u0125\u0126\7\35\2\2\u0126\u0128\5\32\16"+
+ "\2\u0127\u00f7\3\2\2\2\u0127\u00fa\3\2\2\2\u0127\u00fd\3\2\2\2\u0127\u0100"+
+ "\3\2\2\2\u0127\u0103\3\2\2\2\u0127\u0106\3\2\2\2\u0127\u0109\3\2\2\2\u0127"+
+ "\u010c\3\2\2\2\u0127\u010f\3\2\2\2\u0127\u0112\3\2\2\2\u0127\u0115\3\2"+
+ "\2\2\u0127\u0118\3\2\2\2\u0127\u011e\3\2\2\2\u0127\u0121\3\2\2\2\u0127"+
+ "\u0124\3\2\2\2\u0128\u012b\3\2\2\2\u0129\u0127\3\2\2\2\u0129\u012a\3\2"+
+ "\2\2\u012a!\3\2\2\2\u012b\u0129\3\2\2\2\u012c\u012d\t\t\2\2\u012d\u013a"+
+ "\5$\23\2\u012e\u012f\5$\23\2\u012f\u0130\t\t\2\2\u0130\u013a\3\2\2\2\u0131"+
+ "\u013a\5$\23\2\u0132\u0133\t\n\2\2\u0133\u013a\5\"\22\2\u0134\u0135\7"+
+ "\t\2\2\u0135\u0136\5\32\16\2\u0136\u0137\7\n\2\2\u0137\u0138\5\"\22\2"+
+ "\u0138\u013a\3\2\2\2\u0139\u012c\3\2\2\2\u0139\u012e\3\2\2\2\u0139\u0131"+
+ "\3\2\2\2\u0139\u0132\3\2\2\2\u0139\u0134\3\2\2\2\u013a#\3\2\2\2\u013b"+
+ "\u013f\5&\24\2\u013c\u013e\5(\25\2\u013d\u013c\3\2\2\2\u013e\u0141\3\2"+
+ "\2\2\u013f\u013d\3\2\2\2\u013f\u0140\3\2\2\2\u0140\u014c\3\2\2\2\u0141"+
+ "\u013f\3\2\2\2\u0142\u0143\5\32\16\2\u0143\u0147\5*\26\2\u0144\u0146\5"+
+ "(\25\2\u0145\u0144\3\2\2\2\u0146\u0149\3\2\2\2\u0147\u0145\3\2\2\2\u0147"+
+ "\u0148\3\2\2\2\u0148\u014c\3\2\2\2\u0149\u0147\3\2\2\2\u014a\u014c\5\62"+
+ "\32\2\u014b\u013b\3\2\2\2\u014b\u0142\3\2\2\2\u014b\u014a\3\2\2\2\u014c"+
+ "%\3\2\2\2\u014d\u014e\7\t\2\2\u014e\u014f\5 \21\2\u014f\u0150\7\n\2\2"+
+ "\u0150\u0160\3\2\2\2\u0151\u0160\t\13\2\2\u0152\u0160\7P\2\2\u0153\u0160"+
+ "\7Q\2\2\u0154\u0160\7R\2\2\u0155\u0160\7N\2\2\u0156\u0160\7O\2\2\u0157"+
+ "\u0160\5\64\33\2\u0158\u0160\5\66\34\2\u0159\u0160\7T\2\2\u015a\u015b"+
+ "\7T\2\2\u015b\u0160\5:\36\2\u015c\u015d\7\30\2\2\u015d\u015e\7S\2\2\u015e"+
+ "\u0160\5:\36\2\u015f\u014d\3\2\2\2\u015f\u0151\3\2\2\2\u015f\u0152\3\2"+
+ "\2\2\u015f\u0153\3\2\2\2\u015f\u0154\3\2\2\2\u015f\u0155\3\2\2\2\u015f"+
+ "\u0156\3\2\2\2\u015f\u0157\3\2\2\2\u015f\u0158\3\2\2\2\u015f\u0159\3\2"+
+ "\2\2\u015f\u015a\3\2\2\2\u015f\u015c\3\2\2\2\u0160\'\3\2\2\2\u0161\u0165"+
+ "\5,\27\2\u0162\u0165\5.\30\2\u0163\u0165\5\60\31\2\u0164\u0161\3\2\2\2"+
+ "\u0164\u0162\3\2\2\2\u0164\u0163\3\2\2\2\u0165)\3\2\2\2\u0166\u0169\5"+
+ ",\27\2\u0167\u0169\5.\30\2\u0168\u0166\3\2\2\2\u0168\u0167\3\2\2\2\u0169"+
+ "+\3\2\2\2\u016a\u016b\t\f\2\2\u016b\u016c\7V\2\2\u016c\u016d\5:\36\2\u016d"+
+ "-\3\2\2\2\u016e\u016f\t\f\2\2\u016f\u0170\t\r\2\2\u0170/\3\2\2\2\u0171"+
+ "\u0172\7\7\2\2\u0172\u0173\5 \21\2\u0173\u0174\7\b\2\2\u0174\61\3\2\2"+
+ "\2\u0175\u0176\7\30\2\2\u0176\u017b\7S\2\2\u0177\u0178\7\7\2\2\u0178\u0179"+
+ "\5 \21\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*\26\2\u0180\u0182\5(\25\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"+
+ "\u019f\3\2\2\2\u0188\u0189\7\30\2\2\u0189\u018a\7S\2\2\u018a\u018b\7\7"+
+ "\2\2\u018b\u018c\7\b\2\2\u018c\u0195\7\5\2\2\u018d\u0192\5 \21\2\u018e"+
+ "\u018f\7\r\2\2\u018f\u0191\5 \21\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\u0197\3\2"+
+ "\2\2\u0197\u019b\7\6\2\2\u0198\u019a\5(\25\2\u0199\u0198\3\2\2\2\u019a"+
"\u019d\3\2\2\2\u019b\u0199\3\2\2\2\u019b\u019c\3\2\2\2\u019c\u019f\3\2"+
- "\2\2\u019d\u019b\3\2\2\2\u019e\u0172\3\2\2\2\u019e\u0185\3\2\2\2\u019f"+
- "\61\3\2\2\2\u01a0\u01a1\7\7\2\2\u01a1\u01a6\5\36\20\2\u01a2\u01a3\7\r"+
- "\2\2\u01a3\u01a5\5\36\20\2\u01a4\u01a2\3\2\2\2\u01a5\u01a8\3\2\2\2\u01a6"+
- "\u01a4\3\2\2\2\u01a6\u01a7\3\2\2\2\u01a7\u01a9\3\2\2\2\u01a8\u01a6\3\2"+
- "\2\2\u01a9\u01aa\7\b\2\2\u01aa\u01ae\3\2\2\2\u01ab\u01ac\7\7\2\2\u01ac"+
- "\u01ae\7\b\2\2\u01ad\u01a0\3\2\2\2\u01ad\u01ab\3\2\2\2\u01ae\63\3\2\2"+
- "\2\u01af\u01b0\7\7\2\2\u01b0\u01b5\5\66\34\2\u01b1\u01b2\7\r\2\2\u01b2"+
- "\u01b4\5\66\34\2\u01b3\u01b1\3\2\2\2\u01b4\u01b7\3\2\2\2\u01b5\u01b3\3"+
- "\2\2\2\u01b5\u01b6\3\2\2\2\u01b6\u01b8\3\2\2\2\u01b7\u01b5\3\2\2\2\u01b8"+
- "\u01b9\7\b\2\2\u01b9\u01be\3\2\2\2\u01ba\u01bb\7\7\2\2\u01bb\u01bc\7\66"+
- "\2\2\u01bc\u01be\7\b\2\2\u01bd\u01af\3\2\2\2\u01bd\u01ba\3\2\2\2\u01be"+
- "\65\3\2\2\2\u01bf\u01c0\5\36\20\2\u01c0\u01c1\7\66\2\2\u01c1\u01c2\5\36"+
- "\20\2\u01c2\67\3\2\2\2\u01c3\u01cc\7\t\2\2\u01c4\u01c9\5:\36\2\u01c5\u01c6"+
- "\7\r\2\2\u01c6\u01c8\5:\36\2\u01c7\u01c5\3\2\2\2\u01c8\u01cb\3\2\2\2\u01c9"+
- "\u01c7\3\2\2\2\u01c9\u01ca\3\2\2\2\u01ca\u01cd\3\2\2\2\u01cb\u01c9\3\2"+
- "\2\2\u01cc\u01c4\3\2\2\2\u01cc\u01cd\3\2\2\2\u01cd\u01ce\3\2\2\2\u01ce"+
- "\u01cf\7\n\2\2\u01cf9\3\2\2\2\u01d0\u01d4\5\36\20\2\u01d1\u01d4\5<\37"+
- "\2\u01d2\u01d4\5@!\2\u01d3\u01d0\3\2\2\2\u01d3\u01d1\3\2\2\2\u01d3\u01d2"+
- "\3\2\2\2\u01d4;\3\2\2\2\u01d5\u01e3\5> \2\u01d6\u01df\7\t\2\2\u01d7\u01dc"+
- "\5> \2\u01d8\u01d9\7\r\2\2\u01d9\u01db\5> \2\u01da\u01d8\3\2\2\2\u01db"+
- "\u01de\3\2\2\2\u01dc\u01da\3\2\2\2\u01dc\u01dd\3\2\2\2\u01dd\u01e0\3\2"+
- "\2\2\u01de\u01dc\3\2\2\2\u01df\u01d7\3\2\2\2\u01df\u01e0\3\2\2\2\u01e0"+
- "\u01e1\3\2\2\2\u01e1\u01e3\7\n\2\2\u01e2\u01d5\3\2\2\2\u01e2\u01d6\3\2"+
- "\2\2\u01e3\u01e4\3\2\2\2\u01e4\u01e7\79\2\2\u01e5\u01e8\5\f\7\2\u01e6"+
- "\u01e8\5\36\20\2\u01e7\u01e5\3\2\2\2\u01e7\u01e6\3\2\2\2\u01e8=\3\2\2"+
- "\2\u01e9\u01eb\5\26\f\2\u01ea\u01e9\3\2\2\2\u01ea\u01eb\3\2\2\2\u01eb"+
- "\u01ec\3\2\2\2\u01ec\u01ed\7T\2\2\u01ed?\3\2\2\2\u01ee\u01ef\7S\2\2\u01ef"+
- "\u01f0\78\2\2\u01f0\u01fc\7T\2\2\u01f1\u01f2\5\26\f\2\u01f2\u01f3\78\2"+
- "\2\u01f3\u01f4\7\30\2\2\u01f4\u01fc\3\2\2\2\u01f5\u01f6\7T\2\2\u01f6\u01f7"+
- "\78\2\2\u01f7\u01fc\7T\2\2\u01f8\u01f9\7\34\2\2\u01f9\u01fa\78\2\2\u01fa"+
- "\u01fc\7T\2\2\u01fb\u01ee\3\2\2\2\u01fb\u01f1\3\2\2\2\u01fb\u01f5\3\2"+
- "\2\2\u01fb\u01f8\3\2\2\2\u01fcA\3\2\2\2\62EK^amu\u0082\u0086\u008a\u008f"+
- "\u00b2\u00bb\u00bf\u00c5\u00ce\u00d8\u00e0\u00e6\u0124\u0126\u0136\u013c"+
- "\u0144\u0148\u015c\u0161\u0165\u017a\u0180\u0183\u018f\u0192\u0195\u019b"+
- "\u019e\u01a6\u01ad\u01b5\u01bd\u01c9\u01cc\u01d3\u01dc\u01df\u01e2\u01e7"+
- "\u01ea\u01fb";
+ "\2\2\u019d\u019b\3\2\2\2\u019e\u0175\3\2\2\2\u019e\u0188\3\2\2\2\u019f"+
+ "\63\3\2\2\2\u01a0\u01a1\7\7\2\2\u01a1\u01a6\5 \21\2\u01a2\u01a3\7\r\2"+
+ "\2\u01a3\u01a5\5 \21\2\u01a4\u01a2\3\2\2\2\u01a5\u01a8\3\2\2\2\u01a6\u01a4"+
+ "\3\2\2\2\u01a6\u01a7\3\2\2\2\u01a7\u01a9\3\2\2\2\u01a8\u01a6\3\2\2\2\u01a9"+
+ "\u01aa\7\b\2\2\u01aa\u01ae\3\2\2\2\u01ab\u01ac\7\7\2\2\u01ac\u01ae\7\b"+
+ "\2\2\u01ad\u01a0\3\2\2\2\u01ad\u01ab\3\2\2\2\u01ae\65\3\2\2\2\u01af\u01b0"+
+ "\7\7\2\2\u01b0\u01b5\58\35\2\u01b1\u01b2\7\r\2\2\u01b2\u01b4\58\35\2\u01b3"+
+ "\u01b1\3\2\2\2\u01b4\u01b7\3\2\2\2\u01b5\u01b3\3\2\2\2\u01b5\u01b6\3\2"+
+ "\2\2\u01b6\u01b8\3\2\2\2\u01b7\u01b5\3\2\2\2\u01b8\u01b9\7\b\2\2\u01b9"+
+ "\u01be\3\2\2\2\u01ba\u01bb\7\7\2\2\u01bb\u01bc\7\66\2\2\u01bc\u01be\7"+
+ "\b\2\2\u01bd\u01af\3\2\2\2\u01bd\u01ba\3\2\2\2\u01be\67\3\2\2\2\u01bf"+
+ "\u01c0\5 \21\2\u01c0\u01c1\7\66\2\2\u01c1\u01c2\5 \21\2\u01c29\3\2\2\2"+
+ "\u01c3\u01cc\7\t\2\2\u01c4\u01c9\5<\37\2\u01c5\u01c6\7\r\2\2\u01c6\u01c8"+
+ "\5<\37\2\u01c7\u01c5\3\2\2\2\u01c8\u01cb\3\2\2\2\u01c9\u01c7\3\2\2\2\u01c9"+
+ "\u01ca\3\2\2\2\u01ca\u01cd\3\2\2\2\u01cb\u01c9\3\2\2\2\u01cc\u01c4\3\2"+
+ "\2\2\u01cc\u01cd\3\2\2\2\u01cd\u01ce\3\2\2\2\u01ce\u01cf\7\n\2\2\u01cf"+
+ ";\3\2\2\2\u01d0\u01d4\5 \21\2\u01d1\u01d4\5> \2\u01d2\u01d4\5B\"\2\u01d3"+
+ "\u01d0\3\2\2\2\u01d3\u01d1\3\2\2\2\u01d3\u01d2\3\2\2\2\u01d4=\3\2\2\2"+
+ "\u01d5\u01e3\5@!\2\u01d6\u01df\7\t\2\2\u01d7\u01dc\5@!\2\u01d8\u01d9\7"+
+ "\r\2\2\u01d9\u01db\5@!\2\u01da\u01d8\3\2\2\2\u01db\u01de\3\2\2\2\u01dc"+
+ "\u01da\3\2\2\2\u01dc\u01dd\3\2\2\2\u01dd\u01e0\3\2\2\2\u01de\u01dc\3\2"+
+ "\2\2\u01df\u01d7\3\2\2\2\u01df\u01e0\3\2\2\2\u01e0\u01e1\3\2\2\2\u01e1"+
+ "\u01e3\7\n\2\2\u01e2\u01d5\3\2\2\2\u01e2\u01d6\3\2\2\2\u01e3\u01e4\3\2"+
+ "\2\2\u01e4\u01e7\79\2\2\u01e5\u01e8\5\20\t\2\u01e6\u01e8\5 \21\2\u01e7"+
+ "\u01e5\3\2\2\2\u01e7\u01e6\3\2\2\2\u01e8?\3\2\2\2\u01e9\u01eb\5\32\16"+
+ "\2\u01ea\u01e9\3\2\2\2\u01ea\u01eb\3\2\2\2\u01eb\u01ec\3\2\2\2\u01ec\u01ed"+
+ "\7T\2\2\u01edA\3\2\2\2\u01ee\u01ef\7S\2\2\u01ef\u01f0\78\2\2\u01f0\u01fc"+
+ "\7T\2\2\u01f1\u01f2\5\32\16\2\u01f2\u01f3\78\2\2\u01f3\u01f4\7\30\2\2"+
+ "\u01f4\u01fc\3\2\2\2\u01f5\u01f6\7T\2\2\u01f6\u01f7\78\2\2\u01f7\u01fc"+
+ "\7T\2\2\u01f8\u01f9\7\34\2\2\u01f9\u01fa\78\2\2\u01fa\u01fc\7T\2\2\u01fb"+
+ "\u01ee\3\2\2\2\u01fb\u01f1\3\2\2\2\u01fb\u01f5\3\2\2\2\u01fb\u01f8\3\2"+
+ "\2\2\u01fcC\3\2\2\2\65GMQcfnx\u0080\u0085\u0089\u008d\u0092\u00aa\u00ac"+
+ "\u00bd\u00c1\u00c7\u00cb\u00d3\u00dd\u00e5\u00eb\u0127\u0129\u0139\u013f"+
+ "\u0147\u014b\u015f\u0164\u0168\u017d\u0183\u0186\u0192\u0195\u019b\u019e"+
+ "\u01a6\u01ad\u01b5\u01bd\u01c9\u01cc\u01d3\u01dc\u01df\u01e2\u01e7\u01ea"+
+ "\u01fb";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserBaseVisitor.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserBaseVisitor.java
index 8c4741e672533..81e7166d9a9ae 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserBaseVisitor.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserBaseVisitor.java
@@ -38,21 +38,21 @@ class PainlessParserBaseVisitor extends AbstractParseTreeVisitor implement
* The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.
*/
- @Override public T visitIf(PainlessParser.IfContext ctx) { return visitChildren(ctx); }
+ @Override public T visitStatement(PainlessParser.StatementContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.
*/
- @Override public T visitWhile(PainlessParser.WhileContext ctx) { return visitChildren(ctx); }
+ @Override public T visitIf(PainlessParser.IfContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.
*/
- @Override public T visitDo(PainlessParser.DoContext ctx) { return visitChildren(ctx); }
+ @Override public T visitWhile(PainlessParser.WhileContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
@@ -80,35 +80,42 @@ class PainlessParserBaseVisitor extends AbstractParseTreeVisitor implement
* The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.
*/
- @Override public T visitDecl(PainlessParser.DeclContext ctx) { return visitChildren(ctx); }
+ @Override public T visitTry(PainlessParser.TryContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.
*/
- @Override public T visitContinue(PainlessParser.ContinueContext ctx) { return visitChildren(ctx); }
+ @Override public T visitDo(PainlessParser.DoContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.
*/
- @Override public T visitBreak(PainlessParser.BreakContext ctx) { return visitChildren(ctx); }
+ @Override public T visitDecl(PainlessParser.DeclContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.
*/
- @Override public T visitReturn(PainlessParser.ReturnContext ctx) { return visitChildren(ctx); }
+ @Override public T visitContinue(PainlessParser.ContinueContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.
*/
- @Override public T visitTry(PainlessParser.TryContext ctx) { return visitChildren(ctx); }
+ @Override public T visitBreak(PainlessParser.BreakContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitReturn(PainlessParser.ReturnContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
@@ -186,13 +193,6 @@ class PainlessParserBaseVisitor extends AbstractParseTreeVisitor implement
* {@link #visitChildren} on {@code ctx}.
*/
@Override public T visitTrap(PainlessParser.TrapContext ctx) { return visitChildren(ctx); }
- /**
- * {@inheritDoc}
- *
- * The default implementation returns the result of calling
- * {@link #visitChildren} on {@code ctx}.
- */
- @Override public T visitDelimiter(PainlessParser.DelimiterContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserVisitor.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserVisitor.java
index 47bfd4a1d05b9..ec3e251f3e9ad 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserVisitor.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserVisitor.java
@@ -29,92 +29,98 @@ interface PainlessParserVisitor extends ParseTreeVisitor {
*/
T visitParameters(PainlessParser.ParametersContext ctx);
/**
- * Visit a parse tree produced by the {@code if}
- * labeled alternative in {@link PainlessParser#statement}.
+ * Visit a parse tree produced by {@link PainlessParser#statement}.
* @param ctx the parse tree
* @return the visitor result
*/
- T visitIf(PainlessParser.IfContext ctx);
+ T visitStatement(PainlessParser.StatementContext ctx);
/**
- * Visit a parse tree produced by the {@code while}
- * labeled alternative in {@link PainlessParser#statement}.
+ * Visit a parse tree produced by the {@code if}
+ * labeled alternative in {@link PainlessParser#rstatement}.
* @param ctx the parse tree
* @return the visitor result
*/
- T visitWhile(PainlessParser.WhileContext ctx);
+ T visitIf(PainlessParser.IfContext ctx);
/**
- * Visit a parse tree produced by the {@code do}
- * labeled alternative in {@link PainlessParser#statement}.
+ * Visit a parse tree produced by the {@code while}
+ * labeled alternative in {@link PainlessParser#rstatement}.
* @param ctx the parse tree
* @return the visitor result
*/
- T visitDo(PainlessParser.DoContext ctx);
+ T visitWhile(PainlessParser.WhileContext ctx);
/**
* Visit a parse tree produced by the {@code for}
- * labeled alternative in {@link PainlessParser#statement}.
+ * labeled alternative in {@link PainlessParser#rstatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFor(PainlessParser.ForContext ctx);
/**
* Visit a parse tree produced by the {@code each}
- * labeled alternative in {@link PainlessParser#statement}.
+ * labeled alternative in {@link PainlessParser#rstatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitEach(PainlessParser.EachContext ctx);
/**
* Visit a parse tree produced by the {@code ineach}
- * labeled alternative in {@link PainlessParser#statement}.
+ * labeled alternative in {@link PainlessParser#rstatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitIneach(PainlessParser.IneachContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code try}
+ * labeled alternative in {@link PainlessParser#rstatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitTry(PainlessParser.TryContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code do}
+ * labeled alternative in {@link PainlessParser#dstatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitDo(PainlessParser.DoContext ctx);
/**
* Visit a parse tree produced by the {@code decl}
- * labeled alternative in {@link PainlessParser#statement}.
+ * labeled alternative in {@link PainlessParser#dstatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDecl(PainlessParser.DeclContext ctx);
/**
* Visit a parse tree produced by the {@code continue}
- * labeled alternative in {@link PainlessParser#statement}.
+ * labeled alternative in {@link PainlessParser#dstatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitContinue(PainlessParser.ContinueContext ctx);
/**
* Visit a parse tree produced by the {@code break}
- * labeled alternative in {@link PainlessParser#statement}.
+ * labeled alternative in {@link PainlessParser#dstatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitBreak(PainlessParser.BreakContext ctx);
/**
* Visit a parse tree produced by the {@code return}
- * labeled alternative in {@link PainlessParser#statement}.
+ * labeled alternative in {@link PainlessParser#dstatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitReturn(PainlessParser.ReturnContext ctx);
- /**
- * Visit a parse tree produced by the {@code try}
- * labeled alternative in {@link PainlessParser#statement}.
- * @param ctx the parse tree
- * @return the visitor result
- */
- T visitTry(PainlessParser.TryContext ctx);
/**
* Visit a parse tree produced by the {@code throw}
- * labeled alternative in {@link PainlessParser#statement}.
+ * labeled alternative in {@link PainlessParser#dstatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitThrow(PainlessParser.ThrowContext ctx);
/**
* Visit a parse tree produced by the {@code expr}
- * labeled alternative in {@link PainlessParser#statement}.
+ * labeled alternative in {@link PainlessParser#dstatement}.
* @param ctx the parse tree
* @return the visitor result
*/
@@ -173,12 +179,6 @@ interface PainlessParserVisitor extends ParseTreeVisitor {
* @return the visitor result
*/
T visitTrap(PainlessParser.TrapContext ctx);
- /**
- * Visit a parse tree produced by {@link PainlessParser#delimiter}.
- * @param ctx the parse tree
- * @return the visitor result
- */
- T visitDelimiter(PainlessParser.DelimiterContext ctx);
/**
* Visit a parse tree produced by the {@code single}
* labeled alternative in {@link PainlessParser#expression}.
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java
index a15f87966eae2..3ac6cb7fd37c4 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java
@@ -56,7 +56,6 @@
import org.elasticsearch.painless.antlr.PainlessParser.DeclarationContext;
import org.elasticsearch.painless.antlr.PainlessParser.DecltypeContext;
import org.elasticsearch.painless.antlr.PainlessParser.DeclvarContext;
-import org.elasticsearch.painless.antlr.PainlessParser.DelimiterContext;
import org.elasticsearch.painless.antlr.PainlessParser.DoContext;
import org.elasticsearch.painless.antlr.PainlessParser.DynamicContext;
import org.elasticsearch.painless.antlr.PainlessParser.EachContext;
@@ -264,6 +263,10 @@ public ANode visitSource(SourceContext ctx) {
statements.add((AStatement)visit(statement));
}
+ if (ctx.dstatement() != null) {
+ statements.add((AStatement)visit(ctx.dstatement()));
+ }
+
return new SSource(scriptClassInfo, settings, sourceName, sourceText, debugStream, (MainMethodReserved)reserved.pop(),
location(ctx), functions, globals, statements);
}
@@ -290,6 +293,10 @@ public ANode visitFunction(FunctionContext ctx) {
statements.add((AStatement)visit(statement));
}
+ if (ctx.block().dstatement() != null) {
+ statements.add((AStatement)visit(ctx.block().dstatement()));
+ }
+
return new SFunction((FunctionReserved)reserved.pop(), location(ctx), rtnType, name,
paramTypes, paramNames, statements, false);
}
@@ -299,6 +306,17 @@ public ANode visitParameters(ParametersContext ctx) {
throw location(ctx).createError(new IllegalStateException("Illegal tree structure."));
}
+ @Override
+ public ANode visitStatement(StatementContext ctx) {
+ if (ctx.rstatement() != null) {
+ return visit(ctx.rstatement());
+ } else if (ctx.dstatement() != null) {
+ return visit(ctx.dstatement());
+ } else {
+ throw location(ctx).createError(new IllegalStateException("Illegal tree structure."));
+ }
+ }
+
@Override
public ANode visitIf(IfContext ctx) {
AExpression expression = (AExpression)visit(ctx.expression());
@@ -446,7 +464,7 @@ public ANode visitTrailer(TrailerContext ctx) {
@Override
public ANode visitBlock(BlockContext ctx) {
- if (ctx.statement().isEmpty()) {
+ if (ctx.statement().isEmpty() && ctx.dstatement() == null) {
return null;
} else {
List statements = new ArrayList<>();
@@ -455,6 +473,10 @@ public ANode visitBlock(BlockContext ctx) {
statements.add((AStatement)visit(statement));
}
+ if (ctx.dstatement() != null) {
+ statements.add((AStatement)visit(ctx.dstatement()));
+ }
+
return new SBlock(location(ctx), statements);
}
}
@@ -514,11 +536,6 @@ public ANode visitTrap(TrapContext ctx) {
return new SCatch(location(ctx), type, name, block);
}
- @Override
- public ANode visitDelimiter(DelimiterContext ctx) {
- throw location(ctx).createError(new IllegalStateException("Illegal tree structure."));
- }
-
@Override
public ANode visitSingle(SingleContext ctx) {
return visit(ctx.unary());
@@ -1074,6 +1091,10 @@ public ANode visitLambda(LambdaContext ctx) {
for (StatementContext statement : ctx.block().statement()) {
statements.add((AStatement)visit(statement));
}
+
+ if (ctx.block().dstatement() != null) {
+ statements.add((AStatement)visit(ctx.block().dstatement()));
+ }
}
FunctionReserved lambdaReserved = (FunctionReserved)reserved.pop();
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/RegexTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/RegexTests.java
index 0a66b67a2e8ac..911a50468cc17 100644
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/RegexTests.java
+++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/RegexTests.java
@@ -278,6 +278,6 @@ public void testBogusRegexFlag() {
IllegalArgumentException e = expectScriptThrows(IllegalArgumentException.class, () -> {
exec("/asdf/b", false); // Not picky so we get a non-assertion error
});
- assertEquals("unexpected token ['b'] was expecting one of [{, ';'}].", e.getMessage());
+ assertEquals("invalid sequence of tokens near ['b'].", e.getMessage());
}
}
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java
index d60da7b795fbc..1bb754db84745 100644
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java
+++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java
@@ -256,7 +256,7 @@ public void testRCurlyNotDelim() {
// We don't want PICKY here so we get the normal error message
exec("def i = 1} return 1", emptyMap(), emptyMap(), null, false);
});
- assertEquals("unexpected token ['}'] was expecting one of [].", e.getMessage());
+ assertEquals("invalid sequence of tokens near ['}'].", e.getMessage());
}
public void testBadBoxingCast() {