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

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

здесь M = 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();

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

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


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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
0
939
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

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

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

Ответ принят как подходящий

Вы можете использовать Инженерная библиотека байтового кода с двоичными файлами. Вы можете использовать По убыванию Посетитель для посещения членов и ссылок класса. Я использовал его на найти зависимости классов.

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

Включает ли 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 ()). Вы хотите включить вызовы внутренних классов или вызовы основного класса, сделанные во внутреннем классе? Вы хотите включить вызовы других методов в тот же класс?

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

Другие вопросы по теме