sonar-openedge
sonar-openedge copied to clipboard
How to find all "define input parameter anyname as memptr"
I currently have a reason to find all occurences of the pattern "define input parameter * as memptr *." Because I have to look at them one by one and decide if I must refactor them to OUTPUT or INPUT-OUTPUT or leave as is.
What is the best way to do that? Using one of the template rules, like "Custom Groovy rule" or "Custom XREF rule". (Or maybe grep)
Anyone here willing to give me a working example? Please?
The custom Groovy rule is the best way if you don't want to create a full plugin. Pseudo-code is:
for (TreeParserSymbolScope scope : unit.getRootSymbolScope().getChildScopesDeep()) {
for (Parameter p : scope.getRoutine().getParameters()) {
if (p.getDirectionNode() == ABLNodeType.INPUT) && (p.getSymbol().getDatatype() == DataType.MEMPTR)
reportIssue(...)
}
}
I had some time ago a Docker image to quickly test custom Groovy rules, I'll try to make it available next week.
Awesome, thanks! I have time to wait for the Docker image.
Not a Docker image, but a standalone JAR file: https://dl.rssw.eu/standalone-groovy-rule.jar
Example usage:
java -jar standalone-groovy-rule.jar --databases dump/sp2k.df,dump/empty.df:newdb --aliases sp2k,foobar;newdb,db2 --propath src/classes,src/procedures,src/tests --charset utf-8 --groovy file.groovy --input src/procedures/sample/test1.p
Source code: https://github.com/Riverside-Software/standalone-groovy-rule
Sorry I don't know how to get it to work.
The example with standalone-groovy-ruile.jar keeps saying nothing but Error: Could not find or load main class eu.rssw.sonar.GroovyRule. I have downloaded sonar-openedge-plugin-2.14.0.jar and sonar-plugin-api-7.9.4 to the current directory and all sonar extensions, but the error remains.
So then I thought, I will just enter the groovy script it in Sonarqube, because Sonarqube will have all dependencies.
But the pseudo code is indeed psudo code, it does not run in Sonarqube. TreeParserSymbolScope and Parameter classes are unable to resolve.
I have searched the internet for an example of a working groovy custom rule but did not find any and also did not find a help/manual/webpage of which classes, methods or attributes might work in the groovy rule, so I don't know what to try or where to begin. Where should I look?
Custom groovy rules would be great, but I am stuck here.
Sorry for the delay 😢 I'll provide more detailed instructions today.
The example with standalone-groovy-ruile.jar keeps saying nothing but Error: Could not find or load main class eu.rssw.sonar.GroovyRule.
The JAR file has been updated on the server, please download again.
A sample rule was posted in a comment some time ago: https://github.com/Riverside-Software/sonar-openedge/issues/702#issuecomment-525265601 This is the very basic structure of any Groovy rule. And it assumes that you know how to develop in Java (at least, Groovy is very similar).
The Proparse API is visible from the source code (just git clone this repo), and Javadoc is published on Maven Central. Or directly here.
JPNode class with various query() methods is the main entry point to parse the source code. You can use it from unit.getTopNode().query(...). Another entry point is through the SymbolScope object: unit.getRootScope() where you'll have access to the various routines, and in turn to the parameter. The parameter is in turn linked to the JPNode object where it is defined.
I'll let you play with that !
I just tried to setup the standalone-groovy-rule.jar to play around with groovy rule develpment but it doesn't seem to work. Am i missing something? My groovy rule is the example from the template.
java -jar standalone-groovy-rule.jar --databases issdata.df:issdata --propath C:\Users\doa\Desktop\Groovy --charset utf-8 --groovy C:\Users\doa\Desktop\Groovy\GroovyRule.groovy --input C:\Users\doa\Desktop\Groovy\Test.p
Setting Proparse session with propath: C:\Users\doa\Desktop\Groovy - Charset: utf-8
Reading issdata schema from issdata.df
Parsing C:\Users\doa\Desktop\Groovy\Test.p
Reading Groovy script from C:\Users\doa\Desktop\Groovy\GroovyRule.groovy
Exception in thread "main" org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
C:\Users\doa\Desktop\Groovy\GroovyRule.groovy: 1: unable to resolve class eu.rssw.antlr.proparse.checks.GroovyTemplate.RuleLink
@ line 1, column 1.
import eu.rssw.antlr.proparse.checks.GroovyTemplate.RuleLink;
^
1 error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:295)
at org.codehaus.groovy.control.CompilationUnit$ISourceUnitOperation.doPhaseOperation(CompilationUnit.java:914)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:627)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:389)
at groovy.lang.GroovyClassLoader.lambda$parseClass$3(GroovyClassLoader.java:332)
at org.codehaus.groovy.runtime.memoize.StampedCommonCache.compute(StampedCommonCache.java:163)
at org.codehaus.groovy.runtime.memoize.StampedCommonCache.getAndPut(StampedCommonCache.java:154)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:330)
at groovy.lang.GroovyShell.parseClass(GroovyShell.java:526)
at groovy.lang.GroovyShell.parse(GroovyShell.java:538)
at groovy.lang.GroovyShell.parse(GroovyShell.java:547)
at eu.rssw.sonar.GroovyRule.execute(GroovyRule.java:87)
at eu.rssw.sonar.GroovyRule.main(GroovyRule.java:103)
The RuleLink class is nested in GroovyRule (a modified version of GroovyTemplate) , so the import statement is different in this case ; it should be:
import eu.rssw.sonar.GroovyRule.RuleLink;
Works now, thx.
But I have another question. In https://github.com/Riverside-Software/sonar-openedge/issues/702#issuecomment-539646226 yout told me that it is possible to access comments.
What i try i do is check our method header doc comments (For example, all parameters should be there). I already have the METHOD node and i see that the comments before are in the hiddenTokens array but i'm not sure if this is the right approach. Basically i need the first Comment before my METHOD node.
You're right, comments are stored as hidden tokens (as a linked list) before the METHOD node. Note that whitespaces are on the same channel.
Ok so i guess i have to find the first comment before my Method with the start and end positions?
Token.getNodeType() will tell you if it's a comment or whitespace, then Token.getText() will give you the content
Well....my groovy rule now works locally but i cant put it into sonar because its too long. Is there a way to bypass this limit?

The value (in the DB) seems to be limited to 4000 characters. Is your code longer than that ?
Yes it is. Considering the imports that i need are already 400 chars long, 4k seems way to tight. My rule currently sits at around 9K chars, i could surely trim it down some but not to 4k.
Increasing the column size is not recommended by SonarSource, so your best option is to create a rules plugin. You can clone this plugin: https://github.com/riverside-Software/rules-plugin-template Presentation on this topic : https://www.pugchallenge.eu/docs/default-source/presentations-2018/custom-rules-development-with-sonarqube.pdf
The code that you've written can almost be copy / pasted.