SDA SE Wiki

Software Engineering for Smart Data Analytics & Smart Data Analytics for Software Engineering

User Tools

Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

research:cultivate:tutorialeigenedetektorenschreiben [2018/05/09 01:59] (current)
Line 1: Line 1:
  
 +==== 0. Ziel des Tutorials ====
 +
 +
 +In diesem Tutorial soll gezeigt werden, wie man in einem Testprojekt einen einfachen Detektor zum Erkennen ​
 +von ";"​ ohne vorherige Statements schreibt. So dass also der folgende Code zu zwei Warnungen führt:
 +
 +
 +
 +<Code lang-java>​
 +
 +package a;
 +
 +public class A {
 +  ​
 + public void x() {
 + ;;
 + }
 +
 +
 +</​Code>​
 +
 +
 +
 +
 +
 +
 +
 +Dies entspricht dem bereits in Cultivate enthaltenen NopSmell-Detektor. Dabei wird hauptsächlich der syntaktische Rahmen für Detektoren erklärt, auf Prolog selber und Smell-Erkennung im Allgemeinen wird nicht eingegangen.
 +
 +
 +
 +
 +
 +
 +==== 1. Vorraussetzungen ====
 +
 +=== a. Eclipse Installation ===
 +
 +siehe [[cultivateconfiguration]]
 +=== b. Testprojekt ===
 +
 +Downloaden Sie die Datei "​{{doc.test-project.zip|test-project.zip}}",​ die ein Projekt "​test"​ enthält. Für das Tutorial muss dieses Projekt im Workspace von Eclipse verfügbar sein. Alternativ kann einfach die unter 0. genannte Klasse in ein leeres Projekt kopiert werden.
 +=== c. JTransformer und Prolog Project Nature ===
 +
 +Sowohl die JTransformer als auch die Prolog Project Nature müssen im Testprojekt aktiviert sein. Dies kann per Rechtklick auf den Projekt-Ordner geprüft werden. Allerdings kann man pro Workspace nur eine JTransformer-Nature haben, d.h. eine eventuell gesetzt andere JTransformer-Nature muss vorher abgewählt werden. Achtung: Sie ist nur als aktiv sichtbar, wenn der JTransformer schon gestartet ist.
 +=== d. Cultivate Nature ===
 +
 +
 +In der Eigenschaftsseite des Projektes muss unter dem Punkt Cultivate die Cultivate Nature aktiv sein. Dieser Punkt ist nur verfügbar, wenn vorher die JTransformer Nature aktiviert wurde.
 +
 +
 +==== 2. Anlegen der conventions.pl ====
 +
 +
 +Im Hautpverzeichnis des test-Projektes muss eine Datei "​conventions.pl"​ mit folgendem
 +Inhalt angelegt werden:
 +
 +<​Code>​
 +:- multifile detector_/​4.
 +:- multifile detector_description/​4.</​Code>​
 +
 +Projektspezifische Detektoren können in dieser Datei 
 +oder in von dieser Datei über 
 +
 +<​Code>​
 +:- consult('​eineAndereDatei.pl'​).
 +:- consult('​inEinemUnterverzeichnis/​nochEineAndereDatei.pl'​).</​Code> ​
 +verlinkten Dateien abgelegt werden.
 +==== 3. Anlegen eines leeren Detektors ====
 +
 +
 +In die Datei "​conventions.pl"​ wird nun ein erster Detektor eingefügt:
 +
 +<​Code>​
 +detector_description(meinErsterDetektor,'​ein kurzer Hilfetext',​statement,​unrated).
 +
 +detector_(meinErsterDetektor,​occurrence,​[(statement,​CallID)],​[]) :- 
 + fail. ​   </​Code>​
 +
 +
 +
 +
 +
 +Dabei haben die Argumente der Prädikate folgende Bedeutung:
 +
 +
 +  * ''​detector_description''​
 +    - Der Name des Detektors. Er muss bei beiden Prädikaten gleich sein.
 +    - Eine kurze Beschreibung des Detektors. In einfachen Hochkommata anzugeben.
 +    - Name der Rolle, die als Quelltext-Referenz dient. Eine Detektor liefert Referenzen auf Quelltextelemente (IDs) und ggf. Relationen zwischen diesen. Zu jeder ID wird dabei eine Rolle angegeben. Da ein Detektor mehrere IDs zurückgeben kann, ist hier durch Angabe der Rolle eine von ihnen als Quelltext-Referenz auszuwählen. Bei Rollen, die von mehreren Quelltextelementen gespielt werden, wird das erste Element in dieser Rolle als Referenz verwendet.
 +    - Das Bewertungschema[[#​ref-tutorialeigenedetektorenschreiben-1|[1]]] "​unrated"​ ist für einfache Detektoren ausreichend.
 +  * ''​detector_''​ (Unterstrich beachten!)
 +    - Der Name des Detektors. Er muss bei beiden Prädikaten gleich sein.
 +    - Da wir das Bewertungsschema "​unrated"​ verwenden, müssen alle Bewertungen[[#​ref-tutorialeigenedetektorenschreiben-1|[1]]] "​occurrence"​ sein
 +    - Eine Liste von IDs mit den zugehörigen Rollen. In diesem Fall enthält die Liste ein Element das aus Sicht des Detektors die Rolle '​statement'​ einnimmt. ​
 +    - Relationen zwischen Quelltext-Elementen. Es kann eine leere Liste ("​[]"​) angegeben werden. Die Rückgabe von Relationen geht über den Rahmen dieses Tutorials hinaus.
 +
 +Nach dem Speichern von "​conventions.pl"​ sollten über den Menüpunkt "​**Refresh Detector Definitions**"​ im Kontextmenu des Projektes jetzt die Detektor-Beschreibungen aktualisiert werden:
 +
 +
 +
 +{{Pic.tutorial_1_2.png|}}
 +
 +
 +==== 4. Anzeigen der Detektor-Ergebnisse ====
 +
 +
 +Über den Menüpunkt "​**Window / Show View / Other**"​ und dann "​**Cultivate / Metrics and Detector Results**"​
 +kann man die Ansicht mit den Detektor-Ergebnissen öffnen. Diese Ansicht hat rechts oben ein Menü, in dem man den eben geschriebenen Detektor "​meinErsterDetektor"​ auswählen kann:
 +
 +
 +
 +{{Pic.tutorial_1_1.png|}}
 +
 +
 +
 +Er liefert allerdings noch keine Ergebnisse zurück, da er mit "​fail"​ implementiert ist, d.h. dass heißt, dass es auf kein Quelltextelement zutrifft.
 +
 +
 +==== 5. Implementieren des Detektors ====
 +
 +
 +Als nächstes ersetzt man das "​detector_(meinErsterDetektor,​..)"​ - Prädikat durch folgendes:
 +
 +<​Code>​
 +detector_(meinErsterDetektor,​ occurrence, [(statement,​ CallID)], []) :- 
 +    nopT(CallID,​ _, _).</​Code>​
 +
 +Das war einfach, oder? '':​-)''​ Wir greifen auf eine Darstellung unseres Java Codes in einer Faktenbasis zu. Man darf sich darunter ruhig auch eine relationale Datenbank vorstellen, auf die man aber mit einer ausgefuchsteren Abfragesprache (Prolog) zugreifen kann. Für diesen Detektor hatten wir das Glück, dass ein einsames Semikolon durch einen einfachen Fakt nopT repräsentiert ist. (Relational gedacht: Durch ein Tupel in der Tabelle nopT).
 +
 +
 +
 +Auf weitere Details wird hier nicht eingegangen,​ auf folgenden Seiten kann man aber weitere Informationen dazu finden:
 +
 +
 +  * [[designprolog]]:​ Notizen zu unserer Verwendung von Prolog.
 +  * [[prologdetectorapi]]:​ Formalerer Beschreibung der von einem Detektor bereitzustellenden Schnittstelle.
 +  * [[analysispredicatesapi]]:​ Verfügbare Analyse-Prädikate
 +  * [[http://​roots.iai.uni-bonn.de/​jtransformer/​Wiki.jsp?​page=PrologAST|PEFs]]:​ Definition der Program Element Facts, d.h. unserer Repräsentation des Java Codes.
 +
 +Nach dem Speichern von "​conventions.pl"​ sollten über den Menüpunkt "​**Refresh Detector Definitions**"​ im Kontextmenu des Projektes jetzt die Detektor-Beschreibungen aktualisiert werden.
 +
 +
 +
 +In der Ansicht "​**Metric and Detector Results**"​ sollten nun zwei Ergebnisse für den Detektor "​meinErsterDetektor"​ auftauchen. Ein Doppelklick öffnet die entsprechenden Quelltextstellen.
 +
 +
 +==== 6. Weitere Beispiele ====
 +
 +=== Zugriffsrestriktionen auf Paketebene ===
 +<​Code>​
 +/* Utility predicate that checks if a class is in a package */
 +package_contains_class(PackageName,​ClassID) :-
 +    packageT(PackageID,​PackageName),​
 +    classDefT_In(PackageID,​ClassID).
 +
 +/* Simple convention to identify classes that form the model */
 +model_class(ClassID) :-
 +    package_contains_class('​model',​ClassID).
 +
 +/* Simple convention to identify classes that form the view */
 +view_class(ClassID) :-
 +    package_contains_class('​view',​ClassID).
 +
 +/* Forbid any access from model classes to view classes. */
 +detector_description(modelAccessRestriction,'​model must not reference view elements',​class,​unrated).
 +
 +detector_(modelAccessRestriction,​occurrence,​[(class,​ ModelClassID)],​[]) :- 
 +    model_class(ModelClassID),​
 +    view_class(ViewClassID),​
 +    detector(classDependency,​occurrence,​[(class,​ ModelClassID),​(referenced_class,​ ViewClassID)],​[]).</​Code>​
 +
 +In diesem Beispiel wird der Zugriff von Klassen des Paketes "​model"​ auf Klassen des Paketes "​view"​ gesucht. ​
 +Dabei werden mit "​_In"​[[#​ref-tutorialeigenedetektorenschreiben-2|[2]]] erweiterte PEFs[[#​ref-tutorialeigenedetektorenschreiben-3|[3]]] verwendet und über das detector-Prädikat ein anderer Detektor[[#​ref-tutorialeigenedetektorenschreiben-4|[4]]]
 +zum Suchen der Klassenabhängigkeit aufgerufen. (Achtung: Es ist KEIN Tippfehler, dass hier "​detector"​ ohne Unterstrich am Ende steht. Hinter der Unterscheidung steckt die Implementierung des Cachings. Die Regel ist einfach: Definiere "​detector_(...)",​ benutze "​detector(...)"​.)
 +
 +
 +
 +Das Beispiel soll außerdem eine Leitlinie für die Implementierung von Konventionen illustrieren. Man kann drei Ebene unterscheiden:​
 +
 +
 +  - ''​package_contains_class''​ steht exemplarisch für all die nützlichen Prädikate, die mir erlauben etwas mehr semantische Information aus der Repräsentation des Java Codes zu gewinnen, als sich aus der Struktur der Faktenbasis ergibt.
 +  - ''​model_class''​ und  ''​view_class''​ deklarieren gewisse Konventionen über die Code Struktur, die nicht direkt in Java Code ausgedrückt werden können, wie z.B. eine Untergliederung in "​Subsysteme"​ o. Ä.
 +  - ''​detector_(modelAccessRestriction...)''​ Nutzt nun die beide Ebenen um darauf aufbauen Programmierrichtlinien zu entwickeln, die in Java selbst nicht ausdrückbar wären, für die Erweiterbarkeit und Wartbarkeit des Systems aber entscheidend sind. Der Entwickler wird von der lästigen Pflicht entlastet, diese Richtlinien selbst zu überprüfen.
 +
 +
 +
 +
 +==== 7. Abschließende Hinweise ====
 +
 +=== Mögliche Fehlerquellen ===
 +
 +  * Nachdem eigene Detektoren geändert wurden, müssen die entsprechenden Dateien gespeichert und über den Menüpunkt "​**Refresh Detector Definitions**"​ im Kontextmenu des Projektes aktualisiert werden, damit die Ergebnisse in Cultivate verfügbar sind.
 +  * Beim Bewertungsschema "​unrated"​ muss die Bewertung "​occurrence"​ sein.
 +  * Auf Prolog-Ebene können Fehler in den Prädikaten sein oder Prädikate nicht gefunden werden.
 +=== Suchen von Fehlern ===
 +
 +  * Es lohnt sich, im Error Log View von Eclipse nachzuschauen,​ wenn ein eigener Detektor nicht funktioniert. Bei vielen einfachen Fehlern (ungültige Bewertung, ungültige Bewertungsinformationen),​ aber auch bei Fehlern auf Prolog-Ebene (nicht gefundene Prädikate etc.) kann man dort Hinweise finden. Dazu muss man allerdings eventuell genauer auf den StackTrace und die verschiedenen Meldungen der einzelnen Fehlerstufen schauen.
 +==== 8. Weiterführende Informationen ====
 +
 +  * **[[designprolog|Allgemeine Infos zu Prolog in Cultivate]]**
 +  * [[[#​1]|[#​1]]] [[prologdetectorapi]] (u.a. Bewertungen)
 +  * [[[#​2]|[#​2]]] [[pefsuffixes|_In und _InEncl]]
 +  * [[[#​3]|[#​3]]] [[http://​roots.iai.uni-bonn.de/​jtransformer/​Wiki.jsp?​page=PrologAST|Program Element Facts (PEFs)]]
 +  * [[[#​4]|[#​4]]] [[smelldetectorsandmetrics|Verfügbare Detektoren]]
 +  * [[analysispredicatesapi|Verfügbare Analyse-Prädikate]]
research/cultivate/tutorialeigenedetektorenschreiben.txt · Last modified: 2018/05/09 01:59 (external edit)

SEWiki, © 2019