Add nodes to handle types (#49785)
This PR adds 3 nodes to handle types defined by a front-end creating a Painless AST. These types are decided with data immutability in mind - hence the reason for more than a single node.
This commit is contained in:
parent
abd6fa149c
commit
cd3744c0b7
|
@ -109,6 +109,7 @@ import org.elasticsearch.painless.lookup.PainlessLookup;
|
|||
import org.elasticsearch.painless.node.AExpression;
|
||||
import org.elasticsearch.painless.node.ANode;
|
||||
import org.elasticsearch.painless.node.AStatement;
|
||||
import org.elasticsearch.painless.node.DUnresolvedType;
|
||||
import org.elasticsearch.painless.node.EAssignment;
|
||||
import org.elasticsearch.painless.node.EBinary;
|
||||
import org.elasticsearch.painless.node.EBool;
|
||||
|
@ -478,8 +479,9 @@ public final class Walker extends PainlessParserBaseVisitor<ANode> {
|
|||
for (DeclvarContext declvar : ctx.declvar()) {
|
||||
String name = declvar.ID().getText();
|
||||
AExpression expression = declvar.expression() == null ? null : (AExpression)visit(declvar.expression());
|
||||
DUnresolvedType unresolvedType = new DUnresolvedType(location(declvar), type);
|
||||
|
||||
declarations.add(new SDeclaration(location(declvar), type, name, expression));
|
||||
declarations.add(new SDeclaration(location(declvar), unresolvedType, name, expression));
|
||||
}
|
||||
|
||||
return new SDeclBlock(location(ctx), declarations);
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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.lookup.PainlessLookup;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents a Painless type as a {@link Class}. This may still
|
||||
* require resolution to ensure the type in the {@link PainlessLookup}.
|
||||
*/
|
||||
public class DResolvedType extends DType {
|
||||
|
||||
protected final Class<?> type;
|
||||
|
||||
/**
|
||||
* If set to {@code true} ensures the type is in the {@link PainlessLookup}.
|
||||
* If set to {@code false} assumes the type is valid.
|
||||
*/
|
||||
protected final boolean checkInLookup;
|
||||
|
||||
public DResolvedType(Location location, Class<?> type) {
|
||||
this(location, type, true);
|
||||
}
|
||||
|
||||
public DResolvedType(Location location, Class<?> type, boolean checkInLookup) {
|
||||
super(location);
|
||||
this.type = Objects.requireNonNull(type);
|
||||
this.checkInLookup = checkInLookup;
|
||||
}
|
||||
|
||||
/**
|
||||
* If {@link #checkInLookup} is {@code true} checks if the type is in the
|
||||
* {@link PainlessLookup}, otherwise returns {@code this}.
|
||||
* @throws IllegalArgumentException if both checking the type is in the {@link PainlessLookup}
|
||||
* and the type cannot be resolved from the {@link PainlessLookup}
|
||||
* @return a {@link DResolvedType} where the resolved Painless type is retrievable
|
||||
*/
|
||||
@Override
|
||||
public DResolvedType resolveType(PainlessLookup painlessLookup) {
|
||||
if (checkInLookup == false) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (painlessLookup.getClasses().contains(type) == false) {
|
||||
throw location.createError(new IllegalArgumentException(
|
||||
"cannot resolve type [" + PainlessLookupUtility.typeToCanonicalTypeName(type) + "]"));
|
||||
}
|
||||
|
||||
return new DResolvedType(location, type, false);
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return " (DResolvedType [" + PainlessLookupUtility.typeToCanonicalTypeName(type) + "])";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.lookup.PainlessLookup;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents an abstract Painless type. {@link DType} nodes must be
|
||||
* resolved using {@link #resolveType(PainlessLookup)} to retrieve the
|
||||
* actual Painless type. {@link DType} exists as a base class so consumers
|
||||
* may have either a {@link DUnresolvedType} representing a Painless
|
||||
* canonical type name or a {@link DResolvedType} representing a Painless
|
||||
* type as the Painless AST is constructed. This allows Painless types already
|
||||
* resolved at the time of Painless AST construction to not be forced to
|
||||
* convert back to a Painless canonical type name and then re-resolved.
|
||||
*/
|
||||
public abstract class DType {
|
||||
|
||||
protected final Location location;
|
||||
|
||||
public DType(Location location) {
|
||||
this.location = Objects.requireNonNull(location);
|
||||
}
|
||||
|
||||
public abstract DResolvedType resolveType(PainlessLookup painlessLookup);
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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.lookup.PainlessLookup;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents a canonical Painless type name as a {@link String}
|
||||
* that requires resolution.
|
||||
*/
|
||||
public class DUnresolvedType extends DType {
|
||||
|
||||
protected final String typeName;
|
||||
|
||||
public DUnresolvedType(Location location, String typeName) {
|
||||
super(location);
|
||||
this.typeName = Objects.requireNonNull(typeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the canonical Painless type name to a Painless type.
|
||||
* @throws IllegalArgumentException if the type cannot be resolved from the {@link PainlessLookup}
|
||||
* @return a {@link DResolvedType} where the resolved Painless type is retrievable
|
||||
*/
|
||||
@Override
|
||||
public DResolvedType resolveType(PainlessLookup painlessLookup) {
|
||||
Class<?> type = painlessLookup.canonicalTypeNameToType(typeName);
|
||||
|
||||
if (type == null) {
|
||||
throw location.createError(new IllegalArgumentException("cannot resolve type [" + typeName + "]"));
|
||||
}
|
||||
|
||||
return new DResolvedType(location, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(DUnresolvedType [" + typeName + "])";
|
||||
}
|
||||
}
|
||||
|
|
@ -36,13 +36,13 @@ import java.util.Set;
|
|||
*/
|
||||
public final class SDeclaration extends AStatement {
|
||||
|
||||
private final String type;
|
||||
private final DType type;
|
||||
private final String name;
|
||||
private AExpression expression;
|
||||
|
||||
private Variable variable = null;
|
||||
|
||||
public SDeclaration(Location location, String type, String name, AExpression expression) {
|
||||
public SDeclaration(Location location, DType type, String name, AExpression expression) {
|
||||
super(location);
|
||||
|
||||
this.type = Objects.requireNonNull(type);
|
||||
|
@ -61,19 +61,15 @@ public final class SDeclaration extends AStatement {
|
|||
|
||||
@Override
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
Class<?> clazz = scriptRoot.getPainlessLookup().canonicalTypeNameToType(this.type);
|
||||
|
||||
if (clazz == null) {
|
||||
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
|
||||
}
|
||||
DResolvedType resolvedType = type.resolveType(scriptRoot.getPainlessLookup());
|
||||
|
||||
if (expression != null) {
|
||||
expression.expected = clazz;
|
||||
expression.expected = resolvedType.getType();
|
||||
expression.analyze(scriptRoot, locals);
|
||||
expression = expression.cast(scriptRoot, locals);
|
||||
}
|
||||
|
||||
variable = locals.addVariable(location, clazz, name, false);
|
||||
variable = locals.addVariable(location, resolvedType.getType(), name, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -54,7 +54,7 @@ public class NodeToStringTests extends ESTestCase {
|
|||
public void testEAssignment() {
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration def i))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [def]) i))\n"
|
||||
+ " (SExpression (EAssignment (EVariable i) = (ENumeric 2)))\n"
|
||||
+ " (SReturn (EVariable i)))",
|
||||
"def i;\n"
|
||||
|
@ -63,7 +63,7 @@ public class NodeToStringTests extends ESTestCase {
|
|||
for (String operator : new String[] {"+", "-", "*", "/", "%", "&", "^", "|", "<<", ">>", ">>>"}) {
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration def i (ENumeric 1)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [def]) i (ENumeric 1)))\n"
|
||||
+ " (SExpression (EAssignment (EVariable i) " + operator + "= (ENumeric 2)))\n"
|
||||
+ " (SReturn (EVariable i)))",
|
||||
"def i = 1;\n"
|
||||
|
@ -73,31 +73,31 @@ public class NodeToStringTests extends ESTestCase {
|
|||
// Compound
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration def i))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [def]) i))\n"
|
||||
+ " (SReturn (EAssignment (EVariable i) = (ENumeric 2))))",
|
||||
"def i;\n"
|
||||
+ "return i = 2");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration def i))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [def]) i))\n"
|
||||
+ " (SReturn (EAssignment (EVariable i) ++ post)))",
|
||||
"def i;\n"
|
||||
+ "return i++");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration def i))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [def]) i))\n"
|
||||
+ " (SReturn (EAssignment (EVariable i) ++ pre)))",
|
||||
"def i;\n"
|
||||
+ "return ++i");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration def i))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [def]) i))\n"
|
||||
+ " (SReturn (EAssignment (EVariable i) -- post)))",
|
||||
"def i;\n"
|
||||
+ "return i--");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration def i))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [def]) i))\n"
|
||||
+ " (SReturn (EAssignment (EVariable i) -- pre)))",
|
||||
"def i;\n"
|
||||
+ "return --i");
|
||||
|
@ -153,7 +153,8 @@ public class NodeToStringTests extends ESTestCase {
|
|||
public void testECapturingFunctionRef() {
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration Integer x (PCallInvoke (EStatic Integer) valueOf (Args (ENumeric 5)))))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [Integer]) x "
|
||||
+ "(PCallInvoke (EStatic Integer) valueOf (Args (ENumeric 5)))))\n"
|
||||
+ " (SReturn (PCallInvoke (PCallInvoke (EStatic Optional) empty) orElseGet (Args (ECapturingFunctionRef x toString)))))",
|
||||
"Integer x = Integer.valueOf(5);\n"
|
||||
+ "return Optional.empty().orElseGet(x::toString)");
|
||||
|
@ -349,7 +350,7 @@ public class NodeToStringTests extends ESTestCase {
|
|||
assertToString("(SClass (SReturn (EVariable params)))", "return params");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration def a (ENumeric 1)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [def]) a (ENumeric 1)))\n"
|
||||
+ " (SReturn (EVariable a)))",
|
||||
"def a = 1;\n"
|
||||
+ "return a");
|
||||
|
@ -373,13 +374,13 @@ public class NodeToStringTests extends ESTestCase {
|
|||
assertToString("(SClass (SReturn (PField nullSafe (EVariable params) a)))", "return params?.a");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration int[] a (ENewArray int[] dims (Args (ENumeric 10)))))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int[]]) a (ENewArray int[] dims (Args (ENumeric 10)))))\n"
|
||||
+ " (SReturn (PField (EVariable a) length)))",
|
||||
"int[] a = new int[10];\n"
|
||||
+ "return a.length");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration org.elasticsearch.painless.FeatureTestObject a"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [org.elasticsearch.painless.FeatureTestObject]) a"
|
||||
+ " (ENewObj org.elasticsearch.painless.FeatureTestObject)))\n"
|
||||
+ " (SExpression (EAssignment (PField (EVariable a) x) = (ENumeric 10)))\n"
|
||||
+ " (SReturn (PField (EVariable a) x)))",
|
||||
|
@ -511,13 +512,13 @@ public class NodeToStringTests extends ESTestCase {
|
|||
public void testSBreak() {
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration int itr (ENumeric 2)))\n"
|
||||
+ " (SDeclBlock (SDeclaration int a (ENumeric 1)))\n"
|
||||
+ " (SDeclBlock (SDeclaration int b (ENumeric 1)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) itr (ENumeric 2)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) a (ENumeric 1)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) b (ENumeric 1)))\n"
|
||||
+ " (SDo (EComp (EVariable b) < (ENumeric 1000)) (SBlock\n"
|
||||
+ " (SExpression (EAssignment (EVariable itr) ++ post))\n"
|
||||
+ " (SIf (EComp (EVariable itr) > (ENumeric 10000)) (SBlock (SBreak)))\n"
|
||||
+ " (SDeclBlock (SDeclaration int tmp (EVariable a)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) tmp (EVariable a)))\n"
|
||||
+ " (SExpression (EAssignment (EVariable a) = (EVariable b)))\n"
|
||||
+ " (SExpression (EAssignment (EVariable b) = (EBinary (EVariable tmp) + (EVariable b))))))\n"
|
||||
+ " (SReturn (EVariable b)))",
|
||||
|
@ -539,13 +540,13 @@ public class NodeToStringTests extends ESTestCase {
|
|||
public void testSContinue() {
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration int itr (ENumeric 2)))\n"
|
||||
+ " (SDeclBlock (SDeclaration int a (ENumeric 1)))\n"
|
||||
+ " (SDeclBlock (SDeclaration int b (ENumeric 1)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) itr (ENumeric 2)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) a (ENumeric 1)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) b (ENumeric 1)))\n"
|
||||
+ " (SDo (EComp (EVariable b) < (ENumeric 1000)) (SBlock\n"
|
||||
+ " (SExpression (EAssignment (EVariable itr) ++ post))\n"
|
||||
+ " (SIf (EComp (EVariable itr) < (ENumeric 10000)) (SBlock (SContinue)))\n"
|
||||
+ " (SDeclBlock (SDeclaration int tmp (EVariable a)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) tmp (EVariable a)))\n"
|
||||
+ " (SExpression (EAssignment (EVariable a) = (EVariable b)))\n"
|
||||
+ " (SExpression (EAssignment (EVariable b) = (EBinary (EVariable tmp) + (EVariable b))))))\n"
|
||||
+ " (SReturn (EVariable b)))",
|
||||
|
@ -567,7 +568,7 @@ public class NodeToStringTests extends ESTestCase {
|
|||
public void testSDeclBlock() {
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration def a))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [def]) a))\n"
|
||||
+ " (SExpression (EAssignment (EVariable a) = (ENumeric 10)))\n"
|
||||
+ " (SReturn (EVariable a)))",
|
||||
"def a;\n"
|
||||
|
@ -575,34 +576,34 @@ public class NodeToStringTests extends ESTestCase {
|
|||
+ "return a");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration def a (ENumeric 10)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [def]) a (ENumeric 10)))\n"
|
||||
+ " (SReturn (EVariable a)))",
|
||||
"def a = 10;\n"
|
||||
+ "return a");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock\n"
|
||||
+ " (SDeclaration def a)\n"
|
||||
+ " (SDeclaration def b)\n"
|
||||
+ " (SDeclaration def c))\n"
|
||||
+ " (SDeclaration (DUnresolvedType [def]) a)\n"
|
||||
+ " (SDeclaration (DUnresolvedType [def]) b)\n"
|
||||
+ " (SDeclaration (DUnresolvedType [def]) c))\n"
|
||||
+ " (SReturn (EVariable a)))",
|
||||
"def a, b, c;\n"
|
||||
+ "return a");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock\n"
|
||||
+ " (SDeclaration def a (ENumeric 10))\n"
|
||||
+ " (SDeclaration def b (ENumeric 20))\n"
|
||||
+ " (SDeclaration def c (ENumeric 100)))\n"
|
||||
+ " (SDeclaration (DUnresolvedType [def]) a (ENumeric 10))\n"
|
||||
+ " (SDeclaration (DUnresolvedType [def]) b (ENumeric 20))\n"
|
||||
+ " (SDeclaration (DUnresolvedType [def]) c (ENumeric 100)))\n"
|
||||
+ " (SReturn (EVariable a)))",
|
||||
"def a = 10, b = 20, c = 100;\n"
|
||||
+ "return a");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock\n"
|
||||
+ " (SDeclaration def a (ENumeric 10))\n"
|
||||
+ " (SDeclaration def b)\n"
|
||||
+ " (SDeclaration def c (ENumeric 100)))\n"
|
||||
+ " (SDeclaration (DUnresolvedType [def]) a (ENumeric 10))\n"
|
||||
+ " (SDeclaration (DUnresolvedType [def]) b)\n"
|
||||
+ " (SDeclaration (DUnresolvedType [def]) c (ENumeric 100)))\n"
|
||||
+ " (SReturn (EVariable a)))",
|
||||
"def a = 10, b, c = 100;\n"
|
||||
+ "return a");
|
||||
|
@ -610,9 +611,9 @@ public class NodeToStringTests extends ESTestCase {
|
|||
"(SClass\n"
|
||||
+ " (SIf (PField (EVariable params) a) (SBlock\n"
|
||||
+ " (SDeclBlock\n"
|
||||
+ " (SDeclaration def a (ENumeric 10))\n"
|
||||
+ " (SDeclaration def b)\n"
|
||||
+ " (SDeclaration def c (ENumeric 100)))\n"
|
||||
+ " (SDeclaration (DUnresolvedType [def]) a (ENumeric 10))\n"
|
||||
+ " (SDeclaration (DUnresolvedType [def]) b)\n"
|
||||
+ " (SDeclaration (DUnresolvedType [def]) c (ENumeric 100)))\n"
|
||||
+ " (SReturn (EVariable a))))\n"
|
||||
+ " (SReturn (EBoolean false)))",
|
||||
"if (params.a) {"
|
||||
|
@ -625,12 +626,12 @@ public class NodeToStringTests extends ESTestCase {
|
|||
public void testSDo() {
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration int itr (ENumeric 2)))\n"
|
||||
+ " (SDeclBlock (SDeclaration int a (ENumeric 1)))\n"
|
||||
+ " (SDeclBlock (SDeclaration int b (ENumeric 1)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) itr (ENumeric 2)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) a (ENumeric 1)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) b (ENumeric 1)))\n"
|
||||
+ " (SDo (EComp (EVariable b) < (ENumeric 1000)) (SBlock\n"
|
||||
+ " (SExpression (EAssignment (EVariable itr) ++ post))\n"
|
||||
+ " (SDeclBlock (SDeclaration int tmp (EVariable a)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) tmp (EVariable a)))\n"
|
||||
+ " (SExpression (EAssignment (EVariable a) = (EVariable b)))\n"
|
||||
+ " (SExpression (EAssignment (EVariable b) = (EBinary (EVariable tmp) + (EVariable b))))))\n"
|
||||
+ " (SReturn (EVariable b)))",
|
||||
|
@ -649,7 +650,7 @@ public class NodeToStringTests extends ESTestCase {
|
|||
public void testSEach() {
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration int l (ENumeric 0)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) l (ENumeric 0)))\n"
|
||||
+ " (SEach String s (EListInit (EString 'cat') (EString 'dog') (EString 'chicken')) (SBlock "
|
||||
+ "(SExpression (EAssignment (EVariable l) += (PCallInvoke (EVariable s) length)))))\n"
|
||||
+ " (SReturn (EVariable l)))",
|
||||
|
@ -660,9 +661,9 @@ public class NodeToStringTests extends ESTestCase {
|
|||
+ "return l");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration int l (ENumeric 0)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) l (ENumeric 0)))\n"
|
||||
+ " (SEach String s (EListInit (EString 'cat') (EString 'dog') (EString 'chicken')) (SBlock\n"
|
||||
+ " (SDeclBlock (SDeclaration String s2 (EBinary (EString 'dire ') + (EVariable s))))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [String]) s2 (EBinary (EString 'dire ') + (EVariable s))))\n"
|
||||
+ " (SExpression (EAssignment (EVariable l) += (PCallInvoke (EVariable s2) length)))))\n"
|
||||
+ " (SReturn (EVariable l)))",
|
||||
"int l = 0;\n"
|
||||
|
@ -676,9 +677,9 @@ public class NodeToStringTests extends ESTestCase {
|
|||
public void testSFor() {
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration int sum (ENumeric 0)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) sum (ENumeric 0)))\n"
|
||||
+ " (SFor\n"
|
||||
+ " (SDeclBlock (SDeclaration int i (ENumeric 0)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) i (ENumeric 0)))\n"
|
||||
+ " (EComp (EVariable i) < (ENumeric 1000))\n"
|
||||
+ " (EAssignment (EVariable i) ++ post)\n"
|
||||
+ " (SBlock (SExpression (EAssignment (EVariable sum) += (EVariable i)))))\n"
|
||||
|
@ -690,13 +691,13 @@ public class NodeToStringTests extends ESTestCase {
|
|||
+ "return sum");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration int sum (ENumeric 0)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) sum (ENumeric 0)))\n"
|
||||
+ " (SFor\n"
|
||||
+ " (SDeclBlock (SDeclaration int i (ENumeric 0)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) i (ENumeric 0)))\n"
|
||||
+ " (EComp (EVariable i) < (ENumeric 1000))\n"
|
||||
+ " (EAssignment (EVariable i) ++ post)\n"
|
||||
+ " (SBlock (SFor\n"
|
||||
+ " (SDeclBlock (SDeclaration int j (ENumeric 0)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) j (ENumeric 0)))\n"
|
||||
+ " (EComp (EVariable j) < (ENumeric 1000))\n"
|
||||
+ " (EAssignment (EVariable j) ++ post)\n"
|
||||
+ " (SBlock (SExpression (EAssignment (EVariable sum) += (EBinary (EVariable i) * (EVariable j))))))))\n"
|
||||
|
@ -740,7 +741,7 @@ public class NodeToStringTests extends ESTestCase {
|
|||
+ "}");
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration int i (ENumeric 0)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) i (ENumeric 0)))\n"
|
||||
+ " (SIfElse (PField (EVariable param) a)\n"
|
||||
+ " (SBlock (SIfElse (PField (EVariable param) b)\n"
|
||||
+ " (SBlock (SReturn (EBoolean true)))\n"
|
||||
|
@ -789,7 +790,7 @@ public class NodeToStringTests extends ESTestCase {
|
|||
public void testSWhile() {
|
||||
assertToString(
|
||||
"(SClass\n"
|
||||
+ " (SDeclBlock (SDeclaration int i (ENumeric 0)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) i (ENumeric 0)))\n"
|
||||
+ " (SWhile (EComp (EVariable i) < (ENumeric 10)) (SBlock (SExpression (EAssignment (EVariable i) ++ post))))\n"
|
||||
+ " (SReturn (EVariable i)))",
|
||||
"int i = 0;\n"
|
||||
|
@ -822,7 +823,7 @@ public class NodeToStringTests extends ESTestCase {
|
|||
"(SClass\n"
|
||||
+ " (SFunction def a (Args (Pair int i) (Pair int j))\n"
|
||||
+ " (SIf (EComp (EVariable i) < (EVariable j)) (SBlock (SReturn (EBoolean true))))\n"
|
||||
+ " (SDeclBlock (SDeclaration int k (EBinary (EVariable i) + (EVariable j))))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) k (EBinary (EVariable i) + (EVariable j))))\n"
|
||||
+ " (SReturn (EVariable k)))\n"
|
||||
+ " (SReturn (EBoolean true)))",
|
||||
"def a(int i, int j) {\n"
|
||||
|
@ -860,7 +861,7 @@ public class NodeToStringTests extends ESTestCase {
|
|||
+ "}");
|
||||
assertToString(
|
||||
"(SClass (STry (SBlock\n"
|
||||
+ " (SDeclBlock (SDeclaration int i (ENumeric 1)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) i (ENumeric 1)))\n"
|
||||
+ " (SReturn (ENumeric 1)))\n"
|
||||
+ " (SCatch Exception e (SBlock (SReturn (ENumeric 2))))))",
|
||||
"try {\n"
|
||||
|
@ -872,7 +873,7 @@ public class NodeToStringTests extends ESTestCase {
|
|||
assertToString(
|
||||
"(SClass (STry (SBlock (SReturn (ENumeric 1)))\n"
|
||||
+ " (SCatch Exception e (SBlock\n"
|
||||
+ " (SDeclBlock (SDeclaration int i (ENumeric 1)))\n"
|
||||
+ " (SDeclBlock (SDeclaration (DUnresolvedType [int]) i (ENumeric 1)))\n"
|
||||
+ " (SReturn (ENumeric 2))))))",
|
||||
"try {\n"
|
||||
+ " return 1\n"
|
||||
|
|
Loading…
Reference in New Issue