diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Switch.java b/src/main/java/com/sk89q/worldedit/expression/runtime/Switch.java index 4cea9ae55..c3e2c4194 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Switch.java +++ b/src/main/java/com/sk89q/worldedit/expression/runtime/Switch.java @@ -20,6 +20,7 @@ package com.sk89q.worldedit.expression.runtime; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -118,7 +119,50 @@ public class Switch extends Node implements RValue { @Override public RValue optimize() throws EvaluationException { + final RValue optimizedParameter = parameter.optimize(); final List newSequence = new ArrayList(); + + if (optimizedParameter instanceof Constant) { + final double parameter = optimizedParameter.getValue(); + + final Integer index = valueMap.get(parameter); + if (index == null) { + return defaultCase == null ? new Constant(getPosition(), 0.0) : defaultCase.optimize(); + } + + boolean breakDetected = false; + for (int i = index; i < caseStatements.length && !breakDetected ; ++i) { + final RValue invokable = caseStatements[i].optimize(); + + if (invokable instanceof Sequence) { + for (RValue subInvokable : ((Sequence) invokable).sequence) { + if (subInvokable instanceof Break) { + breakDetected = true; + break; + } + + newSequence.add(subInvokable); + } + } else { + newSequence.add(invokable); + } + } + + if (defaultCase != null && !breakDetected) { + final RValue invokable = defaultCase.optimize(); + + if (invokable instanceof Sequence) { + for (RValue subInvokable : ((Sequence) invokable).sequence) { + newSequence.add(subInvokable); + } + } else { + newSequence.add(invokable); + } + } + + return new Switch(getPosition(), optimizedParameter, Collections.singletonMap(parameter, 0), newSequence, null); + } + final Map newValueMap = new HashMap(); Map backMap = new HashMap(); @@ -143,6 +187,6 @@ public class Switch extends Node implements RValue { } } - return new Switch(getPosition(), parameter.optimize(), newValueMap, newSequence, defaultCase.optimize()); + return new Switch(getPosition(), optimizedParameter, newValueMap, newSequence, defaultCase.optimize()); } }