I'm using JavaCC for the first time and I'm noticing it's generating a lot of dead code. There are many lines that look like (pardon the spacing, it's automatic):
{if ("" != null) return result;}
throw new Error("Missing return statement in function");
}
Is it possible to avoid generating this dead code? It causes tens of compiler warnings that are hopefully avoidable.
Thanks!
Here's a full minimal example from the .jj file:
Statement UseStatement():
{
String dbName;
}
{
<USE> dbName=DbObjectName()
{
return new UseStatement(dbName);
}
}
Which generates:
final public Statement UseStatement() throws ParseException {String dbName;
jj_consume_token(USE);
dbName = DbObjectName();
{if ("" != null) return new UseStatement(dbName);}
throw new Error("Missing return statement in function");
}
Additionally JavaCC is generating a ParserTokenManager file which throws a TokenMgrError - but the code doesn't compile. It declares a protected int curChar
where it should declare it a char
. Googling this phrase shows many examples where it is correctly declared a char
- is this just a lot of people hand-editing the result?
I went to the source and to prevent the dead code you have to trigger Options.isLegacyExceptionHandling
.
// Add if statement to prevent subsequent code generated
// from being dead code.
// NB: eclipse now detects 'if (true)' as dead code, so use the more complicated
// 'if ("" != null)'
if (inAction && (Options.isLegacyExceptionHandling()) ) {
t.image = "{if (\"\" != null) return";
jumpPatched = true;
}
which then triggers:
if (p.isJumpPatched() && !voidReturn) {
if (isJavaDialect) {
// TODO :: I don't think we need to throw an Error/Exception to mark that a return statement is missing as the compiler will flag this error automatically
if (Options.isLegacyExceptionHandling()) {
codeGenerator.genCodeLine(" throw new "+(Options.isLegacyExceptionHandling() ? "Error" : "RuntimeException")+"(\"Missing return statement in function\");");
}
} else {
codeGenerator.genCodeLine(" throw \"Missing return statement in function\";");
}
}
Legacy exception handling is a derived option that is false only when JAVA_TEMPLATE_TYPE=modern
. The only way to get it set correctly is to include it in the options
block in the .jj file as so:
options {
JAVA_TEMPLATE_TYPE="modern";
}
In theory it is also settable via the command line options, but as of this writing it's actually impossible to set the derived option before the command line arguments are parsed (#25)