[ANN] MetricsReloaded 0.5 released
Announcing the release of MetricsReloaded 0.5. MetricsReloaded is a plugin to IntelliJ
IDEA which calculates and displays a large number of source code metrics for any IDEA
project. MetricsReloaded is designed for use in project tracking, quality assurance, and
developer training. Over 220 metrics are currently available at the project, module, package,
class, and method levels. Metrics can be sorted, graphed, compared with previous metrics runs,
and exported to file. Additionally, MetricReloaded offers detection, display, and visualization
of class and package dependency cycles, and calculates a variety of graph-theoretic metrics for each cycle.
MetricsReloaded is available via the Plugin Manager.
MetricsReloaded 0.5 is only supported against the EAP 5.0 (Irida) version of IDEA.
Calculating project metrics with MetricsReloaded:
In use, MetricsReloaded acts much like the "Inspect Code..." panel built into IDEA,
except that instead of finding code weaknesses, it calculates numeric values
about the code. MetricsReloaded can be run from the main menu (under Analyze/Calculate Metrics...)
or by right-clicking in the Project or Package views, or in the editor. If selected from the main menu,
metrics will be calculated for all files in the project. If selected from the Project or
Package views, metrics are calculated for the selected file, package, directory, or module.
If selected in the editor, metrics will only be calculated for the active file.
Next, a panel will appear, asking whether you wish to calculate metrics for all java files,
only product files, or only test files. After you've selected here, you are then shown
the main metrics configuration panel. Like choosing inspections in the inspection panel,
the metrics configuration panel lets you choose which metrics you wish to run. Also like
the inspection panel, the user may create multiple named inspection profiles, allowing him
to have standard sets of metrics to run for different uses. Finally, the metrics configuration
panel allows the user to configure thresholds for each metric. Metrics values which
are outside of the selected threshold values will be highlighted in the metrics display.
When calculation is complete, the metrics display panel will be become visible. The metrics
display panel consists of a tabbed set of tables, filled with metrics values. Metrics
values can be sorted on any column, saved as a snapshot file, compared with values from a previous
snapshot file, or exported to a comma-separated value (.csv) file. By right-clicking on a column,
that metric's values may be displayed in a histogram, distribution graph, or pie chart (if
appropriate). It should all be pretty obvious.
Metrics Currently Supported
223 metrics
Project Metrics
Average cyclomatic complexity
Comment lines of code
Comment ratio
Javadoc class coverage
Javadoc field coverage
Javadoc lines of code
Javadoc method coverage
Lines of HTML
Lines of JSP
Lines of XML
Lines of code
Lines of product code
Lines of test code
Number of HTML files
Number of JSP files
Number of XML files
Number of abstract classes
Number of classes
Number of concrete classes
Number of interfaces
Number of methods
Number of packages
Number of product classes
Number of test classes
Number of top-level classes
Number of top-level interfaces
Source lines of code
Test ratio
Total cyclomatic complexity
True comment ratio
Module Metrics
Average cyclomatic complexity
Comment lines of code
Comment ratio
Encapsulation ratio
Javadoc class coverage
Javadoc field coverage
Javadoc lines of code
Javadoc method coverage
Lines of HTML
Lines of JSP
Lines of XML
Lines of code
Lines of product code
Lines of test code
Number of HTML files
Number of JSP files
Number of XML files
Number of abstract classes
Number of classes
Number of concrete classes
Number of interfaces
Number of methods
Number of product classes
Number of test classes
Number of top-level classes
Number of top-level interfaces
Source lines of code
Test ratio
Total cyclomatic complexity
True comment ratio
Package Metrics
Abstractness
Afferent coupling
Average cyclomatic complexity
Comment lines of code
Comment lines of code (recursive)
Comment ratio
Comment ratio (recursive)
Distance to main sequence
Efferent coupling
Encapsulation ratio
Instability
Javadoc class coverage
Javadoc class coverage (recursive)
Javadoc field coverage
Javadoc field coverage (recursive)
Javadoc lines of code
Javadoc lines of code (recursive)
Javadoc method coverage
Javadoc method coverage (recursive)
Lines of code
Lines of code (recursive)
Lines of product code
Lines of product code (recursive)
Lines of test code
Lines of test code (recursive)
Number of abstract classes
Number of abstract classes (recursive)
Number of classes
Number of classes (recursive)
Number of concrete classes
Number of concrete classes (recursive)
Number of dependent packages
Number of interfaces
Number of interfaces (recursive)
Number of methods
Number of methods (recursive)
Number of package dependencies
Number of product classes
Number of product classes (recursive)
Number of test classes
Number of test classes (recursive)
Number of top-level classes
Number of top-level classes (recursive)
Number of top-level interfaces
Number of top-level interfaces (recursive)
Source lines of code
Source lines of code (recursive)
Test ratio
Total cyclomatic complexity
True comment ratio
True comment ratio (recursive)
Interface Metrics
Adjusted level order
Comment lines of code
Comment ratio
Coupling between objects
Interface size (attributes)
Interface size (operations + attributes)
Interface size (operations)
Javadoc field coverage
Javadoc lines of code
Javadoc method coverage
Level order
Lines of code
Number of commands
Number of cyclic dependencies
Number of dependencies
Number of dependent packages
Number of dependents
Number of implementations
Number of package dependencies
Number of queries
Number of subinterfaces
Number of transitive dependencies
Number of transitive dependents
Source lines of code
True comment ratio
Class Metrics
Adjusted level order
Average number of parameters
Average operation complexity
Average operation size
Class size (attributes)
Class size (operations + attributes)
Class size (operations)
Comment lines of code
Comment ratio
Coupling between objects
Depth of inheritance tree
Halstead bugs
Halstead difficulty
Halstead effort
Halstead length
Halstead vocabulary
Halstead volume
Javadoc field coverage
Javadoc lines of code
Javadoc method coverage
Level order
Lines of code
Maximum operation complexity
Maximum operation size
Number of attributes added
Number of attributes inherited
Number of commands
Number of constructors
Number of cyclic dependencies
Number of dependencies
Number of dependent packages
Number of dependents
Number of inner classes
Number of interfaces implemented
Number of operations added
Number of operations inherited
Number of operations overridden
Number of package dependencies
Number of queries
Number of statements
Number of subclasses
Number of transitive dependencies
Number of transitive dependents
Source lines of code
True comment ratio
Weighted method complexity
Method Metrics
Comment lines of code
Comment ratio
Conditional nesting depth
Control density
Cyclomatic complexity
Design complexity
Essential cyclomatic complexity
Extended cyclomatic complexity
Halstead bugs
Halstead difficulty
Halstead effort
Halstead length
Halstead vocabulary
Halstead volume
Javadoc lines of code
Lines of code
Loop nesting depth
Nesting depth
Number of branch statements
Number of control statements
Number of exceptions caught
Number of exceptions thrown
Number of executable statements
Number of expressions
Number of implementations
Number of loop statements
Number of method calls
Number of overriding methods
Number of parameters
Number of return points
Number of statements
Number of times called
Number of times called in product code
Number of times called in test code
Number of type cast expressions
Quality Criteria Profile (Correctness)
Quality Criteria Profile (Maintainability)
Quality Criteria Profile (Reliability)
Relative lines of code
Source lines of code
True comment ratio
Finding class and package dependency cycles using MetricsReloaded:
MetricsReloaded can create reports of class or package dependency cycles in a project.
Simply select "Show Package Cycles..." or "Show Class Cycles..." under the "Analyze" menu.
A small popup will ask whether test code should be included in the analysis, and whether
(for class dependency cycles) inner classes should be considered separately or together with
their outer classes. After analyzing the project, a report window will be generated, describing
the mutually dependent sets of classes or packages found, and showing certain graph-theoretic
metrics for each of the cycle's complexity. Class and package cycles are known "code smells",
indicating a probably weakness in the project's design and higher costs to understand or modify
the code. While the topological metrics calculated for each dependency cycle have a variety of
interesting mathematical properties, basically all you need to know is that any of them are over
three or so the cycle is going to be a major pain in the ass to refactor. For further insight
into a dependency cycle's structure, click on the cycle's row and select "Show dependency graph".
A small visualization of the dependencies and their strengths will be displayed.
Caveats:
MetricsReloaded is available in beta form. This implies that there are certain
to be bugs still in the code. Users of MetricsReloaded are encouraged to report bugs
on the IDEA Plugins forum.
Changes since 0.4:
Updated with changes for Irida APIs.
Package and class dependency cycle reporting, metrics and visualization.
12 new metrics added, for calculating numbers and sizes of JSP, XML, and HTML files on
a per-project or per-module basis.
Many bug fixes, UI improvements, and general code improvements.
Terms of use:
MetricsReloaded is public domain software, available in either binary or source
form for any use, commercial or non-commercial. In particular, inclusion of MetricsReloaded
in the core IntelliJ IDEA product is expressly allowed and desired. The graphing
functionality of MetricsReloaded is provided by the open source JFreeChart library
(http://www.jfree.org). JFreeChart is available under the GNU Lessser General Public License,
a copy of which is included with the MetricsReloaded distribution. Any redistribution
of MetricsReloaded or JFreeChart is expected to follow the letter and spirit of that license.
The graph visualization functionality of MetricsReloaded is provided by the Jung graph
visualization library. Jung is available under the BSD License. Any redistribution
of MetricsReloaded or Jung is expected to follow the letter and spirit of that license.
More information about Jung is available at http://jung.sourceforge.net.
Jung depends on the Apache common-collections library for it's internal data models.
commons-collections is released under the Apache License. Any redistribution of
MetricsReloaded or common-collections is expected to follow the letter and spirit of
that license. More information about the commons-collection library is available at
http://jakarta.apache.org/commons/collections.
Important Admonition:
The primary purpose of MetricsReloaded is to allow developers and quality
assurance personnel greater insight into their code, so as to help them find weaknesses
and places for improvement. As a secondary purpose, MetricsReloaded can be used by
individual developers as a project management tool, to track their efforts and help them
improve their estimates. The one thing MetricsReloaded shouldn't be used for however,
is development management. USING THE NUMBERS CREATED BY METRICSRELOADED FOR PURPOSES OF
RANKING DEVELOPER OUTPUTS FOR HIRING, REVIEW, PROMOTION, OR RETENTION IS DISCOURAGED
IN THE STRONGEST TERMS.
请先登录再写评论。
Dave,
I'm clueless, and overwhelmed: I don't know where to start. So many
options, so many technical terms I saw once in a book, so many switches.
If you had to pick 5 rules, which ones would they be.
If you had to pick 10, or 15?
I'm sure there is a gem, or many, hidden amongst the 220+ rules, that
can help me write better code, like IG did, but I have no clue where it is.
TIA
Alain
Is it identical to 0.4 apart from Irrida support?
No, if it was just Irida updates I'd have done it weeks ago. The problem was that I was half-way through a bunch of big changes when Irida hit. From above, here's the changes:
Changes since 0.4:
Updated with changes for Irida APIs.
Package and class dependency cycle reporting, metrics and visualization.
12 new metrics added, for calculating numbers and sizes of JSP, XML, and HTML files on
a per-project or per-module basis.
Many bug fixes, UI improvements, and general code improvements.
--Dave Griffith
I think that this early in EAP with bugs such as XML editing causing a
stack overflow there is still room for Pallada updates.
I, for one, cannot currently use Irida because of the XML issue.
I would be very happy if I could update my MetricsReloaded on Pallada,
at least until I can work in Irida.
Amnon
To be honest, I find I'm using the metrics more for getting overviews of project status and quality, rather than more direct "improve my coding style" feedback. IG is just too good at that, so the ideas for improvement tend to get put into IG rather than MR. But to your questions, what I actually do isn't run 5 or 15 metrics, but have a handful of different profiles of about 5-10 metrics each, and use them for different purposes. Profiles I've got include:
Complexity--All of the method complexity metrics (plus nesting-depth and loop count), plus the per-class average and total method complexities. Tells me where control logic is starting to get too snarled.
Project size -- counts of classes and lines of code, divied up by package (and module, if appropriate). I'll be adding the new XML/HTML/JSP counts/line counts to this as well. Good for giving you a good idea just how big your project is, and how it's growing.
Martin Metrics--Package metrics including afferent coupling, efferent coupling, instability, abstractness, and distance to the main sequence. With a little interpretation, these can give some good insight into package structure.
Class coupling-- it's very useful to know which classes use a lot of other classes, and which classes are used by a lot of other classes, directly or indirectly. Any time where these numbers get too high, you're asking for high maintenance costs.
Javadoc--Per-class and per-package javadoc counts and ratios. Used for projects with javadoc requirements.
I'm also finding the new class and package dependency cycle stuff very strong for finding places for design improvement. I intend to do a lot more with code visualizations like that in the future.
Notes on best use of Metrics Reloaded:
1)Use thresholds where appropriate to highlight problem areas.
2)Use the histograms, distribution graphs and pie charts to give you a better overview of the code as a whole.
3)Don't get caught up in specific values of specific metrics. These are just guidelines, you shouldn't be betting your paycheck on them.
--Dave Griffith
There is indeed value in releasing MetricsReloaded 0.5 for Pallada, but looking over my schedule there's just about no chance I'll actually do it. If some kind soul feels like creating such a release, it should be pretty easy. The source is included in the distribution, and only a couple of changes should be necessary.
--Dave Griffith
Dave Griffith wrote:
I totally understand your constraints...
I might give it a whirl, though I never tried a plug-in before.
Thanks for the info,
Amnon
I really like this new functionality!
One first feature request: One of my projects contains quite a few
cyclic package dependencies that I'm trying to clean up, and the display
gets quite unreadable. I'd love to be able to switch to seeing only
edges to/from a single package at a time, and back to seeing everything
at the same time again. Right now I have to keep dragging package nodes
around to see which edges and numbers move along with the node.
>I really like this new functionality!
Glad to hear it. I intentionally put the visualization stuff out somewhat "raw", so as to get feedback and ideas for improvement. Some of the future directions I've thought of include:
*Tooltips over nodes and edges with more descriptive data, including possibly some metrics.
*Temporary/togglable highlighting of the edges to/from a node.
*Layouts more advanced that a simple circle (DAG, web, etc.).
*(Auto-)scroll from visualization to editor.
*Various other "right-click" menu options.
*More information-rich renderings of nodes and edges (ideally while keeping nodes sizes small, so as to enable larger graphs without cluttering.
*Triggering refactorings from the visualization.
*Temporary "hiding" of nodes/edges.
This is somewhat uncharted territory, putting visualizations into an IDE, but I think it could be very valuable indeed. I'm eager to hear people's ideas. I had originally thought to build an entire large plugin (to be called BattleSpaces) which would turn IDEA be the best possible code visualization platform, and realized that I simply didn't know enough to do so. With luck and community input, perhaps I can get there in easy stages.
--Dave Griffith
Every time i try to calculate metrics i just get:
java.lang.NullPointerException
at com.siyeh.metrics.utils.ClassUtils.calculateModuleName(ClassUtils.java:70)
at com.siyeh.metrics.moduleCalculators.ElementRatioModuleCalculator.incrementNumerator(ElementRatioModuleCalculator.java:48)
at com.siyeh.metrics.moduleCalculators.CommentRatioModuleCalculator.beforeComment(CommentRatioModuleCalculator.java:17)
at com.siyeh.metrics.execution.Traversal.visitComment(Traversal.java:46)
at com.intellij.psi.impl.source.tree.ba.accept(ba.java)
at com.intellij.psi.impl.source.TreeWrapperPsiElement.acceptChildren(TreeWrapperPsiElement.java:101)
at com.intellij.psi.PsiRecursiveElementVisitor.visitElement(PsiRecursiveElementVisitor.java:11)
at com.intellij.psi.JavaElementVisitor.visitFile(JavaElementVisitor.java:130)
at com.siyeh.metrics.execution.Traversal.visitFile(Traversal.java:219)
at com.intellij.psi.JavaElementVisitor.visitJspFile(JavaElementVisitor.java:328)
at com.intellij.psi.impl.source.jsp.JspFileImpl.accept(JspFileImpl.java:507)
at com.siyeh.metrics.execution.MetricsExecutionContextImpl$1.run(MetricsExecutionContextImpl.java:78)
at com.intellij.openapi.progress.a.a.runProcess(a.java:61)
at com.intellij.openapi.application.impl.ApplicationImpl$1a_.run(ApplicationImpl$1a_.java:8)
Build 3103, Linux.
/Kreiger
Attachment(s):
signature.asc
Dave,
We are using todos more and more to track technical debts (refactorings that are not done on the spot but should).
I would love to see the number of todos as a metric. MR would get the todo patterns and filters from IDEA for the user to chose from.
Right now we have our continuous build trend the overall project todo count but it is too general. MR could give more detailed report.
Again, awesome plugin even though I cannot use 0.5 since I am in the same camp as Amnon.
Jacques
Hello Dave,
That might be a little different than what you had in mind but I have always wished for a project home page inside the IDE. This project home page would present a high level status of the project things like test quality metrics and design quality metrics. I would see something like
failing/passing acceptance tests, test coverage, # class/package, # unit tests, avg complexity, # todo, # cycle, build time
Given the proper sub-plugin architecture this could become the portal for multiple tools to hook in. The information could be populated locally or from a continous integration server.
Jacques
I just coded up TODO counts. They'll be in 0.6.
--Dave Griffith
Not related specifically to this thread but it might be useful to you:
(just running a bunch of metrics)
java.lang.NullPointerException
at
com.siyeh.metrics.utils.StringToFractionMap.put(StringToFractionMap.java:43)
at
com.siyeh.metrics.metricModel.MetricsResultImpl.postValue(MetricsResultImpl.
java:32)
at
com.siyeh.metrics.metricModel.MetricsResultImpl.postValue(MetricsResultImpl.
java:22)
at
com.siyeh.metrics.metricModel.MetricsRunImpl.postMetric(MetricsRunImpl.java:
45)
at
com.siyeh.metrics.execution.BaseMetricsCalculator.postMetric(BaseMetricsCalc
ulator.java:183)
at
com.siyeh.metrics.classCalculators.ClassCalculator.postMetric(ClassCalculato
r.java:9)
at
com.siyeh.metrics.classCalculators.ClassCalculator.postMetric(ClassCalculato
r.java:18)
at
com.siyeh.metrics.classCalculators.ClassSizeAttributesCalculator.beforeClass
(ClassSizeAttributesCalculator.java:25)
at com.siyeh.metrics.execution.Traversal.visitClass(Traversal.java:227)
at
com.intellij.psi.JavaElementVisitor.visitTypeParameter(JavaElementVisitor.ja
va:384)
at com.intellij.psi.impl.source.tree.a.cx.accept(cx.java)
at
com.intellij.psi.impl.source.TreeWrapperPsiElement.acceptChildren(TreeWrappe
rPsiElement.java:101)
at
com.intellij.psi.PsiRecursiveElementVisitor.visitElement(PsiRecursiveElement
Visitor.java:11)
at
com.intellij.psi.JavaElementVisitor.visitTypeParameterList(JavaElementVisito
r.java:260)
at com.intellij.psi.impl.source.tree.a.cz.accept(cz.java:34)
at
com.intellij.psi.impl.source.TreeWrapperPsiElement.acceptChildren(TreeWrappe
rPsiElement.java:101)
at
com.intellij.psi.PsiRecursiveElementVisitor.visitElement(PsiRecursiveElement
Visitor.java:11)
at
com.intellij.psi.JavaElementVisitor.visitClass(JavaElementVisitor.java:54)
at com.siyeh.metrics.execution.Traversal.visitClass(Traversal.java:229)
at com.intellij.psi.impl.source.l.accept(l.java:8)
at
com.intellij.psi.impl.source.TreeWrapperPsiElement.acceptChildren(TreeWrappe
rPsiElement.java:101)
at
com.intellij.psi.PsiRecursiveElementVisitor.visitElement(PsiRecursiveElement
Visitor.java:11)
at
com.intellij.psi.JavaElementVisitor.visitFile(JavaElementVisitor.java:130)
at com.siyeh.metrics.execution.Traversal.visitFile(Traversal.java:219)
at
com.intellij.psi.JavaElementVisitor.visitJavaFile(JavaElementVisitor.java:32
0)
at com.siyeh.metrics.execution.Traversal.visitJavaFile(Traversal.java:151)
at com.intellij.psi.impl.source.t.accept(t.java:113)
at
com.siyeh.metrics.execution.MetricsExecutionContextImpl$1.run(MetricsExecuti
onContextImpl.java:78)
at com.intellij.openapi.progress.a.a.runProcess(a.java:61)
at
com.intellij.openapi.application.impl.ApplicationImpl$1a_.run(ApplicationImp
l$1a_.java:8)
Vince.
Error during dispatching of
java.awt.event.MouseEvent[MOUSE_RELEASED,(24,182),button=1,modifiers=Button1,clickCount=1]
on dialog45
java.lang.NullPointerException
at
com.siyeh.metrics.ui.metricdisplay.MetricsConfigurationPanel$2.textChanged(MetricsConfigurationPanel.java:150)
at
com.siyeh.metrics.ui.metricdisplay.MetricsConfigurationPanel$2.removeUpdate(MetricsConfigurationPanel.java:143)
at
javax.swing.text.AbstractDocument.fireRemoveUpdate(AbstractDocument.java:242)
at
javax.swing.text.AbstractDocument.handleRemove(AbstractDocument.java:607)
at
javax.swing.text.AbstractDocument$DefaultFilterBypass.replace(AbstractDocument.java:3116)
at javax.swing.text.DefaultFormatter.replace(DefaultFormatter.java:568)
at
javax.swing.text.InternationalFormatter.replace(InternationalFormatter.java:735)
at javax.swing.text.DefaultFormatter.replace(DefaultFormatter.java:533)
at
javax.swing.text.InternationalFormatter.replace(InternationalFormatter.java:582)
at javax.swing.text.NumberFormatter.replace(NumberFormatter.java:353)
at
javax.swing.text.DefaultFormatter$DefaultDocumentFilter.replace(DefaultFormatter.java:737)
at javax.swing.text.AbstractDocument.replace(AbstractDocument.java:665)
at javax.swing.text.JTextComponent.setText(JTextComponent.java:1441)
at
com.siyeh.metrics.ui.metricdisplay.MetricsConfigurationPanel.clearSelection(MetricsConfigurationPanel.java:448)
at
com.siyeh.metrics.ui.metricdisplay.MetricsConfigurationPanel.valueChanged(MetricsConfigurationPanel.java:462)
How to reproduce:
in the result panel, 2xclick on the cell in the class column:
Error during dispatching of
java.awt.event.MouseEvent[MOUSE_CLICKED,(248,651),button=1,modifiers=Button1,clickCount=2]
on frame1:
com.intellij.openapi.fileEditor.OpenFileDescriptor.(Lcom/intellij/openapi/vfs/VirtualFile;I)V java.lang.NoSuchMethodError: com.intellij.openapi.fileEditor.OpenFileDescriptor.]]>(Lcom/intellij/openapi/vfs/VirtualFile;I)V
at
com.siyeh.metrics.utils.EditorCaretMover.openInEditor(EditorCaretMover.java:65)
at
com.siyeh.metrics.ui.metricdisplay.MetricTableMouseListener.mouseClicked(MetricTableMouseListener.java:48)
at
java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:212)
at java.awt.Component.processMouseEvent(Component.java:5565)
Would it be possible to bundle a few profiles like those with in the standard plugin distribution? That way it would be easier to get some value from the plug in out of the box, without a lot of configuration effort first.
I understand what metrics to include in profiles and what thresholds to set are somewhat project and taste dependent decisions, but some kind of initial configurations would be better than nothing.
The same applies to inspection gadgets too, to some extent. Both are very promising looking plug ins, they just require so much reading through configuration options before use.
-- Hans
The much-delayed MetricsReloaded 0.6 will include prebuilt profiles.
Including prebuilt profiles in InspectionGadgets would require JetBrains to make OpenAPI changes. Good idea, though.
Glad you thing these profiles are promising.
--Dave Griffith