Алгоритм для выполнения расчета RFC в Java


2

RFC для Java-класса - это набор всех методов, которые могут быть вызваны в ответ на сообщение объекту класса или некоторым методом в классе. RFC = M + R где M = Количество методов в классе. R = Общее количество других методов, непосредственно вызываемых из M.

Мышление C является .class, а J - это .java-файл, который нам нужно рассчитать RFC.

 
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(); 
    } 
} 

здесь М = 6 и R = 9 (Не беспокойтесь о вызове внутри цикла. Это рассматривается как один вызов)

Расчет M легко. Загрузите C с помощью загрузчика классов и используйте отражение, чтобы получить количество методов.

Расчет R не является прямым. Нам нужно подсчитать количество вызовов методов из класса. Только первый уровень.

Для вычисления R я должен использовать регулярное выражение. Обычно формат будет (звонки без использования. Не учитывается)

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

или

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

с амбулаторной точкой с запятой, когда обратный вызовом непосредственно становится параметром в другой метод. или

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

это становится два метода вызывает

Какие другие модели вызова метода вы можете думать? Есть ли другой способ, кроме использования регулярных выражений, которые могут быть использованы для расчета R.


UPDATE:
@McDowell Похоже, с помощью BCEL я могу упростить весь процесс. Позвольте мне попробовать.

2

Вы можете использовать Byte Code Engineering Library с двоичными файлами. Вы можете использовать DescendingVisitor для посещения членов класса и ссылок. Я использовал его для find class dependencies.

В качестве альтернативы вы можете повторно использовать некоторую модель исходных файлов. Я почти уверен, что редактор Java в Eclipse JDT поддерживается некоторой формой модели.


0

Вы должны найти свой ответ в Java language specification.

Вы забыли статический метод вызова, вызов метода внутри параметров ...


0

Вызов метода с помощью отражения (имя метода в виде строки).


0

Включает ли M призывы к своим методам? Или звонки во внутренние классы? Например:

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(); } 
    } 
} 

Какова будет величина M этого? Существует только три вызова функций для метода, не определенного в этом классе (вызовы функций d() и g()).Вы хотите включить вызовы во внутренние классы или вызовы основного класса, сделанные во внутреннем классе? Вы хотите включить вызовы других методов в один класс?

Если вы ищете любые вызовы методов, независимо от источника, то, возможно, будет работать регулярное выражение, но было бы сложно получить правильное значение (правильно ли ваше регулярное выражение игнорирует строки, содержащие контент-вызов типа? вызов конструктора вызовов правильно?). Если вам небезразличен источник вызова метода, регулярные выражения, вероятно, не помогут вам в том, что вы хотите. Вам нужно будет использовать рефлексию (хотя, к сожалению, я недостаточно знаю об отражении, чтобы быть полезной там).