Add a ScriptRoot to consolidate global data necessary for multiple passes (#47532)
This PR is to get plumbing in for a ScriptRoot class that will consolidate several pieces of state required by potentially multiple passes including PainlessLookup, CompilerSettings, FunctionTable, the root class node, and a synthetic counter. It's possible more may be added to this as we move forward and slowly make the the nodes have less mutable state.
This commit is contained in:
parent
9b3e5409c1
commit
e3aab1295e
|
@ -20,7 +20,6 @@
|
|||
package org.elasticsearch.painless;
|
||||
|
||||
import org.elasticsearch.painless.ScriptClassInfo.MethodArgument;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookup;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -38,19 +37,6 @@ import static org.elasticsearch.painless.lookup.PainlessLookupUtility.typeToJava
|
|||
* Tracks user defined variables across compilation phases.
|
||||
*/
|
||||
public final class Locals {
|
||||
private int syntheticCounter = 0;
|
||||
|
||||
/**
|
||||
* Returns a unique identifier for generating the name of a synthetic method.
|
||||
*/
|
||||
public String getNextSyntheticName() {
|
||||
Locals locals = this;
|
||||
while (locals.getParent() != null) {
|
||||
locals = locals.getParent();
|
||||
}
|
||||
|
||||
return "lambda$" + locals.syntheticCounter++;
|
||||
}
|
||||
|
||||
/** Reserved word: loop counter */
|
||||
public static final String LOOP = "#loop";
|
||||
|
@ -64,9 +50,7 @@ public final class Locals {
|
|||
|
||||
/** Creates a new local variable scope (e.g. loop) inside the current scope */
|
||||
public static Locals newLocalScope(Locals currentScope) {
|
||||
Locals locals = new Locals(currentScope);
|
||||
|
||||
return locals;
|
||||
return new Locals(currentScope);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,7 +60,7 @@ public final class Locals {
|
|||
*/
|
||||
public static Locals newLambdaScope(Locals programScope, String name, Class<?> returnType, List<Parameter> parameters,
|
||||
int captureCount, int maxLoopCounter) {
|
||||
Locals locals = new Locals(programScope, programScope.painlessLookup, programScope.baseClass, returnType, KEYWORDS);
|
||||
Locals locals = new Locals(programScope, returnType, KEYWORDS);
|
||||
List<Class<?>> typeParameters = parameters.stream().map(parameter -> typeToJavaType(parameter.clazz)).collect(Collectors.toList());
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
Parameter parameter = parameters.get(i);
|
||||
|
@ -96,7 +80,7 @@ public final class Locals {
|
|||
|
||||
/** Creates a new function scope inside the current scope */
|
||||
public static Locals newFunctionScope(Locals programScope, Class<?> returnType, List<Parameter> parameters, int maxLoopCounter) {
|
||||
Locals locals = new Locals(programScope, programScope.painlessLookup, programScope.baseClass, returnType, KEYWORDS);
|
||||
Locals locals = new Locals(programScope, returnType, KEYWORDS);
|
||||
for (Parameter parameter : parameters) {
|
||||
locals.addVariable(parameter.location, parameter.clazz, parameter.name, false);
|
||||
}
|
||||
|
@ -109,8 +93,7 @@ public final class Locals {
|
|||
|
||||
/** Creates a new main method scope */
|
||||
public static Locals newMainMethodScope(ScriptClassInfo scriptClassInfo, Locals programScope, int maxLoopCounter) {
|
||||
Locals locals = new Locals(programScope, programScope.painlessLookup,
|
||||
scriptClassInfo.getBaseClass(), scriptClassInfo.getExecuteMethodReturnType(), KEYWORDS);
|
||||
Locals locals = new Locals(programScope, scriptClassInfo.getExecuteMethodReturnType(), KEYWORDS);
|
||||
// This reference. Internal use only.
|
||||
locals.defineVariable(null, Object.class, THIS, true);
|
||||
|
||||
|
@ -127,8 +110,8 @@ public final class Locals {
|
|||
}
|
||||
|
||||
/** Creates a new program scope as the root of all scopes */
|
||||
public static Locals newProgramScope(ScriptClassInfo scriptClassInfo, PainlessLookup painlessLookup) {
|
||||
return new Locals(null, painlessLookup, scriptClassInfo.getBaseClass(), null, null);
|
||||
public static Locals newProgramScope() {
|
||||
return new Locals(null, null, null);
|
||||
}
|
||||
|
||||
/** Checks if a variable exists or not, in this scope or any parents. */
|
||||
|
@ -180,22 +163,8 @@ public final class Locals {
|
|||
return locals;
|
||||
}
|
||||
|
||||
/** Whitelist against which this script is being compiled. */
|
||||
public PainlessLookup getPainlessLookup() {
|
||||
return painlessLookup;
|
||||
}
|
||||
|
||||
/** Base class for the compiled script. */
|
||||
public Class<?> getBaseClass() {
|
||||
return baseClass;
|
||||
}
|
||||
|
||||
///// private impl
|
||||
|
||||
/** Whitelist against which this script is being compiled. */
|
||||
private final PainlessLookup painlessLookup;
|
||||
/** Base class for the compiled script. */
|
||||
private final Class<?> baseClass;
|
||||
// parent scope
|
||||
private final Locals parent;
|
||||
// return type of this scope
|
||||
|
@ -211,16 +180,14 @@ public final class Locals {
|
|||
* Create a new Locals
|
||||
*/
|
||||
private Locals(Locals parent) {
|
||||
this(parent, parent.painlessLookup, parent.baseClass, parent.returnType, parent.keywords);
|
||||
this(parent, parent.returnType, parent.keywords);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Locals with specified return type
|
||||
*/
|
||||
private Locals(Locals parent, PainlessLookup painlessLookup, Class<?> baseClass, Class<?> returnType, Set<String> keywords) {
|
||||
private Locals(Locals parent, Class<?> returnType, Set<String> keywords) {
|
||||
this.parent = parent;
|
||||
this.painlessLookup = painlessLookup;
|
||||
this.baseClass = baseClass;
|
||||
this.returnType = returnType;
|
||||
this.keywords = keywords;
|
||||
if (parent == null) {
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import org.elasticsearch.painless.lookup.PainlessLookup;
|
||||
import org.elasticsearch.painless.node.SClass;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Stores information for use across the entirety of compilation.
|
||||
*/
|
||||
public class ScriptRoot {
|
||||
|
||||
protected final PainlessLookup painlessLookup;
|
||||
protected final CompilerSettings compilerSettings;
|
||||
protected final ScriptClassInfo scriptClassInfo;
|
||||
|
||||
protected final SClass classNode;
|
||||
|
||||
protected final FunctionTable functionTable = new FunctionTable();
|
||||
protected int syntheticCounter = 0;
|
||||
|
||||
public ScriptRoot(PainlessLookup painlessLookup, CompilerSettings compilerSettings, ScriptClassInfo scriptClassInfo, SClass classRoot) {
|
||||
this.painlessLookup = Objects.requireNonNull(painlessLookup);
|
||||
this.compilerSettings = Objects.requireNonNull(compilerSettings);
|
||||
this.scriptClassInfo = Objects.requireNonNull(scriptClassInfo);
|
||||
this.classNode = Objects.requireNonNull(classRoot);
|
||||
}
|
||||
|
||||
public PainlessLookup getPainlessLookup() {
|
||||
return painlessLookup;
|
||||
}
|
||||
|
||||
public CompilerSettings getCompilerSettings() {
|
||||
return compilerSettings;
|
||||
}
|
||||
|
||||
public ScriptClassInfo getScriptClassInfo() {
|
||||
return scriptClassInfo;
|
||||
}
|
||||
|
||||
public SClass getClassNode() {
|
||||
return classNode;
|
||||
}
|
||||
|
||||
public FunctionTable getFunctionTable() {
|
||||
return functionTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unique identifier for generating the name of a synthetic value.
|
||||
*/
|
||||
public String getNextSyntheticName(String prefix) {
|
||||
return prefix + "$synthetic$" + syntheticCounter++;
|
||||
}
|
||||
}
|
|
@ -24,7 +24,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.lookup.PainlessCast;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
@ -118,7 +118,7 @@ public abstract class AExpression extends ANode {
|
|||
* 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(FunctionTable functions, Locals locals) {
|
||||
AExpression cast(ScriptRoot scriptRoot, Locals locals) {
|
||||
PainlessCast cast = AnalyzerCaster.getLegalCast(location, actual, expected, explicit, internal);
|
||||
|
||||
if (cast == null) {
|
||||
|
@ -136,7 +136,7 @@ public abstract class AExpression extends ANode {
|
|||
// will already be the same.
|
||||
|
||||
EConstant econstant = new EConstant(location, constant);
|
||||
econstant.analyze(functions, locals);
|
||||
econstant.analyze(scriptRoot, locals);
|
||||
|
||||
if (!expected.equals(econstant.actual)) {
|
||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||
|
@ -170,7 +170,7 @@ public abstract class AExpression extends ANode {
|
|||
constant = AnalyzerCaster.constCast(location, constant, cast);
|
||||
|
||||
EConstant econstant = new EConstant(location, constant);
|
||||
econstant.analyze(functions, locals);
|
||||
econstant.analyze(scriptRoot, locals);
|
||||
|
||||
if (!expected.equals(econstant.actual)) {
|
||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||
|
@ -201,7 +201,7 @@ public abstract class AExpression extends ANode {
|
|||
// the EConstant will already be the same.
|
||||
|
||||
EConstant econstant = new EConstant(location, constant);
|
||||
econstant.analyze(functions, locals);
|
||||
econstant.analyze(scriptRoot, locals);
|
||||
|
||||
if (!actual.equals(econstant.actual)) {
|
||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -72,7 +72,7 @@ public abstract class ANode {
|
|||
/**
|
||||
* Checks for errors and collects data for the writing phase.
|
||||
*/
|
||||
abstract void analyze(FunctionTable functions, Locals locals);
|
||||
abstract void analyze(ScriptRoot scriptRoot, Locals locals);
|
||||
|
||||
/**
|
||||
* Writes ASM based on the data collected during the analysis phase.
|
||||
|
|
|
@ -31,7 +31,7 @@ import org.elasticsearch.painless.MethodWriter;
|
|||
import org.elasticsearch.painless.Operation;
|
||||
import org.elasticsearch.painless.lookup.PainlessCast;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -84,26 +84,26 @@ public final class EAssignment extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
analyzeLHS(functions, locals);
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
analyzeLHS(scriptRoot, locals);
|
||||
analyzeIncrDecr();
|
||||
|
||||
if (operation != null) {
|
||||
analyzeCompound(functions, locals);
|
||||
analyzeCompound(scriptRoot, locals);
|
||||
} else if (rhs != null) {
|
||||
analyzeSimple(functions, locals);
|
||||
analyzeSimple(scriptRoot, locals);
|
||||
} else {
|
||||
throw new IllegalStateException("Illegal tree structure.");
|
||||
}
|
||||
}
|
||||
|
||||
private void analyzeLHS(FunctionTable functions, Locals locals) {
|
||||
private void analyzeLHS(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (lhs instanceof AStoreable) {
|
||||
AStoreable lhs = (AStoreable)this.lhs;
|
||||
|
||||
lhs.read = read;
|
||||
lhs.write = true;
|
||||
lhs.analyze(functions, locals);
|
||||
lhs.analyze(scriptRoot, locals);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Left-hand side cannot be assigned a value.");
|
||||
}
|
||||
|
@ -147,9 +147,8 @@ public final class EAssignment extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
private void analyzeCompound(FunctionTable functions, Locals locals) {
|
||||
rhs.analyze(functions, locals);
|
||||
|
||||
private void analyzeCompound(ScriptRoot scriptRoot, Locals locals) {
|
||||
rhs.analyze(scriptRoot, locals);
|
||||
boolean shift = false;
|
||||
|
||||
if (operation == Operation.MUL) {
|
||||
|
@ -211,7 +210,7 @@ public final class EAssignment extends AExpression {
|
|||
rhs.expected = promote;
|
||||
}
|
||||
|
||||
rhs = rhs.cast(functions, locals);
|
||||
rhs = rhs.cast(scriptRoot, locals);
|
||||
|
||||
there = AnalyzerCaster.getLegalCast(location, lhs.actual, promote, false, false);
|
||||
back = AnalyzerCaster.getLegalCast(location, promote, lhs.actual, true, false);
|
||||
|
@ -220,12 +219,12 @@ public final class EAssignment extends AExpression {
|
|||
this.actual = read ? lhs.actual : void.class;
|
||||
}
|
||||
|
||||
private void analyzeSimple(FunctionTable functions, Locals locals) {
|
||||
private void analyzeSimple(ScriptRoot scriptRoot, Locals locals) {
|
||||
AStoreable lhs = (AStoreable)this.lhs;
|
||||
|
||||
// If the lhs node is a def optimized node we update the actual type to remove the need for a cast.
|
||||
if (lhs.isDefOptimized()) {
|
||||
rhs.analyze(functions, locals);
|
||||
rhs.analyze(scriptRoot, locals);
|
||||
|
||||
if (rhs.actual == void.class) {
|
||||
throw createError(new IllegalArgumentException("Right-hand side cannot be a [void] type for assignment."));
|
||||
|
@ -236,10 +235,10 @@ public final class EAssignment extends AExpression {
|
|||
// Otherwise, we must adapt the rhs type to the lhs type with a cast.
|
||||
} else {
|
||||
rhs.expected = lhs.actual;
|
||||
rhs.analyze(functions, locals);
|
||||
rhs.analyze(scriptRoot, locals);
|
||||
}
|
||||
|
||||
rhs = rhs.cast(functions, locals);
|
||||
rhs = rhs.cast(scriptRoot, locals);
|
||||
|
||||
this.statement = true;
|
||||
this.actual = read ? lhs.actual : void.class;
|
||||
|
|
|
@ -31,7 +31,7 @@ import org.elasticsearch.painless.Operation;
|
|||
import org.elasticsearch.painless.WriterConstants;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -73,43 +73,43 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
originallyExplicit = explicit;
|
||||
|
||||
if (operation == Operation.MUL) {
|
||||
analyzeMul(functions, locals);
|
||||
analyzeMul(scriptRoot, locals);
|
||||
} else if (operation == Operation.DIV) {
|
||||
analyzeDiv(functions, locals);
|
||||
analyzeDiv(scriptRoot, locals);
|
||||
} else if (operation == Operation.REM) {
|
||||
analyzeRem(functions, locals);
|
||||
analyzeRem(scriptRoot, locals);
|
||||
} else if (operation == Operation.ADD) {
|
||||
analyzeAdd(functions, locals);
|
||||
analyzeAdd(scriptRoot, locals);
|
||||
} else if (operation == Operation.SUB) {
|
||||
analyzeSub(functions, locals);
|
||||
analyzeSub(scriptRoot, locals);
|
||||
} else if (operation == Operation.FIND) {
|
||||
analyzeRegexOp(functions, locals);
|
||||
analyzeRegexOp(scriptRoot, locals);
|
||||
} else if (operation == Operation.MATCH) {
|
||||
analyzeRegexOp(functions, locals);
|
||||
analyzeRegexOp(scriptRoot, locals);
|
||||
} else if (operation == Operation.LSH) {
|
||||
analyzeLSH(functions, locals);
|
||||
analyzeLSH(scriptRoot, locals);
|
||||
} else if (operation == Operation.RSH) {
|
||||
analyzeRSH(functions, locals);
|
||||
analyzeRSH(scriptRoot, locals);
|
||||
} else if (operation == Operation.USH) {
|
||||
analyzeUSH(functions, locals);
|
||||
analyzeUSH(scriptRoot, locals);
|
||||
} else if (operation == Operation.BWAND) {
|
||||
analyzeBWAnd(functions, locals);
|
||||
analyzeBWAnd(scriptRoot, locals);
|
||||
} else if (operation == Operation.XOR) {
|
||||
analyzeXor(functions, locals);
|
||||
analyzeXor(scriptRoot, locals);
|
||||
} else if (operation == Operation.BWOR) {
|
||||
analyzeBWOr(functions, locals);
|
||||
analyzeBWOr(scriptRoot, locals);
|
||||
} else {
|
||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||
}
|
||||
}
|
||||
|
||||
private void analyzeMul(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeMul(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
|
||||
|
||||
|
@ -132,8 +132,8 @@ public final class EBinary extends AExpression {
|
|||
right.expected = promote;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (promote == int.class) {
|
||||
|
@ -150,9 +150,9 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
private void analyzeDiv(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeDiv(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
|
||||
|
||||
|
@ -176,8 +176,8 @@ public final class EBinary extends AExpression {
|
|||
right.expected = promote;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
try {
|
||||
|
@ -198,9 +198,9 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
private void analyzeRem(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeRem(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
|
||||
|
||||
|
@ -224,8 +224,8 @@ public final class EBinary extends AExpression {
|
|||
right.expected = promote;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
try {
|
||||
|
@ -246,9 +246,9 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
private void analyzeAdd(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeAdd(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promote = AnalyzerCaster.promoteAdd(left.actual, right.actual);
|
||||
|
||||
|
@ -284,8 +284,8 @@ public final class EBinary extends AExpression {
|
|||
right.expected = promote;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (promote == int.class) {
|
||||
|
@ -305,9 +305,9 @@ public final class EBinary extends AExpression {
|
|||
|
||||
}
|
||||
|
||||
private void analyzeSub(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeSub(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
|
||||
|
||||
|
@ -331,8 +331,8 @@ public final class EBinary extends AExpression {
|
|||
right.expected = promote;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (promote == int.class) {
|
||||
|
@ -349,23 +349,23 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
private void analyzeRegexOp(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeRegexOp(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
left.expected = String.class;
|
||||
right.expected = Pattern.class;
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
promote = boolean.class;
|
||||
actual = boolean.class;
|
||||
}
|
||||
|
||||
private void analyzeLSH(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeLSH(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
Class<?> lhspromote = AnalyzerCaster.promoteNumeric(left.actual, false);
|
||||
Class<?> rhspromote = AnalyzerCaster.promoteNumeric(right.actual, false);
|
||||
|
@ -397,8 +397,8 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (promote == int.class) {
|
||||
|
@ -411,9 +411,9 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
private void analyzeRSH(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeRSH(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
Class<?> lhspromote = AnalyzerCaster.promoteNumeric(left.actual, false);
|
||||
Class<?> rhspromote = AnalyzerCaster.promoteNumeric(right.actual, false);
|
||||
|
@ -445,8 +445,8 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (promote == int.class) {
|
||||
|
@ -459,9 +459,9 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
private void analyzeUSH(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeUSH(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
Class<?> lhspromote = AnalyzerCaster.promoteNumeric(left.actual, false);
|
||||
Class<?> rhspromote = AnalyzerCaster.promoteNumeric(right.actual, false);
|
||||
|
@ -493,8 +493,8 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (promote == int.class) {
|
||||
|
@ -507,9 +507,9 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
private void analyzeBWAnd(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeBWAnd(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, false);
|
||||
|
||||
|
@ -533,8 +533,8 @@ public final class EBinary extends AExpression {
|
|||
right.expected = promote;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (promote == int.class) {
|
||||
|
@ -547,9 +547,9 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
private void analyzeXor(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeXor(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promote = AnalyzerCaster.promoteXor(left.actual, right.actual);
|
||||
|
||||
|
@ -572,8 +572,8 @@ public final class EBinary extends AExpression {
|
|||
right.expected = promote;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (promote == boolean.class) {
|
||||
|
@ -588,9 +588,9 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
private void analyzeBWOr(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeBWOr(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, false);
|
||||
|
||||
|
@ -613,8 +613,8 @@ public final class EBinary extends AExpression {
|
|||
right.expected = promote;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (promote == int.class) {
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.Operation;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
|
@ -63,14 +63,14 @@ public final class EBool extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
left.expected = boolean.class;
|
||||
left.analyze(functions, locals);
|
||||
left = left.cast(functions, locals);
|
||||
left.analyze(scriptRoot, locals);
|
||||
left = left.cast(scriptRoot, locals);
|
||||
|
||||
right.expected = boolean.class;
|
||||
right.analyze(functions, locals);
|
||||
right = right.cast(functions, locals);
|
||||
right.analyze(scriptRoot, locals);
|
||||
right = right.cast(scriptRoot, locals);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (operation == Operation.AND) {
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -51,7 +51,7 @@ public final class EBoolean extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (!read) {
|
||||
throw createError(new IllegalArgumentException("Must read from constant [" + constant + "]."));
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.elasticsearch.painless.MethodWriter;
|
|||
import org.elasticsearch.painless.lookup.PainlessClassBinding;
|
||||
import org.elasticsearch.painless.lookup.PainlessInstanceBinding;
|
||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Type;
|
||||
|
@ -76,8 +77,8 @@ public final class ECallLocal extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
localFunction = functions.getFunction(name, arguments.size());
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
localFunction = scriptRoot.getFunctionTable().getFunction(name, arguments.size());
|
||||
|
||||
// user cannot call internal functions, reset to null if an internal function is found
|
||||
if (localFunction != null && localFunction.isInternal()) {
|
||||
|
@ -85,14 +86,14 @@ public final class ECallLocal extends AExpression {
|
|||
}
|
||||
|
||||
if (localFunction == null) {
|
||||
importedMethod = locals.getPainlessLookup().lookupImportedPainlessMethod(name, arguments.size());
|
||||
importedMethod = scriptRoot.getPainlessLookup().lookupImportedPainlessMethod(name, arguments.size());
|
||||
|
||||
if (importedMethod == null) {
|
||||
classBinding = locals.getPainlessLookup().lookupPainlessClassBinding(name, arguments.size());
|
||||
classBinding = scriptRoot.getPainlessLookup().lookupPainlessClassBinding(name, arguments.size());
|
||||
|
||||
// check to see if this class binding requires an implicit this reference
|
||||
if (classBinding != null && classBinding.typeParameters.isEmpty() == false &&
|
||||
classBinding.typeParameters.get(0) == locals.getBaseClass()) {
|
||||
classBinding.typeParameters.get(0) == scriptRoot.getScriptClassInfo().getBaseClass()) {
|
||||
classBinding = null;
|
||||
}
|
||||
|
||||
|
@ -103,11 +104,11 @@ public final class ECallLocal extends AExpression {
|
|||
// will likely involve adding a class instance binding where any instance can have a class binding
|
||||
// as part of its API. However, the situation at run-time is difficult and will modifications that
|
||||
// are a substantial change if even possible to do.
|
||||
classBinding = locals.getPainlessLookup().lookupPainlessClassBinding(name, arguments.size() + 1);
|
||||
classBinding = scriptRoot.getPainlessLookup().lookupPainlessClassBinding(name, arguments.size() + 1);
|
||||
|
||||
if (classBinding != null) {
|
||||
if (classBinding.typeParameters.isEmpty() == false &&
|
||||
classBinding.typeParameters.get(0) == locals.getBaseClass()) {
|
||||
classBinding.typeParameters.get(0) == scriptRoot.getScriptClassInfo().getBaseClass()) {
|
||||
classBindingOffset = 1;
|
||||
} else {
|
||||
classBinding = null;
|
||||
|
@ -115,7 +116,7 @@ public final class ECallLocal extends AExpression {
|
|||
}
|
||||
|
||||
if (classBinding == null) {
|
||||
instanceBinding = locals.getPainlessLookup().lookupPainlessInstanceBinding(name, arguments.size());
|
||||
instanceBinding = scriptRoot.getPainlessLookup().lookupPainlessInstanceBinding(name, arguments.size());
|
||||
|
||||
if (instanceBinding == null) {
|
||||
throw createError(new IllegalArgumentException(
|
||||
|
@ -152,8 +153,8 @@ public final class ECallLocal extends AExpression {
|
|||
|
||||
expression.expected = typeParameters.get(argument + classBindingOffset);
|
||||
expression.internal = true;
|
||||
expression.analyze(functions, locals);
|
||||
arguments.set(argument, expression.cast(functions, locals));
|
||||
expression.analyze(scriptRoot, locals);
|
||||
arguments.set(argument, expression.cast(scriptRoot, locals));
|
||||
}
|
||||
|
||||
statement = true;
|
||||
|
|
|
@ -30,7 +30,7 @@ import org.elasticsearch.painless.Location;
|
|||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
|
@ -66,7 +66,7 @@ public final class ECapturingFunctionRef extends AExpression implements ILambda
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
captured = locals.getVariable(location, variable);
|
||||
if (expected == null) {
|
||||
if (captured.clazz == def.class) {
|
||||
|
@ -81,7 +81,7 @@ public final class ECapturingFunctionRef extends AExpression implements ILambda
|
|||
defPointer = null;
|
||||
// static case
|
||||
if (captured.clazz != def.class) {
|
||||
ref = FunctionRef.create(locals.getPainlessLookup(), functions, location,
|
||||
ref = FunctionRef.create(scriptRoot.getPainlessLookup(), scriptRoot.getFunctionTable(), location,
|
||||
expected, PainlessLookupUtility.typeToCanonicalTypeName(captured.clazz), call, 1);
|
||||
}
|
||||
actual = expected;
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.elasticsearch.painless.Location;
|
|||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessCast;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -58,7 +58,7 @@ final class ECast extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import org.elasticsearch.painless.MethodWriter;
|
|||
import org.elasticsearch.painless.Operation;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
|
@ -72,31 +72,31 @@ public final class EComp extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (operation == Operation.EQ) {
|
||||
analyzeEq(functions, locals);
|
||||
analyzeEq(scriptRoot, locals);
|
||||
} else if (operation == Operation.EQR) {
|
||||
analyzeEqR(functions, locals);
|
||||
analyzeEqR(scriptRoot, locals);
|
||||
} else if (operation == Operation.NE) {
|
||||
analyzeNE(functions, locals);
|
||||
analyzeNE(scriptRoot, locals);
|
||||
} else if (operation == Operation.NER) {
|
||||
analyzeNER(functions, locals);
|
||||
analyzeNER(scriptRoot, locals);
|
||||
} else if (operation == Operation.GTE) {
|
||||
analyzeGTE(functions, locals);
|
||||
analyzeGTE(scriptRoot, locals);
|
||||
} else if (operation == Operation.GT) {
|
||||
analyzeGT(functions, locals);
|
||||
analyzeGT(scriptRoot, locals);
|
||||
} else if (operation == Operation.LTE) {
|
||||
analyzeLTE(functions, locals);
|
||||
analyzeLTE(scriptRoot, locals);
|
||||
} else if (operation == Operation.LT) {
|
||||
analyzeLT(functions, locals);
|
||||
analyzeLT(scriptRoot, locals);
|
||||
} else {
|
||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||
}
|
||||
}
|
||||
|
||||
private void analyzeEq(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeEq(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promotedType = AnalyzerCaster.promoteEquality(left.actual, right.actual);
|
||||
|
||||
|
@ -114,8 +114,8 @@ public final class EComp extends AExpression {
|
|||
right.expected = promotedType;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.isNull && right.isNull) {
|
||||
throw createError(new IllegalArgumentException("Extraneous comparison of null constants."));
|
||||
|
@ -144,9 +144,9 @@ public final class EComp extends AExpression {
|
|||
actual = boolean.class;
|
||||
}
|
||||
|
||||
private void analyzeEqR(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeEqR(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promotedType = AnalyzerCaster.promoteEquality(left.actual, right.actual);
|
||||
|
||||
|
@ -159,8 +159,8 @@ public final class EComp extends AExpression {
|
|||
left.expected = promotedType;
|
||||
right.expected = promotedType;
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.isNull && right.isNull) {
|
||||
throw createError(new IllegalArgumentException("Extraneous comparison of null constants."));
|
||||
|
@ -185,9 +185,9 @@ public final class EComp extends AExpression {
|
|||
actual = boolean.class;
|
||||
}
|
||||
|
||||
private void analyzeNE(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeNE(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promotedType = AnalyzerCaster.promoteEquality(left.actual, right.actual);
|
||||
|
||||
|
@ -205,8 +205,8 @@ public final class EComp extends AExpression {
|
|||
right.expected = promotedType;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.isNull && right.isNull) {
|
||||
throw createError(new IllegalArgumentException("Extraneous comparison of null constants."));
|
||||
|
@ -235,9 +235,9 @@ public final class EComp extends AExpression {
|
|||
actual = boolean.class;
|
||||
}
|
||||
|
||||
private void analyzeNER(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeNER(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promotedType = AnalyzerCaster.promoteEquality(left.actual, right.actual);
|
||||
|
||||
|
@ -250,8 +250,8 @@ public final class EComp extends AExpression {
|
|||
left.expected = promotedType;
|
||||
right.expected = promotedType;
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.isNull && right.isNull) {
|
||||
throw createError(new IllegalArgumentException("Extraneous comparison of null constants."));
|
||||
|
@ -276,9 +276,9 @@ public final class EComp extends AExpression {
|
|||
actual = boolean.class;
|
||||
}
|
||||
|
||||
private void analyzeGTE(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeGTE(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promotedType = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
|
||||
|
||||
|
@ -296,8 +296,8 @@ public final class EComp extends AExpression {
|
|||
right.expected = promotedType;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (promotedType == int.class) {
|
||||
|
@ -316,9 +316,9 @@ public final class EComp extends AExpression {
|
|||
actual = boolean.class;
|
||||
}
|
||||
|
||||
private void analyzeGT(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeGT(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promotedType = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
|
||||
|
||||
|
@ -336,8 +336,8 @@ public final class EComp extends AExpression {
|
|||
right.expected = promotedType;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (promotedType == int.class) {
|
||||
|
@ -356,9 +356,9 @@ public final class EComp extends AExpression {
|
|||
actual = boolean.class;
|
||||
}
|
||||
|
||||
private void analyzeLTE(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeLTE(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promotedType = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
|
||||
|
||||
|
@ -376,8 +376,8 @@ public final class EComp extends AExpression {
|
|||
right.expected = promotedType;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (promotedType == int.class) {
|
||||
|
@ -396,9 +396,9 @@ public final class EComp extends AExpression {
|
|||
actual = boolean.class;
|
||||
}
|
||||
|
||||
private void analyzeLT(FunctionTable functions, Locals variables) {
|
||||
left.analyze(functions, variables);
|
||||
right.analyze(functions, variables);
|
||||
private void analyzeLT(ScriptRoot scriptRoot, Locals variables) {
|
||||
left.analyze(scriptRoot, variables);
|
||||
right.analyze(scriptRoot, variables);
|
||||
|
||||
promotedType = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
|
||||
|
||||
|
@ -416,8 +416,8 @@ public final class EComp extends AExpression {
|
|||
right.expected = promotedType;
|
||||
}
|
||||
|
||||
left = left.cast(functions, variables);
|
||||
right = right.cast(functions, variables);
|
||||
left = left.cast(scriptRoot, variables);
|
||||
right = right.cast(scriptRoot, variables);
|
||||
|
||||
if (left.constant != null && right.constant != null) {
|
||||
if (promotedType == int.class) {
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
|
@ -65,10 +65,10 @@ public final class EConditional extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
condition.expected = boolean.class;
|
||||
condition.analyze(functions, locals);
|
||||
condition = condition.cast(functions, locals);
|
||||
condition.analyze(scriptRoot, locals);
|
||||
condition = condition.cast(scriptRoot, locals);
|
||||
|
||||
if (condition.constant != null) {
|
||||
throw createError(new IllegalArgumentException("Extraneous conditional statement."));
|
||||
|
@ -82,8 +82,8 @@ public final class EConditional extends AExpression {
|
|||
right.internal = internal;
|
||||
actual = expected;
|
||||
|
||||
left.analyze(functions, locals);
|
||||
right.analyze(functions, locals);
|
||||
left.analyze(scriptRoot, locals);
|
||||
right.analyze(scriptRoot, locals);
|
||||
|
||||
if (expected == null) {
|
||||
Class<?> promote = AnalyzerCaster.promoteConditional(left.actual, right.actual, left.constant, right.constant);
|
||||
|
@ -93,8 +93,8 @@ public final class EConditional extends AExpression {
|
|||
actual = promote;
|
||||
}
|
||||
|
||||
left = left.cast(functions, locals);
|
||||
right = right.cast(functions, locals);
|
||||
left = left.cast(scriptRoot, locals);
|
||||
right = right.cast(scriptRoot, locals);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -52,7 +52,7 @@ final class EConstant extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (constant instanceof String) {
|
||||
actual = String.class;
|
||||
} else if (constant instanceof Double) {
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -54,7 +54,7 @@ public final class EDecimal extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (!read) {
|
||||
throw createError(new IllegalArgumentException("Must read from constant [" + value + "]."));
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
|
||||
import java.util.Set;
|
||||
|
@ -61,7 +61,7 @@ public class EElvis extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (expected != null && expected.isPrimitive()) {
|
||||
throw createError(new IllegalArgumentException("Elvis operator cannot return primitives"));
|
||||
}
|
||||
|
@ -72,8 +72,8 @@ public class EElvis extends AExpression {
|
|||
rhs.explicit = explicit;
|
||||
rhs.internal = internal;
|
||||
actual = expected;
|
||||
lhs.analyze(functions, locals);
|
||||
rhs.analyze(functions, locals);
|
||||
lhs.analyze(scriptRoot, locals);
|
||||
rhs.analyze(scriptRoot, locals);
|
||||
|
||||
if (lhs.isNull) {
|
||||
throw createError(new IllegalArgumentException("Extraneous elvis operator. LHS is null."));
|
||||
|
@ -96,8 +96,8 @@ public class EElvis extends AExpression {
|
|||
actual = promote;
|
||||
}
|
||||
|
||||
lhs = lhs.cast(functions, locals);
|
||||
rhs = rhs.cast(functions, locals);
|
||||
lhs = lhs.cast(scriptRoot, locals);
|
||||
rhs = rhs.cast(scriptRoot, locals);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -56,8 +56,8 @@ public final class EExplicit extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
actual = locals.getPainlessLookup().canonicalTypeNameToType(type);
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
actual = scriptRoot.getPainlessLookup().canonicalTypeNameToType(type);
|
||||
|
||||
if (actual == null) {
|
||||
throw createError(new IllegalArgumentException("Not a type [" + type + "]."));
|
||||
|
@ -65,8 +65,8 @@ public final class EExplicit extends AExpression {
|
|||
|
||||
child.expected = actual;
|
||||
child.explicit = true;
|
||||
child.analyze(functions, locals);
|
||||
child = child.cast(functions, locals);
|
||||
child.analyze(scriptRoot, locals);
|
||||
child = child.cast(scriptRoot, locals);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -74,12 +74,12 @@ public final class EExplicit extends AExpression {
|
|||
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||
}
|
||||
|
||||
AExpression cast(FunctionTable functions, Locals locals) {
|
||||
AExpression cast(ScriptRoot scriptRoot, Locals locals) {
|
||||
child.expected = expected;
|
||||
child.explicit = explicit;
|
||||
child.internal = internal;
|
||||
|
||||
return child.cast(functions, locals);
|
||||
return child.cast(scriptRoot, locals);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.util.Objects;
|
||||
|
@ -60,14 +60,14 @@ public final class EFunctionRef extends AExpression implements ILambda {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (expected == null) {
|
||||
ref = null;
|
||||
actual = String.class;
|
||||
defPointer = "S" + type + "." + call + ",0";
|
||||
} else {
|
||||
defPointer = null;
|
||||
ref = FunctionRef.create(locals.getPainlessLookup(), functions, location, expected, type, call, 0);
|
||||
ref = FunctionRef.create(scriptRoot.getPainlessLookup(), scriptRoot.getFunctionTable(), location, expected, type, call, 0);
|
||||
actual = expected;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -61,10 +61,9 @@ public final class EInstanceof extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
// ensure the specified type is part of the definition
|
||||
Class<?> clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
|
||||
Class<?> clazz = scriptRoot.getPainlessLookup().canonicalTypeNameToType(this.type);
|
||||
|
||||
if (clazz == null) {
|
||||
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
|
||||
|
@ -75,9 +74,9 @@ public final class EInstanceof extends AExpression {
|
|||
PainlessLookupUtility.typeToJavaType(clazz);
|
||||
|
||||
// analyze and cast the expression
|
||||
expression.analyze(functions, locals);
|
||||
expression.analyze(scriptRoot, locals);
|
||||
expression.expected = expression.actual;
|
||||
expression = expression.cast(functions, locals);
|
||||
expression = expression.cast(scriptRoot, locals);
|
||||
|
||||
// record if the expression returns a primitive
|
||||
primitiveExpression = expression.actual.isPrimitive();
|
||||
|
|
|
@ -30,7 +30,7 @@ import org.elasticsearch.painless.MethodWriter;
|
|||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -111,7 +111,7 @@ public final class ELambda extends AExpression implements ILambda {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
Class<?> returnType;
|
||||
List<String> actualParamTypeStrs;
|
||||
PainlessMethod interfaceMethod;
|
||||
|
@ -132,7 +132,7 @@ public final class ELambda extends AExpression implements ILambda {
|
|||
|
||||
} else {
|
||||
// we know the method statically, infer return type and any unknown/def types
|
||||
interfaceMethod = locals.getPainlessLookup().lookupFunctionalInterfacePainlessMethod(expected);
|
||||
interfaceMethod = scriptRoot.getPainlessLookup().lookupFunctionalInterfacePainlessMethod(expected);
|
||||
if (interfaceMethod == null) {
|
||||
throw createError(new IllegalArgumentException("Cannot pass lambda to " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "], not a functional interface"));
|
||||
|
@ -176,14 +176,15 @@ public final class ELambda extends AExpression implements ILambda {
|
|||
paramNames.addAll(paramNameStrs);
|
||||
|
||||
// desugar lambda body into a synthetic method
|
||||
String name = locals.getNextSyntheticName();
|
||||
desugared = new SFunction(location, PainlessLookupUtility.typeToCanonicalTypeName(returnType), name, paramTypes, paramNames,
|
||||
String name = scriptRoot.getNextSyntheticName("lambda");
|
||||
desugared = new SFunction(
|
||||
location, PainlessLookupUtility.typeToCanonicalTypeName(returnType), name, paramTypes, paramNames,
|
||||
new SBlock(location, statements), true);
|
||||
desugared.storeSettings(settings);
|
||||
desugared.generateSignature(locals.getPainlessLookup());
|
||||
desugared.analyze(functions, Locals.newLambdaScope(locals.getProgramScope(), desugared.name, returnType,
|
||||
desugared.generateSignature(scriptRoot.getPainlessLookup());
|
||||
desugared.analyze(scriptRoot, Locals.newLambdaScope(locals.getProgramScope(), desugared.name, returnType,
|
||||
desugared.parameters, captures.size(), settings.getMaxLoopCounter()));
|
||||
functions.addFunction(desugared.name, desugared.returnType, desugared.typeParameters, true);
|
||||
scriptRoot.getFunctionTable().addFunction(desugared.name, desugared.returnType, desugared.typeParameters, true);
|
||||
|
||||
// setup method reference to synthetic method
|
||||
if (expected == null) {
|
||||
|
@ -192,8 +193,8 @@ public final class ELambda extends AExpression implements ILambda {
|
|||
defPointer = "Sthis." + name + "," + captures.size();
|
||||
} else {
|
||||
defPointer = null;
|
||||
ref = FunctionRef.create(
|
||||
locals.getPainlessLookup(), functions, location, expected, "this", desugared.name, captures.size());
|
||||
ref = FunctionRef.create(scriptRoot.getPainlessLookup(), scriptRoot.getFunctionTable(),
|
||||
location, expected, "this", desugared.name, captures.size());
|
||||
actual = expected;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.elasticsearch.painless.MethodWriter;
|
|||
import org.elasticsearch.painless.lookup.PainlessConstructor;
|
||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.Method;
|
||||
|
||||
|
@ -68,21 +68,21 @@ public final class EListInit extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (!read) {
|
||||
throw createError(new IllegalArgumentException("Must read from list initializer."));
|
||||
}
|
||||
|
||||
actual = ArrayList.class;
|
||||
|
||||
constructor = locals.getPainlessLookup().lookupPainlessConstructor(actual, 0);
|
||||
constructor = scriptRoot.getPainlessLookup().lookupPainlessConstructor(actual, 0);
|
||||
|
||||
if (constructor == null) {
|
||||
throw createError(new IllegalArgumentException(
|
||||
"constructor [" + typeToCanonicalTypeName(actual) + ", <init>/0] not found"));
|
||||
}
|
||||
|
||||
method = locals.getPainlessLookup().lookupPainlessMethod(actual, false, "add", 1);
|
||||
method = scriptRoot.getPainlessLookup().lookupPainlessMethod(actual, false, "add", 1);
|
||||
|
||||
if (method == null) {
|
||||
throw createError(new IllegalArgumentException("method [" + typeToCanonicalTypeName(actual) + ", add/1] not found"));
|
||||
|
@ -93,8 +93,8 @@ public final class EListInit extends AExpression {
|
|||
|
||||
expression.expected = def.class;
|
||||
expression.internal = true;
|
||||
expression.analyze(functions, locals);
|
||||
values.set(index, expression.cast(functions, locals));
|
||||
expression.analyze(scriptRoot, locals);
|
||||
values.set(index, expression.cast(scriptRoot, locals));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.elasticsearch.painless.MethodWriter;
|
|||
import org.elasticsearch.painless.lookup.PainlessConstructor;
|
||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.Method;
|
||||
|
||||
|
@ -78,21 +78,21 @@ public final class EMapInit extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (!read) {
|
||||
throw createError(new IllegalArgumentException("Must read from map initializer."));
|
||||
}
|
||||
|
||||
actual = HashMap.class;
|
||||
|
||||
constructor = locals.getPainlessLookup().lookupPainlessConstructor(actual, 0);
|
||||
constructor = scriptRoot.getPainlessLookup().lookupPainlessConstructor(actual, 0);
|
||||
|
||||
if (constructor == null) {
|
||||
throw createError(new IllegalArgumentException(
|
||||
"constructor [" + typeToCanonicalTypeName(actual) + ", <init>/0] not found"));
|
||||
}
|
||||
|
||||
method = locals.getPainlessLookup().lookupPainlessMethod(actual, false, "put", 2);
|
||||
method = scriptRoot.getPainlessLookup().lookupPainlessMethod(actual, false, "put", 2);
|
||||
|
||||
if (method == null) {
|
||||
throw createError(new IllegalArgumentException("method [" + typeToCanonicalTypeName(actual) + ", put/2] not found"));
|
||||
|
@ -107,8 +107,8 @@ public final class EMapInit extends AExpression {
|
|||
|
||||
expression.expected = def.class;
|
||||
expression.internal = true;
|
||||
expression.analyze(functions, locals);
|
||||
keys.set(index, expression.cast(functions, locals));
|
||||
expression.analyze(scriptRoot, locals);
|
||||
keys.set(index, expression.cast(scriptRoot, locals));
|
||||
}
|
||||
|
||||
for (int index = 0; index < values.size(); ++index) {
|
||||
|
@ -116,8 +116,8 @@ public final class EMapInit extends AExpression {
|
|||
|
||||
expression.expected = def.class;
|
||||
expression.internal = true;
|
||||
expression.analyze(functions, locals);
|
||||
values.set(index, expression.cast(functions, locals));
|
||||
expression.analyze(scriptRoot, locals);
|
||||
values.set(index, expression.cast(scriptRoot, locals));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
@ -63,12 +63,12 @@ public final class ENewArray extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (!read) {
|
||||
throw createError(new IllegalArgumentException("A newly created array must be read from."));
|
||||
}
|
||||
|
||||
Class<?> clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
|
||||
Class<?> clazz = scriptRoot.getPainlessLookup().canonicalTypeNameToType(this.type);
|
||||
|
||||
if (clazz == null) {
|
||||
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
|
||||
|
@ -79,8 +79,8 @@ public final class ENewArray extends AExpression {
|
|||
|
||||
expression.expected = initialize ? clazz.getComponentType() : int.class;
|
||||
expression.internal = true;
|
||||
expression.analyze(functions, locals);
|
||||
arguments.set(argument, expression.cast(functions, locals));
|
||||
expression.analyze(scriptRoot, locals);
|
||||
arguments.set(argument, expression.cast(scriptRoot, locals));
|
||||
}
|
||||
|
||||
actual = clazz;
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -63,17 +63,18 @@ public final class ENewArrayFunctionRef extends AExpression implements ILambda {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
SReturn code = new SReturn(location, new ENewArray(location, type, Arrays.asList(new EVariable(location, "size")), false));
|
||||
function = new SFunction(location, type, locals.getNextSyntheticName(),
|
||||
function = new SFunction(
|
||||
location, type, scriptRoot.getNextSyntheticName("newarray"),
|
||||
Collections.singletonList("int"), Collections.singletonList("size"),
|
||||
new SBlock(location, Collections.singletonList(code)), true);
|
||||
function.storeSettings(settings);
|
||||
function.generateSignature(locals.getPainlessLookup());
|
||||
function.generateSignature(scriptRoot.getPainlessLookup());
|
||||
function.extractVariables(null);
|
||||
function.analyze(functions, Locals.newLambdaScope(locals.getProgramScope(), function.name, function.returnType,
|
||||
function.analyze(scriptRoot, Locals.newLambdaScope(locals.getProgramScope(), function.name, function.returnType,
|
||||
function.parameters, 0, settings.getMaxLoopCounter()));
|
||||
functions.addFunction(function.name, function.returnType, function.typeParameters, true);
|
||||
scriptRoot.getFunctionTable().addFunction(function.name, function.returnType, function.typeParameters, true);
|
||||
|
||||
if (expected == null) {
|
||||
ref = null;
|
||||
|
@ -81,7 +82,8 @@ public final class ENewArrayFunctionRef extends AExpression implements ILambda {
|
|||
defPointer = "Sthis." + function.name + ",0";
|
||||
} else {
|
||||
defPointer = null;
|
||||
ref = FunctionRef.create(locals.getPainlessLookup(), functions, location, expected, "this", function.name, 0);
|
||||
ref = FunctionRef.create(scriptRoot.getPainlessLookup(), scriptRoot.getFunctionTable(),
|
||||
location, expected, "this", function.name, 0);
|
||||
actual = expected;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.elasticsearch.painless.Location;
|
|||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessConstructor;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.Method;
|
||||
|
||||
|
@ -69,14 +69,14 @@ public final class ENewObj extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
actual = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
actual = scriptRoot.getPainlessLookup().canonicalTypeNameToType(this.type);
|
||||
|
||||
if (actual == null) {
|
||||
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
|
||||
}
|
||||
|
||||
constructor = locals.getPainlessLookup().lookupPainlessConstructor(actual, arguments.size());
|
||||
constructor = scriptRoot.getPainlessLookup().lookupPainlessConstructor(actual, arguments.size());
|
||||
|
||||
if (constructor == null) {
|
||||
throw createError(new IllegalArgumentException(
|
||||
|
@ -97,8 +97,8 @@ public final class ENewObj extends AExpression {
|
|||
|
||||
expression.expected = types[argument];
|
||||
expression.internal = true;
|
||||
expression.analyze(functions, locals);
|
||||
arguments.set(argument, expression.cast(functions, locals));
|
||||
expression.analyze(scriptRoot, locals);
|
||||
arguments.set(argument, expression.cast(scriptRoot, locals));
|
||||
}
|
||||
|
||||
statement = true;
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.Set;
|
||||
|
@ -51,7 +51,7 @@ public final class ENull extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (!read) {
|
||||
throw createError(new IllegalArgumentException("Must read from null constant."));
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -56,7 +56,7 @@ public final class ENumeric extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (!read) {
|
||||
throw createError(new IllegalArgumentException("Must read from constant [" + value + "]."));
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.WriterConstants;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -69,7 +69,7 @@ public final class ERegex extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (false == settings.areRegexesEnabled()) {
|
||||
throw createError(new IllegalStateException("Regexes are disabled. Set [script.painless.regex.enabled] to [true] "
|
||||
+ "in elasticsearch.yaml to allow them. Be careful though, regexes break out of Painless's protection against deep "
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -54,8 +54,8 @@ public final class EStatic extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
actual = locals.getPainlessLookup().canonicalTypeNameToType(type);
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
actual = scriptRoot.getPainlessLookup().canonicalTypeNameToType(type);
|
||||
|
||||
if (actual == null) {
|
||||
throw createError(new IllegalArgumentException("Not a type [" + type + "]."));
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -52,7 +52,7 @@ public final class EString extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (!read) {
|
||||
throw createError(new IllegalArgumentException("Must read from constant [" + constant + "]."));
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ import org.elasticsearch.painless.MethodWriter;
|
|||
import org.elasticsearch.painless.Operation;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
|
@ -67,26 +67,26 @@ public final class EUnary extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
originallyExplicit = explicit;
|
||||
|
||||
if (operation == Operation.NOT) {
|
||||
analyzeNot(functions, locals);
|
||||
analyzeNot(scriptRoot, locals);
|
||||
} else if (operation == Operation.BWNOT) {
|
||||
analyzeBWNot(functions, locals);
|
||||
analyzeBWNot(scriptRoot, locals);
|
||||
} else if (operation == Operation.ADD) {
|
||||
analyzerAdd(functions, locals);
|
||||
analyzerAdd(scriptRoot, locals);
|
||||
} else if (operation == Operation.SUB) {
|
||||
analyzerSub(functions, locals);
|
||||
analyzerSub(scriptRoot, locals);
|
||||
} else {
|
||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||
}
|
||||
}
|
||||
|
||||
void analyzeNot(FunctionTable functions, Locals variables) {
|
||||
void analyzeNot(ScriptRoot scriptRoot, Locals variables) {
|
||||
child.expected = boolean.class;
|
||||
child.analyze(functions, variables);
|
||||
child = child.cast(functions, variables);
|
||||
child.analyze(scriptRoot, variables);
|
||||
child = child.cast(scriptRoot, variables);
|
||||
|
||||
if (child.constant != null) {
|
||||
constant = !(boolean)child.constant;
|
||||
|
@ -95,8 +95,8 @@ public final class EUnary extends AExpression {
|
|||
actual = boolean.class;
|
||||
}
|
||||
|
||||
void analyzeBWNot(FunctionTable functions, Locals variables) {
|
||||
child.analyze(functions, variables);
|
||||
void analyzeBWNot(ScriptRoot scriptRoot, Locals variables) {
|
||||
child.analyze(scriptRoot, variables);
|
||||
|
||||
promote = AnalyzerCaster.promoteNumeric(child.actual, false);
|
||||
|
||||
|
@ -106,7 +106,7 @@ public final class EUnary extends AExpression {
|
|||
}
|
||||
|
||||
child.expected = promote;
|
||||
child = child.cast(functions, variables);
|
||||
child = child.cast(scriptRoot, variables);
|
||||
|
||||
if (child.constant != null) {
|
||||
if (promote == int.class) {
|
||||
|
@ -125,8 +125,8 @@ public final class EUnary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
void analyzerAdd(FunctionTable functions, Locals variables) {
|
||||
child.analyze(functions, variables);
|
||||
void analyzerAdd(ScriptRoot scriptRoot, Locals variables) {
|
||||
child.analyze(scriptRoot, variables);
|
||||
|
||||
promote = AnalyzerCaster.promoteNumeric(child.actual, true);
|
||||
|
||||
|
@ -136,7 +136,7 @@ public final class EUnary extends AExpression {
|
|||
}
|
||||
|
||||
child.expected = promote;
|
||||
child = child.cast(functions, variables);
|
||||
child = child.cast(scriptRoot, variables);
|
||||
|
||||
if (child.constant != null) {
|
||||
if (promote == int.class) {
|
||||
|
@ -159,8 +159,8 @@ public final class EUnary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
void analyzerSub(FunctionTable functions, Locals variables) {
|
||||
child.analyze(functions, variables);
|
||||
void analyzerSub(ScriptRoot scriptRoot, Locals variables) {
|
||||
child.analyze(scriptRoot, variables);
|
||||
|
||||
promote = AnalyzerCaster.promoteNumeric(child.actual, true);
|
||||
|
||||
|
@ -170,7 +170,7 @@ public final class EUnary extends AExpression {
|
|||
}
|
||||
|
||||
child.expected = promote;
|
||||
child = child.cast(functions, variables);
|
||||
child = child.cast(scriptRoot, variables);
|
||||
|
||||
if (child.constant != null) {
|
||||
if (promote == int.class) {
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Locals.Variable;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.Objects;
|
||||
|
@ -58,7 +58,7 @@ public final class EVariable extends AStoreable {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
variable = locals.getVariable(location, name);
|
||||
|
||||
if (write && variable.readonly) {
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.elasticsearch.painless.Location;
|
|||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -62,10 +62,10 @@ public final class PBrace extends AStoreable {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
prefix.analyze(functions, locals);
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
prefix.analyze(scriptRoot, locals);
|
||||
prefix.expected = prefix.actual;
|
||||
prefix = prefix.cast(functions, locals);
|
||||
prefix = prefix.cast(scriptRoot, locals);
|
||||
|
||||
if (prefix.actual.isArray()) {
|
||||
sub = new PSubBrace(location, prefix.actual, index);
|
||||
|
@ -84,7 +84,7 @@ public final class PBrace extends AStoreable {
|
|||
sub.read = read;
|
||||
sub.expected = expected;
|
||||
sub.explicit = explicit;
|
||||
sub.analyze(functions, locals);
|
||||
sub.analyze(scriptRoot, locals);
|
||||
actual = sub.actual;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.elasticsearch.painless.Location;
|
|||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
@ -73,16 +73,16 @@ public final class PCallInvoke extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
prefix.analyze(functions, locals);
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
prefix.analyze(scriptRoot, locals);
|
||||
prefix.expected = prefix.actual;
|
||||
prefix = prefix.cast(functions, locals);
|
||||
prefix = prefix.cast(scriptRoot, locals);
|
||||
|
||||
if (prefix.actual == def.class) {
|
||||
sub = new PSubDefCall(location, name, arguments);
|
||||
} else {
|
||||
PainlessMethod method =
|
||||
locals.getPainlessLookup().lookupPainlessMethod(prefix.actual, prefix instanceof EStatic, name, arguments.size());
|
||||
scriptRoot.getPainlessLookup().lookupPainlessMethod(prefix.actual, prefix instanceof EStatic, name, arguments.size());
|
||||
|
||||
if (method == null) {
|
||||
throw createError(new IllegalArgumentException(
|
||||
|
@ -98,7 +98,7 @@ public final class PCallInvoke extends AExpression {
|
|||
|
||||
sub.expected = expected;
|
||||
sub.explicit = explicit;
|
||||
sub.analyze(functions, locals);
|
||||
sub.analyze(scriptRoot, locals);
|
||||
actual = sub.actual;
|
||||
|
||||
statement = true;
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.elasticsearch.painless.lookup.PainlessField;
|
|||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -66,38 +66,38 @@ public final class PField extends AStoreable {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
prefix.analyze(functions, locals);
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
prefix.analyze(scriptRoot, locals);
|
||||
prefix.expected = prefix.actual;
|
||||
prefix = prefix.cast(functions, locals);
|
||||
prefix = prefix.cast(scriptRoot, locals);
|
||||
|
||||
if (prefix.actual.isArray()) {
|
||||
sub = new PSubArrayLength(location, PainlessLookupUtility.typeToCanonicalTypeName(prefix.actual), value);
|
||||
} else if (prefix.actual == def.class) {
|
||||
sub = new PSubDefField(location, value);
|
||||
} else {
|
||||
PainlessField field = locals.getPainlessLookup().lookupPainlessField(prefix.actual, prefix instanceof EStatic, value);
|
||||
PainlessField field = scriptRoot.getPainlessLookup().lookupPainlessField(prefix.actual, prefix instanceof EStatic, value);
|
||||
|
||||
if (field == null) {
|
||||
PainlessMethod getter;
|
||||
PainlessMethod setter;
|
||||
|
||||
getter = locals.getPainlessLookup().lookupPainlessMethod(prefix.actual, false,
|
||||
getter = scriptRoot.getPainlessLookup().lookupPainlessMethod(prefix.actual, false,
|
||||
"get" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 0);
|
||||
|
||||
if (getter == null) {
|
||||
getter = locals.getPainlessLookup().lookupPainlessMethod(prefix.actual, false,
|
||||
getter = scriptRoot.getPainlessLookup().lookupPainlessMethod(prefix.actual, false,
|
||||
"is" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 0);
|
||||
}
|
||||
|
||||
setter = locals.getPainlessLookup().lookupPainlessMethod(prefix.actual, false,
|
||||
setter = scriptRoot.getPainlessLookup().lookupPainlessMethod(prefix.actual, false,
|
||||
"set" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 0);
|
||||
|
||||
if (getter != null || setter != null) {
|
||||
sub = new PSubShortcut(location, value, PainlessLookupUtility.typeToCanonicalTypeName(prefix.actual), getter, setter);
|
||||
} else {
|
||||
EConstant index = new EConstant(location, value);
|
||||
index.analyze(functions, locals);
|
||||
index.analyze(scriptRoot, locals);
|
||||
|
||||
if (Map.class.isAssignableFrom(prefix.actual)) {
|
||||
sub = new PSubMapShortcut(location, prefix.actual, index);
|
||||
|
@ -125,7 +125,7 @@ public final class PField extends AStoreable {
|
|||
sub.read = read;
|
||||
sub.expected = expected;
|
||||
sub.explicit = explicit;
|
||||
sub.analyze(functions, locals);
|
||||
sub.analyze(scriptRoot, locals);
|
||||
actual = sub.actual;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -56,7 +56,7 @@ final class PSubArrayLength extends AStoreable {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if ("length".equals(value)) {
|
||||
if (write) {
|
||||
throw createError(new IllegalArgumentException("Cannot write to read-only field [length] for an array."));
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -56,10 +56,10 @@ final class PSubBrace extends AStoreable {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
index.expected = int.class;
|
||||
index.analyze(functions, locals);
|
||||
index = index.cast(functions, locals);
|
||||
index.analyze(scriptRoot, locals);
|
||||
index = index.cast(scriptRoot, locals);
|
||||
|
||||
actual = clazz.getComponentType();
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
@ -60,14 +60,14 @@ final class PSubCallInvoke extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
for (int argument = 0; argument < arguments.size(); ++argument) {
|
||||
AExpression expression = arguments.get(argument);
|
||||
|
||||
expression.expected = method.typeParameters.get(argument);
|
||||
expression.internal = true;
|
||||
expression.analyze(functions, locals);
|
||||
arguments.set(argument, expression.cast(functions, locals));
|
||||
expression.analyze(scriptRoot, locals);
|
||||
arguments.set(argument, expression.cast(scriptRoot, locals));
|
||||
}
|
||||
|
||||
statement = true;
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
@ -57,10 +57,10 @@ final class PSubDefArray extends AStoreable {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
index.analyze(functions, locals);
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
index.analyze(scriptRoot, locals);
|
||||
index.expected = index.actual;
|
||||
index = index.cast(functions, locals);
|
||||
index = index.cast(scriptRoot, locals);
|
||||
|
||||
// TODO: remove ZonedDateTime exception when JodaCompatibleDateTime is removed
|
||||
actual = expected == null || expected == ZonedDateTime.class || explicit ? def.class : expected;
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
@ -66,7 +66,7 @@ final class PSubDefCall extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
recipe = new StringBuilder();
|
||||
int totalCaptures = 0;
|
||||
|
||||
|
@ -74,7 +74,7 @@ final class PSubDefCall extends AExpression {
|
|||
AExpression expression = arguments.get(argument);
|
||||
|
||||
expression.internal = true;
|
||||
expression.analyze(functions, locals);
|
||||
expression.analyze(scriptRoot, locals);
|
||||
|
||||
if (expression instanceof ILambda) {
|
||||
ILambda lambda = (ILambda) expression;
|
||||
|
@ -90,7 +90,7 @@ final class PSubDefCall extends AExpression {
|
|||
}
|
||||
|
||||
expression.expected = expression.actual;
|
||||
arguments.set(argument, expression.cast(functions, locals));
|
||||
arguments.set(argument, expression.cast(scriptRoot, locals));
|
||||
}
|
||||
|
||||
// TODO: remove ZonedDateTime exception when JodaCompatibleDateTime is removed
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Objects;
|
||||
|
@ -57,7 +57,7 @@ final class PSubDefField extends AStoreable {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
// TODO: remove ZonedDateTime exception when JodaCompatibleDateTime is removed
|
||||
actual = expected == null || expected == ZonedDateTime.class || explicit ? def.class : expected;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.elasticsearch.painless.Location;
|
|||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessField;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
|
@ -58,7 +58,7 @@ final class PSubField extends AStoreable {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (write && Modifier.isFinal(field.javaField.getModifiers())) {
|
||||
throw createError(new IllegalArgumentException("Cannot write to read-only field [" + field.javaField.getName() + "] " +
|
||||
"for type [" + PainlessLookupUtility.typeToCanonicalTypeName(field.javaField.getDeclaringClass()) + "]."));
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.elasticsearch.painless.MethodWriter;
|
|||
import org.elasticsearch.painless.WriterConstants;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -62,11 +62,11 @@ final class PSubListShortcut extends AStoreable {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
String canonicalClassName = PainlessLookupUtility.typeToCanonicalTypeName(targetClass);
|
||||
|
||||
getter = locals.getPainlessLookup().lookupPainlessMethod(targetClass, false, "get", 1);
|
||||
setter = locals.getPainlessLookup().lookupPainlessMethod(targetClass, false, "set", 2);
|
||||
getter = scriptRoot.getPainlessLookup().lookupPainlessMethod(targetClass, false, "get", 1);
|
||||
setter = scriptRoot.getPainlessLookup().lookupPainlessMethod(targetClass, false, "set", 2);
|
||||
|
||||
if (getter != null && (getter.returnType == void.class || getter.typeParameters.size() != 1 ||
|
||||
getter.typeParameters.get(0) != int.class)) {
|
||||
|
@ -84,8 +84,8 @@ final class PSubListShortcut extends AStoreable {
|
|||
|
||||
if ((read || write) && (!read || getter != null) && (!write || setter != null)) {
|
||||
index.expected = int.class;
|
||||
index.analyze(functions, locals);
|
||||
index = index.cast(functions, locals);
|
||||
index.analyze(scriptRoot, locals);
|
||||
index = index.cast(scriptRoot, locals);
|
||||
|
||||
actual = setter != null ? setter.typeParameters.get(1) : getter.returnType;
|
||||
} else {
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.elasticsearch.painless.Location;
|
|||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -61,11 +61,11 @@ final class PSubMapShortcut extends AStoreable {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
String canonicalClassName = PainlessLookupUtility.typeToCanonicalTypeName(targetClass);
|
||||
|
||||
getter = locals.getPainlessLookup().lookupPainlessMethod(targetClass, false, "get", 1);
|
||||
setter = locals.getPainlessLookup().lookupPainlessMethod(targetClass, false, "put", 2);
|
||||
getter = scriptRoot.getPainlessLookup().lookupPainlessMethod(targetClass, false, "get", 1);
|
||||
setter = scriptRoot.getPainlessLookup().lookupPainlessMethod(targetClass, false, "put", 2);
|
||||
|
||||
if (getter != null && (getter.returnType == void.class || getter.typeParameters.size() != 1)) {
|
||||
throw createError(new IllegalArgumentException("Illegal map get shortcut for type [" + canonicalClassName + "]."));
|
||||
|
@ -82,8 +82,8 @@ final class PSubMapShortcut extends AStoreable {
|
|||
|
||||
if ((read || write) && (!read || getter != null) && (!write || setter != null)) {
|
||||
index.expected = setter != null ? setter.typeParameters.get(0) : getter.typeParameters.get(0);
|
||||
index.analyze(functions, locals);
|
||||
index = index.cast(functions, locals);
|
||||
index.analyze(scriptRoot, locals);
|
||||
index = index.cast(scriptRoot, locals);
|
||||
|
||||
actual = setter != null ? setter.typeParameters.get(1) : getter.returnType;
|
||||
} else {
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
|
||||
import java.util.Set;
|
||||
|
@ -57,8 +57,8 @@ public class PSubNullSafeCallInvoke extends AExpression {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
guarded.analyze(functions, locals);
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
guarded.analyze(scriptRoot, locals);
|
||||
actual = guarded.actual;
|
||||
if (actual.isPrimitive()) {
|
||||
throw new IllegalArgumentException("Result of null safe operator must be nullable");
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
|
||||
import java.util.Set;
|
||||
|
@ -52,12 +52,12 @@ public class PSubNullSafeField extends AStoreable {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (write) {
|
||||
throw createError(new IllegalArgumentException("Can't write to null safe reference"));
|
||||
}
|
||||
guarded.read = read;
|
||||
guarded.analyze(functions, locals);
|
||||
guarded.analyze(scriptRoot, locals);
|
||||
actual = guarded.actual;
|
||||
if (actual.isPrimitive()) {
|
||||
throw new IllegalArgumentException("Result of null safe operator must be nullable");
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -60,7 +60,7 @@ final class PSubShortcut extends AStoreable {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (getter != null && (getter.returnType == void.class || !getter.typeParameters.isEmpty())) {
|
||||
throw createError(new IllegalArgumentException(
|
||||
"Illegal get shortcut on field [" + value + "] for type [" + type + "]."));
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -61,7 +61,7 @@ public final class SBlock extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (statements == null || statements.isEmpty()) {
|
||||
throw createError(new IllegalArgumentException("A block must contain at least one statement."));
|
||||
}
|
||||
|
@ -78,8 +78,7 @@ public final class SBlock extends AStatement {
|
|||
statement.inLoop = inLoop;
|
||||
statement.lastSource = lastSource && statement == last;
|
||||
statement.lastLoop = (beginLoop || lastLoop) && statement == last;
|
||||
|
||||
statement.analyze(functions, locals);
|
||||
statement.analyze(scriptRoot, locals);
|
||||
|
||||
methodEscape = statement.methodEscape;
|
||||
loopEscape = statement.loopEscape;
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -49,7 +49,7 @@ public final class SBreak extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (!inLoop) {
|
||||
throw createError(new IllegalArgumentException("Break statement outside of a loop."));
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Locals.Variable;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
|
@ -73,8 +73,8 @@ public final class SCatch extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
Class<?> clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
|
||||
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 + "]."));
|
||||
|
@ -90,8 +90,7 @@ public final class SCatch extends AStatement {
|
|||
block.lastSource = lastSource;
|
||||
block.inLoop = inLoop;
|
||||
block.lastLoop = lastLoop;
|
||||
|
||||
block.analyze(functions, locals);
|
||||
block.analyze(scriptRoot, locals);
|
||||
|
||||
methodEscape = block.methodEscape;
|
||||
loopEscape = block.loopEscape;
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.elasticsearch.painless.MethodWriter;
|
|||
import org.elasticsearch.painless.ScriptClassInfo;
|
||||
import org.elasticsearch.painless.WriterConstants;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookup;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.Label;
|
||||
|
@ -87,7 +88,7 @@ public final class SClass extends AStatement {
|
|||
|
||||
private CompilerSettings settings;
|
||||
|
||||
private FunctionTable table;
|
||||
private ScriptRoot table;
|
||||
private Locals mainMethod;
|
||||
private final Set<String> extractedVariables;
|
||||
private final List<org.objectweb.asm.commons.Method> getMethods;
|
||||
|
@ -134,30 +135,30 @@ public final class SClass extends AStatement {
|
|||
}
|
||||
|
||||
public void analyze(PainlessLookup painlessLookup) {
|
||||
table = new FunctionTable();
|
||||
table = new ScriptRoot(painlessLookup, settings, scriptClassInfo, this);
|
||||
|
||||
for (SFunction function : functions) {
|
||||
function.generateSignature(painlessLookup);
|
||||
|
||||
String key = FunctionTable.buildLocalFunctionKey(function.name, function.parameters.size());
|
||||
|
||||
if (table.getFunction(key) != null) {
|
||||
throw createError(new IllegalArgumentException("function [" + key + "] already defined"));
|
||||
if (table.getFunctionTable().getFunction(key) != null) {
|
||||
throw createError(new IllegalArgumentException("Illegal duplicate functions [" + key + "]."));
|
||||
}
|
||||
|
||||
table.addFunction(function.name, function.returnType, function.typeParameters, false);
|
||||
table.getFunctionTable().addFunction(function.name, function.returnType, function.typeParameters, false);
|
||||
}
|
||||
|
||||
Locals locals = Locals.newProgramScope(scriptClassInfo, painlessLookup);
|
||||
Locals locals = Locals.newProgramScope();
|
||||
analyze(table, locals);
|
||||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals program) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals program) {
|
||||
for (SFunction function : this.functions) {
|
||||
Locals functionLocals =
|
||||
Locals.newFunctionScope(program, function.returnType, function.parameters, settings.getMaxLoopCounter());
|
||||
function.analyze(functions, functionLocals);
|
||||
function.analyze(scriptRoot, functionLocals);
|
||||
}
|
||||
|
||||
if (statements == null || statements.isEmpty()) {
|
||||
|
@ -188,8 +189,7 @@ public final class SClass extends AStatement {
|
|||
}
|
||||
|
||||
statement.lastSource = statement == last;
|
||||
|
||||
statement.analyze(functions, mainMethod);
|
||||
statement.analyze(scriptRoot, mainMethod);
|
||||
|
||||
methodEscape = statement.methodEscape;
|
||||
allEscape = statement.allEscape;
|
||||
|
@ -348,7 +348,7 @@ public final class SClass extends AStatement {
|
|||
bytes = classWriter.getClassBytes();
|
||||
|
||||
Map<String, Object> statics = new HashMap<>();
|
||||
statics.put("$FUNCTIONS", table);
|
||||
statics.put("$FUNCTIONS", table.getFunctionTable());
|
||||
|
||||
for (Map.Entry<Object, String> instanceBinding : globals.getInstanceBindings().entrySet()) {
|
||||
statics.put(instanceBinding.getValue(), instanceBinding.getKey());
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -49,7 +49,7 @@ public final class SContinue extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (!inLoop) {
|
||||
throw createError(new IllegalArgumentException("Continue statement outside of a loop."));
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -61,9 +61,9 @@ public final class SDeclBlock extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
for (SDeclaration declaration : declarations) {
|
||||
declaration.analyze(functions, locals);
|
||||
declaration.analyze(scriptRoot, locals);
|
||||
}
|
||||
|
||||
statementCount = declarations.size();
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Locals.Variable;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.Objects;
|
||||
|
@ -68,8 +68,8 @@ public final class SDeclaration extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
Class<?> clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
|
||||
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 + "]."));
|
||||
|
@ -77,8 +77,8 @@ public final class SDeclaration extends AStatement {
|
|||
|
||||
if (expression != null) {
|
||||
expression.expected = clazz;
|
||||
expression.analyze(functions, locals);
|
||||
expression = expression.cast(functions, locals);
|
||||
expression.analyze(scriptRoot, locals);
|
||||
expression = expression.cast(scriptRoot, locals);
|
||||
}
|
||||
|
||||
variable = locals.addVariable(location, clazz, name, false);
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
|
@ -68,7 +68,7 @@ public final class SDo extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
locals = Locals.newLocalScope(locals);
|
||||
|
||||
if (block == null) {
|
||||
|
@ -77,16 +77,15 @@ public final class SDo extends AStatement {
|
|||
|
||||
block.beginLoop = true;
|
||||
block.inLoop = true;
|
||||
|
||||
block.analyze(functions, locals);
|
||||
block.analyze(scriptRoot, locals);
|
||||
|
||||
if (block.loopEscape && !block.anyContinue) {
|
||||
throw createError(new IllegalArgumentException("Extraneous do while loop."));
|
||||
}
|
||||
|
||||
condition.expected = boolean.class;
|
||||
condition.analyze(functions, locals);
|
||||
condition = condition.cast(functions, locals);
|
||||
condition.analyze(scriptRoot, locals);
|
||||
condition = condition.cast(scriptRoot, locals);
|
||||
|
||||
if (condition.constant != null) {
|
||||
continuous = (boolean)condition.constant;
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.elasticsearch.painless.Location;
|
|||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -75,12 +75,12 @@ public class SEach extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
expression.analyze(functions, locals);
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
expression.analyze(scriptRoot, locals);
|
||||
expression.expected = expression.actual;
|
||||
expression = expression.cast(functions, locals);
|
||||
expression = expression.cast(scriptRoot, locals);
|
||||
|
||||
Class<?> clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
|
||||
Class<?> clazz = scriptRoot.getPainlessLookup().canonicalTypeNameToType(this.type);
|
||||
|
||||
if (clazz == null) {
|
||||
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
|
||||
|
@ -98,7 +98,7 @@ public class SEach extends AStatement {
|
|||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(expression.actual) + "]."));
|
||||
}
|
||||
|
||||
sub.analyze(functions, locals);
|
||||
sub.analyze(scriptRoot, locals);
|
||||
|
||||
if (block == null) {
|
||||
throw createError(new IllegalArgumentException("Extraneous for each loop."));
|
||||
|
@ -106,7 +106,7 @@ public class SEach extends AStatement {
|
|||
|
||||
block.beginLoop = true;
|
||||
block.inLoop = true;
|
||||
block.analyze(functions, locals);
|
||||
block.analyze(scriptRoot, locals);
|
||||
block.statementCount = Math.max(1, block.statementCount);
|
||||
|
||||
if (block.loopEscape && !block.anyContinue) {
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -54,12 +54,12 @@ public final class SExpression extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
Class<?> rtnType = locals.getReturnType();
|
||||
boolean isVoid = rtnType == void.class;
|
||||
|
||||
expression.read = lastSource && !isVoid;
|
||||
expression.analyze(functions, locals);
|
||||
expression.analyze(scriptRoot, locals);
|
||||
|
||||
if (!lastSource && !expression.statement) {
|
||||
throw createError(new IllegalArgumentException("Not a statement."));
|
||||
|
@ -69,7 +69,7 @@ public final class SExpression extends AStatement {
|
|||
|
||||
expression.expected = rtn ? rtnType : expression.actual;
|
||||
expression.internal = rtn;
|
||||
expression = expression.cast(functions, locals);
|
||||
expression = expression.cast(scriptRoot, locals);
|
||||
|
||||
methodEscape = rtn;
|
||||
loopEscape = rtn;
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
|
@ -94,24 +94,24 @@ public final class SFor extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
locals = Locals.newLocalScope(locals);
|
||||
|
||||
if (initializer != null) {
|
||||
if (initializer instanceof SDeclBlock) {
|
||||
initializer.analyze(functions, locals);
|
||||
initializer.analyze(scriptRoot, locals);
|
||||
} else if (initializer instanceof AExpression) {
|
||||
AExpression initializer = (AExpression)this.initializer;
|
||||
|
||||
initializer.read = false;
|
||||
initializer.analyze(functions, locals);
|
||||
initializer.analyze(scriptRoot, locals);
|
||||
|
||||
if (!initializer.statement) {
|
||||
throw createError(new IllegalArgumentException("Not a statement."));
|
||||
}
|
||||
|
||||
initializer.expected = initializer.actual;
|
||||
this.initializer = initializer.cast(functions, locals);
|
||||
this.initializer = initializer.cast(scriptRoot, locals);
|
||||
} else {
|
||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||
}
|
||||
|
@ -119,8 +119,8 @@ public final class SFor extends AStatement {
|
|||
|
||||
if (condition != null) {
|
||||
condition.expected = boolean.class;
|
||||
condition.analyze(functions, locals);
|
||||
condition = condition.cast(functions, locals);
|
||||
condition.analyze(scriptRoot, locals);
|
||||
condition = condition.cast(scriptRoot, locals);
|
||||
|
||||
if (condition.constant != null) {
|
||||
continuous = (boolean)condition.constant;
|
||||
|
@ -139,21 +139,21 @@ public final class SFor extends AStatement {
|
|||
|
||||
if (afterthought != null) {
|
||||
afterthought.read = false;
|
||||
afterthought.analyze(functions, locals);
|
||||
afterthought.analyze(scriptRoot, locals);
|
||||
|
||||
if (!afterthought.statement) {
|
||||
throw createError(new IllegalArgumentException("Not a statement."));
|
||||
}
|
||||
|
||||
afterthought.expected = afterthought.actual;
|
||||
afterthought = afterthought.cast(functions, locals);
|
||||
afterthought = afterthought.cast(scriptRoot, locals);
|
||||
}
|
||||
|
||||
if (block != null) {
|
||||
block.beginLoop = true;
|
||||
block.inLoop = true;
|
||||
|
||||
block.analyze(functions, locals);
|
||||
block.analyze(scriptRoot, locals);
|
||||
|
||||
if (block.loopEscape && !block.anyContinue) {
|
||||
throw createError(new IllegalArgumentException("Extraneous for loop."));
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.elasticsearch.painless.Location;
|
|||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookup;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.lang.invoke.MethodType;
|
||||
|
@ -127,7 +127,7 @@ public final class SFunction extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (block.statements.isEmpty()) {
|
||||
throw createError(new IllegalArgumentException("Cannot generate an empty function [" + name + "]."));
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ public final class SFunction extends AStatement {
|
|||
locals = Locals.newLocalScope(locals);
|
||||
|
||||
block.lastSource = true;
|
||||
block.analyze(functions, locals);
|
||||
block.analyze(scriptRoot, locals);
|
||||
methodEscape = block.methodEscape;
|
||||
|
||||
if (!methodEscape && returnType != void.class) {
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
|
@ -66,10 +66,10 @@ public final class SIf extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
condition.expected = boolean.class;
|
||||
condition.analyze(functions, locals);
|
||||
condition = condition.cast(functions, locals);
|
||||
condition.analyze(scriptRoot, locals);
|
||||
condition = condition.cast(scriptRoot, locals);
|
||||
|
||||
if (condition.constant != null) {
|
||||
throw createError(new IllegalArgumentException("Extraneous if statement."));
|
||||
|
@ -83,7 +83,7 @@ public final class SIf extends AStatement {
|
|||
ifblock.inLoop = inLoop;
|
||||
ifblock.lastLoop = lastLoop;
|
||||
|
||||
ifblock.analyze(functions, Locals.newLocalScope(locals));
|
||||
ifblock.analyze(scriptRoot, Locals.newLocalScope(locals));
|
||||
|
||||
anyContinue = ifblock.anyContinue;
|
||||
anyBreak = ifblock.anyBreak;
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
|
@ -79,10 +79,10 @@ public final class SIfElse extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
condition.expected = boolean.class;
|
||||
condition.analyze(functions, locals);
|
||||
condition = condition.cast(functions, locals);
|
||||
condition.analyze(scriptRoot, locals);
|
||||
condition = condition.cast(scriptRoot, locals);
|
||||
|
||||
if (condition.constant != null) {
|
||||
throw createError(new IllegalArgumentException("Extraneous if statement."));
|
||||
|
@ -96,7 +96,7 @@ public final class SIfElse extends AStatement {
|
|||
ifblock.inLoop = inLoop;
|
||||
ifblock.lastLoop = lastLoop;
|
||||
|
||||
ifblock.analyze(functions, Locals.newLocalScope(locals));
|
||||
ifblock.analyze(scriptRoot, Locals.newLocalScope(locals));
|
||||
|
||||
anyContinue = ifblock.anyContinue;
|
||||
anyBreak = ifblock.anyBreak;
|
||||
|
@ -110,7 +110,7 @@ public final class SIfElse extends AStatement {
|
|||
elseblock.inLoop = inLoop;
|
||||
elseblock.lastLoop = lastLoop;
|
||||
|
||||
elseblock.analyze(functions, Locals.newLocalScope(locals));
|
||||
elseblock.analyze(scriptRoot, Locals.newLocalScope(locals));
|
||||
|
||||
methodEscape = ifblock.methodEscape && elseblock.methodEscape;
|
||||
loopEscape = ifblock.loopEscape && elseblock.loopEscape;
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.painless.Locals;
|
|||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -58,7 +58,7 @@ public final class SReturn extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (expression == null) {
|
||||
if (locals.getReturnType() != void.class) {
|
||||
throw location.createError(new ClassCastException("Cannot cast from " +
|
||||
|
@ -68,8 +68,8 @@ public final class SReturn extends AStatement {
|
|||
} else {
|
||||
expression.expected = locals.getReturnType();
|
||||
expression.internal = true;
|
||||
expression.analyze(functions, locals);
|
||||
expression = expression.cast(functions, locals);
|
||||
expression.analyze(scriptRoot, locals);
|
||||
expression = expression.cast(scriptRoot, locals);
|
||||
}
|
||||
|
||||
methodEscape = true;
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.elasticsearch.painless.Location;
|
|||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.lookup.PainlessCast;
|
||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
|
@ -68,7 +68,7 @@ final class SSubEachArray extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
// We must store the array and index as variables for securing slots on the stack, and
|
||||
// also add the location offset to make the names unique in case of nested for each loops.
|
||||
array = locals.addVariable(location, expression.actual, "#array" + location.getOffset(), true);
|
||||
|
|
|
@ -32,7 +32,7 @@ import org.elasticsearch.painless.lookup.PainlessCast;
|
|||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||
import org.elasticsearch.painless.lookup.def;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
|
@ -77,7 +77,7 @@ final class SSubEachIterable extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
// We must store the iterator as a variable for securing a slot on the stack, and
|
||||
// also add the location offset to make the name unique in case of nested for each loops.
|
||||
iterator = locals.addVariable(location, Iterator.class, "#itr" + location.getOffset(), true);
|
||||
|
@ -85,7 +85,7 @@ final class SSubEachIterable extends AStatement {
|
|||
if (expression.actual == def.class) {
|
||||
method = null;
|
||||
} else {
|
||||
method = locals.getPainlessLookup().lookupPainlessMethod(expression.actual, false, "iterator", 0);
|
||||
method = scriptRoot.getPainlessLookup().lookupPainlessMethod(expression.actual, false, "iterator", 0);
|
||||
|
||||
if (method == null) {
|
||||
throw createError(new IllegalArgumentException(
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -54,10 +54,10 @@ public final class SThrow extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
expression.expected = Exception.class;
|
||||
expression.analyze(functions, locals);
|
||||
expression = expression.cast(functions, locals);
|
||||
expression.analyze(scriptRoot, locals);
|
||||
expression = expression.cast(scriptRoot, locals);
|
||||
|
||||
methodEscape = true;
|
||||
loopEscape = true;
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
|
||||
import java.util.Collections;
|
||||
|
@ -71,7 +71,7 @@ public final class STry extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
if (block == null) {
|
||||
throw createError(new IllegalArgumentException("Extraneous try statement."));
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ public final class STry extends AStatement {
|
|||
block.inLoop = inLoop;
|
||||
block.lastLoop = lastLoop;
|
||||
|
||||
block.analyze(functions, Locals.newLocalScope(locals));
|
||||
block.analyze(scriptRoot, Locals.newLocalScope(locals));
|
||||
|
||||
methodEscape = block.methodEscape;
|
||||
loopEscape = block.loopEscape;
|
||||
|
@ -95,7 +95,7 @@ public final class STry extends AStatement {
|
|||
catc.inLoop = inLoop;
|
||||
catc.lastLoop = lastLoop;
|
||||
|
||||
catc.analyze(functions, Locals.newLocalScope(locals));
|
||||
catc.analyze(scriptRoot, Locals.newLocalScope(locals));
|
||||
|
||||
methodEscape &= catc.methodEscape;
|
||||
loopEscape &= catc.loopEscape;
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.painless.Globals;
|
|||
import org.elasticsearch.painless.Locals;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||
import org.elasticsearch.painless.ScriptRoot;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
|
@ -67,12 +67,12 @@ public final class SWhile extends AStatement {
|
|||
}
|
||||
|
||||
@Override
|
||||
void analyze(FunctionTable functions, Locals locals) {
|
||||
void analyze(ScriptRoot scriptRoot, Locals locals) {
|
||||
locals = Locals.newLocalScope(locals);
|
||||
|
||||
condition.expected = boolean.class;
|
||||
condition.analyze(functions, locals);
|
||||
condition = condition.cast(functions, locals);
|
||||
condition.analyze(scriptRoot, locals);
|
||||
condition = condition.cast(scriptRoot, locals);
|
||||
|
||||
if (condition.constant != null) {
|
||||
continuous = (boolean)condition.constant;
|
||||
|
@ -90,7 +90,7 @@ public final class SWhile extends AStatement {
|
|||
block.beginLoop = true;
|
||||
block.inLoop = true;
|
||||
|
||||
block.analyze(functions, locals);
|
||||
block.analyze(scriptRoot, locals);
|
||||
|
||||
if (block.loopEscape && !block.anyContinue) {
|
||||
throw createError(new IllegalArgumentException("Extraneous while loop."));
|
||||
|
|
|
@ -459,11 +459,11 @@ public class DefOptimizationTests extends ScriptTestCase {
|
|||
|
||||
public void testLambdaReturnType() {
|
||||
assertBytecodeExists("List l = new ArrayList(); l.removeIf(x -> x < 10)",
|
||||
"synthetic lambda$0(Ljava/lang/Object;)Z");
|
||||
"synthetic lambda$synthetic$0(Ljava/lang/Object;)Z");
|
||||
}
|
||||
|
||||
public void testLambdaArguments() {
|
||||
assertBytecodeExists("List l = new ArrayList(); l.stream().mapToDouble(Double::valueOf).map(x -> x + 1)",
|
||||
"synthetic lambda$0(D)D");
|
||||
"synthetic lambda$synthetic$0(D)D");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ public class FunctionTests extends ScriptTestCase {
|
|||
Exception expected = expectScriptThrows(IllegalArgumentException.class, () -> {
|
||||
exec("void test(int x) {x = 2;} void test(def y) {y = 3;} test()");
|
||||
});
|
||||
assertThat(expected.getMessage(), containsString("already defined"));
|
||||
assertThat(expected.getMessage(), containsString("Illegal duplicate functions"));
|
||||
}
|
||||
|
||||
public void testBadCastFromMethod() {
|
||||
|
|
Loading…
Reference in New Issue