|
12 | 12 | import com.laytonsmith.core.Optimizable; |
13 | 13 | import com.laytonsmith.core.ParseTree; |
14 | 14 | import com.laytonsmith.core.Script; |
| 15 | +import com.laytonsmith.core.Optimizable.OptimizationOption; |
15 | 16 | import com.laytonsmith.core.compiler.CompilerEnvironment; |
16 | 17 | import com.laytonsmith.core.compiler.CompilerWarning; |
17 | 18 | import com.laytonsmith.core.compiler.FileOptions; |
|
35 | 36 | import com.laytonsmith.core.constructs.Target; |
36 | 37 | import com.laytonsmith.core.constructs.Token; |
37 | 38 | import com.laytonsmith.core.environments.Environment; |
| 39 | +import com.laytonsmith.core.environments.Environment.EnvironmentImpl; |
38 | 40 | import com.laytonsmith.core.exceptions.CRE.CRECastException; |
39 | 41 | import com.laytonsmith.core.exceptions.CRE.CRENotFoundException; |
40 | 42 | import com.laytonsmith.core.exceptions.CRE.CREThrowable; |
@@ -1206,7 +1208,7 @@ public ParseTree postParseRewrite(ParseTree ast, Environment env, |
1206 | 1208 | @api |
1207 | 1209 | @noprofile |
1208 | 1210 | @hide("This is only used internally by the compiler.") |
1209 | | - public static class __cast__ extends DummyFunction { |
| 1211 | + public static class __cast__ extends DummyFunction implements Optimizable { |
1210 | 1212 |
|
1211 | 1213 | public static final String NAME = "__cast__"; |
1212 | 1214 |
|
@@ -1292,5 +1294,35 @@ public CClassType typecheck(StaticAnalysis analysis, |
1292 | 1294 | // Return type that is being cast to. |
1293 | 1295 | return castToType; |
1294 | 1296 | } |
| 1297 | + |
| 1298 | + @Override |
| 1299 | + public Set<OptimizationOption> optimizationOptions() { |
| 1300 | + return EnumSet.of( |
| 1301 | + OptimizationOption.OPTIMIZE_DYNAMIC, |
| 1302 | + OptimizationOption.CONSTANT_OFFLINE, |
| 1303 | + OptimizationOption.CACHE_RETURN |
| 1304 | + ); |
| 1305 | + } |
| 1306 | + |
| 1307 | + @Override |
| 1308 | + public ParseTree optimizeDynamic(Target t, Environment env, Set<Class<? extends EnvironmentImpl>> envs, |
| 1309 | + List<ParseTree> children, FileOptions fileOptions) |
| 1310 | + throws ConfigCompileException, ConfigRuntimeException, ConfigCompileGroupException { |
| 1311 | + |
| 1312 | + // Optimize __cast__(__cast__(val, type1), type2) to __cast__(val, type1) if the cast to type2 will always |
| 1313 | + // pass given that the cast to type1 has passed. |
| 1314 | + ParseTree valNode = children.get(0); |
| 1315 | + if(valNode.getData() instanceof CFunction cf && cf.getFunction() != null |
| 1316 | + && cf.getFunction().getName().equals(__cast__.NAME) && valNode.numberOfChildren() == 2) { |
| 1317 | + ParseTree typeNode = children.get(1); |
| 1318 | + ParseTree childTypeNode = valNode.getChildAt(1); |
| 1319 | + if(typeNode.getData() instanceof CClassType type |
| 1320 | + && childTypeNode.getData() instanceof CClassType childType |
| 1321 | + && InstanceofUtil.isInstanceof(childType, type, env)) { |
| 1322 | + return valNode; |
| 1323 | + } |
| 1324 | + } |
| 1325 | + return null; |
| 1326 | + } |
1295 | 1327 | } |
1296 | 1328 | } |
0 commit comments