ArgumentsBuilder builder = new ArgumentsBuilder(reference, mixin.getMixin(), new ExpressionEvaluator(referenceScope, problemsHandler, configuration), problemsHandler);
return builder.build();
}
public GeneralBody buildMixinReferenceReplacement(final MixinReference reference, final IScope callerScope, List<FullMixinDefinition> mixins) {
GeneralBody result = new GeneralBody(reference.getUnderlyingStructure());
if (mixins.isEmpty())
return result;
//candidate mixins with information about their default() function use are stored here
final List<BodyCompilationResult> compiledMixins = new ArrayList<BodyCompilationResult>();
for (final FullMixinDefinition fullMixin : mixins) {
final ReusableStructure mixin = fullMixin.getMixin();
final IScope mixinScope = fullMixin.getScope();
// the following needs to run in snapshot because calculateMixinsWorkingScope modifies that scope
InScopeSnapshotRunner.runInLocalDataSnapshot(mixinScope.getParent(), new ITask() {
@Override
public void run() {
// add arguments
IScope mixinArguments = buildMixinsArguments(reference, callerScope, fullMixin);
mixinScope.getParent().add(mixinArguments);
IScope mixinWorkingScope = scopeManipulation.joinIfIndependent(callerScope, mixinScope);
MixinsGuardsValidator guardsValidator = new MixinsGuardsValidator(mixinWorkingScope, problemsHandler, configuration);
GuardValue guardValue = guardsValidator.evaluateGuards(mixin);
if (guardValue != GuardValue.DO_NOT_USE) {
//OPTIMIZATION POSSIBLE: there is no need to compile mixins at this point, some of them are not going to be
//used and create snapshot operation is cheap now. It should be done later on.
BodyCompilationResult compiled = resolveCalledBody(callerScope, fullMixin.getMixin(), mixinWorkingScope, ReturnMode.MIXINS_AND_VARIABLES);
//mark the mixin according to its default() function use
compiled.setGuardValue(guardValue);
//store the mixin as candidate
compiledMixins.add(compiled);
}
}
});
}
// filter out mixins we do not want to use
List<BodyCompilationResult> mixinsToBeUsed = defaultGuardHelper.chooseMixinsToBeUsed(compiledMixins, reference);
// update mixin replacements and update scope with imported variables and mixins
for (BodyCompilationResult compiled : mixinsToBeUsed) {
result.addMembers(compiled.getReplacement());
callerScope.addToDataPlaceholder(compiled.getReturnValues());
}
callerScope.closeDataPlaceholder();
resolveImportance(reference, result);