GReQL Regeln: Unterschied zwischen den Versionen

Aus JACK Wiki
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 481: Zeile 481:
</syntaxhighlight>
</syntaxhighlight>
Diese Regel überprüft, ob das Modell eine Klasse "D" enthält, die drei direkte Unterklassen "A", "B" und "C" hat.
Diese Regel überprüft, ob das Modell eine Klasse "D" enthält, die drei direkte Unterklassen "A", "B" und "C" hat.
== Beispiele für statische Prüfregeln für EPML ==
<syntaxhighlight lang="xml" line='line'>
  <rule type="presence" points="5">
  <query>from x: V{Event}
        with
            isEmpty(x &lt;--)
        report 0 end
  </query>
  <feedback prefix="Fehlerhafte Grundelemente">Es gibt kein Startevent.</feedback>
  </rule>
</syntaxhighlight>
Diese Regel testet, ob der gegebene Graph kein Startevent hat


[[Category:R-GReQL]]
[[Category:R-GReQL]]

Version vom 12. August 2019, 09:32 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 <nowiki>&amp;lt;--&amp;amp;{FieldDeclaration} --&amp;gt;</nowiki> 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}*&amp;{WhileStatement}) and
             isEmpty(m -->{Child}*&amp;{DoStatement}) and
             isEmpty(m -->{Child}*&amp;{ForStatement}) and
             isEmpty(m -->{Child}*&amp;{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}&amp;{EmptyStatement}) or
               (not isEmpty(u -->* x -->{IfStatementThenStatement}&amp;{Block}) and isEmpty(u -->* x -->{IfStatementThenStatement}&amp;{Block} -->{Child}))
             ) and
             ( not isEmpty(u -->* x -->{IfStatementElseStatement}&amp;{EmptyStatement}) or
               (not isEmpty(u -->* x -->{IfStatementElseStatement}&amp;{Block}) and isEmpty(u -->* x -->{IfStatementElseStatement}&amp;{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}&amp;{EmptyStatement}) and
             isEmpty(x -->{IfStatementElseStatement}&amp;{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}&amp;{EmptyStatement}) or
             (not isEmpty(u -->* x -->{WhileStatementBody}&amp;{Block}) and
             isEmpty(u -->* x -->{WhileStatementBody}&amp;{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}*&amp;{MethodInvocation} -->{Access}&amp;{MethodDeclaration})* n and
              n -->{Child}*&amp;{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}*&amp;{MethodInvocation} -->{Access}&amp;{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}&amp;{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&lt;C&gt; 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.

Vererbungshierarchie

 <rule type="presence" points="5">
   <query>from t : V{TypeDeclaration}, st : V{SimpleType}
          with
             t.name="A" and
             st.name="B" and
             t -->{TypeDeclarationSuperclassType2} st
          report 0 end
   </query>
   <feedback prefix="Typhierarchie">A ist nicht als Unterklasse von B modelliert.</feedback>
 </rule>

Diese Regel überprüft, ob Klasse A direkte Unterklasse von Klasse B ist.

 <rule type="presence" points="1">
    <query>from t : V{TypeDeclaration}, st : V{SimpleType}
           with
              t.name="A" and
              t -->{TypeDeclarationSuperInterfaceTypes2} st and
              st.name="B"
           report 0 end
   </query>
   <feedback prefix="Typhierarchie">A implementiert nicht das Interface B.</feedback>
 </rule>

Diese Regel überprüft, ob Klasse A das Interface B implementiert.

 <rule type="presence" points="1">
   <query>from t : V{TypeDeclaration}, pt : V{ParameterizedType}, ptt : V{SimpleType}, pta : V{SimpleType}
          with
             t.name="A" and
             t -->{TypeDeclarationSuperInterfaceTypes1} pt and
             pt -->{ParameterizedTypeType} ptt and
             ptt.name="B" and
             pt -->{ParameterizedTypeTypeArguments1} pta and
             pta.name="C"
          report 0 end
   </query>
   <feedback prefix="Typhierarchie">A implementiert nicht das Interface B&lt;C&gt;.</feedback>
 </rule>

Diese Regel überprüft, ob Klasse A das Interface B<C> implementiert.

 <rule type="presence" points="3">
   <query>from u : V{TypeDeclaration}, s : V{SimpleType}
          with
             ((u -->{TypeDeclarationSuperclassType2} s and s.name="Thread") or
             (u -->{TypeDeclarationSuperInterfaceTypes2} s and s.name="Runnable")) and
             u.name="A"
          report 0 end
   </query>
   <feedback>In der Klasse "A" sollte entweder das Interface "Runnable" implementieren oder von "Thread" erben.</feedback>
 </rule>

Diese Regel überprüft, ob Klasse A das Interface Runnable implementiert oder von Thread erbt.

Aufrufbeziehungen

 <rule type="presence" points="5">
   <query>from u : V{TypeDeclaration}, x : V{MethodInvocation}, y : V{SimpleName}
          with
             u -->* x -->{ElementExpression} y and
             u.name="A" and
             x.name="m" and
             y.name="B"
          report 0 end
   </query>
   <feedback>In der Klasse "A" sollte "B.m()" aufgerufen werden.</feedback>
 </rule>

Diese Regel überprüft, ob Klasse A eine Methode B.m aufruft.

 <rule type="presence" points="5">
   <query>from u : V{TypeDeclaration}, x : V{MethodInvocation}, y : V{SimpleName}, z : V{VariableDeclarationStatement}, f : V{VariableDeclarationFragment}, t : V{SimpleType}
          with
             u -->* x -->{ElementExpression} y and
             u -->* z -->{VariableDeclarationStatementType} t and
             u -->* z -->{VariableDeclarationStatementFragments} f and
             u.name="A" and
             x.name="m" and
             y.name=f.name and
             t.name="B"
          report 0 end
   </query>
   <feedback>In der Klasse "A" sollte "m()" auf einem Objekt vom Typ "B" aufgerufen werden.</feedback>
 </rule>

Diese Regel überprüft, ob Klasse A Methode m auf einem Objekt vom Typ B aufruft.

 <rule type="presence" points="4">
   <query>from u : V{TypeDeclaration}, m : V{MethodDeclaration}, x : V{ClassInstanceCreation}, t : V{SimpleType}
          with
             u -->{Child}* m -->* x -->{ClassInstanceCreationType} t and
             u.name="A" and
             m.name="m" and
             t.name="B"
          report 0 end
   </query>
   <feedback>In der Klasse "A" muss in Methode m() mindestens eine Instanz von "B" erzeugt werden.</feedback>
 </rule>

Diese Regel überprüft, ob Klasse A in Methode m eine Instanz von Klasse B erstellt.

Beispiele für statische Prüfregeln für UML-Modelle im XMI2-Format

Klassendiagramme

  <rule type="presence" points="11">
    <query>from x,y : V{Class}
           with
              x --> V{Property} --> V{Association} <-- V{Property} <-- y and
              isDefined(x.name) and x.name="A" and
              isDefined(y.name) and y.name="B"
           report 1 end
    </query>
    <feedback>Das Diagramm enthält keine Beziehung zwischen einem "A" und einem "B" oder keine Klassen mit diesen Namen.</feedback>
  </rule>

Diese Regel überprüft, ob das Modell zwei Klassen "A" und "B" enthält, die über eine Assoziation verbunden sind.

  <rule type="absence" points="0">
    <query>from x,y : V{Class}
           with
              x --> V{Property} --> V{Association} <-- V{Property} <-- y and
              isDefined(x.name) and x.name="A" and
              isDefined(y.name) and y.name="B"
           report 1 end
    </query>
    <feedback prefix="Hinweis">Im Diagramm sind die "B" eines "A" als eigene Klasse abgebildet. Das kannst du durch eine bessere Modellierung vermeiden.</feedback>
  </rule>

Diese Regel überprüft ebenfalls, ob das Modell zwei Klassen "A" und "B" enthält, die über eine Assoziation verbunden sind, definiert dies aber als unerwünschte Situation mit entsprechendem Feedback.

  <rule type="presence" points="11">
    <query>from x,y : V{Class}, z: V{Property}
           with
              x --> z and
              z --> V{Association} <-- V{Property} <-- y and
              isDefined(x.name) and x.name="A" and
              isDefined(y.name) and y.name="B" and
              isDefined(z.lower) and z.lower="1" and (not isDefined(z.upper) or z.upper="1")
           report 1 end
    </query>
    <feedback>Das Diagramm enthält keine Beziehung zwischen einem "A" und einem "B" mit der Kardinalität 1 oder keine Klassen mit diesen Namen.</feedback>
  </rule>

Diese Regel überprüft, ob das Modell zwei Klassen "A" und "B" enthält, die über eine Assoziation mit Kardinalität 1 (jedes A kennt genau ein B) verbunden sind.

  <rule type="presence" points="5">
    <query>from a,b : V{Class}, p: V{Property}
           with
              isEmpty(a -->&{Property} -->&{Association}) and
              b --> p and
              isDefined(p.aggregation) and p.aggregation="composite"
           report 1 end
    </query>
    <feedback>Es sollte im Diagramm zwei Klassen geben, bei denen die eine keine weiteren Bestandteile hat, während die andere weitere Bestandteile gemäß der Komposition hat.</feedback>
  </rule>

Diese Regel überprüft, ob es im Modell eine Klasse ohne ausgehende Assoziationen gibt und eine weitere, die mindestens eine ausgehende Komposition hat.

  <rule type="presence" points="5">
    <query>from x : V{Class}, y : V{Property}, z : V{PrimitiveType}
           with
              isDefined(x.name) and x.name="A" and
              x --> y and
              isDefined(y.name) and y.name="b" and
              y --> z and
              isDefined(z.name) and z.name="String"
           report 1 end
    </query>
    <feedback>Ein "A" soll ein Attribut für die Eigenschaft "b" bereitstellen.</feedback>
  </rule>

Diese Regel überprüft, ob es im Modell eine Klasse "A" mit dem Attribut "b" vom Typ "String" gibt.

  <rule type="presence" points="5">
    <query>from x : V{Class}, y : V{Operation}, z: V{Parameter}
           with
              isDefined(x.name) and x.name="A" and
              x --> y and
              isDefined(y.name) and stringLevenshteinDistance(y.name, "ausführen")<3 and
              y --> z
           report 1 end
    </query>
    <feedback>Ein "A" soll eine Methode bereitstellen, mit der sie etwas ausführen kann.</feedback>
  </rule>

Diese Regel prüft, ob es im Modell eine Klasse "A" mit einer Operation gibt, deren Name "ausführen" oder ähnlich lautet.

  <rule type="absence" points="4">
    <query>let c := count(from y : V{Operation} with isDefined(y.name) report y end) in
              from x : set(1)
              with
                 c<>7
              report c as "count" end
    </query>
    <feedback>Das Diagramm sollte genau 7 Methoden enthalten, enthält aber {count}.</feedback>
  </rule>

Diese Regel überprüft, ob das Modell genau 7 Methoden enthält und gibt im Falle einer anderen Anzahl diese im Feedback mit aus.

  <rule type="presence" points="5">
    <query>from x : V{Class}
           with
              isDefined(x.name) and x.name=A" and
              x.isAbstract and
              not isEmpty(x <--&{Generalization})
           report 1 end
    </query>
    <feedback>Das Diagramm sollte eine abstrakte Klasse "A" enthalten, von der mindestens eine Klasse erbt.</feedback>
  </rule>

Diese Regel überprüft, ob das Modell eine abstrakte Klasse "A" enthält, auf die in mindestens einer Generalisierung verwiesen wird.

  <rule type="presence" points="5">
    <query>from a,b,c,d : V{Class}
           with
              isDefined(a.name) and a.name="A" and
              isDefined(b.name) and b.name="B" and
              isDefined(c.name) and c.name="C" and
              isDefined(d.name) and d.name="D" and
              a --> V{Generalization} --> d and
              b --> V{Generalization} --> d and
              c --> V{Generalization} --> d
           report 1 end
    </query>
    <feedback>Das Diagramm sollte Klassen "A", "B" und "C" enthalten, die von einer gemeinsamen Oberklasse "D" erben.</feedback>
  </rule>

Diese Regel überprüft, ob das Modell eine Klasse "D" enthält, die drei direkte Unterklassen "A", "B" und "C" hat.

Beispiele für statische Prüfregeln für EPML

  <rule type="presence" points="5">
  	<query>from x: V{Event}
  	       with
  	          isEmpty(x &lt;--)
  	       report 0 end
  	</query>
  	<feedback prefix="Fehlerhafte Grundelemente">Es gibt kein Startevent.</feedback>
  </rule>

Diese Regel testet, ob der gegebene Graph kein Startevent hat