Skip to content

Commit

Permalink
Add complexity calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
nbihan-mediware committed Apr 19, 2019
1 parent 140b913 commit 71d2dd5
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 5 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<groupId>com.stepstone.sonar.plugin</groupId>
<artifactId>sonar-coldfusion-plugin</artifactId>
<packaging>sonar-plugin</packaging>
<version>1.7.0-SNAPSHOT</version>
<version>1.7.1-SNAPSHOT</version>

<name>SonarQube Coldfusion Analyzer</name>
<description>Enables scanning of ColdFusion source files</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ColdFusionSensor implements Sensor {

Expand Down Expand Up @@ -116,7 +118,7 @@ private void measureProcessor(SensorContext context) {
for (InputFile inputFile : fs.inputFiles(fs.predicates().hasLanguage(ColdFusionPlugin.LANGUAGE_KEY))) {
Callable<Integer> callableTask = () -> {
try {
metricsLinesCounter(inputFile, context);
metricsCounter(inputFile, context);
return 1;
} catch (IOException e) {
return 0;
Expand All @@ -138,16 +140,19 @@ private void measureProcessor(SensorContext context) {

//Very basic and naive line of code counter for Coldfusion
//Might count a line of code as comment
private void metricsLinesCounter(InputFile inputFile, SensorContext context) throws IOException {
private void metricsCounter(InputFile inputFile, SensorContext context) throws IOException {
String currentLine;
int commentLines = 0;
int blankLines = 0;
int lines = 0;
int complexity = 1;


try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputFile.inputStream()))) {
if (inputFile.inputStream() != null) {
while ((currentLine = reader.readLine()) != null) {
lines++;

if (currentLine.contains("<!--")) {
commentLines++;
if (currentLine.contains("-->")) {
Expand All @@ -161,14 +166,59 @@ private void metricsLinesCounter(InputFile inputFile, SensorContext context) thr
}
} else if (currentLine.trim().isEmpty()) {
blankLines++;
continue;
}

complexity = getLineComplexity(currentLine, complexity);
}
}
}
int linesOfCode = lines-blankLines-commentLines;
// every 100 lines of code add 1 to the content's complexity
complexity = complexity + (linesOfCode / 100);

context.<Integer>newMeasure().forMetric(CoreMetrics.COMMENT_LINES).on(inputFile).withValue(commentLines).save();
context.<Integer>newMeasure().forMetric(CoreMetrics.NCLOC).on(inputFile).withValue(lines-blankLines-commentLines).save();
context.<Integer>newMeasure().forMetric(CoreMetrics.NCLOC).on(inputFile).withValue(linesOfCode).save();
context.<Integer>newMeasure().forMetric(CoreMetrics.LINES).on(inputFile).withValue(lines).save();
context.<Integer>newMeasure().forMetric(CoreMetrics.COMPLEXITY).on(inputFile).withValue(complexity).save();
}

private int getLineComplexity(String currentLine, int complexity) {
int mcCabeComplexity =0;
int lineByLineComplexity = 0;
int lineByLineComplexityIncrement = 4;
int thisLineComplexityAdd = 0;
int thisLineComplexitySubtract = 0;

// SCORE INCREMENTS
mcCabeComplexity += countRegexOccurrences(currentLine, "(<cfif\\s|<cfelseif\\s|<cfcase\\s|<cfloop\\s|<cfoutput\\s*query|iif\\s*\\()");
mcCabeComplexity += countRegexOccurrences(currentLine, "(\\b(if|for|while|do|foreach)\\s*\\(|\\scase\\s+[\\w\"\"\\s]+:)");

thisLineComplexityAdd = countRegexOccurrences(currentLine, "(<cfif\\s|<cfelseif\\s|<cfcase\\s|<cfloop\\s|<cfoutput\\s*query|\\biif\\s*\\()") * lineByLineComplexityIncrement;
// TODO: account for script {braces} as well as non-braced if(?)do;else do;
// The current implementation just counts any opening and closing braces. That's Cheating (and gives inaccurate readings).
thisLineComplexityAdd += countRegexOccurrences(currentLine,"\\{") * lineByLineComplexityIncrement;

lineByLineComplexity += thisLineComplexityAdd;

// SCORE DECREMENTS
// Assume iif closes itself on the same line it opens
thisLineComplexitySubtract = (currentLine.split("(</cfif|</cfcase|</cfloop|iif\\s*\\()").length - 1) * lineByLineComplexityIncrement;
thisLineComplexitySubtract += countRegexOccurrences(currentLine,"\\}") * lineByLineComplexityIncrement;
lineByLineComplexity -= thisLineComplexitySubtract;

complexity += mcCabeComplexity + lineByLineComplexity;
return complexity;
}

private int countRegexOccurrences(String str, String regex) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
int matches = 0;
while (matcher.find()) {
matches = matches + 1;
}
return matches;
}
}

6 changes: 5 additions & 1 deletion src/test/java/com/wellsky/ColdfusionSensorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,18 @@ public void testBasicCFMAnalysis() {

Integer nloc = 0;
Integer comments = 0;
Integer complexity = 0;
for (InputFile o : context.fileSystem().inputFiles()) {
Measure<Integer> measureNloc = context.measure(o.key(),CoreMetrics.NCLOC.key());
Measure<Integer> measureComment = context.measure(o.key(),CoreMetrics.COMMENT_LINES.key());
Measure<Integer> measureComplexity = context.measure(o.key(),CoreMetrics.COMPLEXITY.key());
nloc+=measureNloc.value();
comments+=measureComment.value();
complexity+=measureComplexity.value();
}
assertThat(nloc).isEqualTo(36);
assertThat(nloc).isEqualTo(56);
assertThat(comments).isEqualTo(9);
assertThat(complexity).isEqualTo(10);

}

Expand Down
17 changes: 17 additions & 0 deletions src/test/resources/EpisodeClaim.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@

</cftry>

<cfset M0250 = 0>
<cfscript>
if (local.InfusionTherapy is 1)
{
M0250 = M0250 + 14;
}
if (local.ParentalNutrition is 1)
{
M0250 = M0250 + 20;
}
if (local.EnteralNutrition is 1)
{
M0250 = M0250 + 24;
}
</cfscript>


<cfreturn local.resultStruct />

</cffunction>
Expand Down
6 changes: 6 additions & 0 deletions src/test/resources/testmetrics1.cfm
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@
<!--- this is a second comment --->
the world to see.
</cfif>

<cfif firstName eq "Nico">
Nico!
<cfelse >
the world to see.
</cfif>

0 comments on commit 71d2dd5

Please sign in to comment.