/** {@inheritDoc} */
@Override
public Void visit_Expr_Application(Application application, Object arg) {
Expr consumerExpr = application.getNthExpression(0);
Name.Qualifiable consumerName = getTopLevelConsumerName(consumerExpr);
FunctionalAgent consumerEntity = null;
if(consumerName != null && consumerExpr instanceof Var) {
consumerEntity = super.getFunctionalAgent(consumerName);
}
// Process the standard case where an expression with a statically-identifiable consumer name
// accepts some arguments
if(consumerName != null) {
for(int i = 1; i < application.getNExpressions(); i++) {
processArgumentExpression(consumerName, i, application.getNthExpression(i));
}
}
// Special cases for apply and compose calls
if(consumerEntity != null) {
// `apply arg1 arg2` is effectively `arg1 arg2`
if(consumerEntity.getName().equals(APPLY)) {
Expr effectiveConsumer = application.getNthExpression(1);
Name.Qualifiable effectiveConsumerName = getTopLevelConsumerName(effectiveConsumer);
if(effectiveConsumerName != null) {
processArgumentExpression(effectiveConsumerName, 1, application.getNthExpression(2));
}
}
// `compose arg1 arg2 arg3 ... argn` is effectively `arg1 (arg2 arg3 ... argn)`
if(consumerEntity.getName().equals(COMPOSE)) {
Expr effectiveConsumer1 = application.getNthExpression(1);
Name.Qualifiable effectiveConsumer1Name = getTopLevelConsumerName(effectiveConsumer1);
Expr effectiveConsumer2 = application.getNthExpression(2);
Name.Qualifiable effectiveConsumer2Name = getTopLevelConsumerName(effectiveConsumer2);
if(effectiveConsumer1Name != null) {
processArgumentExpression(effectiveConsumer1Name, 1, effectiveConsumer2);
}