JClassType jsoType = program.getJavaScriptObject();
SourceInfo sourceInfo = jsoType.getSourceInfo();
// Create the new method.
String name = objectMethod.getName() + "__devirtual$";
JMethod newMethod = program.createMethod(sourceInfo.makeChild(
JsoDevirtualizer.class, "Devirtualized method"), name.toCharArray(),
jsoType, objectMethod.getType(), false, true, true, false, false);
// Setup parameters.
JParameter thisParam = program.createParameter(sourceInfo,
"this$static".toCharArray(), program.getTypeJavaLangObject(), true,
true, newMethod);
for (JParameter oldParam : objectMethod.getParams()) {
program.createParameter(sourceInfo, oldParam.getName().toCharArray(),
oldParam.getType(), true, false, newMethod);
}
newMethod.freezeParamTypes();
// Build from bottom up.
JMethodCall condition = new JMethodCall(sourceInfo, null,
isJavaObjectMethod);
condition.addArg(new JParameterRef(sourceInfo, thisParam));
JMethodCall thenValue = new JMethodCall(sourceInfo, new JParameterRef(
sourceInfo, thisParam), objectMethod);
for (JParameter param : newMethod.getParams()) {
if (param != thisParam) {
thenValue.addArg(new JParameterRef(sourceInfo, param));
}
}
JMethodCall elseValue = new JMethodCall(sourceInfo, null, jsoImpl);
for (JParameter param : newMethod.getParams()) {
elseValue.addArg(new JParameterRef(sourceInfo, param));
}
JConditional conditional = new JConditional(sourceInfo, objectMethod.getType(),
condition, thenValue, elseValue);
JReturnStatement returnStatement = new JReturnStatement(sourceInfo,
conditional);
((JMethodBody) newMethod.getBody()).getBlock().addStmt(returnStatement);
return newMethod;
}