Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assignment pointcut access inside DSLD #267

Closed
loicfaure opened this issue Mar 6, 2017 · 13 comments
Closed

Assignment pointcut access inside DSLD #267

loicfaure opened this issue Mar 6, 2017 · 13 comments

Comments

@loicfaure
Copy link

Hello,

It seems that there is no pointcut for accessing an assignment. Example:
I can access the method name by doing a bind on an enclosing call
but in strName = | where my caret is at "|", I need content proposal but I can't access the value strName.
What I need will be something like enclosingAssignmentPointcut or something like that.

Is it possible ?

@eric-milles
Copy link
Member

I'm not too familiar with the DSLD stuff. Have you looked at the UserExtensiblePointcut? If that does not work, this package should give you the guidance you need to create the AssignmentPointcut.

pointcuts

@loicfaure
Copy link
Author

Thanks for your answer.

I already saw that. I'm making my own pointcuts extending directly AbstractPointcut.

The problem seems to be in the GroovyDSLContext.

It seems that in the case of "strName = Something" or "strName = null", there is no way to get a BinaryExpression combining strName as Left and null as Right which would leads to know what is the attribute.

@eric-milles
Copy link
Member

eric-milles commented Mar 6, 2017 via email

@loicfaure
Copy link
Author

Sorry, I have not the experience in this to tell you what changes are needed. My only problem is to be able to give dynamic content proposal on assignment. For example, doing that :
myObject = S (then Ctrl + Space would give me some dynamically created values from let say a file SOME_OBJECT_1 SOME_OBJECT_2
In DSLD, this would give the following
contribute(bind(parameter: currentAssignment())) { and so on

I'm starting to thing that the limitation is from JDT and not Groovy DSL

@loicfaure
Copy link
Author

If someone encounter the same problem, I resolved it by calling getStatementAndExpressionProposal from IProposalProvider which give me the left node of an assignment. This solution is more a workaround because you need a complete assignment to have enough data.

@aeisenberg
Copy link

I haven't worked on this in quite a few years, but my guess is that the problem you are facing is a parser issue. If the code that you are working with is malformed (ie- incomplete), the parser is not able to create a BinaryExpression because there is not a left and a right side available.

Groovy-Eclipse does patch the basic Groovy parser in a few places so that it creates a reasonably valid parse tree even if the syntax is incorrect. This might be one of the situations that is missed.

To see if this is the case, you would need to create a malformed assignment expression (like this: strName = |) in a groovy script and open it in the Groovy AST viewer. Then you would do a properly formed assignment expression (like this: strName = E|) and see how they differ.

My guess is that you need to add some extra parser recovery to the Groovy Parser.

@loicfaure
Copy link
Author

Ok thanks you, I will look at this. As a workaround, I also modified eclipse groovy auto-completion to only produce well-formed BinaryExpression.

@eric-milles
Copy link
Member

I think this is somewhat related. Annotations like @Newify have a target of ElementType.LOCAL_VARIABLE. Is there a pointcut expression that can target a local variable declaration that has an annotation like this applied?

Example:

class Foo {
  static {
    @Newify(Bar)
    def bar = Bar.ne  // caret at end of this line for content assist
  }
}

For the other possible locations of @Newify (constructor, field, method, type) I have these pointcuts: enclosingClass(annos: annotatedBy(Newify)) | enclosingField(annos: annotatedBy(Newify)) | enclosingMethod(annos: annotatedBy(Newify))

Also: Is the enclosingClass pointcut supposed to hit on the static and object initializers? It is missing the static initializers for sure.

@eric-milles
Copy link
Member

@loicfaure It has been a while since I last commented on this issue. I have since spent some time with DSLDs. In the absence of you proposed new pointcut, could you try a wider pointcut like contribute(enclosingMethod()) { } and check the currentNode property?

@loicfaure
Copy link
Author

I'm agree with @aeisenberg, their is a lack of recovery from GroovyEclipse when groovy parse BinaryExpression. I will have time to work on that in august, so I will try what you propose but I don't think enclosingMethod pointcut would be enough because my basic case is
sendObject(Parent) { obj = EN //here I need content proposal }
So enclosingMethod would give me sendObject I think

@eric-milles
Copy link
Member

enclosingMethod will match against each node within the method. You'd just need to do some checks on currentNode to see that it is a BinaryExpression with an operation type of =. Or that currentNode is the right expression of an assignment expression.

@eric-milles
Copy link
Member

@loicfaure I managed to add something that may satisfy your needs and also fills a gap that I had in matching local variable declarations with specific annotations.

You should be able to create a contribution like this to match your case:

contribute(assignedVariable('strName')) {
  // currentNode should be the right expression for "strName = |" if the AST is well-formed
  // bind to the result of assignedVariable if you want access to the BinaryExpression of the assignment
  // be sure to check currentNode against the assignment expression, because this will also get a hit for "strName| = x" and "strName = x.y.z|", which may or may not be desirable for your particular needs
}

@loicfaure
Copy link
Author

loicfaure commented Aug 1, 2017

@eric-milles ok thanks a lot, I will check that ASAP (maybe next week) but I don't know the name of the variables before, it is dynamic but maybe reusing what you do, I can adapt to my problem. I will try to produce well formed AST everytime too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants