views:

263

answers:

5

The RFC for a Java class is set of all methods that can be invoked in response to a message to an object of the class or by some method in the class. RFC = M + R where M = Number of methods in the class. R = Total number of other methods directly invoked from the M.

Thinking C is the .class and J is the .java file of which we need to calculate 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();
  }
}

here M=6 and R=9 (Dont worry about call inside a loop. Its considered as a single call)

Calculating M is easy. Load C using classloader and use reflection to get the count of methods.

Calculating R is not direct. We need to count the number of method calls from the class. First level only.

For calculating R i must use regex. Usually format would be ( calls with out using. are not counted)

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

or

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

with out semicolon when call return is directly becomes parameter to another method. or

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

this becomes two method calls

What other pattern of method call can u think of? Is there any other way other than using RegEx that can be used to calculate R.

A: 

You should find your answer in the Java language specification.

You have forgot static method call, method call inside parameters...

Nicolas
A: 

Calling a method using reflection (the name of the method is in a string).

kokos
+2  A: 

You could use the Byte Code Engineering Library with binaries. You can use a DescendingVisitor to visit a class' members and references. I've used it to find class dependencies.

Alternatively, you could reuse some model of the source files. I'm pretty sure the Java editor in the Eclipse JDT is backed by some form of model.

McDowell
A: 

Does M include calls to its own methods? Or calls to inner classes? For instance:

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

What would the M value of this be? There's only three function calls to a method not defined in this class (the calls in the d() and g() functions). Do you want to include calls to inner classes, or calls to the main class made in the inner class? Do you want to include calls to other methods on the same class?

If you're looking at any method calls, regardless of the source, then a regex could probably work, but would be tricky to get right (does your regex properly ignore strings that contain method-call like contents? Does it handle constructor calls properly?). If you care about the source of the method call then regexes probably won't get you what you want. You'd need to use reflection (though unfortunately I don't know enough about reflection to be helpful there).

Herms
A: 

@McDowell Looks like using BCEL I can simplify the whole process. Let me try it.

Thej