- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Tool to compute source code metrics?
Wed, 2011-07-13, 14:21
Hi all,
does anyone know about a tool to compute source code metrics for Scala
code? Using an existing tool like ckjm
unfortunately produces garbled
results, as all the compiler-inserted methods and classes are rather
idiosyncratic. Preferably such a tool would be independent of the build
system used, e.g., by consuming class files rather than source files
(ckjm works like this).
Does anyone know such a tool (Google didn't turn up something useful) or
is hacking into scalap my best bet?
Best wishes,
Andreas
Wed, 2011-07-20, 11:47
#2
Re: Re: Tool to compute source code metrics?
Hi Dave,
sorry for not replying sooner; was offline for a couple of days.
> I ran this tool on scala-library.jar though I had to unpack it
> otherwise it couldn't find the class files.
>
> What is idiosyncratic about the metrics?
The problem is that metrics like NPM (Number of Public Methods) or WMC
(Weighted Methods per Class) also take into account methods the
programmer never wrote, i.e., "infrastructure" methods inserted by
scalac. As such, these metrics are not very suitable for judging the
complexity of the source code; the ckjm tool rather judges the
complexity of the bytecode (which is, for Java, almost the same thing).
Of course, depending on your needs, this may be what you are looking for.
That being said, consuming bytecode rather than source code is IMHO
greatly preferable form a usability perspective; you don't have to
integrate with build tool X but can just throw a JAR at the analysis.
And at least in Scala's case, I think the class files contain enough
information to reconstruct the method-level structure of the Scala
source. (That's what scalap does, after all.)
> But for 2826 classes I get error that it can not find the class file
> but the class files are there in the directory. Why is it saying that
> it can not find it. Do you get these errors too?:
Yes, I do get these errors.
> java.lang.ClassNotFoundException: Exception while looking for class
> scala.runtime.AbstractFunction1: java.io.IOException: Couldn't find:
> scala.runtime.AbstractFunction1.class
> java.lang.ClassNotFoundException: Exception while looking for class
> scala.runtime.AbstractFunction1$mcVI$sp: java.io.IOException: Couldn't
> find: scala.runtime.AbstractFunction1$mcVI$sp.class
The odd thing is that ckjm *does* compute metrics for both of these
classes, but nevertheless outputs an error message:
> java -jar ckjm-1.9.jar scala/runtime/AbstractFunction1.class
scala/runtime/AbstractFunction1\$mcVI\$sp.class
java.lang.ClassNotFoundException: Exception while looking for class
scala.runtime.AbstractFunction1: java.io.IOException: Couldn't find:
scala.runtime.AbstractFunction1.class
scala.runtime.AbstractFunction1$mcVI$sp 7 0 0 6 16 21 0 7
scala.runtime.AbstractFunction1 76 1 1 3 153 2850 1 76
Looks like a bug to me, but I yethave to dig into ckjm's source to find
out what's going on.
Best wishes,
Andreas
Wed, 2011-07-20, 12:57
#3
Re: Tool to compute source code metrics?
Probably if you want full and accurate software metrics and since
Scala is also a functional programming language there must be also
something like FP metrics (Chidamber and Kemerer is for OO metrics)
Here I found a paper for metrics in Haskell:
http://kar.kent.ac.uk/14117/1/SOFTWARE_MEASUREMENT_FOR.pdf
Or are you only interested in OO metrics?
Sat, 2011-07-23, 02:37
#4
Re: Tool to compute source code metrics?
On Wednesday 13 July 2011, Andreas Sewe wrote:
> Hi all,
>
> does anyone know about a tool to compute source code metrics for
> Scala code? ...
What do you want to measure?
> Andreas
Randall Schulz
Mon, 2011-07-25, 08:27
#5
Re: Tool to compute source code metrics?
Hi Randall,
>> does anyone know about a tool to compute source code metrics for
>> Scala code? ...
>
> What do you want to measure?
doesn't necessarily have to be Chidamber and Kemerer
or the FP-metrics Dave pointed me to; I am not married to a particular
set of metrics. In fact, something simpler like the number of mixins
used per class would be of interest, too.
I was just wondering, what's already out there.
Best wishes,
Andreas
Hi Andreas,
I don't know anything else and I read that it was made out of
frustration that there was nothing similar doing Chidamber and Kemerer
metrics.
Do you think it is possible to get it working for Scala? It is open
source after all.
I ran this tool on scala-library.jar though I had to unpack it
otherwise it couldn't find the class files.
With cygwin bin directory in my path environment variable I can do
this on Windows:
C:\Users\Dave\scala\SCALA-~1\build\pack\lib>jar xvf scala-library.jar
C:\Users\Dave\scala\SCALA-~1\build\pack\lib>jar tf scala-library.jar |
sed -n '/\.class$/ p' | java -jar ckjm-1.9.jar > metrics.txt
C:\Users\Dave\scala\SCALA-~1\build\pack\lib>jar tf scala-library.jar |
sed -n '/\.class$/ p' | java -jar ckjm-1.9.jar 2> errormetrics.txt
What is idiosyncratic about the metrics?
Do you understand this below (I list only a few)?
For 5434 classes I get the metrics like:
metrics.txt
========
scala.xml.parsing.XhtmlEntities 4 1 0 3 8 6 0 4
scala.sys.process.ProcessBuilderImpl$IStreamBuilder 3 0 2 6 5 3 4 3
scala.collection.generic.GenericParTemplate 5 1 0 6 5 10 38 5
scala.concurrent.pilib 2 1 0 3 4 1 0 2
scala.actors.threadpool.locks.Lock 6 1 0 2 6 15 6 6
scala.Function0$mcC$sp$class 2 1 0 2 3 1 1 2
scala.collection.mutable.Stack$ 6 0 0 10 10 11 1 5
scala.util.automata.BaseBerrySethi$$anonfun$compLast$1 4 0 0 5 7 4 1 4
scala.collection.TraversableViewLike$TakenWhile 0 1 0 2 0 0 2 0
scala.math.LowPriorityEquiv 1 1 0 2 1 0 1 1
scala.xml.dtd.Scanner$$anonfun$accS$1 4 0 0 5 8 4 1 4
scala.collection.immutable.Stream$$anonfun$scanLeft$1 4 0 0 8 11 4 1 4
scala.collection.parallel.ParSeqLike$$anonfun$zip$1 4 0 0 5 6 6 1 4
scala.collection.parallel.ParMap$ 6 0 0 10 9 15 2 5
scala.io.BufferedSource$$anonfun$iter$3 4 0 0 4 7 6 1 4
scala.io.BufferedSource$$anonfun$iter$2 5 0 0 4 8 10 1 5
scala.io.BufferedSource$$anonfun$iter$1 6 0 0 7 11 9 2 6
scala.Function2$mcZDD$sp$$anonfun$curried$mcZDD$sp$1 4 0 0 6 8 4 2 4
scala.collection.immutable.HashSet$SerializationProxy$$anonfun
$readObject$1 5 0 0 6 12 8 1 5
scala.collection.immutable.IntMap$$anonfun$unionWith$2 3 0 0 5 6 1 1 3
scala.collection.immutable.IntMap$$anonfun$unionWith$1 3 0 0 5 6 1 1 3
scala.actors.OutputChannel 4 1 0 1 4 6 52 4
scala.collection.parallel.mutable.ParHashTable 1 1 0 2 1 0 5 1
scala.xml.dtd.Decl 1 1 1 1 2 0 3 1
scala.Function$$anonfun$curried$2$$anonfun$apply$3 5 0 0 5 7 8 2 5
scala.AnyValCompanion 0 1 0 1 0 0 10 0
scala.collection.immutable.Traversable 2 1 0 6 2 1 42 2
scala.Function2$mcVJD$sp$class 8 1 0 5 14 28 1 8
scala.collection.parallel.ParIterableLike$TakeWhile$$anonfun$split$14
4 0 0 5 8 6 1 4
scala.collection.JavaConversions$JCollectionWrapper 148 1 0 62 289
10876 2 147
[..]
But for 2826 classes I get error that it can not find the class file
but the class files are there in the directory. Why is it saying that
it can not find it. Do you get these errors too?:
errormetrics.txt
===========
java.lang.ClassNotFoundException: Exception while looking for class
scala.runtime.AbstractFunction1: java.io.IOException: Couldn't find:
scala.runtime.AbstractFunction1.class
java.lang.ClassNotFoundException: Exception while looking for class
scala.runtime.AbstractFunction1$mcVI$sp: java.io.IOException: Couldn't
find: scala.runtime.AbstractFunction1$mcVI$sp.class
java.lang.ClassNotFoundException: Exception while looking for class
scala.runtime.AbstractFunction1: java.io.IOException: Couldn't find:
scala.runtime.AbstractFunction1.class
java.lang.ClassNotFoundException: Exception while looking for class
scala.runtime.AbstractFunction1$mcVJ$sp: java.io.IOException: Couldn't
find: scala.runtime.AbstractFunction1$mcVJ$sp.class
java.lang.ClassNotFoundException: Exception while looking for class
scala.runtime.AbstractFunction1$mcVF$sp: java.io.IOException: Couldn't
find: scala.runtime.AbstractFunction1$mcVF$sp.class
java.lang.ClassNotFoundException: Exception while looking for class
scala.runtime.AbstractFunction1$mcVD$sp: java.io.IOException: Couldn't
find: scala.runtime.AbstractFunction1$mcVD$sp.class
java.lang.ClassNotFoundException: Exception while looking for class
scala.runtime.AbstractFunction1: java.io.IOException: Couldn't find:
scala.runtime.AbstractFunction1.class
java.lang.ClassNotFoundException: Exception while looking for class
scala.runtime.AbstractFunction1: java.io.IOException: Couldn't find:
scala.runtime.AbstractFunction1.class
java.lang.ClassNotFoundException: Exception while looking for class
scala.runtime.AbstractFunction1: java.io.IOException: Couldn't find:
scala.runtime.AbstractFunction1.class
java.lang.ClassNotFoundException: Exception while looking for class
scala.runtime.AbstractFunction1: java.io.IOException: Couldn't find:
scala.runtime.AbstractFunction1.class
[..]