GReQL Regeln
Beispiele für statische Prüfregeln für Java-Code
Codestil
<rule type="absence" points="0"> <query>from x : V{MethodDeclaration} with x.name=capitalizeFirst(x.name) and x.constructor="false" report 0 end </query> <feedback prefix="Hinweis (ohne Punktabzug)">Du verwendest Methodennamen, die mit einem Großbuchstaben beginnen. Das ist möglich, aber es entspricht nicht dem üblichen Programmierstil für Java.</feedback> </rule>
Diese Regel sucht nach groß geschriebenen Methodennamen.
<rule type="absence" points="0"> <query>from x : V{TypeDeclaration} with not (x.name=capitalizeFirst(x.name)) report 0 end </query> <feedback prefix="Hinweis (ohne Punktabzug)">Du verwendest Klassennamen, die nicht mit einem Großbuchstaben beginnen. Das ist möglich, aber es entspricht nicht dem üblichen Programmierstil für Java.</feedback> </rule>
Diese Regel sucht nach klein geschriebenen Klassennamen.
<rule type="absence" points="0"> <query>from x : V{VariableDeclarationFragment} with x.name=capitalizeFirst(x.name) and isEmpty(from m : V{Modifier} with x <--&{FieldDeclaration} --> m and m.name="final" report m end) report 0 end </query> <feedback prefix="Hinweis (ohne Punktabzug)">Du verwendest Variablennamen, die mit einem Großbuchstaben beginnen. Das ist möglich, aber es entspricht nicht dem üblichen Programmierstil für Java.</feedback> </rule>
Diese Regel sucht nach groß geschriebenen Variablennamen, wobei als "final" deklarierte Klassenvariablen ausgelassen werden.
Einfache Inhalte
<rule type="presence" points="2"> <query>from m : V{MethodDeclaration}, s : V{StringLiteral} with m.name="m" and m -->{Child}* s and s.content = "\"Zeichenkette\"" report 0 end </query> <feedback>Deine Lösung verwendet nicht den String "Zeichenkette".</feedback> </rule>
Diese Regel sucht in der Methode m
nach einem String-Literal mit einem vorgegebenen Inhalt.
<rule type="absence" points="2"> <query>from m : V{MethodDeclaration}, s : V{StringLiteral} with m.name="m" and m -->{Child}* s and stringLength(s.content) > 4 report s.line as "line" end </query> <feedback>Du verwendest in Zeile {line} ein festes String-Literal. Ist deine Lösung allgemeingültig?</feedback> </rule>
Diese Regel sucht in der Methode m
nach einem String-Literal der Länge 4 oder länger (inklusive Anführungszeichen) und meldet es mit Angabe der Zeilennummer als Fehler.
<rule type="absence" points="0"> <query>from p : V{PackageDeclaration} report 0 end </query> <feedback prefix="Paketdefinition">Deine Lösung beinhaltet eine package-Angabe. Bitte entferne diese.</feedback> </rule>
Diese Regel sucht nach Paketdefinitionen und meldet diese als Fehler.
<rule type="absence" points="1"> <query>from u : V{CompilationUnit}, x : V{MethodInvocation}, y : V{SimpleName} with u -->* x -->{ElementExpression} y and x.name="exit" and y.name="System" report u.name as "name", x.line as "line" end </query> <feedback>Der Aufruf von "System.exit()" in der Datei {name} in Zeile {line} ist nicht gestattet.</feedback> </rule>
Diese Regel sucht nach Aufrufen von System.exit() und melde diese unter Angabe von Klasse und Zeilennummer als Fehler.
Kontrollstrukturen
<rule type="absence" points="4"> <query>from m : V{MethodDeclaration} with m.name="m" and isEmpty(m -->{Child}*&{WhileStatement}) and isEmpty(m -->{Child}*&{DoStatement}) and isEmpty(m -->{Child}*&{ForStatement}) and isEmpty(m -->{Child}*&{EnhancedForStatement}) report 0 end </query> <feedback>In der Methode "m()" wird kein Schleifenkonstrukt verwendet.</feedback> </rule>
Diese Regel überprüft, ob Methode m
ein beliebiges Schleifenkonstrukt enthält.
<rule type="absence" points="2"> <query>from u : V{CompilationUnit}, x : V{IfStatement} with ( not isEmpty(u -->* x -->{IfStatementThenStatement}&{EmptyStatement}) or (not isEmpty(u -->* x -->{IfStatementThenStatement}&{Block}) and isEmpty(u -->* x -->{IfStatementThenStatement}&{Block} -->{Child})) ) and ( not isEmpty(u -->* x -->{IfStatementElseStatement}&{EmptyStatement}) or (not isEmpty(u -->* x -->{IfStatementElseStatement}&{Block}) and isEmpty(u -->* x -->{IfStatementElseStatement}&{Block} -->{Child})) ) report u.name as "name", x.line as "line" end </query> <feedback>In der Datei {name} enthält das if-Statement in Zeile {line} in beiden Zweigen keinen Code und ist dadurch sinnlos.</feedback> </rule>
Diese Regel sucht nach einer if-Anweisung, die nur leere Zweige enthält und meldet eine solche Anweisung als Fehler.
<rule type="absence" points="2"> <query>from u : V{CompilationUnit}, x : V{IfStatement} with not isEmpty(u -->* x -->{IfStatementThenStatement}&{EmptyStatement}) and isEmpty(x -->{IfStatementElseStatement}&{Statement}) report u.name as "name", x.line as "line" end </query> <feedback>In der Datei {name} endet das if-Statement in Zeile {line} hinter der Bedingung sofort mit einem Semikolon. Die Bedingung ist dadurch wirkungslos und die folgende Anweisung wird immer ausgeführt.</feedback> </rule>
Diese Regel sucht nach einer if-Anweisung, die keine Zweige enthält und meldet eine solche Anweisung als Fehler.