exceptions);
- /**
- * If a function needs a code tree instead of a resolved construct, it should return true here. Most functions will
- * return false for this value.
- *
- * @return
- */
- public boolean useSpecialExec();
-
- /**
- * If useSpecialExec indicates it needs the code tree instead of the resolved constructs, this gets called instead
- * of exec. If execs is needed, exec should return CVoid.
- *
- * @param t
- * @param env
- * @param nodes
- * @return
- */
- public Mixed execs(Target t, Environment env, Script parent, ParseTree... nodes);
-
/**
* Returns an array of example scripts, which are used for documentation purposes.
*
@@ -193,7 +172,7 @@ public ParseTree postParseRewrite(ParseTree ast, Environment env,
public LogLevel profileAt();
/**
- * Returns the message to use when this function gets profiled, if useSpecialExec returns false.
+ * Returns the message to use when this function gets profiled with resolved args.
*
* @param env
* @param args
@@ -202,7 +181,7 @@ public ParseTree postParseRewrite(ParseTree ast, Environment env,
public String profileMessage(Environment env, Mixed... args);
/**
- * Returns the message to use when this function gets profiled, if useSpecialExec returns true.
+ * Returns the message to use when this function gets profiled with unresolved parse tree args.
*
* @param args
* @return
diff --git a/src/main/java/com/laytonsmith/core/functions/IncludeCache.java b/src/main/java/com/laytonsmith/core/functions/IncludeCache.java
index f841f11414..c679bbedda 100644
--- a/src/main/java/com/laytonsmith/core/functions/IncludeCache.java
+++ b/src/main/java/com/laytonsmith/core/functions/IncludeCache.java
@@ -16,10 +16,10 @@
import com.laytonsmith.core.exceptions.CRE.CREIOException;
import com.laytonsmith.core.exceptions.CRE.CREIncludeException;
import com.laytonsmith.core.exceptions.CRE.CRESecurityException;
+import com.laytonsmith.core.exceptions.CancelCommandException;
import com.laytonsmith.core.exceptions.ConfigCompileException;
import com.laytonsmith.core.exceptions.ConfigCompileGroupException;
import com.laytonsmith.core.exceptions.ConfigRuntimeException;
-import com.laytonsmith.core.exceptions.ProgramFlowManipulationException;
import com.laytonsmith.core.profiler.ProfilePoint;
import com.laytonsmith.core.profiler.Profiler;
import java.io.File;
@@ -238,7 +238,7 @@ public void executeAutoIncludes(Environment env, Script s) {
try {
MethodScriptCompiler.execute(
IncludeCache.get(f, env, env.getEnvClasses(), new Target(0, f, 0)), env, null, s);
- } catch (ProgramFlowManipulationException e) {
+ } catch (CancelCommandException e) {
ConfigRuntimeException.HandleUncaughtException(ConfigRuntimeException.CreateUncatchableException(
"Cannot break program flow in auto include files.", e.getTarget()), env);
} catch (ConfigRuntimeException e) {
diff --git a/src/main/java/com/laytonsmith/core/functions/Math.java b/src/main/java/com/laytonsmith/core/functions/Math.java
index a19862d89f..0d94e0a888 100644
--- a/src/main/java/com/laytonsmith/core/functions/Math.java
+++ b/src/main/java/com/laytonsmith/core/functions/Math.java
@@ -10,12 +10,15 @@
import com.laytonsmith.annotations.core;
import com.laytonsmith.annotations.seealso;
import com.laytonsmith.core.ArgumentValidation;
+import com.laytonsmith.core.FlowFunction;
import com.laytonsmith.core.MSVersion;
import com.laytonsmith.core.Optimizable;
import com.laytonsmith.core.ParseTree;
-import com.laytonsmith.core.Script;
import com.laytonsmith.core.SimpleDocumentation;
import com.laytonsmith.core.Static;
+import com.laytonsmith.core.StepAction.Complete;
+import com.laytonsmith.core.StepAction.Evaluate;
+import com.laytonsmith.core.StepAction.StepResult;
import com.laytonsmith.core.compiler.FileOptions;
import com.laytonsmith.core.compiler.OptimizationUtilities;
import com.laytonsmith.core.constructs.CArray;
@@ -517,93 +520,145 @@ public Set optimizationOptions() {
}
/**
- * If we have the case {@code @array[0]++}, we have to increment it as though it were a variable, so we have to do
- * that with execs. This method consolidates the code to do so.
- *
- * @return
+ * Shared state for the inc/dec/postinc/postdec FlowFunction implementations.
*/
- private static Mixed doIncrementDecrement(ParseTree[] nodes,
- Script parent, Environment env, Target t,
- Function func, boolean pre, boolean inc) {
- if(nodes[0].getData() instanceof CFunction && ((CFunction) nodes[0].getData()).hasFunction()) {
+ static class IncDecState {
+ enum Phase { EVAL_ARRAY, EVAL_INDEX, EVAL_DELTA, EVAL_ARG0, EVAL_ARG1 }
+ Phase phase;
+ ParseTree[] nodes;
+ boolean pre;
+ boolean inc;
+ Function func;
+ boolean arrayMode;
+ // Array path fields
+ Mixed array;
+ Mixed index;
+ // Variable path fields
+ Mixed[] args;
+ int argCount;
+
+ @Override
+ public String toString() {
+ return phase.name() + (arrayMode ? " (array)" : " (var)")
+ + (pre ? " pre" : " post") + (inc ? "inc" : "dec");
+ }
+ }
+
+ private static StepResult incDecBegin(Target t, ParseTree[] children,
+ Environment env, Function func, boolean pre, boolean inc) {
+ IncDecState state = new IncDecState();
+ state.nodes = children;
+ state.pre = pre;
+ state.inc = inc;
+ state.func = func;
+
+ if(children[0].getData() instanceof CFunction && ((CFunction) children[0].getData()).hasFunction()) {
Function f;
try {
- f = ((CFunction) nodes[0].getData()).getFunction();
- } catch (ConfigCompileException ex) {
- // This can't really happen, as the compiler would have already caught this
+ f = ((CFunction) children[0].getData()).getFunction();
+ } catch(ConfigCompileException ex) {
throw new Error(ex);
}
- if(f.getName().equals(new ArrayHandling.array_get().getName())) {
- //Ok, so, this is it, we're in charge here.
- //First, pull out the current value. We're gonna do this manually though, and we will actually
- //skip the whole array_get execution.
- ParseTree eval = nodes[0];
- Mixed array = parent.seval(eval.getChildAt(0), env);
- Mixed index = parent.seval(eval.getChildAt(1), env);
- Mixed cdelta = new CInt(1, t);
- if(nodes.length == 2) {
- cdelta = parent.seval(nodes[1], env);
- }
- long delta = ArgumentValidation.getInt(cdelta, t, env);
- //First, error check, then get the old value, and store it in temp.
- if(!(array.isInstanceOf(CArray.TYPE, null, env)) && !(array.isInstanceOf(ArrayAccess.TYPE, null, env))) {
- //Let's just evaluate this like normal with array_get, so it will
- //throw the appropriate exception.
- new ArrayHandling.array_get().exec(t, env, null, array, index);
- throw ConfigRuntimeException.CreateUncatchableException("Shouldn't have gotten here. Please report this error, and how you got here.", t);
- } else if(!(array.isInstanceOf(CArray.TYPE, null, env))) {
- //It's an ArrayAccess type, but we can't use that here, so, throw our
- //own exception.
- throw new CRECastException("Cannot increment/decrement a non-array array"
- + " accessed value. (The value passed in was \"" + array.val() + "\")", t);
- }
- //Ok, we're good. Data types should all be correct.
- CArray myArray = ((CArray) array);
- Mixed value = myArray.get(index, t, env);
-
- //Alright, now let's actually perform the increment, and store that in the array.
- if(value.isInstanceOf(CInt.TYPE, null, env)) {
- CInt newVal;
- if(inc) {
- newVal = new CInt(ArgumentValidation.getInt(value, t, env) + delta, t);
- } else {
- newVal = new CInt(ArgumentValidation.getInt(value, t, env) - delta, t);
- }
- new ArrayHandling.array_set().exec(t, env, null, array, index, newVal);
- if(pre) {
- return newVal;
- } else {
- return value;
- }
- } else if(value.isInstanceOf(CDouble.TYPE, null, env)) {
- CDouble newVal;
- if(inc) {
- newVal = new CDouble(ArgumentValidation.getDouble(value, t, env) + delta, t);
- } else {
- newVal = new CDouble(ArgumentValidation.getDouble(value, t, env) - delta, t);
+ if(f.getName().equals(ArrayHandling.array_get.NAME)) {
+ state.arrayMode = true;
+ state.phase = IncDecState.Phase.EVAL_ARRAY;
+ return new StepResult<>(new Evaluate(children[0].getChildAt(0)), state);
+ }
+ }
+
+ // Variable path — evaluate args with keepIVariable=true
+ state.arrayMode = false;
+ state.argCount = children.length;
+ state.args = new Mixed[state.argCount];
+ state.phase = IncDecState.Phase.EVAL_ARG0;
+ return new StepResult<>(new Evaluate(children[0], null, true), state);
+ }
+
+ private static StepResult incDecChildCompleted(Target t, IncDecState state,
+ Mixed result, Environment env) {
+ if(state.arrayMode) {
+ switch(state.phase) {
+ case EVAL_ARRAY:
+ state.array = result;
+ state.phase = IncDecState.Phase.EVAL_INDEX;
+ return new StepResult<>(new Evaluate(state.nodes[0].getChildAt(1)), state);
+ case EVAL_INDEX:
+ state.index = result;
+ if(state.nodes.length == 2) {
+ state.phase = IncDecState.Phase.EVAL_DELTA;
+ return new StepResult<>(new Evaluate(state.nodes[1]), state);
}
- new ArrayHandling.array_set().exec(t, env, null, array, index, newVal);
- if(pre) {
- return newVal;
- } else {
- return value;
+ return new StepResult<>(new Complete(
+ performArrayIncDec(t, state, new CInt(1, t), env)), state);
+ case EVAL_DELTA:
+ return new StepResult<>(new Complete(
+ performArrayIncDec(t, state, result, env)), state);
+ default:
+ throw ConfigRuntimeException.CreateUncatchableException(
+ "Invalid inc/dec state: " + state.phase, t);
+ }
+ } else {
+ // Variable path
+ switch(state.phase) {
+ case EVAL_ARG0:
+ state.args[0] = result;
+ if(state.argCount > 1) {
+ state.phase = IncDecState.Phase.EVAL_ARG1;
+ return new StepResult<>(new Evaluate(state.nodes[1], null, true), state);
}
- } else {
- throw new CRECastException("Cannot increment/decrement a non numeric value.", t);
- }
+ return new StepResult<>(new Complete(
+ state.func.exec(t, env, null, state.args)), state);
+ case EVAL_ARG1:
+ state.args[1] = result;
+ return new StepResult<>(new Complete(
+ state.func.exec(t, env, null, state.args)), state);
+ default:
+ throw ConfigRuntimeException.CreateUncatchableException(
+ "Invalid inc/dec state: " + state.phase, t);
}
}
- Mixed[] args = new Mixed[nodes.length];
- for(int i = 0; i < args.length; i++) {
- args[i] = parent.eval(nodes[i], env);
+ }
+
+ private static Mixed performArrayIncDec(Target t, IncDecState state, Mixed cdelta, Environment env) {
+ long delta = ArgumentValidation.getInt(cdelta, t, env);
+ if(!(state.array.isInstanceOf(CArray.TYPE, null, env))
+ && !(state.array.isInstanceOf(ArrayAccess.TYPE, null, env))) {
+ new ArrayHandling.array_get().exec(t, env, null, state.array, state.index);
+ throw ConfigRuntimeException.CreateUncatchableException(
+ "Shouldn't have gotten here. Please report this error, and how you got here.", t);
+ } else if(!(state.array.isInstanceOf(CArray.TYPE, null, env))) {
+ throw new CRECastException("Cannot increment/decrement a non-array array"
+ + " accessed value. (The value passed in was \"" + state.array.val() + "\")", t);
+ }
+ CArray myArray = ((CArray) state.array);
+ Mixed value = myArray.get(state.index, t, env);
+ if(value.isInstanceOf(CInt.TYPE, null, env)) {
+ CInt newVal;
+ if(state.inc) {
+ newVal = new CInt(ArgumentValidation.getInt(value, t, env) + delta, t);
+ } else {
+ newVal = new CInt(ArgumentValidation.getInt(value, t, env) - delta, t);
+ }
+ new ArrayHandling.array_set().exec(t, env, null, state.array, state.index, newVal);
+ return state.pre ? newVal : value;
+ } else if(value.isInstanceOf(CDouble.TYPE, null, env)) {
+ CDouble newVal;
+ if(state.inc) {
+ newVal = new CDouble(ArgumentValidation.getDouble(value, t, env) + delta, t);
+ } else {
+ newVal = new CDouble(ArgumentValidation.getDouble(value, t, env) - delta, t);
+ }
+ new ArrayHandling.array_set().exec(t, env, null, state.array, state.index, newVal);
+ return state.pre ? newVal : value;
+ } else {
+ throw new CRECastException("Cannot increment/decrement a non numeric value.", t);
}
- return func.exec(t, env, null, args);
}
@api
@seealso({dec.class, postdec.class, postinc.class})
@OperatorPreferred("++")
- public static class inc extends AbstractFunction implements Optimizable {
+ public static class inc extends AbstractFunction implements Optimizable, FlowFunction {
public static final String NAME = "inc";
@@ -618,13 +673,14 @@ public Integer[] numArgs() {
}
@Override
- public boolean useSpecialExec() {
- return true;
+ public StepResult begin(Target t, ParseTree[] children, Environment env) {
+ return incDecBegin(t, children, env, this, true, true);
}
@Override
- public Mixed execs(Target t, Environment env, Script parent, ParseTree... nodes) {
- return doIncrementDecrement(nodes, parent, env, t, this, true, true);
+ public StepResult childCompleted(Target t, IncDecState state,
+ Mixed result, Environment env) {
+ return incDecChildCompleted(t, state, result, env);
}
@Override
@@ -723,7 +779,7 @@ public Set optimizationOptions() {
@api
@seealso({postdec.class, inc.class, dec.class})
@OperatorPreferred("++")
- public static class postinc extends AbstractFunction implements Optimizable {
+ public static class postinc extends AbstractFunction implements Optimizable, FlowFunction {
public static final String NAME = "postinc";
@@ -738,13 +794,14 @@ public Integer[] numArgs() {
}
@Override
- public boolean useSpecialExec() {
- return true;
+ public StepResult begin(Target t, ParseTree[] children, Environment env) {
+ return incDecBegin(t, children, env, this, false, true);
}
@Override
- public Mixed execs(Target t, Environment env, Script parent, ParseTree... nodes) {
- return Math.doIncrementDecrement(nodes, parent, env, t, this, false, true);
+ public StepResult childCompleted(Target t, IncDecState state,
+ Mixed result, Environment env) {
+ return incDecChildCompleted(t, state, result, env);
}
@Override
@@ -853,7 +910,7 @@ public ExampleScript[] examples() throws ConfigCompileException {
@api
@seealso({inc.class, postdec.class, postinc.class})
@OperatorPreferred("--")
- public static class dec extends AbstractFunction implements Optimizable {
+ public static class dec extends AbstractFunction implements Optimizable, FlowFunction {
public static final String NAME = "dec";
@@ -868,13 +925,14 @@ public Integer[] numArgs() {
}
@Override
- public boolean useSpecialExec() {
- return true;
+ public StepResult begin(Target t, ParseTree[] children, Environment env) {
+ return incDecBegin(t, children, env, this, true, false);
}
@Override
- public Mixed execs(Target t, Environment env, Script parent, ParseTree... nodes) {
- return doIncrementDecrement(nodes, parent, env, t, this, true, false);
+ public StepResult childCompleted(Target t, IncDecState state,
+ Mixed result, Environment env) {
+ return incDecChildCompleted(t, state, result, env);
}
@Override
@@ -973,7 +1031,7 @@ public ExampleScript[] examples() throws ConfigCompileException {
@api
@seealso({postinc.class, inc.class, dec.class})
@OperatorPreferred("--")
- public static class postdec extends AbstractFunction implements Optimizable {
+ public static class postdec extends AbstractFunction implements Optimizable, FlowFunction {
public static final String NAME = "postdec";
@@ -988,13 +1046,14 @@ public Integer[] numArgs() {
}
@Override
- public boolean useSpecialExec() {
- return true;
+ public StepResult begin(Target t, ParseTree[] children, Environment env) {
+ return incDecBegin(t, children, env, this, false, false);
}
@Override
- public Mixed execs(Target t, Environment env, Script parent, ParseTree... nodes) {
- return doIncrementDecrement(nodes, parent, env, t, this, false, false);
+ public StepResult childCompleted(Target t, IncDecState state,
+ Mixed result, Environment env) {
+ return incDecChildCompleted(t, state, result, env);
}
@Override
diff --git a/src/main/java/com/laytonsmith/core/functions/Meta.java b/src/main/java/com/laytonsmith/core/functions/Meta.java
index 1bb57c5915..e9ee6399b1 100644
--- a/src/main/java/com/laytonsmith/core/functions/Meta.java
+++ b/src/main/java/com/laytonsmith/core/functions/Meta.java
@@ -16,6 +16,7 @@
import com.laytonsmith.annotations.seealso;
import com.laytonsmith.core.AliasCore;
import com.laytonsmith.core.ArgumentValidation;
+import com.laytonsmith.core.FlowFunction;
import com.laytonsmith.core.MSLog;
import com.laytonsmith.core.MSVersion;
import com.laytonsmith.core.LogLevel;
@@ -25,6 +26,9 @@
import com.laytonsmith.core.Prefs;
import com.laytonsmith.core.Script;
import com.laytonsmith.core.Static;
+import com.laytonsmith.core.StepAction.Complete;
+import com.laytonsmith.core.StepAction.Evaluate;
+import com.laytonsmith.core.StepAction.StepResult;
import com.laytonsmith.core.compiler.BranchStatement;
import com.laytonsmith.core.compiler.FileOptions;
import com.laytonsmith.core.compiler.VariableScope;
@@ -713,7 +717,8 @@ public Set optimizationOptions() {
}
@api(environments = {CommandHelperEnvironment.class, GlobalEnv.class})
- public static class scriptas extends AbstractFunction implements VariableScope, BranchStatement {
+ public static class scriptas extends AbstractFunction implements VariableScope, BranchStatement,
+ FlowFunction {
@Override
public String getName() {
@@ -764,32 +769,70 @@ public Mixed exec(Target t, Environment env, GenericParameters generics, Mixed..
return null;
}
+ static class ScriptasState {
+ enum Phase { EVAL_SENDER, EVAL_LABEL, EVAL_BODY }
+ Phase phase = Phase.EVAL_SENDER;
+ ParseTree[] children;
+ MCCommandSender originalSender;
+ String originalLabel;
+
+ ScriptasState(ParseTree[] children) {
+ this.children = children;
+ }
+
+ @Override
+ public String toString() {
+ return phase.name();
+ }
+ }
+
@Override
- public Mixed execs(Target t, Environment env, Script parent, ParseTree... nodes) throws ConfigRuntimeException {
- String senderName = parent.seval(nodes[0], env).val();
- MCCommandSender sender = Static.GetCommandSender(senderName, t);
- MCCommandSender originalSender = env.getEnv(CommandHelperEnvironment.class).GetCommandSender();
- int offset = 0;
- String originalLabel = env.getEnv(GlobalEnv.class).GetLabel();
- if(nodes.length == 3) {
- offset++;
- String label = parent.seval(nodes[1], env).val();
- env.getEnv(GlobalEnv.class).SetLabel(label);
- } else {
- env.getEnv(GlobalEnv.class).SetLabel(parent.getLabel());
+ public StepResult begin(Target t, ParseTree[] children, Environment env) {
+ ScriptasState state = new ScriptasState(children);
+ return new StepResult<>(new Evaluate(children[0]), state);
+ }
+
+ @Override
+ public StepResult childCompleted(Target t, ScriptasState state,
+ Mixed result, Environment env) {
+ switch(state.phase) {
+ case EVAL_SENDER -> {
+ MCCommandSender sender = Static.GetCommandSender(result.val(), t);
+ state.originalSender = env.getEnv(CommandHelperEnvironment.class).GetCommandSender();
+ state.originalLabel = env.getEnv(GlobalEnv.class).GetLabel();
+ env.getEnv(CommandHelperEnvironment.class).SetCommandSender(sender);
+ if(state.children.length == 3) {
+ state.phase = ScriptasState.Phase.EVAL_LABEL;
+ return new StepResult<>(new Evaluate(state.children[1]), state);
+ } else {
+ // No explicit label — use parent script's label
+ // (enforceLabelPermissions is called in execs but we can't access
+ // parent here; the label is already set from the enclosing scope)
+ state.phase = ScriptasState.Phase.EVAL_BODY;
+ return new StepResult<>(new Evaluate(state.children[1]), state);
+ }
+ }
+ case EVAL_LABEL -> {
+ env.getEnv(GlobalEnv.class).SetLabel(result.val());
+ state.phase = ScriptasState.Phase.EVAL_BODY;
+ return new StepResult<>(new Evaluate(state.children[2]), state);
+ }
+ case EVAL_BODY -> {
+ return new StepResult<>(new Complete(CVoid.VOID), state);
+ }
}
- env.getEnv(CommandHelperEnvironment.class).SetCommandSender(sender);
- parent.enforceLabelPermissions(env);
- ParseTree tree = nodes[1 + offset];
- parent.eval(tree, env);
- env.getEnv(CommandHelperEnvironment.class).SetCommandSender(originalSender);
- env.getEnv(GlobalEnv.class).SetLabel(originalLabel);
- return CVoid.VOID;
+ throw ConfigRuntimeException.CreateUncatchableException(
+ "Invalid scriptas state: " + state.phase, t);
}
@Override
- public boolean useSpecialExec() {
- return true;
+ public void cleanup(Target t, ScriptasState state, Environment env) {
+ if(state != null) {
+ if(state.originalSender != null) {
+ env.getEnv(CommandHelperEnvironment.class).SetCommandSender(state.originalSender);
+ env.getEnv(GlobalEnv.class).SetLabel(state.originalLabel);
+ }
+ }
}
@Override
diff --git a/src/main/java/com/laytonsmith/core/functions/ObjectManagement.java b/src/main/java/com/laytonsmith/core/functions/ObjectManagement.java
index 6d8053aead..4d5ae8da58 100644
--- a/src/main/java/com/laytonsmith/core/functions/ObjectManagement.java
+++ b/src/main/java/com/laytonsmith/core/functions/ObjectManagement.java
@@ -8,10 +8,13 @@
import com.laytonsmith.core.ArgumentValidation;
import com.laytonsmith.core.natives.interfaces.Callable;
import com.laytonsmith.core.FullyQualifiedClassName;
+import com.laytonsmith.core.FlowFunction;
import com.laytonsmith.core.MSVersion;
import com.laytonsmith.core.Optimizable;
import com.laytonsmith.core.ParseTree;
-import com.laytonsmith.core.Script;
+import com.laytonsmith.core.StepAction.Complete;
+import com.laytonsmith.core.StepAction.Evaluate;
+import com.laytonsmith.core.StepAction.StepResult;
import com.laytonsmith.core.UnqualifiedClassName;
import com.laytonsmith.core.compiler.CompilerEnvironment;
import com.laytonsmith.core.compiler.FileOptions;
@@ -109,7 +112,7 @@ public Version since() {
@api
@hide("Not meant for normal use")
- public static class define_object extends AbstractFunction implements Optimizable {
+ public static class define_object extends AbstractFunction implements FlowFunction, Optimizable {
@Override
public Class extends CREThrowable>[] thrown() {
@@ -127,13 +130,19 @@ public Boolean runAsync() {
}
@Override
- public boolean useSpecialExec() {
- return true;
+ public Mixed exec(Target t, Environment env, GenericParameters generics, Mixed... args) throws ConfigRuntimeException {
+ throw new Error();
}
@Override
- public Mixed exec(Target t, Environment env, GenericParameters generics, Mixed... args) throws ConfigRuntimeException {
- throw new Error();
+ public StepResult begin(Target t, ParseTree[] children, Environment env) {
+ doDefineObject(t, env, children);
+ return new StepResult<>(new Complete(CVoid.VOID), null);
+ }
+
+ @Override
+ public StepResult childCompleted(Target t, Void state, Mixed result, Environment env) {
+ throw new Error("define_object does not evaluate children");
}
/**
@@ -207,8 +216,8 @@ private Mixed evaluateMixed(ParseTree data, Target t) {
return data.getData();
}
- @Override
- public Mixed execs(Target t, Environment env, Script parent, ParseTree... nodes) {
+
+ private void doDefineObject(Target t, Environment env, ParseTree... nodes) {
// 0 - Access Modifier
AccessModifier accessModifier = ArgumentValidation.getEnum(evaluateStringNoNull(nodes[0], t, env),
AccessModifier.class, t);
@@ -372,7 +381,6 @@ public Mixed execs(Target t, Environment env, Script parent, ParseTree... nodes)
}
}
- return CVoid.VOID;
}
@Override
@@ -380,8 +388,7 @@ public ParseTree optimizeDynamic(Target t, Environment env,
Set> envs,
List children, FileOptions fileOptions)
throws ConfigCompileException, ConfigRuntimeException {
- // Do the same thing as execs, but remove this call
- execs(t, env, null, children.toArray(new ParseTree[children.size()]));
+ doDefineObject(t, env, children.toArray(new ParseTree[children.size()]));
return REMOVE_ME;
}
@@ -426,7 +433,7 @@ public Set