String[] mainClassNames, JProgram program) throws UnableToCompleteException {
Event findEntryPointsEvent = SpeedTracerLogger.start(CompilerEventType.FIND_ENTRY_POINTS);
JMethod bootStrapMethod = program.getIndexedMethod("EntryMethodHolder.init");
JMethodBody body = (JMethodBody) bootStrapMethod.getBody();
JBlock block = body.getBlock();
SourceInfo info = block.getSourceInfo().makeChild();
// Also remember $entry, which we'll handle specially in GenerateJsAst
JMethod registerEntry = program.getIndexedMethod("Impl.registerEntry");
program.addEntryMethod(registerEntry);
for (String mainClassName : mainClassNames) {
block.addStmt(makeStatsCalls(info, program, mainClassName));
JDeclaredType mainType = program.getFromTypeMap(mainClassName);
if (mainType == null) {
logger.log(TreeLogger.ERROR, "Could not find module entry point class '" + mainClassName
+ "'", null);
throw new UnableToCompleteException();
}
JMethod mainMethod = findMainMethod(mainType);
if (mainMethod != null && mainMethod.isStatic()) {
JMethodCall onModuleLoadCall = new JMethodCall(info, null, mainMethod);
block.addStmt(onModuleLoadCall.makeStatement());
continue;
}
// Couldn't find a static main method; must rebind the class
String[] resultTypeNames = rpo.getAllPossibleRebindAnswers(logger, mainClassName);
List<JClassType> resultTypes = new ArrayList<JClassType>();
List<JExpression> entryCalls = new ArrayList<JExpression>();
for (String resultTypeName : resultTypeNames) {
JDeclaredType resultType = program.getFromTypeMap(resultTypeName);
if (resultType == null) {
logger.log(TreeLogger.ERROR, "Could not find module entry point class '" + resultTypeName
+ "' after rebinding from '" + mainClassName + "'", null);
throw new UnableToCompleteException();
}
JMethodCall onModuleLoadCall =
createReboundModuleLoad(logger, info, resultType, mainClassName, bootStrapMethod
.getEnclosingType());
resultTypes.add((JClassType) resultType);
entryCalls.add(onModuleLoadCall);
}
if (resultTypes.size() == 1) {
block.addStmt(entryCalls.get(0).makeStatement());
} else {
JReboundEntryPoint reboundEntryPoint =
new JReboundEntryPoint(info, mainType, resultTypes, entryCalls);
block.addStmt(reboundEntryPoint);
}
}
program.addEntryMethod(bootStrapMethod);
findEntryPointsEvent.end();
}