Overloaded method determination [message #1755794] |
Wed, 08 March 2017 04:17  |
Eclipse User |
|
|
|
Hello,
A few days ago I noticed that the overloaded methods aren't working well. If I want to Ctrl+click or hovering on the function call, it jumps/shows the first occurence of the function, no matter whether arguments are correct or not.
I recognized, SimpleNameProvider gets the wrong EObject as parameter in getFullyQualifiedName method.
I am looking for a solution in which I can specify the correct function. Could you help me, please?
(Is it possible, that I should change something in the .xtext file in order to make it work?)
Thanks for your help.
|
|
|
|
|
|
|
|
|
|
|
|
|
Re: Overloaded method determination [message #1755871 is a reply to message #1755846] |
Wed, 08 March 2017 13:25   |
Eclipse User |
|
|
|
Idea: Store the signature infos in the xtext index / scope entries and adapt scoping.
lets start with a way way way less complicated grammar
Model:
functions+=Function*
calls+=Call*;
Function:
"func" name=ID '(' (types+=DeclaredParameter (',' types+=DeclaredParameter)*)? ')' ':' returnType=Type
;
DeclaredParameter:
name=ID ":" type=Type
;
Expression:
Literal | Call
;
Literal:
IntegerLiteral | StringLiteral
;
IntegerLiteral:
value=INT
;
StringLiteral:
value=STRING
;
enum Type: String | Integer;
Call:
func=[Function] '(' (params+=Expression (',' params+=Expression)*)? ')'
;
// indexing
class MyDslResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy {
private final static Logger LOG = Logger.getLogger(MyDslResourceDescriptionStrategy);
override createEObjectDescriptions(EObject eObject, IAcceptor<IEObjectDescription> acceptor) {
if (eObject instanceof Function) {
if (getQualifiedNameProvider() === null)
return false;
try {
val QualifiedName qualifiedName = getQualifiedNameProvider().getFullyQualifiedName(eObject);
if (qualifiedName !== null) {
val userData = newHashMap
if (eObject.returnType !== null) {
userData.put("RETURN_TYPE", eObject.returnType.literal)
}
userData.put("PARAM_TYPES", eObject.types.map[type.literal].join(","))
acceptor.accept(EObjectDescription.create(qualifiedName, eObject, userData));
}
} catch (Exception exc) {
LOG.error(exc.getMessage(), exc);
}
return true;
}
return super.createEObjectDescriptions(eObject, acceptor)
}
}
// scope entries for local file
class MyDslImportedNamespaceAwareLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider {
override protected internalGetAllDescriptions(Resource resource) {
var Iterable<EObject> allContents = new Iterable<EObject>() {
override Iterator<EObject> iterator() {
return EcoreUtil.getAllContents(resource, false)
}
}
var Iterable<IEObjectDescription> allDescriptions = scopedElementsFor(allContents, qualifiedNameProvider)
return new MultimapBasedSelectable(allDescriptions)
}
def static <T extends EObject> Iterable<IEObjectDescription> scopedElementsFor(Iterable<? extends T> elements,
Function<T, QualifiedName> nameComputation) {
var Iterable<IEObjectDescription> transformed = Iterables.transform(elements, [ T from |
val QualifiedName qualifiedName = nameComputation.apply(from)
if (qualifiedName !== null) {
if (from instanceof org.xtext.example.mydsl1.myDsl.Function) {
val userData = newHashMap
if (from.returnType !== null) {
userData.put("RETURN_TYPE", from.returnType.literal)
}
userData.put("PARAM_TYPES", from.types.map[type.literal].join(","))
return new EObjectDescription(qualifiedName, from, userData)
}
return new EObjectDescription(qualifiedName, from, null)
}
])
return Iterables.filter(transformed, Predicates.notNull())
}
}
// scope provider
class MyDslScopeProvider extends AbstractMyDslScopeProvider {
override getScope(EObject context, EReference reference) {
if (reference === MyDslPackage.Literals.CALL__FUNC) {
if (context instanceof Call) {
val actualSignature =
context.params.map[
p |
if (p instanceof StringLiteral) {
return Type.STRING.literal
}
if (p instanceof IntegerLiteral) {
return Type.INTEGER.literal
}
if (p instanceof Call) {
return p.func.returnType.literal
}
].join(",")
return new FilteringScope(delegateGetScope(context, reference)) [
val sig = getUserData("PARAM_TYPES")
if (sig !== null) {
return actualSignature == sig
}
return true
]
}
}
super.getScope(context, reference)
}
}
// bindings
class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
def Class<? extends IDefaultResourceDescriptionStrategy> bindIDefaultResourceDescriptionStrategy() {
MyDslResourceDescriptionStrategy
}
override configureIScopeProviderDelegate(Binder binder) {
binder.bind(IScopeProvider).annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(
MyDslImportedNamespaceAwareLocalScopeProvider);
}
}
|
|
|
Re: Overloaded method determination [message #1756025 is a reply to message #1755871] |
Fri, 10 March 2017 03:55  |
Eclipse User |
|
|
|
Wow, this solution is working, thank you for your help!
I just tried it and I believe, that adaptation to our language will be hard (e.g. I'm afraid of rules that "returns Expression"). Anyway, it's my turn, I need to think over all of this, that takes some time.
You, sir, are really great.
|
|
|
Powered by
FUDForum. Page generated in 0.03977 seconds