Алгоритм выполнения RFC-вычисления в Java - PullRequest
4 голосов
/ 21 августа 2008

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

Мышление C - это класс .c, а 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 (не беспокойтесь о вызове внутри цикла. Он рассматривается как один вызов)

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

Расчет 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();

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

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


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

Ответы [ 4 ]

2 голосов
/ 21 августа 2008

Вы можете использовать библиотеку Byte Code Engineering с двоичными файлами. Вы можете использовать DescendingVisitor , чтобы посетить членов класса и ссылки. Я использовал его, чтобы найти классовые зависимости .

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

0 голосов
/ 21 августа 2008

Включает ли 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(); }
  }
}

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

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

0 голосов
/ 21 августа 2008

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

0 голосов
/ 21 августа 2008

Вы должны найти свой ответ в спецификации языка Java .

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...