package com.pablissimo.sonar;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.measures.CoreMetrics;
public class LOCSensorImpl implements LOCSensor {
private static final Logger LOG = LoggerFactory.getLogger(LOCSensorImpl.class);
@Override
public String toString() {
return getClass().getSimpleName();
}
private BufferedReader getReaderFromFile(InputFile inputFile) throws FileNotFoundException {
return new BufferedReader(new FileReader(inputFile.file()));
}
private Set<Integer> getNonCommentLineNumbers(InputFile inputFile) {
HashSet<Integer> toReturn = new HashSet<>();
int lineNumber = 0;
BufferedReader br;
try {
br = this.getReaderFromFile(inputFile);
boolean isEOF;
boolean isCommentOpen = false;
boolean isACommentLine;
do {
String line = br.readLine();
lineNumber++;
if (line != null) {
isACommentLine = isCommentOpen;
line = line.trim();
if (isCommentOpen) {
if (line.contains("*/")) {
isCommentOpen = false;
isACommentLine = true;
}
} else {
if (line.startsWith("//")) {
isACommentLine = true;
}
if (line.startsWith("/*")) {
if (line.contains("*/")) {
isCommentOpen = false;
} else {
isCommentOpen = true;
}
isACommentLine = true;
} else if (line.contains("/*")) {
if (line.contains("*/")) {
isCommentOpen = false;
} else {
isCommentOpen = true;
}
isACommentLine = false;
}
}
isEOF = true;
line = line.replaceAll("\\n|\\t|\\s", "");
if (!("".equals(line) || isACommentLine)) {
toReturn.add(lineNumber);
}
} else {
isEOF = false;
}
} while (isEOF);
br.close();
} catch (FileNotFoundException e) {
LOG.error("File not found", e);
} catch (IOException e) {
LOG.error("Error while reading BufferedReader", e);
}
return toReturn;
}
@Override
public Map<InputFile, Set<Integer>> execute(SensorContext ctx) {
HashMap<InputFile, Set<Integer>> toReturn = new HashMap<>();
Iterable<InputFile> affectedFiles =
ctx
.fileSystem()
.inputFiles(ctx.fileSystem().predicates().hasLanguage(TypeScriptLanguage.LANGUAGE_KEY));
for (InputFile inputFile : affectedFiles) {
Set<Integer> nonCommentLineNumbers = this.getNonCommentLineNumbers(inputFile);
toReturn.put(inputFile, nonCommentLineNumbers);
ctx.<Integer>newMeasure().forMetric(CoreMetrics.NCLOC).on(inputFile).withValue(nonCommentLineNumbers.size()).save();
}
return toReturn;
}
}