GReQLJavaChecker
Der GReQLJavaChecker ermöglicht statische Checks auf Programmcode und verwendet dazu Abfragen auf dem Syntaxgraphen. Um einen statischen Check mit dem Checker durchzuführen, müssen die zu untersuchenden Dateien in der Liste "Source Files" ausgewählt werden und eine einzelne Datei mit Prüfregeln ("Rule File") angegeben werden. Die Regeln werden in dieser Datei im XML-Format organisiert und verwenden die Sprache GReQL für Abfragen auf dem Syntaxbaum.
Beispiele und Eigenschaften von Regeln
Als erstes Element im XML Dokument muss <checkerrules> stehen, entsprechend muss </checkerrules> als letztes Element in dem XML Dokument sein.
Zwei beispielhafte Abfragen in dieser Sprache sehen so aus:
<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>
<rule type="presence" points="4">
<query>from t : V{TypeDeclaration}, m : V{MethodDeclaration} with
t.name="Miniprojekt2" and
t -->{TypeDeclarationBodyDeclarations2} m and
hasSignature(m, "public static String geometrie1(int)")
report 0 end</query>
<feedback prefix="Signaturcheck">Die Methode "public static String geometrie1(int laenge)" in
der Klasse "Miniprojekt2" fehlt. Hast du die vorgegebene Methodensignatur veraendert?</feedback>
</rule>
Die obere Regel ist vom Typ "absence", d.h. sie definiert einen Codestruktur, die nicht in der untersuchten Lösung vorkommen soll. Als Abfrage wird eine Struktur aus Elementen des Syntaxbaums definiert. Als Meldung wird ein String definiert, der zur Fehlerliste hinzugefügt wird, wenn die in der Abfrage definierte Struktur gefunden wird. Dabei dienen {name} und {line} als Platzhalter für Werte, die in der Abfrage in der report-Klausel ausgegeben wurden. Die zweite Regel ist vom Typ "presence" und definiert folglich eine Codestruktur, die in der untersuchten Lösung vorkommen soll. D.h., in diesem Fall wird die definierte Fehlermeldung ausgegeben, wenn die in der Abfrage definierte Struktur nicht auftritt. Folglich können in dieser Regel auch keine Platzhalter in der Ausgabe verwendet werden.
Die Funktion hasSignature
ist eine spezielle, von JACK bereitgestellte Erweiterung der GReQL-Syntax, die eine bequeme Überprüfung von Methodensignaturen ermöglicht. Wie im Beispiel dargestellt, braucht die übergebene Zeichenkette keine vollständige Methodensignatur zu sein, sondern es reicht die Angabe der zu überprüfenden Bestandteile. D.h., Namen der Methodenparameter können ebenso entfallen wie Modifier oder der Rückgabetyp. Es ist allerdings nicht möglich, nur Modifier anzugeben und keinen Rückgabetyp.
→ Weitere Beispiele: GReQL Regeln
Auswertung eines Regelsatzes
Bei der Durchführung des statischen Checks wird zunächst der abstrakte Syntaxgraph der abgegebenen Lösung erzeugt und anschließend alle Regeln angewendet. Alle erzeugten Fehlernachrichten werden als Ausgabe des statischen Tests gesammelt. Die vergebene Punktzahl ergibt sich aus den Punkten der einzelnen Regeln, wobei die Gesamtsumme der Punkte in der Regeldatei stets auf 100 normiert wird. D.h., im oben gezeigten Beispiel erhält eine korrekte Lösung 100 Punkte, während eine Lösung, die die erste Regel verletzt, nur 67 Punkte erhält. Tritt während des Checks ein technischer Fehler auf, wird der Check abgebrochen und die Lösung mit einem "internal error" als fehlerhaft markiert.
Versionsunterschiede
Je nach eingesetzter Checker-Version müssen einige Abfragen zur Code-Struktur leicht unterschiedlich formuliert werden. Dies betrifft insbesondere die beiden Checker-Versionen, die in JACK 2 und JACK 3 zum Einsatz kommen.
Art der Änderung | Alt (insb. JACK 2) | Neu (insb. JACK 3 und Moodle-Plugin) |
---|---|---|
Geänderter Kantentyp | TypeDeclarationBodyDeclarations2 |
TypeDeclarationBodyDeclarations1
|
Geänderter Kantentyp | TypeDeclarationSuperclassType2 |
TypeDeclarationSuperclassType
|
Geänderter Kantentyp | ParameterizedTypeTypeArguments1 ParameterizedTypeTypeArguments2 |
ParameterizedTypeTypeArguments
|
Geänderter Kantentyp | TypeDeclarationSuperInterfaceTypes1 TypeDeclarationSuperInterfaceTypes2 |
TypeDeclarationSuperInterfaceTypes
|
Erweiterte Funktion | Die Funktion hasSignature kann nicht auf geworfene Exceptions prüfen |
Die Prüfung ist möglich |