I'm attempting to implement bracket access overloading. I've almost got it working using the following code.
protected void _computeTypes(final XAbstractFeatureCall featureCall, ITypeComputationState state) {
List<? extends IFeatureLinkingCandidate> candidates = state.getLinkingCandidates(featureCall);
IFeatureLinkingCandidate best = (IFeatureLinkingCandidate) getBestCandidate(candidates);
// If type was unable to be resolved and has one argument of type
// closure it might be bracket access
if (best instanceof UnresolvableFeatureCall)
{
EList<XExpression> args = featureCall.getActualArguments();
if (args.size () == 1 && args.get(0) instanceof XClosure)
{
XExpression expression = ((XClosure) args.get(0)).getExpression();
if (expression instanceof XBlockExpression)
expression = ((XBlockExpression) expression).getExpressions().get(0);
args.clear();
XMemberFeatureCall get = XbaseFactory.eINSTANCE.createXMemberFeatureCall();
EObject parent = featureCall.eContainer();
Object value = parent.eGet(featureCall.eContainingFeature(), false);
if (value instanceof List)
{
List list = (List) value;
int pos = list.indexOf (featureCall);
get.setMemberCallTarget(featureCall);
list.add(pos, get);
} else
{
parent.eSet(featureCall.eContainingFeature(), get);
get.setMemberCallTarget(featureCall);
}
get.getMemberCallArguments().add(expression);
_computeTypes(featureCall, state);
candidates = state.getLinkingCandidatesByName(QualifiedName.create("get"), get);
best = (IFeatureLinkingCandidate) getBestCandidate(candidates);
get.setFeature (best.getFeature());
state.computeTypes(expression);
return;
}
}
if (best.isTypeLiteral()) {
checkTypeParameterNotAllowedAsLiteral(featureCall, (JvmType) best.getFeature(), state);
}
best.applyToComputationState();
}
The problem here is that the 'get' XMemberFeatureCall is never rolled into the resolved types so further calls don't resolve correctly ('list[0]' compiles but 'list[0].charAt(0)' does not). Calling 'best.applyToComputationState()' for the get linking candidates would resolve the type problem, but as the XExpression doesn't have any Nodes back it other problems arise. One possible way to solve the problem would be to create the Nodes and Grammer elements to go along with the XExpressions, but I'm rather at a loss on how to do that.