use of com.intellij.rt.coverage.data.ClassData in project go-lang-idea-plugin by go-lang-plugin-org.
the class GoCoverageRunner method parseCoverage.
@Nullable
public static GoCoverageProjectData parseCoverage(@NotNull BufferedReader dataReader, @NotNull Project project, @Nullable Module module) throws IOException {
GoCoverageProjectData result = new GoCoverageProjectData();
String line;
while ((line = dataReader.readLine()) != null) {
if (line.isEmpty())
continue;
List<String> fileNameTail = StringUtil.split(line, ":");
VirtualFile file = GoPackageUtil.findByImportPath(fileNameTail.get(0), project, module);
if (file == null)
continue;
String filePath = file.getPath();
List<String> tailParts = StringUtil.split(fileNameTail.get(1), " ");
if (tailParts.size() != 3)
continue;
int statements = Integer.parseInt(tailParts.get(1));
int hit = Integer.parseInt(tailParts.get(2));
String offsets = tailParts.get(0);
int firstDot = offsets.indexOf('.');
int comma = offsets.indexOf(',', firstDot);
int secondDot = offsets.indexOf('.', comma);
if (firstDot == -1 || comma == -1 || secondDot == -1)
continue;
int lineStart = Integer.parseInt(offsets.substring(0, firstDot));
int columnStart = Integer.parseInt(offsets.substring(firstDot + 1, comma));
int lineEnd = Integer.parseInt(offsets.substring(comma + 1, secondDot));
int columnEnd = Integer.parseInt(offsets.substring(secondDot + 1));
result.addData(filePath, lineStart, columnStart, lineEnd, columnEnd, statements, hit);
}
result.processFiles(fileData -> {
ClassData classData = result.getOrCreateClassData(fileData.myFilePath);
int max = -1;
TIntObjectHashMap<LineData> linesMap = new TIntObjectHashMap<>();
for (GoCoverageProjectData.RangeData rangeData : fileData.myRangesData.values()) {
for (int i = rangeData.startLine; i <= rangeData.endLine; i++) {
LineData existingData = linesMap.get(i);
if (existingData != null) {
existingData.setHits(existingData.getHits() + rangeData.hits);
existingData.setFalseHits(0, 0);
existingData.setTrueHits(0, 0);
} else {
LineData newData = new LineData(i, null);
newData.setHits(newData.getHits() + rangeData.hits);
linesMap.put(i, newData);
}
}
max = Math.max(max, rangeData.endLine);
}
LineData[] linesArray = new LineData[max + 1];
linesMap.forEachValue(data -> {
data.fillArrays();
linesArray[data.getLineNumber()] = data;
return true;
});
classData.setLines(linesArray);
return true;
});
return result;
}
use of com.intellij.rt.coverage.data.ClassData in project intellij-community by JetBrains.
the class IDEACoverageRunner method loadSourceMap.
public void loadSourceMap(ProjectData projectData, File sourceMapFile) throws IOException {
Map map = SaveHook.loadSourceMapFromFile(new HashMap(), sourceMapFile);
for (Object o : map.entrySet()) {
@SuppressWarnings("unchecked") Map.Entry<String, String> entry = (Map.Entry<String, String>) o;
String className = entry.getKey();
String source = entry.getValue();
ClassData data = projectData.getClassData(className);
if (data != null) {
data.setSource(source);
}
}
}
use of com.intellij.rt.coverage.data.ClassData in project intellij-community by JetBrains.
the class PackageAnnotator method collectClassCoverageInformation.
private void collectClassCoverageInformation(final File classFile, @Nullable final PsiClass psiClass, final PackageCoverageInfo packageCoverageInfo, final ProjectData projectInfo, final Map<String, ClassCoverageInfo> toplevelClassCoverage, final String className, final String toplevelClassSrcFQName) {
final ClassCoverageInfo toplevelClassCoverageInfo = new ClassCoverageInfo();
final ClassData classData = projectInfo.getClassData(className);
if (classData != null && classData.getLines() != null) {
final Object[] lines = classData.getLines();
for (Object l : lines) {
if (l instanceof LineData) {
final LineData lineData = (LineData) l;
if (lineData.getStatus() == LineCoverage.FULL) {
toplevelClassCoverageInfo.fullyCoveredLineCount++;
} else if (lineData.getStatus() == LineCoverage.PARTIAL) {
toplevelClassCoverageInfo.partiallyCoveredLineCount++;
}
toplevelClassCoverageInfo.totalLineCount++;
packageCoverageInfo.totalLineCount++;
}
}
boolean touchedClass = false;
final Collection methodSigs = classData.getMethodSigs();
for (final Object nameAndSig : methodSigs) {
final int covered = classData.getStatus((String) nameAndSig);
if (covered != LineCoverage.NONE) {
touchedClass = true;
}
if (isGeneratedDefaultConstructor(psiClass, (String) nameAndSig)) {
continue;
}
if (covered != LineCoverage.NONE) {
toplevelClassCoverageInfo.coveredMethodCount++;
}
toplevelClassCoverageInfo.totalMethodCount++;
}
if (!methodSigs.isEmpty()) {
if (touchedClass) {
packageCoverageInfo.coveredClassCount++;
}
packageCoverageInfo.totalClassCount++;
packageCoverageInfo.coveredLineCount += toplevelClassCoverageInfo.fullyCoveredLineCount;
packageCoverageInfo.coveredLineCount += toplevelClassCoverageInfo.partiallyCoveredLineCount;
packageCoverageInfo.coveredMethodCount += toplevelClassCoverageInfo.coveredMethodCount;
packageCoverageInfo.totalMethodCount += toplevelClassCoverageInfo.totalMethodCount;
} else {
LOG.debug("Did not find any method signatures in " + classFile.getName());
return;
}
} else {
if (!collectNonCoveredClassInfo(classFile, psiClass, toplevelClassCoverageInfo, packageCoverageInfo)) {
LOG.debug("Did not collect non-covered class info for " + classFile.getName());
return;
}
}
ClassCoverageInfo classCoverageInfo = getOrCreateClassCoverageInfo(toplevelClassCoverage, toplevelClassSrcFQName);
LOG.debug("Adding coverage of " + classFile.getName() + " to top-level class " + toplevelClassSrcFQName);
classCoverageInfo.totalLineCount += toplevelClassCoverageInfo.totalLineCount;
classCoverageInfo.fullyCoveredLineCount += toplevelClassCoverageInfo.fullyCoveredLineCount;
classCoverageInfo.partiallyCoveredLineCount += toplevelClassCoverageInfo.partiallyCoveredLineCount;
classCoverageInfo.totalMethodCount += toplevelClassCoverageInfo.totalMethodCount;
classCoverageInfo.coveredMethodCount += toplevelClassCoverageInfo.coveredMethodCount;
if (toplevelClassCoverageInfo.getCoveredLineCount() > 0) {
classCoverageInfo.coveredClassCount++;
}
}
use of com.intellij.rt.coverage.data.ClassData in project intellij-community by JetBrains.
the class CoverageIntegrationTest method testJaCoCo.
public void testJaCoCo() {
CoverageSuitesBundle bundle = loadCoverageSuite(JaCoCoCoverageRunner.class, "simple$foo_in_simple.jacoco.coverage");
ClassData classData = bundle.getCoverageData().getClassData("foo.FooClass");
// getStatus() never returns full coverage; it can only distinguish between none and partial
assertEquals(LineCoverage.PARTIAL, classData.getStatus("method1()I").intValue());
}
use of com.intellij.rt.coverage.data.ClassData in project intellij-community by JetBrains.
the class SrcFileAnnotator method showCoverageInformation.
public void showCoverageInformation(final CoverageSuitesBundle suite) {
// Store the values of myFile and myEditor in local variables to avoid an NPE after dispose() has been called in the EDT.
final PsiFile psiFile = myFile;
final Editor editor = myEditor;
final Document document = myDocument;
if (editor == null || psiFile == null || document == null)
return;
final VirtualFile file = getVirtualFile(psiFile);
final MyEditorBean editorBean = new MyEditorBean(editor, file, document);
final MarkupModel markupModel = DocumentMarkupModel.forDocument(document, myProject, true);
final List<RangeHighlighter> highlighters = new ArrayList<>();
final ProjectData data = suite.getCoverageData();
if (data == null) {
coverageDataNotFound(suite);
return;
}
final CoverageEngine engine = suite.getCoverageEngine();
final Set<String> qualifiedNames = engine.getQualifiedNames(psiFile);
// let's find old content in local history and build mapping from old lines to new one
// local history doesn't index libraries, so let's distinguish libraries content with other one
final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
final long fileTimeStamp = file.getTimeStamp();
final long coverageTimeStamp = suite.getLastCoverageTimeStamp();
final TIntIntHashMap oldToNewLineMapping;
//do not show coverage info over cls
if (engine.isInLibraryClasses(myProject, file)) {
return;
}
// if in libraries content
if (projectFileIndex.isInLibrarySource(file)) {
// compare file and coverage timestamps
if (fileTimeStamp > coverageTimeStamp) {
showEditorWarningMessage(CodeInsightBundle.message("coverage.data.outdated"));
return;
}
oldToNewLineMapping = null;
} else {
// check local history
oldToNewLineMapping = getOldToNewLineMapping(coverageTimeStamp, editorBean);
if (oldToNewLineMapping == null) {
// if history for file isn't available let's check timestamps
if (fileTimeStamp > coverageTimeStamp && classesArePresentInCoverageData(data, qualifiedNames)) {
showEditorWarningMessage(CodeInsightBundle.message("coverage.data.outdated"));
return;
}
}
}
if (editor.getUserData(COVERAGE_HIGHLIGHTERS) != null) {
//highlighters already collected - no need to do it twice
return;
}
final Module module = ApplicationManager.getApplication().runReadAction(new Computable<Module>() {
@Nullable
@Override
public Module compute() {
return ModuleUtilCore.findModuleForPsiElement(psiFile);
}
});
if (module != null) {
if (engine.recompileProjectAndRerunAction(module, suite, () -> CoverageDataManager.getInstance(myProject).chooseSuitesBundle(suite))) {
return;
}
}
// now if oldToNewLineMapping is null we should use f(x)=id(x) mapping
// E.g. all *.class files for java source file with several classes
final Set<File> outputFiles = engine.getCorrespondingOutputFiles(psiFile, module, suite);
final boolean subCoverageActive = CoverageDataManager.getInstance(myProject).isSubCoverageActive();
final boolean coverageByTestApplicable = suite.isCoverageByTestApplicable() && !(subCoverageActive && suite.isCoverageByTestEnabled());
final TreeMap<Integer, LineData> executableLines = new TreeMap<>();
final TreeMap<Integer, Object[]> classLines = new TreeMap<>();
final TreeMap<Integer, String> classNames = new TreeMap<>();
class HighlightersCollector {
private void collect(File outputFile, final String qualifiedName) {
final ClassData fileData = data.getClassData(qualifiedName);
if (fileData != null) {
final Object[] lines = fileData.getLines();
if (lines != null) {
final Object[] postProcessedLines = suite.getCoverageEngine().postProcessExecutableLines(lines, editor);
for (Object lineData : postProcessedLines) {
if (lineData instanceof LineData) {
final int line = ((LineData) lineData).getLineNumber() - 1;
final int lineNumberInCurrent;
if (oldToNewLineMapping != null) {
// use mapping based on local history
if (!oldToNewLineMapping.contains(line)) {
continue;
}
lineNumberInCurrent = oldToNewLineMapping.get(line);
} else {
// use id mapping
lineNumberInCurrent = line;
}
executableLines.put(line, (LineData) lineData);
classLines.put(line, postProcessedLines);
classNames.put(line, qualifiedName);
ApplicationManager.getApplication().invokeLater(() -> {
if (lineNumberInCurrent >= document.getLineCount())
return;
if (editorBean.isDisposed())
return;
final RangeHighlighter highlighter = createRangeHighlighter(suite.getLastCoverageTimeStamp(), markupModel, coverageByTestApplicable, executableLines, qualifiedName, line, lineNumberInCurrent, suite, postProcessedLines, editorBean);
highlighters.add(highlighter);
});
}
}
}
} else if (outputFile != null && !subCoverageActive && engine.includeUntouchedFileInCoverage(qualifiedName, outputFile, psiFile, suite)) {
collectNonCoveredFileInfo(outputFile, highlighters, markupModel, executableLines, coverageByTestApplicable, editorBean);
}
}
}
final HighlightersCollector collector = new HighlightersCollector();
if (!outputFiles.isEmpty()) {
for (File outputFile : outputFiles) {
final String qualifiedName = engine.getQualifiedName(outputFile, psiFile);
if (qualifiedName != null) {
collector.collect(outputFile, qualifiedName);
}
}
} else {
//check non-compilable classes which present in ProjectData
for (String qName : qualifiedNames) {
collector.collect(null, qName);
}
}
ApplicationManager.getApplication().invokeLater(() -> {
if (!editorBean.isDisposed() && highlighters.size() > 0) {
editor.putUserData(COVERAGE_HIGHLIGHTERS, highlighters);
}
});
final DocumentListener documentListener = new DocumentAdapter() {
@Override
public void documentChanged(final DocumentEvent e) {
myNewToOldLines = null;
myOldToNewLines = null;
List<RangeHighlighter> rangeHighlighters = editor.getUserData(COVERAGE_HIGHLIGHTERS);
if (rangeHighlighters == null)
rangeHighlighters = new ArrayList<>();
int offset = e.getOffset();
final int lineNumber = document.getLineNumber(offset);
final int lastLineNumber = document.getLineNumber(offset + e.getNewLength());
final TextRange changeRange = new TextRange(document.getLineStartOffset(lineNumber), document.getLineEndOffset(lastLineNumber));
for (Iterator<RangeHighlighter> it = rangeHighlighters.iterator(); it.hasNext(); ) {
final RangeHighlighter highlighter = it.next();
if (!highlighter.isValid() || TextRange.create(highlighter).intersects(changeRange)) {
highlighter.dispose();
it.remove();
}
}
final List<RangeHighlighter> highlighters = rangeHighlighters;
myUpdateAlarm.cancelAllRequests();
if (!myUpdateAlarm.isDisposed()) {
myUpdateAlarm.addRequest(() -> {
final TIntIntHashMap newToOldLineMapping = getNewToOldLineMapping(suite.getLastCoverageTimeStamp(), editorBean);
if (newToOldLineMapping != null) {
ApplicationManager.getApplication().invokeLater(() -> {
if (editorBean.isDisposed())
return;
for (int line = lineNumber; line <= lastLineNumber; line++) {
final int oldLineNumber = newToOldLineMapping.get(line);
final LineData lineData = executableLines.get(oldLineNumber);
if (lineData != null) {
RangeHighlighter rangeHighlighter = createRangeHighlighter(suite.getLastCoverageTimeStamp(), markupModel, coverageByTestApplicable, executableLines, classNames.get(oldLineNumber), oldLineNumber, line, suite, classLines.get(oldLineNumber), editorBean);
highlighters.add(rangeHighlighter);
}
}
editor.putUserData(COVERAGE_HIGHLIGHTERS, highlighters.size() > 0 ? highlighters : null);
});
}
}, 100);
}
}
};
document.addDocumentListener(documentListener);
editor.putUserData(COVERAGE_DOCUMENT_LISTENER, documentListener);
}
Aggregations