GReQL Regeln: Unterschied zwischen den Versionen
(Die Seite wurde neu angelegt: „== Beispiele für statische Prüfregeln für Java-Code == === Codestil === <rule type="absence" points="0"> <query>from x : V{MethodDeclaration}…“) |
|||
| Zeile 118: | Zeile 118: | ||
</rule> | </rule> | ||
Diese Regel sucht nach einer if-Anweisung, die keine Zweige enthält und meldet eine solche Anweisung als Fehler. | Diese Regel sucht nach einer if-Anweisung, die keine Zweige enthält und meldet eine solche Anweisung als Fehler. | ||
<rule type="absence" points="2"> | |||
<query>from u : V{CompilationUnit}, x : V{WhileStatement} | |||
with | |||
not isEmpty(u -->* x -->{WhileStatementBody}&{EmptyStatement}) or | |||
(not isEmpty(u -->* x -->{WhileStatementBody}&{Block}) and | |||
isEmpty(u -->* x -->{WhileStatementBody}&{Block} -->{Child})) | |||
report u.name as "name", x.line as "line" end | |||
</query> | |||
<feedback>In der Datei {name} besteht die while-Schleife in Zeile {line} nur aus einer Abbruchbedingung und ist dadurch sinnlos.</feedback> | |||
</rule> | |||
Diese Regel sucht nach einer while-Schleife, die nur aus einer Abbruchbedingung besteht und meldet eine solche Schleife als Fehler. | |||
<rule type="presence" points="1"> | |||
<query>from m : V{MethodDeclaration}, n : V{MethodDeclaration} | |||
with | |||
m (-->{Child}*&{MethodInvocation} -->{Access}&{MethodDeclaration})* n and | |||
n -->{Child}*&{MethodInvocation} -->{Access} m and | |||
m.name="m" | |||
report 0 end | |||
</query> | |||
<feedback prefix="Rekursionscheck"> Die Methode "m()" enthält nicht die geforderte Rekursion.</feedback> | |||
</rule> | |||
Diese Regel überprüft, ob Methode <code>m</code> rekursiv arbeitet. Dabei ist es egal, ob sich die Methode direkt selber aufruft, oder über einen oder mehrere Zwischenschritte aufgerufen wird. | |||
<rule type="presence" points="5"> | |||
<query>from m : V{MethodDeclaration} | |||
with | |||
m (-->{Child}*&{MethodInvocation} -->{Access}&{MethodDeclaration}) m and | |||
m.name="m" | |||
report 0 end | |||
</query> | |||
<feedback prefix="Rekursionscheck">Die Methode "m()" enthält nicht die geforderte Rekursion.</feedback> | |||
</rule> | |||
Diese Regel überprüft, ob Methode <code>m</code> rekursiv arbeitet und sich insbesondere ohne Zwischenschritte über andere Methoden selber wieder aufruft. | |||
=== Methoden === | |||
<rule type="presence" points="4"> | |||
<query>from t : V{TypeDeclaration}, m : V{MethodDeclaration} | |||
with | |||
t.name="A" and | |||
t -->{TypeDeclarationBodyDeclarations2} m and | |||
hasSignature(m, "public static String method(int)") | |||
report 0 end | |||
</query> | |||
<feedback prefix="Signaturcheck">Die Methode "public static String method(int param)" in der Klasse "A" fehlt. Hast du die vorgegebene Methodensignatur veraendert?</feedback> | |||
</rule> | |||
Diese Regel überprüft, ob Klasse A eine Methode mit einer bestimmten Signatur enthält, wobei der Name des Methodenparameters unerheblich ist. | |||
<rule type="presence" points="4"> | |||
<query>from t : V{TypeDeclaration}, m : V{MethodDeclaration} | |||
with | |||
t.name="A" and | |||
t -->{TypeDeclarationBodyDeclarations2} m and | |||
hasSignature(m, "int method()") and | |||
isEmpty(m -->{Child}&{Modifier}) | |||
report 0 end | |||
</query> | |||
<query>from t : V{TypeDeclaration}, m : V{MethodDeclaration}, mo : V{Modifier} | |||
with | |||
t.name="A" and | |||
t -->{TypeDeclarationBodyDeclarations2} m and | |||
hasSignature(m, "int method()") and | |||
m --> mo and not (mo.name="private") | |||
report 0 end | |||
</query> | |||
<feedback prefix="Signaturcheck">Die Methode "int method()" in der Klasse "A" fehlt oder ist mit dem Modifier "private" versehen. Hast du die vorgegebene Methodensignatur veraendert?</feedback> | |||
</rule> | |||
Diese Regel überprüft, ob Klasse A eine Methode mit einer bestimmten Signatur enthält, die nicht mit dem Modifier private versehen ist. | |||
<rule type="presence" points="1"> | |||
<query>from t : V{TypeDeclaration}, m : V{MethodDeclaration}, pt : V{ParameterizedType}, ptt : V{SimpleType}, pta : V{SimpleType} | |||
with | |||
t.name="A" and | |||
t -->{TypeDeclarationBodyDeclarations2} m and | |||
m.name="m" and | |||
m -->{MethodDeclarationReturnType} pt and | |||
pt -->{ParameterizedTypeType} ptt and | |||
ptt.name="B" and | |||
pt -->{ParameterizedTypeTypeArguments1} pta and | |||
pta.name="C" | |||
report 0 end | |||
</query> | |||
<feedback prefix="Signatur">Der Methode "public B<C> m()" in der Klasse "A" fehlt. Hast du die vorgegebene Methodensignatur veraendert?</feedback> | |||
</rule> | |||
Diese Regel überprüft, ob Klasse A eine Methode m mit parametrisierten Rückgabetyp B<C> enthält. | |||
Version vom 5. April 2017, 11:06 Uhr
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.
<rule type="absence" points="2">
<query>from u : V{CompilationUnit}, x : V{WhileStatement}
with
not isEmpty(u -->* x -->{WhileStatementBody}&{EmptyStatement}) or
(not isEmpty(u -->* x -->{WhileStatementBody}&{Block}) and
isEmpty(u -->* x -->{WhileStatementBody}&{Block} -->{Child}))
report u.name as "name", x.line as "line" end
</query>
<feedback>In der Datei {name} besteht die while-Schleife in Zeile {line} nur aus einer Abbruchbedingung und ist dadurch sinnlos.</feedback>
</rule>
Diese Regel sucht nach einer while-Schleife, die nur aus einer Abbruchbedingung besteht und meldet eine solche Schleife als Fehler.
<rule type="presence" points="1">
<query>from m : V{MethodDeclaration}, n : V{MethodDeclaration}
with
m (-->{Child}*&{MethodInvocation} -->{Access}&{MethodDeclaration})* n and
n -->{Child}*&{MethodInvocation} -->{Access} m and
m.name="m"
report 0 end
</query>
<feedback prefix="Rekursionscheck"> Die Methode "m()" enthält nicht die geforderte Rekursion.</feedback>
</rule>
Diese Regel überprüft, ob Methode m rekursiv arbeitet. Dabei ist es egal, ob sich die Methode direkt selber aufruft, oder über einen oder mehrere Zwischenschritte aufgerufen wird.
<rule type="presence" points="5">
<query>from m : V{MethodDeclaration}
with
m (-->{Child}*&{MethodInvocation} -->{Access}&{MethodDeclaration}) m and
m.name="m"
report 0 end
</query>
<feedback prefix="Rekursionscheck">Die Methode "m()" enthält nicht die geforderte Rekursion.</feedback>
</rule>
Diese Regel überprüft, ob Methode m rekursiv arbeitet und sich insbesondere ohne Zwischenschritte über andere Methoden selber wieder aufruft.
Methoden
<rule type="presence" points="4">
<query>from t : V{TypeDeclaration}, m : V{MethodDeclaration}
with
t.name="A" and
t -->{TypeDeclarationBodyDeclarations2} m and
hasSignature(m, "public static String method(int)")
report 0 end
</query>
<feedback prefix="Signaturcheck">Die Methode "public static String method(int param)" in der Klasse "A" fehlt. Hast du die vorgegebene Methodensignatur veraendert?</feedback>
</rule>
Diese Regel überprüft, ob Klasse A eine Methode mit einer bestimmten Signatur enthält, wobei der Name des Methodenparameters unerheblich ist.
<rule type="presence" points="4">
<query>from t : V{TypeDeclaration}, m : V{MethodDeclaration}
with
t.name="A" and
t -->{TypeDeclarationBodyDeclarations2} m and
hasSignature(m, "int method()") and
isEmpty(m -->{Child}&{Modifier})
report 0 end
</query>
<query>from t : V{TypeDeclaration}, m : V{MethodDeclaration}, mo : V{Modifier}
with
t.name="A" and
t -->{TypeDeclarationBodyDeclarations2} m and
hasSignature(m, "int method()") and
m --> mo and not (mo.name="private")
report 0 end
</query>
<feedback prefix="Signaturcheck">Die Methode "int method()" in der Klasse "A" fehlt oder ist mit dem Modifier "private" versehen. Hast du die vorgegebene Methodensignatur veraendert?</feedback>
</rule>
Diese Regel überprüft, ob Klasse A eine Methode mit einer bestimmten Signatur enthält, die nicht mit dem Modifier private versehen ist.
<rule type="presence" points="1">
<query>from t : V{TypeDeclaration}, m : V{MethodDeclaration}, pt : V{ParameterizedType}, ptt : V{SimpleType}, pta : V{SimpleType}
with
t.name="A" and
t -->{TypeDeclarationBodyDeclarations2} m and
m.name="m" and
m -->{MethodDeclarationReturnType} pt and
pt -->{ParameterizedTypeType} ptt and
ptt.name="B" and
pt -->{ParameterizedTypeTypeArguments1} pta and
pta.name="C"
report 0 end
</query>
<feedback prefix="Signatur">Der Methode "public B<C> m()" in der Klasse "A" fehlt. Hast du die vorgegebene Methodensignatur veraendert?</feedback>
</rule>
Diese Regel überprüft, ob Klasse A eine Methode m mit parametrisierten Rückgabetyp B<C> enthält.