0
votes

I am very new to Xtext/Xtend, therefore apologies in advance if the answer is obvious.

I would like to allow the end-users of my DSL to define a 'filter', that when applied and 'returns' true it means that they want to 'filter out' the given entity of data from consideration.

I want to allow them 2 ways of defining the filter

A) by introspecting the attributes of a given data object and apply basic rules like

if (obj.field1<CURRENT_DATE && obj.field2=="EXPIRED) 
{ return true;} else {return false;}

B) by executing a controlled snippet using 'eval' of my host language

In other words, the user would be expected to type into a string/code block a valid

code snippet of the hosting language

I had decided that the easiest way for me support case A) would be to leverage the XBase rules (including expressions/etc)

Therefore I defined filters (mostly copying the ideas from Lorenzo's book)

Filter:
(FilterDSL | FilterCode); 


FilterDSL:

'filterDSL' (type=JvmTypeReference)? name=ID 
'(' (params+=FullJvmFormalParameter (',' params+=FullJvmFormalParameter)*)? ')' 
body=XBlockExpression ;


FilterCode:
  'filterCode' (type=JvmTypeReference)? name=ID 
  '(' (params+=FullJvmFormalParameter (',' params+=FullJvmFormalParameter)*)? ')' 
 '{'    
    body=STRING 
 '}';

Now when trying to implement the Java mapping for my DSL, via the inferrer stub in Xtend -- I am running into multiple problems.

All of them likely indicate that I am missing some fundamental understanding

Problem 1) fl.body is not defined. fl Is of type Filter, not FilterDSL or FilterCode

And I do not understand how to check what type a given instance is of, so that I can access the content of a 'body' feature.

Problem 2) I do not understand where 'body' attribute in the inferrer method is defined and why. Is this part of ECore? (I could not find it)

Problem 3) what's the proper way to allow a user to specify a code block? String seems to be not the right thing as it does not allow multiline

Problem 4) How do I correctly convert a code block into something that is accepted by the 'body' such that it ends up in the generated code.

Problem 5) How do I setup multiple inferrers (as I have more than one thing for which I need the code generated (mostly) by xBase code generator)

Appreciate in advance any suggestions, or pointer to code examples solving similar problems.

As a side observation, Inferrer and its interplay with XBase has sofar been the most confusing and difficult thing to understand.

1

1 Answers

1
votes

in general: have a look at the xtend docs at xtend-lang.org

  1. You can do a if (x instanceof Type) or a switch statement with Type guards (see domain model example)

  2. i dont get that question. both your FilterDSL and FilterCode EClasses should have a field+getter/setter named body, FilterCode of type String, FilterDSL of type XBlockExpression. The JvmTypesBuilder add extension methods to JvmOperation called setBody(String) and setBody(XExpression), syntax sugar lets you call body = .... instead of setBody(...) (btw you can do crtl+click to find out where a thing is defined)

  3. strings are actually multiline

  4. is answered by (2)

  5. you dont need multiple inferrers, you can infer multiple stuff e.g. by calling toClass or toField multiple times for the same input