|
|
|
@ -9,6 +9,7 @@ package com.keyware.sonar.cxx; |
|
|
|
|
import com.keyware.sonar.cxx.rules.SecurityDesignRuleRepository; |
|
|
|
|
import com.sonar.cxx.sslr.api.Grammar; |
|
|
|
|
import org.sonar.api.PropertyType; |
|
|
|
|
import org.sonar.api.batch.fs.InputComponent; |
|
|
|
|
import org.sonar.api.batch.fs.InputFile; |
|
|
|
|
import org.sonar.api.batch.fs.TextRange; |
|
|
|
|
import org.sonar.api.batch.rule.CheckFactory; |
|
|
|
@ -39,7 +40,6 @@ import org.sonar.cxx.squidbridge.SquidAstVisitor; |
|
|
|
|
import org.sonar.cxx.squidbridge.api.SourceCode; |
|
|
|
|
import org.sonar.cxx.squidbridge.api.SourceFile; |
|
|
|
|
import org.sonar.cxx.squidbridge.api.SourceProject; |
|
|
|
|
import org.sonar.cxx.squidbridge.indexer.QueryByType; |
|
|
|
|
import org.sonar.cxx.visitors.CxxCpdVisitor; |
|
|
|
|
import org.sonar.cxx.visitors.CxxHighlighterVisitor; |
|
|
|
|
import org.sonar.cxx.visitors.CxxPublicApiVisitor; |
|
|
|
@ -316,7 +316,7 @@ public class CxxSquidSensor implements ProjectSensor { |
|
|
|
|
Iterable<InputFile> inputFiles = getInputFiles(context, squidConfig); |
|
|
|
|
scanner.scanInputFiles(inputFiles); |
|
|
|
|
|
|
|
|
|
Collection<SourceCode> squidSourceFiles = scanner.getIndex().search(new QueryByType(SourceProject.class), new QueryByType(SourceFile.class)); |
|
|
|
|
Collection<SourceCode> squidSourceFiles = scanner.getIndex().search(); |
|
|
|
|
save(squidSourceFiles); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -403,20 +403,21 @@ public class CxxSquidSensor implements ProjectSensor { |
|
|
|
|
private void save(Collection<SourceCode> sourceCodeFiles) { |
|
|
|
|
for (var sourceCode : sourceCodeFiles) { |
|
|
|
|
try { |
|
|
|
|
if (sourceCode instanceof SourceFile) { |
|
|
|
|
var sourceFile = (SourceFile) sourceCode; |
|
|
|
|
if (sourceCode instanceof SourceFile || sourceCode instanceof SourceProject) { |
|
|
|
|
/*var sourceFile = (SourceFile) sourceCode;*/ |
|
|
|
|
InputFile inputFile = context.fileSystem().inputFile( |
|
|
|
|
context.fileSystem().predicates().hasPath(sourceFile.getKey()) |
|
|
|
|
context.fileSystem().predicates().hasPath(sourceCode.getKey()) |
|
|
|
|
); |
|
|
|
|
saveMeasures(inputFile, sourceFile); |
|
|
|
|
saveViolations(inputFile, sourceFile); |
|
|
|
|
saveFileLinesContext(inputFile, sourceFile); |
|
|
|
|
saveCpdTokens(inputFile, sourceFile); |
|
|
|
|
saveHighlighting(inputFile, sourceFile); |
|
|
|
|
} else if (sourceCode instanceof SourceProject) { |
|
|
|
|
saveMeasures(inputFile, sourceCode); |
|
|
|
|
saveViolations(inputFile, sourceCode); |
|
|
|
|
saveFileLinesContext(inputFile, sourceCode); |
|
|
|
|
saveCpdTokens(inputFile, sourceCode); |
|
|
|
|
saveHighlighting(inputFile, sourceCode); |
|
|
|
|
} |
|
|
|
|
/*} else if (sourceCode instanceof SourceProject) { |
|
|
|
|
var sourceProject = (SourceProject) sourceCode; |
|
|
|
|
saveProjectViolations(sourceProject); |
|
|
|
|
} |
|
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
} catch (IllegalStateException e) { |
|
|
|
|
var msg = "Cannot save all measures for file '" + sourceCode.getKey() + "'"; |
|
|
|
@ -425,19 +426,23 @@ public class CxxSquidSensor implements ProjectSensor { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void saveMeasures(InputFile inputFile, SourceFile sourceFile) { |
|
|
|
|
|
|
|
|
|
// NOSONAR
|
|
|
|
|
noSonarFilter.noSonarInFile(inputFile, sourceFile.getNoSonarTagLines()); |
|
|
|
|
private void saveMeasures(InputFile inputFile, SourceCode sourceCode) { |
|
|
|
|
InputComponent input = inputFile; |
|
|
|
|
if(sourceCode instanceof SourceFile){ |
|
|
|
|
// NOSONAR
|
|
|
|
|
noSonarFilter.noSonarInFile(inputFile, ((SourceFile)sourceCode).getNoSonarTagLines()); |
|
|
|
|
}else{ |
|
|
|
|
input = context.project(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// CORE METRICS
|
|
|
|
|
saveMetric(inputFile, CoreMetrics.NCLOC, sourceFile.getInt(CxxMetric.LINES_OF_CODE)); |
|
|
|
|
saveMetric(inputFile, CoreMetrics.STATEMENTS, sourceFile.getInt(CxxMetric.STATEMENTS)); |
|
|
|
|
saveMetric(inputFile, CoreMetrics.FUNCTIONS, sourceFile.getInt(CxxMetric.FUNCTIONS)); |
|
|
|
|
saveMetric(inputFile, CoreMetrics.CLASSES, sourceFile.getInt(CxxMetric.CLASSES)); |
|
|
|
|
saveMetric(inputFile, CoreMetrics.COMPLEXITY, sourceFile.getInt(CxxMetric.COMPLEXITY)); |
|
|
|
|
saveMetric(inputFile, CoreMetrics.COGNITIVE_COMPLEXITY, sourceFile.getInt(CxxMetric.COGNITIVE_COMPLEXITY)); |
|
|
|
|
saveMetric(inputFile, CoreMetrics.COMMENT_LINES, sourceFile.getInt(CxxMetric.COMMENT_LINES)); |
|
|
|
|
saveMetric(input, CoreMetrics.NCLOC, sourceCode.getInt(CxxMetric.LINES_OF_CODE)); |
|
|
|
|
saveMetric(input, CoreMetrics.STATEMENTS, sourceCode.getInt(CxxMetric.STATEMENTS)); |
|
|
|
|
saveMetric(input, CoreMetrics.FUNCTIONS, sourceCode.getInt(CxxMetric.FUNCTIONS)); |
|
|
|
|
saveMetric(input, CoreMetrics.CLASSES, sourceCode.getInt(CxxMetric.CLASSES)); |
|
|
|
|
saveMetric(input, CoreMetrics.COMPLEXITY, sourceCode.getInt(CxxMetric.COMPLEXITY)); |
|
|
|
|
saveMetric(input, CoreMetrics.COGNITIVE_COMPLEXITY, sourceCode.getInt(CxxMetric.COGNITIVE_COMPLEXITY)); |
|
|
|
|
saveMetric(input, CoreMetrics.COMMENT_LINES, sourceCode.getInt(CxxMetric.COMMENT_LINES)); |
|
|
|
|
|
|
|
|
|
// CUSTOM METRICS
|
|
|
|
|
//
|
|
|
|
@ -445,17 +450,17 @@ public class CxxSquidSensor implements ProjectSensor { |
|
|
|
|
// below metrics are calculated by means of DensityMeasureComputer
|
|
|
|
|
//
|
|
|
|
|
// 1. PUBLIC API
|
|
|
|
|
saveMetric(inputFile, CxxMetrics.PUBLIC_API, sourceFile.getInt(CxxMetric.PUBLIC_API)); |
|
|
|
|
saveMetric(inputFile, CxxMetrics.PUBLIC_UNDOCUMENTED_API, sourceFile.getInt(CxxMetric.PUBLIC_UNDOCUMENTED_API)); |
|
|
|
|
saveMetric(input, CxxMetrics.PUBLIC_API, sourceCode.getInt(CxxMetric.PUBLIC_API)); |
|
|
|
|
saveMetric(input, CxxMetrics.PUBLIC_UNDOCUMENTED_API, sourceCode.getInt(CxxMetric.PUBLIC_UNDOCUMENTED_API)); |
|
|
|
|
|
|
|
|
|
// 2. FUNCTION COMPLEXITY
|
|
|
|
|
saveMetric(inputFile, CxxMetrics.COMPLEX_FUNCTIONS, sourceFile.getInt(CxxMetric.COMPLEX_FUNCTIONS)); |
|
|
|
|
saveMetric(inputFile, CxxMetrics.COMPLEX_FUNCTIONS_LOC, sourceFile.getInt(CxxMetric.COMPLEX_FUNCTIONS_LOC)); |
|
|
|
|
saveMetric(input, CxxMetrics.COMPLEX_FUNCTIONS, sourceCode.getInt(CxxMetric.COMPLEX_FUNCTIONS)); |
|
|
|
|
saveMetric(input, CxxMetrics.COMPLEX_FUNCTIONS_LOC, sourceCode.getInt(CxxMetric.COMPLEX_FUNCTIONS_LOC)); |
|
|
|
|
|
|
|
|
|
// 3. FUNCTION SIZE
|
|
|
|
|
saveMetric(inputFile, CxxMetrics.LOC_IN_FUNCTIONS, sourceFile.getInt(CxxMetric.LOC_IN_FUNCTIONS)); |
|
|
|
|
saveMetric(inputFile, CxxMetrics.BIG_FUNCTIONS, sourceFile.getInt(CxxMetric.BIG_FUNCTIONS)); |
|
|
|
|
saveMetric(inputFile, CxxMetrics.BIG_FUNCTIONS_LOC, sourceFile.getInt(CxxMetric.BIG_FUNCTIONS_LOC)); |
|
|
|
|
saveMetric(input, CxxMetrics.LOC_IN_FUNCTIONS, sourceCode.getInt(CxxMetric.LOC_IN_FUNCTIONS)); |
|
|
|
|
saveMetric(input, CxxMetrics.BIG_FUNCTIONS, sourceCode.getInt(CxxMetric.BIG_FUNCTIONS)); |
|
|
|
|
saveMetric(input, CxxMetrics.BIG_FUNCTIONS_LOC, sourceCode.getInt(CxxMetric.BIG_FUNCTIONS_LOC)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -480,9 +485,9 @@ public class CxxSquidSensor implements ProjectSensor { |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void saveViolations(InputFile inputFile, SourceFile sourceFile) { |
|
|
|
|
if (sourceFile.hasCheckMessages()) { |
|
|
|
|
for (var message : sourceFile.getCheckMessages()) { |
|
|
|
|
private void saveViolations(InputFile inputFile, SourceCode sourceCode) { |
|
|
|
|
if (sourceCode.hasCheckMessages()) { |
|
|
|
|
for (var message : sourceCode.getCheckMessages()) { |
|
|
|
|
var line = 1; |
|
|
|
|
if (message.getLine() != null && message.getLine() > 0) { |
|
|
|
|
line = message.getLine(); |
|
|
|
@ -497,10 +502,13 @@ public class CxxSquidSensor implements ProjectSensor { |
|
|
|
|
RuleKey ruleKey = checks.ruleKey(checker); |
|
|
|
|
if (ruleKey != null) { |
|
|
|
|
var newIssue = context.newIssue().forRule(RuleKey.of(repositoryKey, ruleKey.rule())); |
|
|
|
|
var location = newIssue.newLocation() |
|
|
|
|
.on(inputFile) |
|
|
|
|
.at(inputFile.selectLine(line)) |
|
|
|
|
.message(message.getText(Locale.CHINA)); |
|
|
|
|
var location = newIssue.newLocation(); |
|
|
|
|
if(sourceCode instanceof SourceFile){ |
|
|
|
|
location.on(inputFile).at(inputFile.selectLine(line)); |
|
|
|
|
}else{ |
|
|
|
|
location.on(context.project()); |
|
|
|
|
} |
|
|
|
|
location.message(message.getText(Locale.CHINA)); |
|
|
|
|
|
|
|
|
|
newIssue.at(location); |
|
|
|
|
newIssue.save(); |
|
|
|
@ -509,32 +517,37 @@ public class CxxSquidSensor implements ProjectSensor { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (MultiLocatitionSquidCheck.hasMultiLocationCheckMessages(sourceFile)) { |
|
|
|
|
for (var issue : MultiLocatitionSquidCheck.getMultiLocationCheckMessages(sourceFile)) { |
|
|
|
|
var newIssue = context.newIssue().forRule(RuleKey.of(CheckList.REPOSITORY_KEY, issue.getRuleId())); |
|
|
|
|
var locationNr = 0; |
|
|
|
|
for (var location : issue.getLocations()) { |
|
|
|
|
final Integer line = Integer.valueOf(location.getLine()); |
|
|
|
|
final NewIssueLocation newIssueLocation = newIssue.newLocation().on(inputFile).at(inputFile.selectLine(line)) |
|
|
|
|
.message(location.getInfo()); |
|
|
|
|
if (locationNr == 0) { |
|
|
|
|
newIssue.at(newIssueLocation); |
|
|
|
|
} else { |
|
|
|
|
newIssue.addLocation(newIssueLocation); |
|
|
|
|
if(sourceCode instanceof SourceFile) { |
|
|
|
|
var sourceFile = (SourceFile) sourceCode; |
|
|
|
|
if (MultiLocatitionSquidCheck.hasMultiLocationCheckMessages(sourceFile)) { |
|
|
|
|
for (var issue : MultiLocatitionSquidCheck.getMultiLocationCheckMessages(sourceFile)) { |
|
|
|
|
var newIssue = context.newIssue().forRule(RuleKey.of(CheckList.REPOSITORY_KEY, issue.getRuleId())); |
|
|
|
|
var locationNr = 0; |
|
|
|
|
for (var location : issue.getLocations()) { |
|
|
|
|
final Integer line = Integer.valueOf(location.getLine()); |
|
|
|
|
final NewIssueLocation newIssueLocation = newIssue.newLocation().on(inputFile).at(inputFile.selectLine(line)) |
|
|
|
|
.message(location.getInfo()); |
|
|
|
|
if (locationNr == 0) { |
|
|
|
|
newIssue.at(newIssueLocation); |
|
|
|
|
} else { |
|
|
|
|
newIssue.addLocation(newIssueLocation); |
|
|
|
|
} |
|
|
|
|
++locationNr; |
|
|
|
|
} |
|
|
|
|
++locationNr; |
|
|
|
|
newIssue.save(); |
|
|
|
|
} |
|
|
|
|
newIssue.save(); |
|
|
|
|
MultiLocatitionSquidCheck.eraseMultilineCheckMessages(sourceFile); |
|
|
|
|
} |
|
|
|
|
MultiLocatitionSquidCheck.eraseMultilineCheckMessages(sourceFile); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void saveFileLinesContext(InputFile inputFile, SourceFile sourceFile) { |
|
|
|
|
private void saveFileLinesContext(InputFile inputFile, SourceCode sourceCode) { |
|
|
|
|
if(sourceCode instanceof SourceProject || inputFile == null){ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
// measures for the lines of file
|
|
|
|
|
var fileLinesContext = fileLinesContextFactory.createFor(inputFile); |
|
|
|
|
List<Integer> linesOfCode = (List<Integer>) sourceFile.getData(CxxMetric.NCLOC_DATA); |
|
|
|
|
List<Integer> linesOfCode = (List<Integer>) sourceCode.getData(CxxMetric.NCLOC_DATA); |
|
|
|
|
linesOfCode.stream().sequential().distinct().forEach((line) -> { |
|
|
|
|
try { |
|
|
|
|
fileLinesContext.setIntValue(CoreMetrics.NCLOC_DATA_KEY, line, 1); |
|
|
|
@ -543,7 +556,7 @@ public class CxxSquidSensor implements ProjectSensor { |
|
|
|
|
LOG.debug("NCLOC error in file '{}' at line:{}", inputFile.filename(), line); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
List<Integer> executableLines = (List<Integer>) sourceFile.getData(CxxMetric.EXECUTABLE_LINES_DATA); |
|
|
|
|
List<Integer> executableLines = (List<Integer>) sourceCode.getData(CxxMetric.EXECUTABLE_LINES_DATA); |
|
|
|
|
executableLines.stream().sequential().distinct().forEach((line) -> { |
|
|
|
|
try { |
|
|
|
|
fileLinesContext.setIntValue(CoreMetrics.EXECUTABLE_LINES_DATA_KEY, line, 1); |
|
|
|
@ -555,10 +568,13 @@ public class CxxSquidSensor implements ProjectSensor { |
|
|
|
|
fileLinesContext.save(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void saveCpdTokens(InputFile inputFile, SourceFile sourceFile) { |
|
|
|
|
private void saveCpdTokens(InputFile inputFile, SourceCode sourceCode) { |
|
|
|
|
if(sourceCode instanceof SourceProject || inputFile == null){ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
NewCpdTokens cpdTokens = context.newCpdTokens().onFile(inputFile); |
|
|
|
|
|
|
|
|
|
List<CxxCpdVisitor.CpdToken> data = (List<CxxCpdVisitor.CpdToken>) sourceFile.getData(CxxMetric.CPD_TOKENS_DATA); |
|
|
|
|
List<CxxCpdVisitor.CpdToken> data = (List<CxxCpdVisitor.CpdToken>) sourceCode.getData(CxxMetric.CPD_TOKENS_DATA); |
|
|
|
|
data.forEach((item) -> { |
|
|
|
|
try { |
|
|
|
|
TextRange range = inputFile.newRange(item.startLine, item.startCol, item.endLine, item.endCol); |
|
|
|
@ -572,10 +588,13 @@ public class CxxSquidSensor implements ProjectSensor { |
|
|
|
|
cpdTokens.save(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void saveHighlighting(InputFile inputFile, SourceFile sourceFile) { |
|
|
|
|
private void saveHighlighting(InputFile inputFile, SourceCode sourceCode) { |
|
|
|
|
if(sourceCode instanceof SourceProject || inputFile == null){ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
NewHighlighting newHighlighting = context.newHighlighting().onFile(inputFile); |
|
|
|
|
|
|
|
|
|
List<CxxHighlighterVisitor.Highlight> data = (List<CxxHighlighterVisitor.Highlight>) sourceFile.getData( |
|
|
|
|
List<CxxHighlighterVisitor.Highlight> data = (List<CxxHighlighterVisitor.Highlight>) sourceCode.getData( |
|
|
|
|
CxxMetric.HIGHLIGTHING_DATA); |
|
|
|
|
data.forEach((item) -> { |
|
|
|
|
try { |
|
|
|
@ -591,7 +610,7 @@ public class CxxSquidSensor implements ProjectSensor { |
|
|
|
|
newHighlighting.save(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private <T extends Serializable> void saveMetric(InputFile file, Metric<T> metric, T value) { |
|
|
|
|
private <T extends Serializable> void saveMetric(InputComponent file, Metric<T> metric, T value) { |
|
|
|
|
context.<T>newMeasure() |
|
|
|
|
.withValue(value) |
|
|
|
|
.forMetric(metric) |
|
|
|
|