Algorithmus zur RFC-Berechnung in Java


2

Der RFC für eine Java-Klasse besteht aus allen Methoden, die als Reaktion auf eine Nachricht an ein Objekt der Klasse oder durch eine Methode in der Klasse aufgerufen werden können. RFC = M + R wo M = Anzahl der Methoden in der Klasse. R = Gesamtzahl der direkt vom M aufgerufenen Methoden

Denken C ist die .class und J ist die .java-Datei, von der wir RFC berechnen müssen.

 
class J{ 

a(){} 
b(){} 
c(){ 
    e1.e(); 
    e1.f(); 
    e1.g(); 
} 
h(){ 
    i.k(); 
    i.j(); 
    } 
    m(){} 
    n(){ 
    i.o(); 
    i.p(); 
    i.p(); 
    i.p(); 
    } 
} 

hier M = 6 und R = 9 (Keine Sorge in einer Schleife über Anruf. Dieser wird als einziger Aufruf betrachtet wird)

Berechnung M ist einfach. Laden Sie C mit dem Classloader und verwenden Sie reflection, um die Anzahl der Methoden zu ermitteln.

Berechnung von R ist nicht direkt. Wir müssen die Anzahl der Methodenaufrufe von der Klasse zählen. Nur erste Ebene.

Für die Berechnung von R muss ich Regex verwenden. Normalerweise würde Format (Anrufe ohne Verwendung. Werden nicht gezählt) sein

 
[variable_name].[method_name]([zero or more parameters]); 

oder

 
[variable_name].[method_name]([zero or more parameters]) 

mit aus Semikolon, wenn der Anruf Rückkehr wird direkt Parameter an eine andere Methode. oder

 
[variable_name].[method_name]([zero or more parameters]).method2(); 

wird dies zwei Methodenaufrufe

Was andere Muster des Methodenaufruf können Sie sich vorstellen? Gibt es eine andere Art und Weise andere als RegEx verwenden, die verwendet werden können, R. zu berechnen


UPDATE:
@McDowell Sieht aus wie BCEL ich mit dem gesamten Prozess vereinfachen kann. Lass mich es versuchen.

2

Sie könnten die Byte Code Engineering Library mit Binärdateien verwenden. Sie können eine DescendingVisitor verwenden, um Mitglieder und Referenzen einer Klasse zu besuchen. Ich habe es zu find class dependencies verwendet.

Alternativ können Sie ein Modell der Quelldateien erneut verwenden. Ich bin mir ziemlich sicher, dass der Java-Editor in der Eclipse JDT von irgendeiner Form des Modells unterstützt wird.


0

Sie sollten Ihre Antwort in der Java language specification finden.

Sie statischen Methodenaufruf vergessen haben, Methodenaufruf innerhalb Parameter ...


0

ein Verfahren unter Verwendung von Reflexion aufrufen (der Name des Verfahrens ist in einem String).


0

Enthält M Aufrufe an seine eigenen Methoden? Oder ruft zu inneren Klassen? Zum Beispiel:

class J { 
    a() { } 
    b() { this.a(); } 
    c() { jj.aa(); } 
    d() { i.k(); } 
    e() { this.f().a(); } 
    f() { return this; } 
    g() { i.m().n(); } 

    class JJ { 
    aa() { a(); } 
    } 
} 

Was wäre der M-Wert davon? Es gibt nur drei Funktionsaufrufe für eine Methode, die nicht in dieser Klasse definiert ist (die Aufrufe in den Funktionen d() und g()).Möchten Sie Aufrufe an innere Klassen oder Aufrufe an die Hauptklasse in der inneren Klasse einfügen? Möchten Sie Aufrufe an andere Methoden in derselben Klasse einschließen? Wenn Sie irgendeine Methode aufrufen, unabhängig von der Quelle, dann könnte eine Regex wahrscheinlich funktionieren, aber es wäre schwierig, sie richtig zu machen (ignoriert Ihre Regex richtig Strings, die Methodenaufruf wie Inhalt enthalten? Tut es das?) Konstruktor Aufrufe richtig behandeln?). Wenn Sie sich über die Quelle des Methodenaufrufs Gedanken machen, werden Regexes wahrscheinlich nicht bekommen, was Sie wollen. Du solltest Reflektion benutzen (obwohl ich leider nicht genug über Reflektion weiß, um dort hilfreich zu sein).