Skip to content

Commit 2ca7f5e

Browse files
authored
Fix several complex_try raw compile exceptions (#1254)
Fix several raw compile exceptions caused by invalid try/catch MethodScript syntax. Note that the checks performed in this optimization method should eventually be split into postParseRewrite or the try keyword parsing and typechecking. Fixes #1253.
1 parent 78be6f0 commit 2ca7f5e

File tree

1 file changed

+28
-18
lines changed

1 file changed

+28
-18
lines changed

src/main/java/com/laytonsmith/core/functions/Exceptions.java

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -596,28 +596,38 @@ public ParseTree optimizeDynamic(Target t, Environment env,
596596
throws ConfigCompileException, ConfigRuntimeException {
597597
List<CClassType> types = new ArrayList<>();
598598
for(int i = 1; i < children.size() - 1; i += 2) {
599-
// TODO: Eh.. should probably move this check into the keyword, since techincally
600-
// catch (Exception @e = null) { } would work.
601599
ParseTree assign = children.get(i);
602-
if(assign.getChildAt(0).getData().isInstanceOf(CString.TYPE)) {
603-
// This is an unknown exception type, because otherwise it would have been cast to a CClassType
600+
601+
// Check for a container function with a string as first argument, being an unknown type.
602+
if(assign.numberOfChildren() > 0 && assign.getChildAt(0).getData().isInstanceOf(CString.TYPE)) {
604603
throw new ConfigCompileException("Unknown class type: " + assign.getChildAt(0).getData().val(), t);
605604
}
606-
types.add((CClassType) assign.getChildAt(0).getData());
607-
if(CFunction.IsFunction(assign, DataHandling.assign.class)) {
608-
// assign() will validate params 0 and 1
609-
CClassType type = ((CClassType) assign.getChildAt(0).getData());
610-
if(!type.unsafeDoesExtend(CREThrowable.TYPE)) {
611-
throw new ConfigCompileException("The type defined in a catch clause must extend the"
612-
+ " Throwable class.", t);
613-
}
614-
if(!(assign.getChildAt(2).getData() instanceof CNull)) {
615-
throw new ConfigCompileException("Assignments are not allowed in catch clauses", t);
616-
}
617-
continue;
618-
}
619-
throw new ConfigCompileException("Expecting a variable declaration, but instead "
605+
606+
// Validate that the node is an assign with 3 arguments.
607+
if(!CFunction.IsFunction(assign, DataHandling.assign.class) || assign.numberOfChildren() != 3) {
608+
throw new ConfigCompileException("Expecting a variable declaration, but instead "
620609
+ assign.getData().val() + " was found", t);
610+
}
611+
612+
// Validate that the first argument of the assign is a valid type.
613+
if(!(assign.getChildAt(0).getData() instanceof CClassType)) {
614+
throw new ConfigCompileException("Unknown class type: " + assign.getChildAt(0).getData().val(), t);
615+
}
616+
CClassType type = ((CClassType) assign.getChildAt(0).getData());
617+
types.add(type);
618+
619+
// Validate that the exception type extends throwable.
620+
if(!type.unsafeDoesExtend(CREThrowable.TYPE)) {
621+
throw new ConfigCompileException("The type defined in a catch clause must extend the"
622+
+ " Throwable class.", t);
623+
}
624+
625+
// Validate that the assigned value is the by default added null.
626+
// TODO - This check should probably be moved into the keyword,
627+
// since technically catch (Exception @e = null) { } would work.
628+
if(!(assign.getChildAt(2).getData() instanceof CNull)) {
629+
throw new ConfigCompileException("Assignments are not allowed in catch clauses", t);
630+
}
621631
}
622632
for(int i = 0; i < types.size(); i++) {
623633
CClassType t1 = types.get(i);

0 commit comments

Comments
 (0)