mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
coverage: ignore empty private constructors for all engines (IDEA-26988)
This commit is contained in:
@@ -353,6 +353,14 @@ public abstract class CoverageEngine {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return true if highlighting should skip the line as it represents no actual source code
|
||||
*/
|
||||
public boolean isGeneratedCode(Project project, String qualifiedName, Object lineData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String getEditorTitle() {
|
||||
return "Code Coverage";
|
||||
}
|
||||
|
||||
@@ -60,6 +60,9 @@ public class CoverageSuitesBundle {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return mySuites[0].getProject();
|
||||
}
|
||||
|
||||
public long getLastCoverageTimeStamp() {
|
||||
long max = 0;
|
||||
|
||||
@@ -355,7 +355,7 @@ public class SrcFileAnnotator implements Disposable {
|
||||
if (fileData != null) {
|
||||
final Object[] lines = fileData.getLines();
|
||||
if (lines != null) {
|
||||
final Object[] postProcessedLines = suite.getCoverageEngine().postProcessExecutableLines(lines, editor);
|
||||
final Object[] postProcessedLines = engine.postProcessExecutableLines(lines, editor);
|
||||
for (Object lineData : postProcessedLines) {
|
||||
if (lineData instanceof LineData) {
|
||||
final int line = ((LineData)lineData).getLineNumber() - 1;
|
||||
@@ -371,6 +371,7 @@ public class SrcFileAnnotator implements Disposable {
|
||||
// use id mapping
|
||||
lineNumberInCurrent = line;
|
||||
}
|
||||
if (engine.isGeneratedCode(myProject, qualifiedName, lineData)) continue;
|
||||
executableLines.put(line, (LineData)lineData);
|
||||
|
||||
classLines.put(line, postProcessedLines);
|
||||
|
||||
@@ -255,7 +255,7 @@ public class JavaCoverageEngine extends CoverageEngine {
|
||||
}
|
||||
|
||||
try {
|
||||
SourceLineCounterUtil.collectSrcLinesForUntouchedFiles(uncoveredLines, content, suite.isTracingEnabled());
|
||||
SourceLineCounterUtil.collectSrcLinesForUntouchedFiles(uncoveredLines, content, suite.isTracingEnabled(), suite.getProject());
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error("Fail to process class from: " + classFile.getPath(), e);
|
||||
@@ -274,6 +274,7 @@ public class JavaCoverageEngine extends CoverageEngine {
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public String getQualifiedName(@NotNull final File outputFile, @NotNull final PsiFile sourceFile) {
|
||||
final String packageFQName = getPackageName(sourceFile);
|
||||
return StringUtil.getQualifiedName(packageFQName, FileUtil.getNameWithoutExtension(outputFile));
|
||||
@@ -651,6 +652,12 @@ public class JavaCoverageEngine extends CoverageEngine {
|
||||
return "Java Coverage";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGeneratedCode(Project project, String qualifiedName, Object lineData) {
|
||||
PsiClass psiClass = ReadAction.compute(() -> ClassUtil.findPsiClassByJVMName(PsiManager.getInstance(project), qualifiedName));
|
||||
return PackageAnnotator.isGeneratedDefaultConstructor(psiClass, ((LineData)lineData).getMethodSignature());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoverageViewExtension createCoverageViewExtension(Project project,
|
||||
CoverageSuitesBundle suiteBundle,
|
||||
|
||||
@@ -28,10 +28,7 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.PsiPackage;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.rt.coverage.data.ClassData;
|
||||
@@ -509,16 +506,23 @@ public class PackageAnnotator {
|
||||
*/
|
||||
public static boolean isGeneratedDefaultConstructor(@Nullable final PsiClass aClass, String nameAndSig) {
|
||||
if (DEFAULT_CONSTRUCTOR_NAME_SIGNATURE.equals(nameAndSig)) {
|
||||
return hasGeneratedConstructor(aClass);
|
||||
return hasGeneratedOrEmptyPrivateConstructor(aClass);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasGeneratedConstructor(@Nullable final PsiClass aClass) {
|
||||
private static boolean hasGeneratedOrEmptyPrivateConstructor(@Nullable final PsiClass aClass) {
|
||||
if (aClass == null) {
|
||||
return false;
|
||||
}
|
||||
return ReadAction.compute(() -> aClass.getConstructors().length == 0);
|
||||
return ReadAction.compute(() -> {
|
||||
PsiMethod[] constructors = aClass.getConstructors();
|
||||
if (constructors.length == 1 && constructors[0].hasModifierProperty(PsiModifier.PRIVATE)) {
|
||||
PsiCodeBlock body = constructors[0].getBody();
|
||||
return body != null && body.getStatements().length == 0;
|
||||
}
|
||||
return constructors.length == 0;
|
||||
});
|
||||
}
|
||||
|
||||
private static ClassCoverageInfo getOrCreateClassCoverageInfo(final Map<String, ClassCoverageInfo> toplevelClassCoverage,
|
||||
|
||||
@@ -15,12 +15,18 @@
|
||||
*/
|
||||
package com.intellij.coverage;
|
||||
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.util.ClassUtil;
|
||||
import com.intellij.rt.coverage.instrumentation.SourceLineCounter;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SourceLineCounterUtil {
|
||||
public static boolean collectNonCoveredClassInfo(final PackageAnnotator.ClassCoverageInfo classCoverageInfo,
|
||||
@@ -33,14 +39,20 @@ public class SourceLineCounterUtil {
|
||||
|
||||
SourceLineCounter counter = new SourceLineCounter(null, excludeLines, null);
|
||||
reader.accept(counter, 0);
|
||||
classCoverageInfo.totalLineCount += counter.getNSourceLines();
|
||||
packageCoverageInfo.totalLineCount += counter.getNSourceLines();
|
||||
for (Object nameAndSig : counter.getMethodsWithSourceCode()) {
|
||||
if (!PackageAnnotator.isGeneratedDefaultConstructor(psiClass, (String) nameAndSig)) {
|
||||
classCoverageInfo.totalMethodCount++;
|
||||
packageCoverageInfo.totalMethodCount++;
|
||||
}
|
||||
}
|
||||
Set<Object> descriptions = new HashSet<>();
|
||||
TIntObjectHashMap<?> lines = counter.getSourceLines();
|
||||
lines.forEachEntry((line, description) -> {
|
||||
if (!PackageAnnotator.isGeneratedDefaultConstructor(psiClass, (String)description)) {
|
||||
classCoverageInfo.totalLineCount ++;
|
||||
packageCoverageInfo.totalLineCount ++;
|
||||
descriptions.add(description);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
classCoverageInfo.totalMethodCount += descriptions.size();
|
||||
packageCoverageInfo.totalMethodCount += descriptions.size();
|
||||
|
||||
if (!counter.isInterface()) {
|
||||
packageCoverageInfo.totalClassCount++;
|
||||
}
|
||||
@@ -48,14 +60,21 @@ public class SourceLineCounterUtil {
|
||||
}
|
||||
|
||||
public static void collectSrcLinesForUntouchedFiles(final List<Integer> uncoveredLines,
|
||||
byte[] content, final boolean excludeLines) {
|
||||
byte[] content,
|
||||
final boolean excludeLines,
|
||||
final Project project) {
|
||||
final ClassReader reader = new ClassReader(content);
|
||||
final SourceLineCounter collector = new SourceLineCounter(null, excludeLines, null);
|
||||
reader.accept(collector, 0);
|
||||
final TIntObjectHashMap lines = collector.getSourceLines();
|
||||
lines.forEachKey(line -> {
|
||||
line--;
|
||||
uncoveredLines.add(line);
|
||||
|
||||
String qualifiedName = reader.getClassName();
|
||||
PsiClass psiClass = ReadAction.compute(() -> ClassUtil.findPsiClassByJVMName(PsiManager.getInstance(project), qualifiedName));
|
||||
TIntObjectHashMap<?> lines = collector.getSourceLines();
|
||||
lines.forEachEntry((line, description) -> {
|
||||
if (!PackageAnnotator.isGeneratedDefaultConstructor(psiClass, (String)description)) {
|
||||
line--;
|
||||
uncoveredLines.add(line);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class CoverageIntegrationTest extends ModuleTestCase {
|
||||
assertEquals(1, barClassCoverage.coveredMethodCount);
|
||||
PackageAnnotator.PackageCoverageInfo barPackageCoverage = consumer.myPackageCoverage.get("foo.bar");
|
||||
assertEquals(2, barPackageCoverage.coveredLineCount);
|
||||
assertEquals(9, barPackageCoverage.totalLineCount);
|
||||
assertEquals(8, barPackageCoverage.totalLineCount);
|
||||
assertEquals(1, barPackageCoverage.coveredMethodCount);
|
||||
assertEquals(7, barPackageCoverage.totalMethodCount);
|
||||
PackageAnnotator.ClassCoverageInfo uncoveredClassInfo = consumer.myClassCoverageInfo.get("foo.bar.UncoveredClass");
|
||||
|
||||
Reference in New Issue
Block a user