From 32dc05bf3843da71f569524f8b2e745d67c25c8b Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 15 Sep 2017 20:49:20 +0300 Subject: [PATCH] coverage: separate options for implicit & empty constructors --- .../intellij/coverage/JavaCoverageEngine.java | 5 +-- .../coverage/JavaCoverageOptions.java | 19 ++++++---- .../coverage/JavaCoverageOptionsProvider.java | 28 ++++++++++++++- .../intellij/coverage/PackageAnnotator.java | 35 ++++++++++++------- .../coverage/SourceLineCounterUtil.java | 12 +------ 5 files changed, 64 insertions(+), 35 deletions(-) diff --git a/plugins/coverage/src/com/intellij/coverage/JavaCoverageEngine.java b/plugins/coverage/src/com/intellij/coverage/JavaCoverageEngine.java index b36f7847dc83..7d6688c41262 100644 --- a/plugins/coverage/src/com/intellij/coverage/JavaCoverageEngine.java +++ b/plugins/coverage/src/com/intellij/coverage/JavaCoverageEngine.java @@ -654,10 +654,7 @@ public class JavaCoverageEngine extends CoverageEngine { @Override public boolean isGeneratedCode(Project project, String qualifiedName, Object lineData) { - if (JavaCoverageOptionsProvider.getInstance(project).ignoreEmptyPrivateConstructors()) { - PsiClass psiClass = ReadAction.compute(() -> ClassUtil.findPsiClassByJVMName(PsiManager.getInstance(project), qualifiedName)); - return PackageAnnotator.isGeneratedDefaultConstructor(psiClass, ((LineData)lineData).getMethodSignature()); - } + if (JavaCoverageOptionsProvider.getInstance(project).isGeneratedConstructor(qualifiedName, ((LineData)lineData).getMethodSignature())) return true; return super.isGeneratedCode(project, qualifiedName, lineData); } diff --git a/plugins/coverage/src/com/intellij/coverage/JavaCoverageOptions.java b/plugins/coverage/src/com/intellij/coverage/JavaCoverageOptions.java index 2af4314e3c82..f1725e830d87 100644 --- a/plugins/coverage/src/com/intellij/coverage/JavaCoverageOptions.java +++ b/plugins/coverage/src/com/intellij/coverage/JavaCoverageOptions.java @@ -15,10 +15,10 @@ */ package com.intellij.coverage; +import com.intellij.openapi.ui.VerticalFlowLayout; import com.intellij.ui.IdeBorderFactory; import javax.swing.*; -import java.awt.*; public class JavaCoverageOptions extends CoverageOptions { @@ -57,12 +57,14 @@ public class JavaCoverageOptions extends CoverageOptions { private static class JavaCoverageOptionsEditor { - private JPanel myPanel = new JPanel(new BorderLayout(0, 10)); - private JCheckBox myCheckBox = new JCheckBox("Ignore empty private and implicit constructors", true); + private JPanel myPanel = new JPanel(new VerticalFlowLayout()); + private JCheckBox myImplicitCheckBox = new JCheckBox("Ignore implicit constructors", true); + private JCheckBox myEmptyCheckBox = new JCheckBox("Ignore empty private constructors of utility classes", true); public JavaCoverageOptionsEditor() { myPanel.setBorder(IdeBorderFactory.createTitledBorder("Java coverage")); - myPanel.add(myCheckBox, BorderLayout.NORTH); + myPanel.add(myImplicitCheckBox); + myPanel.add(myEmptyCheckBox); } public JPanel getComponent() { @@ -70,15 +72,18 @@ public class JavaCoverageOptions extends CoverageOptions { } public boolean isModified(JavaCoverageOptionsProvider provider) { - return myCheckBox.isSelected() != provider.ignoreEmptyPrivateConstructors(); + return myImplicitCheckBox.isSelected() != provider.ignoreImplicitConstructors() || + myEmptyCheckBox.isSelected() != provider.ignoreEmptyPrivateConstructors(); } public void apply(JavaCoverageOptionsProvider provider) { - provider.setIgnoreEmptyPrivateConstructors(myCheckBox.isSelected()); + provider.setIgnoreImplicitConstructors(myImplicitCheckBox.isSelected()); + provider.setIgnoreEmptyPrivateConstructors(myEmptyCheckBox.isSelected()); } public void reset(JavaCoverageOptionsProvider provider) { - myCheckBox.setSelected(provider.ignoreEmptyPrivateConstructors()); + myImplicitCheckBox.setSelected(provider.ignoreImplicitConstructors()); + myEmptyCheckBox.setSelected(provider.ignoreEmptyPrivateConstructors()); } } } diff --git a/plugins/coverage/src/com/intellij/coverage/JavaCoverageOptionsProvider.java b/plugins/coverage/src/com/intellij/coverage/JavaCoverageOptionsProvider.java index 22fb29900059..7ebdb41fdc32 100644 --- a/plugins/coverage/src/com/intellij/coverage/JavaCoverageOptionsProvider.java +++ b/plugins/coverage/src/com/intellij/coverage/JavaCoverageOptionsProvider.java @@ -15,8 +15,12 @@ */ package com.intellij.coverage; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.components.*; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiManager; +import com.intellij.psi.util.ClassUtil; import org.jetbrains.annotations.Nullable; @State( @@ -27,11 +31,23 @@ import org.jetbrains.annotations.Nullable; ) public class JavaCoverageOptionsProvider implements PersistentStateComponent { private State myState = new State(); - + private Project myProject; + + public JavaCoverageOptionsProvider(Project project) { + myProject = project; + } + + public boolean ignoreImplicitConstructors() { + return myState.myIgnoreImplicitConstructors; + } + public static JavaCoverageOptionsProvider getInstance(Project project) { return ServiceManager.getService(project, JavaCoverageOptionsProvider.class); } + public void setIgnoreImplicitConstructors(boolean state) { + myState.myIgnoreImplicitConstructors = state; + } public void setIgnoreEmptyPrivateConstructors(boolean state) { myState.myIgnoreEmptyPrivateConstructors = state; @@ -41,6 +57,14 @@ public class JavaCoverageOptionsProvider implements PersistentStateComponent ClassUtil.findPsiClassByJVMName(PsiManager.getInstance(myProject), qualifiedName)); + return PackageAnnotator.isGeneratedDefaultConstructor(psiClass, methodSignature, myState.myIgnoreImplicitConstructors, myState.myIgnoreEmptyPrivateConstructors); + } + return false; + } + @Nullable @Override public JavaCoverageOptionsProvider.State getState() { @@ -50,11 +74,13 @@ public class JavaCoverageOptionsProvider implements PersistentStateComponent { PsiMethod[] constructors = aClass.getConstructors(); - if (constructors.length == 1 && constructors[0].hasModifierProperty(PsiModifier.PRIVATE)) { + if (privateEmpty && constructors.length == 1 && constructors[0].hasModifierProperty(PsiModifier.PRIVATE)) { PsiCodeBlock body = constructors[0].getBody(); - return body != null && body.getStatements().length == 0; + return body != null && body.getStatements().length == 0 && + Arrays.stream(aClass.getMethods()).allMatch(method -> method.hasModifierProperty(PsiModifier.STATIC)); } - return constructors.length == 0; + return implicitConstructor && constructors.length == 0; }); } @@ -567,6 +577,7 @@ public class PackageAnnotator { if (coverageSuite == null) return false; return SourceLineCounterUtil .collectNonCoveredClassInfo(classCoverageInfo, packageCoverageInfo, content, coverageSuite.isTracingEnabled(), - myIgnoreEmptyPrivateConstructors ? description -> !isGeneratedDefaultConstructor(psiClass, description) : Condition.TRUE); + myIgnoreEmptyPrivateConstructors || myIgnoreImplicitConstructor + ? description -> !isGeneratedDefaultConstructor(psiClass, description, myIgnoreImplicitConstructor, myIgnoreEmptyPrivateConstructors) : Condition.TRUE); } } diff --git a/plugins/coverage/src/com/intellij/coverage/SourceLineCounterUtil.java b/plugins/coverage/src/com/intellij/coverage/SourceLineCounterUtil.java index b3be240bcdaf..580e6974538b 100644 --- a/plugins/coverage/src/com/intellij/coverage/SourceLineCounterUtil.java +++ b/plugins/coverage/src/com/intellij/coverage/SourceLineCounterUtil.java @@ -15,12 +15,8 @@ */ package com.intellij.coverage; -import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; -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; @@ -68,13 +64,7 @@ public class SourceLineCounterUtil { reader.accept(collector, 0); String qualifiedName = reader.getClassName(); - boolean ignoreEmptyPrivateConstructors = JavaCoverageOptionsProvider.getInstance(project).ignoreEmptyPrivateConstructors(); - PsiClass psiClass = ignoreEmptyPrivateConstructors - ? ReadAction.compute(() -> ClassUtil.findPsiClassByJVMName(PsiManager.getInstance(project), qualifiedName)) - : null; - Condition includeDescriptionCondition = ignoreEmptyPrivateConstructors - ? description -> !PackageAnnotator.isGeneratedDefaultConstructor(psiClass, description) - : Condition.TRUE; + Condition includeDescriptionCondition = description -> !JavaCoverageOptionsProvider.getInstance(project).isGeneratedConstructor(qualifiedName, description); TIntObjectHashMap lines = collector.getSourceLines(); lines.forEachEntry((line, description) -> { if (includeDescriptionCondition.value((String)description)) {