|
|
|
Re: Customize IQualifiedNameProvider Problem [message #1514884 is a reply to message #1514843] |
Wed, 17 December 2014 17:42 |
Alexander R Messages: 211 Registered: July 2013 |
Senior Member |
|
|
Hi,
for the following example:
class B{}
class A {
a:String;
myOp(age: B, name:String){
this.a;
}}
All the QualifiedNames looks like this:
B,
A,
A.a,
A.myOp(age[0..1],String[0..1]):void,
A.myOp(age[0..1],String[0..1]):void.age,
A.myOp(age[0..1],String[0..1]):void.name
For an operation I just create a operation signature. ( for referenced types of parameters I just use the paramterame)
~Alex
[Updated on: Wed, 17 December 2014 17:46] Report message to a moderator
|
|
|
|
|
|
|
|
|
|
|
|
Re: Customize IQualifiedNameProvider Problem [message #1515624 is a reply to message #1515522] |
Thu, 18 December 2014 08:16 |
|
you can adapt IDefaultResourceDescriptionStrategy and (for local elements) ImportedNamespaceAwareLocalScopeProvider
to store the signature in the user data in the index and use that userdata in the scoping to filter
of course this will not work in content assist since you dont know the params yet
do you care about content assist and error messages as well?
Depending on That you may adapt DefaultLinkingService and Validator as well
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
|
Re: Customize IQualifiedNameProvider Problem [message #1515752 is a reply to message #1515717] |
Thu, 18 December 2014 10:41 |
|
yes you can filter within the scope provider
have a look at
Model:
elements+=Element*;
Element:
Operation | Call
;
enum DataType:
string | int | boolean
;
Operation:
"def" name=ID "(" ( parameter+=Parameter ("," parameter+=Parameter )*)? ")"
;
Parameter:
type=DataType name=ID
;
Call:
"call" operation=[Operation] "(" (parameter+=Expression (","parameter+=Expression)*)? ")"
;
Expression:
StringLiteral | IntLiteral | BooleanLiteral
;
StringLiteral:
value=STRING
;
IntLiteral:
value=INT
;
BooleanLiteral:
{BooleanLiteral} (value?='true' | 'false')
;
class MyDslImportedNamespaceAwareLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider {
override ISelectable internalGetAllDescriptions(Resource resource) {
val Iterable<EObject> allContents = new Iterable<EObject>(){
override Iterator<EObject> iterator() {
return EcoreUtil.getAllContents(resource, false);
}
};
val Iterable<IEObjectDescription> allDescriptions = scopedElementsFor(allContents, qualifiedNameProvider);
return new MultimapBasedSelectable(allDescriptions);
}
def <T extends EObject> Iterable<IEObjectDescription> scopedElementsFor(Iterable<? extends T> elements,
Function<T, QualifiedName> nameComputation) {
val Iterable<IEObjectDescription> transformed = Iterables.transform(elements,
new Function<T, IEObjectDescription>() {
override IEObjectDescription apply(T from) {
val QualifiedName qualifiedName = nameComputation.apply(from);
var Map<String,String> data = null
if (from instanceof Operation) {
data = <String,String>newHashMap("signature" -> from.parameter.map[type.literal].join(","))
}
if (qualifiedName != null)
return new EObjectDescription(qualifiedName, from, data);
return null;
}
});
return Iterables.filter(transformed, Predicates.notNull());
}
}
class MyDslResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy {
private final static Logger LOG = Logger.getLogger(MyDslResourceDescriptionStrategy)
override createEObjectDescriptions(EObject eObject, IAcceptor<IEObjectDescription> acceptor) {
if (eObject instanceof Operation) {
createOperationDescriptions(eObject,acceptor)
}
super.createEObjectDescriptions(eObject, acceptor)
}
def boolean createOperationDescriptions(Operation eObject, IAcceptor<IEObjectDescription> acceptor) {
if (getQualifiedNameProvider() == null)
return false;
try {
val QualifiedName qualifiedName = getQualifiedNameProvider().getFullyQualifiedName(eObject);
if (qualifiedName != null) {
val data = newHashMap
data.put("signature", eObject.parameter.map[type.literal].join(","))
acceptor.accept(EObjectDescription.create(qualifiedName, eObject,data));
}
} catch (Exception exc) {
LOG.error(exc.getMessage(), exc);
}
return true;
}
}
class MyDslScopeProvider extends AbstractDeclarativeScopeProvider {
def IScope scope_Call_operation(Call ctx, EReference ref) {
new FilteringScope(delegateGetScope(ctx,ref)) [
val signature = ctx.parameter.map[p|
val x = switch(p) {
StringLiteral: DataType.STRING
BooleanLiteral: DataType.BOOLEAN
IntLiteral: DataType.INT
}
x.literal
].join(",")
getUserData("signature") == signature
]
}
}
public class MyDslRuntimeModule extends org.xtext.example.mydsl2.AbstractMyDslRuntimeModule {
public Class<? extends IDefaultResourceDescriptionStrategy> bindIDefaultResourceDescriptionStrategy() {
return MyDslResourceDescriptionStrategy.class;
}
public void configureIScopeProviderDelegate(Binder binder) {
binder.bind(IScopeProvider.class).annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(MyDslImportedNamespaceAwareLocalScopeProvider.class);
}
}
(but as i said this wont work in content assist )!!!
thus you may need to do this in the linking service as i said
is there a reason you cannot/want not to use Xbase?
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
Re: Customize IQualifiedNameProvider Problem [message #1515821 is a reply to message #1514718] |
Thu, 18 December 2014 12:03 |
Alexander R Messages: 211 Registered: July 2013 |
Senior Member |
|
|
Hi,
first of all thanks for your time and your help!
This project is "grown" like that. It depends on an official specification...
I tried to limit the dependence to other DSLs or Frameworks as much as possible and try to implement the grammar and metamodel the way the spec. wants it..that is a hard way to go..
Btw. What version of xtend did you used in your example code? I am still usig xtend 2.5.4 and have so problems with inner classes (?) like:
new Iterable<EObject>(){
override Iterator<EObject> iterator() {
return EcoreUtil.getAllContents(resource, false);
}
};
Best regards,
Alex
[Updated on: Fri, 26 December 2014 15:26] Report message to a moderator
|
|
|
|
|
Re: Customize IQualifiedNameProvider Problem [message #1515862 is a reply to message #1515836] |
Thu, 18 December 2014 12:46 |
|
Here is a Quick draft for the linking service (dont adapt the scope provider in that case)
class MyDslLinkingService extends DefaultLinkingService {
@Inject
@LinkingScopeProviderBinding
private IScopeProvider scopeProvider;
@Inject
private Provider<ImportedNamesAdapter> importedNamesAdapterProvider;
@Inject
private LinkingHelper linkingHelper;
@Inject
private IQualifiedNameConverter qualifiedNameConverter;
override getLinkedObjects(EObject context, EReference ref, INode node) throws IllegalNodeException {
val o = NodeModelUtils.findActualSemanticObjectFor(node)
println(o)
if (o instanceof Call) {
val signature = o.parameter.map [ p |
val x = switch (p) {
StringLiteral: DataType.STRING
BooleanLiteral: DataType.BOOLEAN
IntLiteral: DataType.INT
}
x.literal
].join(",")
val EClass requiredType = ref.getEReferenceType();
if (requiredType == null)
return Collections.<EObject>emptyList();
val String crossRefString = getCrossRefNodeAsString(node);
if (crossRefString != null && !crossRefString.equals("")) {
val IScope scope = getScope(context, ref);
val QualifiedName qualifiedLinkName = qualifiedNameConverter.toQualifiedName(crossRefString);
val eObjectDescriptions = scope.getElements(qualifiedLinkName);
for (eObjectDescription : eObjectDescriptions) {
if (eObjectDescription != null && eObjectDescription.getUserData("signature") == signature)
return Collections.singletonList(eObjectDescription.getEObjectOrProxy());
}
}
return Collections.emptyList();
}
super.getLinkedObjects(context, ref, node)
}
}
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
|
Re: Customize IQualifiedNameProvider Problem [message #1547265 is a reply to message #1514718] |
Mon, 05 January 2015 10:21 |
Alexander R Messages: 211 Registered: July 2013 |
Senior Member |
|
|
Hello,
I added the features you mentioned and it works. But only if my own ScopeProvider is doing nothing. The problem is, I already implemented a scope strategy. For inheritance of operations and other scenarios ..
Is it possible to customize the MyDslLinkingService and to keep an own implementation of the AbstractDeclarativeScopeProvider?
~Alex
[Updated on: Mon, 05 January 2015 10:34] Report message to a moderator
|
|
|
|
|
|
|
|
|
|
Re: Customize IQualifiedNameProvider Problem [SOLVED] [message #1549122 is a reply to message #1547402] |
Tue, 06 January 2015 10:38 |
Alexander R Messages: 211 Registered: July 2013 |
Senior Member |
|
|
Problem solved in two steps. Both Steps are performed in an customized ScopeProvider after calculating the right scope:
1. Step: Create a IEObjectDescriptionList (with userdata) out of an elementsList
def <T extends EObject> Iterable<IEObjectDescription> scopedElementsForWithSignature(Iterable<? extends T> elements,
Function<T, QualifiedName> nameComputationFunction) {
val Iterable<IEObjectDescription> formatedOperations = Iterables.transform(elements,
new Function<T, IEObjectDescription>() {
override IEObjectDescription apply(T from) {
val QualifiedName qualifiedName = nameComputationFunction.apply(from);
//this is the arbitrary user data of an EOject in an EObjectDescription
var Map<String, String> data = null
if (from instanceof Operation) {
val sig = QualifiedNameFormatter.createOperationSignature(from)
data = <String, String>newHashMap("signature" -> sig)
}
if (qualifiedName != null)
return new EObjectDescription(qualifiedName, from, data);
return null;
}
});
return Iterables.filter(formatedOperations, Predicates.notNull());
}
2. Step: Create the Scope
val eObjectDescrs = createEObjectDesrcList(elements, QualifiedName.wrapper(SimpleAttributeResolver.NAME_RESOLVER));
val finalScope = new SimpleScope(parentScope, innerScopeElementsIObjectDescr);
Thanks a lot for your help Christian!
~Alex
|
|
|
Powered by
FUDForum. Page generated in 0.05200 seconds