Pergunta

A RFC para uma classe Java é um conjunto de todos os métodos que podem ser invocados em resposta a uma mensagem para um objeto da classe ou por algum método da classe.Rfc = m + r onde m = número de métodos na classe.R = Número total de outros métodos invocados diretamente do M.

Pensar que C é o .class e J é o arquivo .java do qual precisamos calcular o 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();
  }
}

Aqui M = 6 e R = 9 (não se preocupe com a chamada dentro de um loop.É considerada uma única chamada)

Calcular M é fácil.Carregue C usando o classloader e use a reflexão para obter a contagem de métodos.

Calcular R não é direto.Precisamos contar o número de chamadas de método da classe.Apenas primeiro nível.

Para calcular R devo usar regex.Normalmente o formato seria (chamadas sem usar .não são contados)

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

ou

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

sem ponto e vírgula quando o retorno da chamada se torna diretamente parâmetro para outro método.ou

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

isso se torna duas chamadas de método

Em quais outros padrões de chamada de método você consegue pensar?Existe alguma outra maneira além de usar RegEx que possa ser usada para calcular R.


ATUALIZAR:
@McDowellParece que usar BCEL posso simplificar todo o processo.Deixe-me tentar.

Foi útil?

Solução

Você poderia usar o Biblioteca de engenharia de código de bytes com binários.Você pode usar um Visitante descendente para visitar os membros e referências de uma classe.Eu usei isso para encontrar dependências de classe.

Alternativamente, você poderia reutilizar algum modelo dos arquivos de origem.Tenho certeza que o editor Java no EclipseJDT é apoiado por alguma forma de modelo.

Outras dicas

Você deve encontrar sua resposta no Especificação da linguagem Java.

Você esqueceu a chamada de método estático, chamada de método dentro de parâmetros...

Chamar um método usando reflexão (o nome do método está em uma string).

M inclui chamadas para seus próprios métodos?Ou chamadas para classes internas?Por exemplo:

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

Qual seria o valor M disso?Existem apenas três chamadas de função para um método não definido nesta classe (as chamadas nas funções d() e g()).Você deseja incluir chamadas para classes internas ou chamadas para a classe principal feitas na classe interna?Você deseja incluir chamadas para outros métodos na mesma classe?

Se você estiver olhando para qualquer chamada de método, independentemente da fonte, então uma regex provavelmente poderia funcionar, mas seria difícil de acertar (sua regex ignora corretamente strings que contêm conteúdo semelhante a chamada de método?Ele lida com chamadas de construtor corretamente?).Se você se preocupa com a origem da chamada do método, as expressões regulares provavelmente não fornecerão o que você deseja.Você precisaria usar reflexão (embora infelizmente eu não saiba o suficiente sobre reflexão para ser útil nisso).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top