diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java index ff53b661a9ba7..8d35968386f32 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java @@ -22,6 +22,7 @@ import org.elasticsearch.painless.AnalyzerCaster; import org.elasticsearch.painless.Location; import org.elasticsearch.painless.Scope; +import org.elasticsearch.painless.ir.CastNode; import org.elasticsearch.painless.ir.ClassNode; import org.elasticsearch.painless.ir.ExpressionNode; import org.elasticsearch.painless.lookup.PainlessCast; @@ -83,10 +84,11 @@ public abstract class AExpression extends ANode { */ boolean internal = false; - /** - * Set to true by {@link ENull} to represent a null value. - */ - boolean isNull = false; + // This is used to support the transition from a mutable to immutable state. + // Currently, the IR tree is built during the user tree "write" phase, so + // this is stored on the node to set during the "semantic" phase and then + // use during the "write" phase. + PainlessCast cast = null; /** * Standard constructor with location used for error tracking. @@ -116,23 +118,21 @@ public abstract class AExpression extends ANode { */ abstract ExpressionNode write(ClassNode classNode); - /** - * Inserts {@link ECast} nodes into the tree for implicit casts. Also replaces - * nodes with the constant variable set to a non-null value with {@link EConstant}. - * @return The new child node for the parent node calling this method. - */ - AExpression cast(ScriptRoot scriptRoot, Scope scope) { - PainlessCast cast = AnalyzerCaster.getLegalCast(location, actual, expected, explicit, internal); + void cast() { + cast = AnalyzerCaster.getLegalCast(location, actual, expected, explicit, internal); + } + ExpressionNode cast(ExpressionNode expressionNode) { if (cast == null) { - return this; - } else { - ECast ecast = new ECast(location, this, cast); - ecast.statement = statement; - ecast.actual = expected; - ecast.isNull = isNull; - - return ecast; + return expressionNode; } + + CastNode castNode = new CastNode(); + castNode.setLocation(location); + castNode.setExpressionType(expected); + castNode.setCast(cast); + castNode.setChildNode(expressionNode); + + return castNode; } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EAssignment.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EAssignment.java index 71d2be8dd1d67..4de8bdcb9a1e1 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EAssignment.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EAssignment.java @@ -188,7 +188,7 @@ private void analyzeCompound(ScriptRoot scriptRoot, Scope scope) { rhs.expected = promote; } - rhs = rhs.cast(scriptRoot, scope); + rhs.cast(); there = AnalyzerCaster.getLegalCast(location, lhs.actual, promote, false, false); back = AnalyzerCaster.getLegalCast(location, promote, lhs.actual, true, false); @@ -216,7 +216,7 @@ private void analyzeSimple(ScriptRoot scriptRoot, Scope scope) { rhs.analyze(scriptRoot, scope); } - rhs = rhs.cast(scriptRoot, scope); + rhs.cast(); this.statement = true; this.actual = read ? lhs.actual : void.class; @@ -233,7 +233,7 @@ AssignmentNode write(ClassNode classNode) { AssignmentNode assignmentNode = new AssignmentNode(); assignmentNode.setLeftNode(lhs.write(classNode)); - assignmentNode.setRightNode(rhs.write(classNode)); + assignmentNode.setRightNode(rhs.cast(rhs.write(classNode))); assignmentNode.setLocation(location); assignmentNode.setExpressionType(actual); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java index 6deca2498b5c7..b5584c4b19360 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java @@ -114,8 +114,8 @@ private void analyzeMul(ScriptRoot scriptRoot, Scope variables) { right.expected = promote; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); } private void analyzeDiv(ScriptRoot scriptRoot, Scope variables) { @@ -144,8 +144,8 @@ private void analyzeDiv(ScriptRoot scriptRoot, Scope variables) { right.expected = promote; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); } private void analyzeRem(ScriptRoot scriptRoot, Scope variables) { @@ -174,8 +174,8 @@ private void analyzeRem(ScriptRoot scriptRoot, Scope variables) { right.expected = promote; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); } private void analyzeAdd(ScriptRoot scriptRoot, Scope variables) { @@ -216,8 +216,8 @@ private void analyzeAdd(ScriptRoot scriptRoot, Scope variables) { right.expected = promote; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); } private void analyzeSub(ScriptRoot scriptRoot, Scope variables) { @@ -246,8 +246,8 @@ private void analyzeSub(ScriptRoot scriptRoot, Scope variables) { right.expected = promote; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); } private void analyzeRegexOp(ScriptRoot scriptRoot, Scope variables) { @@ -257,8 +257,8 @@ private void analyzeRegexOp(ScriptRoot scriptRoot, Scope variables) { left.expected = String.class; right.expected = Pattern.class; - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); promote = boolean.class; actual = boolean.class; @@ -298,8 +298,8 @@ private void analyzeLSH(ScriptRoot scriptRoot, Scope variables) { } } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); } private void analyzeRSH(ScriptRoot scriptRoot, Scope variables) { @@ -336,8 +336,8 @@ private void analyzeRSH(ScriptRoot scriptRoot, Scope variables) { } } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); } private void analyzeUSH(ScriptRoot scriptRoot, Scope variables) { @@ -374,8 +374,8 @@ private void analyzeUSH(ScriptRoot scriptRoot, Scope variables) { } } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); } private void analyzeBWAnd(ScriptRoot scriptRoot, Scope variables) { @@ -404,8 +404,8 @@ private void analyzeBWAnd(ScriptRoot scriptRoot, Scope variables) { right.expected = promote; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); } private void analyzeXor(ScriptRoot scriptRoot, Scope variables) { @@ -433,8 +433,8 @@ private void analyzeXor(ScriptRoot scriptRoot, Scope variables) { right.expected = promote; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); } private void analyzeBWOr(ScriptRoot scriptRoot, Scope variables) { @@ -462,16 +462,16 @@ private void analyzeBWOr(ScriptRoot scriptRoot, Scope variables) { right.expected = promote; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); } @Override BinaryMathNode write(ClassNode classNode) { BinaryMathNode binaryMathNode = new BinaryMathNode(); - binaryMathNode.setLeftNode(left.write(classNode)); - binaryMathNode.setRightNode(right.write(classNode)); + binaryMathNode.setLeftNode(left.cast(left.write(classNode))); + binaryMathNode.setRightNode(right.cast(right.write(classNode))); binaryMathNode.setLocation(location); binaryMathNode.setExpressionType(actual); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java index ec2407dc92016..c7538ffa7a887 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java @@ -49,11 +49,11 @@ public EBool(Location location, Operation operation, AExpression left, AExpressi void analyze(ScriptRoot scriptRoot, Scope scope) { left.expected = boolean.class; left.analyze(scriptRoot, scope); - left = left.cast(scriptRoot, scope); + left.cast(); right.expected = boolean.class; right.analyze(scriptRoot, scope); - right = right.cast(scriptRoot, scope); + right.cast(); actual = boolean.class; } @@ -62,8 +62,8 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { BooleanNode write(ClassNode classNode) { BooleanNode booleanNode = new BooleanNode(); - booleanNode.setLeftNode(left.write(classNode)); - booleanNode.setRightNode(right.write(classNode)); + booleanNode.setLeftNode(left.cast(left.write(classNode))); + booleanNode.setRightNode(right.cast(right.write(classNode))); booleanNode.setLocation(location); booleanNode.setExpressionType(actual); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECallLocal.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECallLocal.java index 00f2032d183a1..fa2e1fce72c4f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECallLocal.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECallLocal.java @@ -144,7 +144,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { expression.expected = typeParameters.get(argument + classBindingOffset); expression.internal = true; expression.analyze(scriptRoot, scope); - arguments.set(argument, expression.cast(scriptRoot, scope)); + expression.cast(); } statement = true; @@ -155,7 +155,7 @@ MemberCallNode write(ClassNode classNode) { MemberCallNode memberCallNode = new MemberCallNode(); for (AExpression argument : arguments) { - memberCallNode.addArgumentNode(argument.write(classNode)); + memberCallNode.addArgumentNode(argument.cast(argument.write(classNode))); } memberCallNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECast.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECast.java deleted file mode 100644 index 78a1c48119e2b..0000000000000 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECast.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.painless.node; - -import org.elasticsearch.painless.Location; -import org.elasticsearch.painless.Scope; -import org.elasticsearch.painless.ir.CastNode; -import org.elasticsearch.painless.ir.ClassNode; -import org.elasticsearch.painless.lookup.PainlessCast; -import org.elasticsearch.painless.lookup.PainlessLookupUtility; -import org.elasticsearch.painless.symbol.ScriptRoot; - -import java.util.Objects; - -/** - * Represents a cast that is inserted into the tree replacing other casts. (Internal only.) Casts are inserted during semantic checking. - */ -final class ECast extends AExpression { - - private AExpression child; - private final PainlessCast cast; - - ECast(Location location, AExpression child, PainlessCast cast) { - super(location); - - this.child = Objects.requireNonNull(child); - this.cast = Objects.requireNonNull(cast); - } - - @Override - void analyze(ScriptRoot scriptRoot, Scope scope) { - throw createError(new IllegalStateException("Illegal tree structure.")); - } - - @Override - CastNode write(ClassNode classNode) { - CastNode castNode = new CastNode(); - - castNode.setChildNode(child.write(classNode)); - - castNode.setLocation(location); - castNode.setExpressionType(actual); - castNode.setCast(cast); - - return castNode; - } - - @Override - public String toString() { - return singleLineToString(PainlessLookupUtility.typeToCanonicalTypeName(cast.targetType), child); - } -} diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java index ff1ac49431da7..512acee938a78 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java @@ -93,13 +93,13 @@ private void analyzeEq(ScriptRoot scriptRoot, Scope variables) { right.expected = promotedType; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); - - if (left.isNull && right.isNull) { + if (left instanceof ENull && right instanceof ENull) { throw createError(new IllegalArgumentException("Extraneous comparison of null constants.")); } + left.cast(); + right.cast(); + actual = boolean.class; } @@ -118,13 +118,13 @@ private void analyzeEqR(ScriptRoot scriptRoot, Scope variables) { left.expected = promotedType; right.expected = promotedType; - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); - - if (left.isNull && right.isNull) { + if (left instanceof ENull && right instanceof ENull) { throw createError(new IllegalArgumentException("Extraneous comparison of null constants.")); } + left.cast(); + right.cast(); + actual = boolean.class; } @@ -148,13 +148,13 @@ private void analyzeNE(ScriptRoot scriptRoot, Scope variables) { right.expected = promotedType; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); - - if (left.isNull && right.isNull) { + if (left instanceof ENull && right instanceof ENull) { throw createError(new IllegalArgumentException("Extraneous comparison of null constants.")); } + left.cast(); + right.cast(); + actual = boolean.class; } @@ -173,13 +173,13 @@ private void analyzeNER(ScriptRoot scriptRoot, Scope variables) { left.expected = promotedType; right.expected = promotedType; - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); - - if (left.isNull && right.isNull) { + if (left instanceof ENull && right instanceof ENull) { throw createError(new IllegalArgumentException("Extraneous comparison of null constants.")); } + left.cast(); + right.cast(); + actual = boolean.class; } @@ -203,8 +203,8 @@ private void analyzeGTE(ScriptRoot scriptRoot, Scope variables) { right.expected = promotedType; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); actual = boolean.class; } @@ -229,8 +229,8 @@ private void analyzeGT(ScriptRoot scriptRoot, Scope variables) { right.expected = promotedType; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); actual = boolean.class; } @@ -255,8 +255,8 @@ private void analyzeLTE(ScriptRoot scriptRoot, Scope variables) { right.expected = promotedType; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); actual = boolean.class; } @@ -281,8 +281,8 @@ private void analyzeLT(ScriptRoot scriptRoot, Scope variables) { right.expected = promotedType; } - left = left.cast(scriptRoot, variables); - right = right.cast(scriptRoot, variables); + left.cast(); + right.cast(); actual = boolean.class; } @@ -291,8 +291,8 @@ private void analyzeLT(ScriptRoot scriptRoot, Scope variables) { ComparisonNode write(ClassNode classNode) { ComparisonNode comparisonNode = new ComparisonNode(); - comparisonNode.setLeftNode(left.write(classNode)); - comparisonNode.setRightNode(right.write(classNode)); + comparisonNode.setLeftNode(left.cast(left.write(classNode))); + comparisonNode.setRightNode(right.cast(right.write(classNode))); comparisonNode.setLocation(location); comparisonNode.setExpressionType(actual); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java index 2f3c04e8d899c..c1eb8fbe510da 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java @@ -50,7 +50,7 @@ public EConditional(Location location, AExpression condition, AExpression left, void analyze(ScriptRoot scriptRoot, Scope scope) { condition.expected = boolean.class; condition.analyze(scriptRoot, scope); - condition = condition.cast(scriptRoot, scope); + condition.cast(); left.expected = expected; left.explicit = explicit; @@ -77,17 +77,17 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { actual = promote; } - left = left.cast(scriptRoot, scope); - right = right.cast(scriptRoot, scope); + left.cast(); + right.cast(); } @Override ConditionalNode write(ClassNode classNode) { ConditionalNode conditionalNode = new ConditionalNode(); - conditionalNode.setLeftNode(left.write(classNode)); - conditionalNode.setRightNode(right.write(classNode)); - conditionalNode.setConditionNode(condition.write(classNode)); + conditionalNode.setLeftNode(left.cast(left.write(classNode))); + conditionalNode.setRightNode(right.cast(right.write(classNode))); + conditionalNode.setConditionNode(condition.cast(condition.write(classNode))); conditionalNode.setLocation(location); conditionalNode.setExpressionType(actual); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EElvis.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EElvis.java index 89eabb439ba72..f9ffb019c7a7e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EElvis.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EElvis.java @@ -58,7 +58,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { lhs.analyze(scriptRoot, scope); rhs.analyze(scriptRoot, scope); - if (lhs.isNull) { + if (lhs instanceof ENull) { throw createError(new IllegalArgumentException("Extraneous elvis operator. LHS is null.")); } if (lhs instanceof EBoolean @@ -71,7 +71,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { if (lhs.actual.isPrimitive()) { throw createError(new IllegalArgumentException("Extraneous elvis operator. LHS is a primitive.")); } - if (rhs.isNull) { + if (rhs instanceof ENull) { throw createError(new IllegalArgumentException("Extraneous elvis operator. RHS is null.")); } @@ -83,16 +83,16 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { actual = promote; } - lhs = lhs.cast(scriptRoot, scope); - rhs = rhs.cast(scriptRoot, scope); + lhs.cast(); + rhs.cast(); } @Override ElvisNode write(ClassNode classNode) { ElvisNode elvisNode = new ElvisNode(); - elvisNode.setLeftNode(lhs.write(classNode)); - elvisNode.setRightNode(rhs.write(classNode)); + elvisNode.setLeftNode(lhs.cast(lhs.write(classNode))); + elvisNode.setRightNode(rhs.cast(rhs.write(classNode))); elvisNode.setLocation(location); elvisNode.setExpressionType(actual); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java index ce6365df9c70d..d3d288bde8162 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java @@ -53,20 +53,12 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { child.expected = actual; child.explicit = true; child.analyze(scriptRoot, scope); - child = child.cast(scriptRoot, scope); + child.cast(); } @Override ExpressionNode write(ClassNode classNode) { - throw createError(new IllegalStateException("Illegal tree structure.")); - } - - AExpression cast(ScriptRoot scriptRoot, Scope scope) { - child.expected = expected; - child.explicit = explicit; - child.internal = internal; - - return child.cast(scriptRoot, scope); + return child.cast(child.write(classNode)); } @Override diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java index 19edc026a80e5..01c789dd89e4f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java @@ -63,7 +63,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { // analyze and cast the expression expression.analyze(scriptRoot, scope); expression.expected = expression.actual; - expression = expression.cast(scriptRoot, scope); + expression.cast(); // record if the expression returns a primitive primitiveExpression = expression.actual.isPrimitive(); @@ -78,7 +78,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { InstanceofNode write(ClassNode classNode) { InstanceofNode instanceofNode = new InstanceofNode(); - instanceofNode.setChildNode(expression.write(classNode)); + instanceofNode.setChildNode(expression.cast(expression.write(classNode))); instanceofNode.setLocation(location); instanceofNode.setExpressionType(actual); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java index c9578ece24b83..27c6d1c7897f1 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java @@ -75,7 +75,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { expression.expected = def.class; expression.internal = true; expression.analyze(scriptRoot, scope); - values.set(index, expression.cast(scriptRoot, scope)); + expression.cast(); } } @@ -84,7 +84,7 @@ ListInitializationNode write(ClassNode classNode) { ListInitializationNode listInitializationNode = new ListInitializationNode(); for (AExpression value : values) { - listInitializationNode.addArgumentNode(value.write(classNode)); + listInitializationNode.addArgumentNode(value.cast(value.write(classNode))); } listInitializationNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java index 3819d20d6a3dc..69eb4e10f8866 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java @@ -81,7 +81,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { expression.expected = def.class; expression.internal = true; expression.analyze(scriptRoot, scope); - keys.set(index, expression.cast(scriptRoot, scope)); + expression.cast(); } for (int index = 0; index < values.size(); ++index) { @@ -90,7 +90,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { expression.expected = def.class; expression.internal = true; expression.analyze(scriptRoot, scope); - values.set(index, expression.cast(scriptRoot, scope)); + expression.cast(); } } @@ -99,7 +99,9 @@ MapInitializationNode write(ClassNode classNode) { MapInitializationNode mapInitializationNode = new MapInitializationNode(); for (int index = 0; index < keys.size(); ++index) { - mapInitializationNode.addArgumentNode(keys.get(index).write(classNode), values.get(index).write(classNode)); + mapInitializationNode.addArgumentNode( + keys.get(index).cast(keys.get(index).write(classNode)), + values.get(index).cast(values.get(index).write(classNode))); } mapInitializationNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java index b8250bf02cc49..7e2a315fc24e1 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java @@ -63,7 +63,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { expression.expected = initialize ? clazz.getComponentType() : int.class; expression.internal = true; expression.analyze(scriptRoot, scope); - arguments.set(argument, expression.cast(scriptRoot, scope)); + expression.cast(); } actual = clazz; @@ -74,7 +74,7 @@ NewArrayNode write(ClassNode classNode) { NewArrayNode newArrayNode = new NewArrayNode(); for (AExpression argument : arguments) { - newArrayNode.addArgumentNode(argument.write(classNode)); + newArrayNode.addArgumentNode(argument.cast(argument.write(classNode))); } newArrayNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewObj.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewObj.java index 067593224ebd8..0696b75696e2d 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewObj.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewObj.java @@ -82,7 +82,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { expression.expected = types[argument]; expression.internal = true; expression.analyze(scriptRoot, scope); - arguments.set(argument, expression.cast(scriptRoot, scope)); + expression.cast(); } statement = true; @@ -93,7 +93,7 @@ NewObjectNode write(ClassNode classNode) { NewObjectNode newObjectNode = new NewObjectNode(); for (AExpression argument : arguments) { - newObjectNode.addArgumentNode(argument.write(classNode)); + newObjectNode.addArgumentNode(argument.cast(argument.write(classNode))); } newObjectNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java index 0ed9d3f200aeb..6d26a7de1e79f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java @@ -41,8 +41,6 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { throw createError(new IllegalArgumentException("Must read from null constant.")); } - isNull = true; - if (expected != null) { if (expected.isPrimitive()) { throw createError(new IllegalArgumentException( diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java index 93d0969da3c91..3fe797f0352ee 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java @@ -70,7 +70,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { void analyzeNot(ScriptRoot scriptRoot, Scope variables) { child.expected = boolean.class; child.analyze(scriptRoot, variables); - child = child.cast(scriptRoot, variables); + child.cast(); actual = boolean.class; } @@ -86,7 +86,7 @@ void analyzeBWNot(ScriptRoot scriptRoot, Scope variables) { } child.expected = promote; - child = child.cast(scriptRoot, variables); + child.cast(); if (promote == def.class && expected != null) { actual = expected; @@ -106,7 +106,7 @@ void analyzerAdd(ScriptRoot scriptRoot, Scope variables) { } child.expected = promote; - child = child.cast(scriptRoot, variables); + child.cast(); if (promote == def.class && expected != null) { actual = expected; @@ -126,7 +126,7 @@ void analyzerSub(ScriptRoot scriptRoot, Scope variables) { } child.expected = promote; - child = child.cast(scriptRoot, variables); + child.cast(); if (promote == def.class && expected != null) { actual = expected; @@ -139,7 +139,7 @@ void analyzerSub(ScriptRoot scriptRoot, Scope variables) { UnaryNode write(ClassNode classNode) { UnaryMathNode unaryMathNode = new UnaryMathNode(); - unaryMathNode.setChildNode(child.write(classNode)); + unaryMathNode.setChildNode(child.cast(child.write(classNode))); unaryMathNode.setLocation(location); unaryMathNode.setExpressionType(actual); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java index 2b4540f03e94d..31246ffe56131 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java @@ -50,7 +50,7 @@ public PBrace(Location location, AExpression prefix, AExpression index) { void analyze(ScriptRoot scriptRoot, Scope scope) { prefix.analyze(scriptRoot, scope); prefix.expected = prefix.actual; - prefix = prefix.cast(scriptRoot, scope); + prefix.cast(); if (prefix.actual.isArray()) { sub = new PSubBrace(location, prefix.actual, index); @@ -77,7 +77,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { BraceNode write(ClassNode classNode) { BraceNode braceNode = new BraceNode(); - braceNode.setLeftNode(prefix.write(classNode)); + braceNode.setLeftNode(prefix.cast(prefix.write(classNode))); braceNode.setRightNode(sub.write(classNode)); braceNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java index 3ff1d026347a0..fe4ab2658302c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java @@ -56,7 +56,7 @@ public PCallInvoke(Location location, AExpression prefix, String name, boolean n void analyze(ScriptRoot scriptRoot, Scope scope) { prefix.analyze(scriptRoot, scope); prefix.expected = prefix.actual; - prefix = prefix.cast(scriptRoot, scope); + prefix.cast(); if (prefix.actual == def.class) { sub = new PSubDefCall(location, name, arguments); @@ -90,7 +90,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { CallNode write(ClassNode classNode) { CallNode callNode = new CallNode(); - callNode.setLeftNode(prefix.write(classNode)); + callNode.setLeftNode(prefix.cast(prefix.write(classNode))); callNode.setRightNode(sub.write(classNode)); callNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java index 8db7771192401..a1ad58d28570d 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java @@ -56,7 +56,7 @@ public PField(Location location, AExpression prefix, boolean nullSafe, String va void analyze(ScriptRoot scriptRoot, Scope scope) { prefix.analyze(scriptRoot, scope); prefix.expected = prefix.actual; - prefix = prefix.cast(scriptRoot, scope); + prefix.cast(); if (prefix.actual.isArray()) { sub = new PSubArrayLength(location, PainlessLookupUtility.typeToCanonicalTypeName(prefix.actual), value); @@ -120,7 +120,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { DotNode write(ClassNode classNode) { DotNode dotNode = new DotNode(); - dotNode.setLeftNode(prefix.write(classNode)); + dotNode.setLeftNode(prefix.cast(prefix.write(classNode))); dotNode.setRightNode(sub.write(classNode)); dotNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubBrace.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubBrace.java index 8e763cfb83856..2ea986ac39625 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubBrace.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubBrace.java @@ -46,7 +46,7 @@ final class PSubBrace extends AStoreable { void analyze(ScriptRoot scriptRoot, Scope scope) { index.expected = int.class; index.analyze(scriptRoot, scope); - index = index.cast(scriptRoot, scope); + index.cast(); actual = clazz.getComponentType(); } @@ -54,7 +54,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { BraceSubNode write(ClassNode classNode) { BraceSubNode braceSubNode = new BraceSubNode(); - braceSubNode.setChildNode(index.write(classNode)); + braceSubNode.setChildNode(index.cast(index.write(classNode))); braceSubNode.setLocation(location); braceSubNode.setExpressionType(actual); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubCallInvoke.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubCallInvoke.java index 49fd1633fb5ee..487621b60046a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubCallInvoke.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubCallInvoke.java @@ -54,7 +54,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { expression.expected = method.typeParameters.get(argument); expression.internal = true; expression.analyze(scriptRoot, scope); - arguments.set(argument, expression.cast(scriptRoot, scope)); + expression.cast(); } statement = true; @@ -66,7 +66,7 @@ CallSubNode write(ClassNode classNode) { CallSubNode callSubNode = new CallSubNode(); for (AExpression argument : arguments) { - callSubNode.addArgumentNode(argument.write(classNode)); + callSubNode.addArgumentNode(argument.cast(argument.write(classNode))); } callSubNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefArray.java index 8665a561a5131..a39a16e26be62 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefArray.java @@ -45,7 +45,7 @@ final class PSubDefArray extends AStoreable { void analyze(ScriptRoot scriptRoot, Scope scope) { index.analyze(scriptRoot, scope); index.expected = index.actual; - index = index.cast(scriptRoot, scope); + index.cast(); // TODO: remove ZonedDateTime exception when JodaCompatibleDateTime is removed actual = expected == null || expected == ZonedDateTime.class || explicit ? def.class : expected; @@ -55,7 +55,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { BraceSubDefNode write(ClassNode classNode) { BraceSubDefNode braceSubDefNode = new BraceSubDefNode(); - braceSubDefNode.setChildNode(index.write(classNode)); + braceSubDefNode.setChildNode(index.cast(index.write(classNode))); braceSubDefNode.setLocation(location); braceSubDefNode.setExpressionType(actual); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefCall.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefCall.java index 2b51cfb892e21..5cface91e59b9 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefCall.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefCall.java @@ -66,7 +66,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { } expression.expected = expression.actual; - arguments.set(argument, expression.cast(scriptRoot, scope)); + expression.cast(); parameterTypes.add(expression.actual); if (expression instanceof ILambda) { @@ -89,7 +89,7 @@ CallSubDefNode write(ClassNode classNode) { CallSubDefNode callSubDefNode = new CallSubDefNode(); for (AExpression argument : arguments) { - callSubDefNode.addArgumentNode(argument.write(classNode)); + callSubDefNode.addArgumentNode(argument.cast(argument.write(classNode))); } callSubDefNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubListShortcut.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubListShortcut.java index 565604bb0fdec..d7ef83e800e02 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubListShortcut.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubListShortcut.java @@ -71,7 +71,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { if ((read || write) && (!read || getter != null) && (!write || setter != null)) { index.expected = int.class; index.analyze(scriptRoot, scope); - index = index.cast(scriptRoot, scope); + index.cast(); actual = setter != null ? setter.typeParameters.get(1) : getter.returnType; } else { @@ -83,7 +83,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { ListSubShortcutNode write(ClassNode classNode) { ListSubShortcutNode listSubShortcutNode = new ListSubShortcutNode(); - listSubShortcutNode.setChildNode(index.write(classNode)); + listSubShortcutNode.setChildNode(index.cast(index.write(classNode))); listSubShortcutNode.setLocation(location); listSubShortcutNode.setExpressionType(actual); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubMapShortcut.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubMapShortcut.java index ccc171964590d..a1468746fc038 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubMapShortcut.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubMapShortcut.java @@ -70,7 +70,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { if ((read || write) && (!read || getter != null) && (!write || setter != null)) { index.expected = setter != null ? setter.typeParameters.get(0) : getter.typeParameters.get(0); index.analyze(scriptRoot, scope); - index = index.cast(scriptRoot, scope); + index.cast(); actual = setter != null ? setter.typeParameters.get(1) : getter.returnType; } else { @@ -82,7 +82,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { MapSubShortcutNode write(ClassNode classNode) { MapSubShortcutNode mapSubShortcutNode = new MapSubShortcutNode(); - mapSubShortcutNode.setChildNode(index.write(classNode)); + mapSubShortcutNode.setChildNode(index.cast(index.write(classNode))); mapSubShortcutNode.setLocation(location); mapSubShortcutNode.setExpressionType(actual); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java index d1dfce2150a9c..e379881bba154 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java @@ -54,7 +54,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { if (expression != null) { expression.expected = resolvedType.getType(); expression.analyze(scriptRoot, scope); - expression = expression.cast(scriptRoot, scope); + expression.cast(); } scope.defineVariable(location, resolvedType.getType(), name, false); @@ -64,7 +64,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { DeclarationNode write(ClassNode classNode) { DeclarationNode declarationNode = new DeclarationNode(); - declarationNode.setExpressionNode(expression == null ? null : expression.write(classNode)); + declarationNode.setExpressionNode(expression == null ? null : expression.cast(expression.write(classNode))); declarationNode.setLocation(location); declarationNode.setDeclarationType(((DResolvedType)type).getType()); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java index 41afc52f878b3..d95b51d8d1a0a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java @@ -62,7 +62,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { condition.expected = boolean.class; condition.analyze(scriptRoot, scope); - condition = condition.cast(scriptRoot, scope); + condition.cast(); if (condition instanceof EBoolean) { continuous = ((EBoolean)condition).constant; @@ -84,7 +84,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { DoWhileLoopNode write(ClassNode classNode) { DoWhileLoopNode doWhileLoopNode = new DoWhileLoopNode(); - doWhileLoopNode.setConditionNode(condition.write(classNode)); + doWhileLoopNode.setConditionNode(condition.cast(condition.write(classNode))); doWhileLoopNode.setBlockNode(block.write(classNode)); doWhileLoopNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java index 3f29d4ab495d4..a64f6451e4dd2 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java @@ -56,7 +56,7 @@ public SEach(Location location, String type, String name, AExpression expression void analyze(ScriptRoot scriptRoot, Scope scope) { expression.analyze(scriptRoot, scope); expression.expected = expression.actual; - expression = expression.cast(scriptRoot, scope); + expression.cast(); Class clazz = scriptRoot.getPainlessLookup().canonicalTypeNameToType(this.type); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java index 361ba65d13ba9..2271b63ee2897 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java @@ -22,6 +22,7 @@ import org.elasticsearch.painless.Location; import org.elasticsearch.painless.Scope; import org.elasticsearch.painless.ir.ClassNode; +import org.elasticsearch.painless.ir.ExpressionNode; import org.elasticsearch.painless.ir.ReturnNode; import org.elasticsearch.painless.ir.StatementExpressionNode; import org.elasticsearch.painless.ir.StatementNode; @@ -58,7 +59,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { expression.expected = rtn ? rtnType : expression.actual; expression.internal = rtn; - expression = expression.cast(scriptRoot, scope); + expression.cast(); methodEscape = rtn; loopEscape = rtn; @@ -68,10 +69,12 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { @Override StatementNode write(ClassNode classNode) { + ExpressionNode expressionNode = expression.cast(expression.write(classNode)); + if (methodEscape) { ReturnNode returnNode = new ReturnNode(); - returnNode.setExpressionNode(expression.write(classNode)); + returnNode.setExpressionNode(expressionNode); returnNode.setLocation(location); @@ -79,7 +82,7 @@ StatementNode write(ClassNode classNode) { } else { StatementExpressionNode statementExpressionNode = new StatementExpressionNode(); - statementExpressionNode.setExpressionNode(expression.write(classNode)); + statementExpressionNode.setExpressionNode(expressionNode); statementExpressionNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java index 970ba8d877f48..a3f71376e061c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java @@ -22,6 +22,7 @@ import org.elasticsearch.painless.Location; import org.elasticsearch.painless.Scope; import org.elasticsearch.painless.ir.ClassNode; +import org.elasticsearch.painless.ir.ExpressionNode; import org.elasticsearch.painless.ir.ForLoopNode; import org.elasticsearch.painless.symbol.ScriptRoot; @@ -68,7 +69,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { } initializer.expected = initializer.actual; - this.initializer = initializer.cast(scriptRoot, scope); + initializer.cast(); } else { throw createError(new IllegalStateException("Illegal tree structure.")); } @@ -77,7 +78,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { if (condition != null) { condition.expected = boolean.class; condition.analyze(scriptRoot, scope); - condition = condition.cast(scriptRoot, scope); + condition.cast(); if (condition instanceof EBoolean) { continuous = ((EBoolean)condition).constant; @@ -103,7 +104,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { } afterthought.expected = afterthought.actual; - afterthought = afterthought.cast(scriptRoot, scope); + afterthought.cast(); } if (block != null) { @@ -131,9 +132,11 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { ForLoopNode write(ClassNode classNode) { ForLoopNode forLoopNode = new ForLoopNode(); - forLoopNode.setInitialzerNode(initializer == null ? null : initializer.write(classNode)); - forLoopNode.setConditionNode(condition == null ? null : condition.write(classNode)); - forLoopNode.setAfterthoughtNode(afterthought == null ? null : afterthought.write(classNode)); + forLoopNode.setInitialzerNode(initializer == null ? null : initializer instanceof AExpression ? + ((AExpression)initializer).cast((ExpressionNode)initializer.write(classNode)) : + initializer.write(classNode)); + forLoopNode.setConditionNode(condition == null ? null : condition.cast(condition.write(classNode))); + forLoopNode.setAfterthoughtNode(afterthought == null ? null : afterthought.cast(afterthought.write(classNode))); forLoopNode.setBlockNode(block == null ? null : block.write(classNode)); forLoopNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIf.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIf.java index f00866a6ef422..3b95ec181dc68 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIf.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIf.java @@ -46,7 +46,7 @@ public SIf(Location location, AExpression condition, SBlock ifblock) { void analyze(ScriptRoot scriptRoot, Scope scope) { condition.expected = boolean.class; condition.analyze(scriptRoot, scope); - condition = condition.cast(scriptRoot, scope); + condition.cast(); if (condition instanceof EBoolean) { throw createError(new IllegalArgumentException("Extraneous if statement.")); @@ -71,7 +71,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { IfNode write(ClassNode classNode) { IfNode ifNode = new IfNode(); - ifNode.setConditionNode(condition.write(classNode)); + ifNode.setConditionNode(condition.cast(condition.write(classNode))); ifNode.setBlockNode(ifblock.write(classNode)); ifNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java index 518094a10c1a4..b3726cee6c114 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java @@ -51,7 +51,7 @@ public SIfElse(Location location, AExpression condition, SBlock ifblock, SBlock void analyze(ScriptRoot scriptRoot, Scope scope) { condition.expected = boolean.class; condition.analyze(scriptRoot, scope); - condition = condition.cast(scriptRoot, scope); + condition.cast(); if (condition instanceof EBoolean) { throw createError(new IllegalArgumentException("Extraneous if statement.")); @@ -93,7 +93,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { IfElseNode write(ClassNode classNode) { IfElseNode ifElseNode = new IfElseNode(); - ifElseNode.setConditionNode(condition.write(classNode)); + ifElseNode.setConditionNode(condition.cast(condition.write(classNode))); ifElseNode.setBlockNode(ifblock.write(classNode)); ifElseNode.setElseBlockNode(elseblock.write(classNode)); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java index fa0f2ec5e0adb..e1d181d78025b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java @@ -51,7 +51,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { expression.expected = scope.getReturnType(); expression.internal = true; expression.analyze(scriptRoot, scope); - expression = expression.cast(scriptRoot, scope); + expression.cast(); } methodEscape = true; @@ -65,7 +65,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { ReturnNode write(ClassNode classNode) { ReturnNode returnNode = new ReturnNode(); - returnNode.setExpressionNode(expression == null ? null : expression.write(classNode)); + returnNode.setExpressionNode(expression == null ? null : expression.cast(expression.write(classNode))); returnNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java index ce21d9352fd87..e3132f024f52b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java @@ -44,7 +44,7 @@ public SThrow(Location location, AExpression expression) { void analyze(ScriptRoot scriptRoot, Scope scope) { expression.expected = Exception.class; expression.analyze(scriptRoot, scope); - expression = expression.cast(scriptRoot, scope); + expression.cast(); methodEscape = true; loopEscape = true; @@ -56,7 +56,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { ThrowNode write(ClassNode classNode) { ThrowNode throwNode = new ThrowNode(); - throwNode.setExpressionNode(expression.write(classNode)); + throwNode.setExpressionNode(expression.cast(expression.write(classNode))); throwNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java index 47909b6ded674..8213e5e1bc559 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java @@ -50,7 +50,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { condition.expected = boolean.class; condition.analyze(scriptRoot, scope); - condition = condition.cast(scriptRoot, scope); + condition.cast(); if (condition instanceof EBoolean) { continuous = ((EBoolean)condition).constant; @@ -89,7 +89,7 @@ void analyze(ScriptRoot scriptRoot, Scope scope) { WhileNode write(ClassNode classNode) { WhileNode whileNode = new WhileNode(); - whileNode.setConditionNode(condition.write(classNode)); + whileNode.setConditionNode(condition.cast(condition.write(classNode))); whileNode.setBlockNode(block == null ? null : block.write(classNode)); whileNode.setLocation(location); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/package-info.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/package-info.java index 266968b39cd1d..cfab19ac5e461 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/package-info.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/package-info.java @@ -40,7 +40,6 @@ * {@link org.elasticsearch.painless.node.EBoolean} - Represents a boolean constant. * {@link org.elasticsearch.painless.node.ECallLocal} - Represents a user-defined call. * {@link org.elasticsearch.painless.node.ECapturingFunctionRef} - Represents a function reference (capturing). - * {@link org.elasticsearch.painless.node.ECast} - Represents a cast inserted into the tree replacing others. (Internal only.) * {@link org.elasticsearch.painless.node.EComp} - Represents a comparison expression. * {@link org.elasticsearch.painless.node.EConditional} - Represents a conditional expression. * {@link org.elasticsearch.painless.node.EConstant} - Represents a constant inserted into the tree replacing others. (Internal only.) diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/node/NodeToStringTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/node/NodeToStringTests.java index 849764a556d1c..bdc683125eb68 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/node/NodeToStringTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/node/NodeToStringTests.java @@ -28,7 +28,6 @@ import org.elasticsearch.painless.ScriptClassInfo; import org.elasticsearch.painless.action.PainlessExecuteAction; import org.elasticsearch.painless.antlr.Walker; -import org.elasticsearch.painless.lookup.PainlessCast; import org.elasticsearch.painless.lookup.PainlessClass; import org.elasticsearch.painless.lookup.PainlessField; import org.elasticsearch.painless.lookup.PainlessLookup; @@ -164,19 +163,6 @@ public void testECapturingFunctionRef() { + "return Optional.empty().orElseGet(x::toString)"); } - public void testECast() { - Location l = new Location(getTestName(), 0); - AExpression child = new EConstant(l, "test"); - PainlessCast cast = PainlessCast.originalTypetoTargetType(String.class, Integer.class, true); - assertEquals("(ECast java.lang.Integer (EConstant String 'test'))", new ECast(l, child, cast).toString()); - - l = new Location(getTestName(), 1); - child = new EBinary(l, Operation.ADD, new EConstant(l, "test"), new EConstant(l, 12)); - cast = PainlessCast.originalTypetoTargetType(Integer.class, Boolean.class, true); - assertEquals("(ECast java.lang.Boolean (EBinary (EConstant String 'test') + (EConstant Integer 12)))", - new ECast(l, child, cast).toString()); - } - public void testEComp() { assertToString( "(SClass (SReturn (EComp (PField (EVariable params) a) < (ENumeric 10))))", "return params.a < 10"); assertToString( "(SClass (SReturn (EComp (PField (EVariable params) a) <= (ENumeric 10))))", "return params.a <= 10");