final JConstructor barConstructor = new JConstructor(nullSourceInfo, barType);
Map<String, JsFunction> functionsByName = new HashMap<String, JsFunction>();
functionsByName.put("JavaClassHierarchySetupUtil.defineClass",
new JsFunction(nullSourceInfo, new JsRootScope(), DEFINE_CLASS_FUNCTION_NAME));
final JsExprStmt defineClassStatement = createDefineClassStatement(barConstructorName);
JsProgram jsProgram = new JsProgram();
jsProgram.setIndexedFunctions(functionsByName);
// Defines the entirety of the JS program being split, to be the one defineClass statement.
jsProgram.getGlobalBlock().getStatements().add(defineClassStatement);
JavaToJavaScriptMap map = new MockJavaToJavaScriptMap() {
@Override
public JMethod nameToMethod(JsName name) {
if (name == barConstructorName) {
// Finds the Bar constructor by name.
return barConstructor;
}
return null;
}
@Override
public JClassType typeForStatement(JsStatement statement) {
if (statement == defineClassStatement) {
// Indicates that Bar is the type associated with the defineClass statement.
return barType;
}
return null;
}
};
fragmentExtractor = new FragmentExtractor(null, jsProgram, map);
constructorLivePredicate = new MockLivenessPredicate() {
@Override
public boolean isLive(JDeclaredType type) {
// Claims that Bar is not made live by the current fragment.
return false;
}
@Override
public boolean isLive(JMethod method) {
// Claims that the bar Constructor *is* made live by the current fragment.
return method == barConstructor;
}
};
}
List<JsStatement> extractedStatements =
fragmentExtractor.extractStatements(constructorLivePredicate, new NothingAlivePredicate());
// Asserts that the single defineClass statement was included in the extraction output.
assertEquals(1, extractedStatements.size());
JsStatement defineClassStatement = extractedStatements.get(0);
assertTrue(defineClassStatement.toString().contains("defineClass"));
}