Search and Replace Structurally "Script Constraints" Documentation

Answered

Hi all,

I'm fiddling with the "Script Constraints" part of the "Search Structurally" and I'm surprised not just by the apparent lack of documentation, but also lack of examples on the topic.


The few examples of script constraints out there come from this forum, and sport references to __context__ variables and API that deal with the PSI tree that seem overkill for most common tasks.

Is there an authoritative source of information? Something that could explain, for instance, why I have to use "variable.name" in some cases, and "variable.text" in others.

Thank you in advance!

Riccardo

2
5 comments
Official comment

Hi Riccardo,

You're right, there is indeed a lack of documentation about Script Constraints. This is at least partially caused by the complexity exposed. Basically the entire API of IntelliJ IDEA is available from here. The possibilities are infinite, and it is hard to know (at least for me) what examples are required to help you. What kind of examples would you like to see? What would you consider "common tasks"?

Here's some explanation of your questions:

The __context__ variable is an artificial variable. All variables used in a pattern can be accessed from the Script Constraints. __context__ corresponds to the Complete Match variable. Because SSR (Structural Search & Replace) does its magic by matching PSI trees (which are basically AST's as you probably know), these variables are in fact just nodes in the PSI tree.

Say you have a SSR variable that matches a method, for example a toString() method. Then the variable is in fact a PsiMethod node. Retrieving variable.parent will produce a PsiClass node, and so forth. So naturally variable.text will give you the entire text of the method. If we just need the name of the method, variable.name will suffice.

In another case the SSR variable may match some expression, for example a reference to a variable, a PsiReferenceExpression. An expression has no name of course, but retrieving the entire text of the expression, will give us the name of the variable it is referring to.

SSR contains a lot of Existing Templates, some of which use Script Constraints. You may want to check these out, to see some more examples. If you are using IntelliJ IDEA 2018.1 (currently in EAP) these are: 

  • sample method invocation with a constant parameter
  • classes
  • classes with parameterless constructors
  • static fields that are not final
  • interface that is not implemented or extended
  • fields/variables read
  • fields/variables with given name pattern updated

If you have any further questions, please ask.

 

Bas

Thank you for the prompt and exhaustive answer, Bas!

I admit that I did overlook the "Copy existing template" button completely, but perhaps is for the better, given the payoff for this post :)

The problem I had at hand was to find all matches of a class reference in a specific position, that didn't match the name of a class, in order to create a custom inspection.

Something along these lines:

class $someclass$ {

private static String $someField$ = someStaticMethod($loaderclass$.class.getClassLoader());
}

Where I want only the matches of $loaderclass$ that are different from $someClass$ (the inverse is trivial).

Possibly there are other simpler ways to find all matches without scripting (are there?), but the "Scripting Constraints" seemed to fit well the problem.

I ended up putting together a script that works (now I even know why :D), and I think that this post will probably fill the gap for other people with the same doubts, but if you are interested in constructive feedback, these are a couple of things that could help further:

but again, a post like yours would have compensated for all of it.

Thank you again, and keep up the amazing work!

Riccardo

0

Thanks Riccardo,

those are some good suggestions. You may want to follow this issue for updates on improving this part of the documentation: https://youtrack.jetbrains.com/issue/DOC-5272

 

Bas

0

Thanks Bas,

I suspect the link points to an internal project/board, as I can't access it. Never mind though, and thank you again for everything!

Riccardo

0

Please sign in to leave a comment.