mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
coverage: setting to ignore trivial constructors
This commit is contained in:
@@ -137,7 +137,6 @@ public class CoverageDataManagerImpl extends CoverageDataManager {
|
||||
|
||||
@Override
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
//noinspection unchecked
|
||||
for (Element suiteElement : element.getChildren(SUITE)) {
|
||||
final CoverageRunner coverageRunner = BaseCoverageSuite.readRunnerAttribute(suiteElement);
|
||||
// skip unknown runners
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
<coverageRunner implementation="com.intellij.coverage.JaCoCoCoverageRunner"/>
|
||||
<coverageEngine implementation="com.intellij.coverage.JavaCoverageEngine" order = "last"/>
|
||||
<projectViewNodeDecorator implementation="com.intellij.coverage.CoverageProjectViewClassNodeDecorator"/>
|
||||
<projectService serviceImplementation="com.intellij.coverage.JavaCoverageOptionsProvider"/>
|
||||
<coverageOptions implementation="com.intellij.coverage.JavaCoverageOptions"/>
|
||||
|
||||
<projectService serviceInterface="com.intellij.coverage.JavaCoverageAnnotator"
|
||||
serviceImplementation="com.intellij.coverage.JavaCoverageAnnotator"/>
|
||||
|
||||
@@ -654,8 +654,11 @@ public class JavaCoverageEngine extends CoverageEngine {
|
||||
|
||||
@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());
|
||||
if (JavaCoverageOptionsProvider.getInstance(project).ignoreEmptyPrivateConstructors()) {
|
||||
PsiClass psiClass = ReadAction.compute(() -> ClassUtil.findPsiClassByJVMName(PsiManager.getInstance(project), qualifiedName));
|
||||
return PackageAnnotator.isGeneratedDefaultConstructor(psiClass, ((LineData)lineData).getMethodSignature());
|
||||
}
|
||||
return super.isGeneratedCode(project, qualifiedName, lineData);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.coverage;
|
||||
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class JavaCoverageOptions extends CoverageOptions {
|
||||
|
||||
private final JavaCoverageOptionsProvider myCoverageOptionsProvider;
|
||||
private JavaCoverageOptionsEditor myEditor;
|
||||
|
||||
public JavaCoverageOptions(JavaCoverageOptionsProvider coverageOptionsProvider) {
|
||||
myCoverageOptionsProvider = coverageOptionsProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
myEditor = new JavaCoverageOptionsEditor();
|
||||
return myEditor.getComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
return myEditor.isModified(myCoverageOptionsProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
myEditor.apply(myCoverageOptionsProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
myEditor.reset(myCoverageOptionsProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeUIResources() {
|
||||
myEditor = null;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
public JavaCoverageOptionsEditor() {
|
||||
myPanel.setBorder(IdeBorderFactory.createTitledBorder("Java coverage"));
|
||||
myPanel.add(myCheckBox, BorderLayout.NORTH);
|
||||
}
|
||||
|
||||
public JPanel getComponent() {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
public boolean isModified(JavaCoverageOptionsProvider provider) {
|
||||
return myCheckBox.isSelected() != provider.ignoreEmptyPrivateConstructors();
|
||||
}
|
||||
|
||||
public void apply(JavaCoverageOptionsProvider provider) {
|
||||
provider.setIgnoreEmptyPrivateConstructors(myCheckBox.isSelected());
|
||||
}
|
||||
|
||||
public void reset(JavaCoverageOptionsProvider provider) {
|
||||
myCheckBox.setSelected(provider.ignoreEmptyPrivateConstructors());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.coverage;
|
||||
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@State(
|
||||
name = "JavaCoverageOptionsProvider",
|
||||
storages = {
|
||||
@Storage(StoragePathMacros.WORKSPACE_FILE)
|
||||
}
|
||||
)
|
||||
public class JavaCoverageOptionsProvider implements PersistentStateComponent<JavaCoverageOptionsProvider.State> {
|
||||
private State myState = new State();
|
||||
|
||||
public static JavaCoverageOptionsProvider getInstance(Project project) {
|
||||
return ServiceManager.getService(project, JavaCoverageOptionsProvider.class);
|
||||
}
|
||||
|
||||
|
||||
public void setIgnoreEmptyPrivateConstructors(boolean state) {
|
||||
myState.myIgnoreEmptyPrivateConstructors = state;
|
||||
}
|
||||
|
||||
public boolean ignoreEmptyPrivateConstructors() {
|
||||
return myState.myIgnoreEmptyPrivateConstructors;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JavaCoverageOptionsProvider.State getState() {
|
||||
return myState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadState(JavaCoverageOptionsProvider.State state) {
|
||||
myState.myIgnoreEmptyPrivateConstructors = state.myIgnoreEmptyPrivateConstructors;
|
||||
}
|
||||
|
||||
|
||||
public static class State {
|
||||
public boolean myIgnoreEmptyPrivateConstructors = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -37,6 +38,7 @@ import com.intellij.rt.coverage.data.LineData;
|
||||
import com.intellij.rt.coverage.data.ProjectData;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.SmartHashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootType;
|
||||
@@ -57,12 +59,14 @@ public class PackageAnnotator {
|
||||
private final Project myProject;
|
||||
private final PsiManager myManager;
|
||||
private final CoverageDataManager myCoverageManager;
|
||||
private final boolean myIgnoreEmptyPrivateConstructors;
|
||||
|
||||
public PackageAnnotator(final PsiPackage aPackage) {
|
||||
myPackage = aPackage;
|
||||
myProject = myPackage.getProject();
|
||||
myManager = PsiManager.getInstance(myProject);
|
||||
myCoverageManager = CoverageDataManager.getInstance(myProject);
|
||||
myIgnoreEmptyPrivateConstructors = JavaCoverageOptionsProvider.getInstance(myProject).ignoreEmptyPrivateConstructors();
|
||||
}
|
||||
|
||||
public interface Annotator {
|
||||
@@ -455,7 +459,7 @@ public class PackageAnnotator {
|
||||
touchedClass = true;
|
||||
}
|
||||
|
||||
if (isGeneratedDefaultConstructor(psiClass, (String)nameAndSig)) {
|
||||
if (myIgnoreEmptyPrivateConstructors && isGeneratedDefaultConstructor(psiClass, (String)nameAndSig)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -505,16 +509,16 @@ public class PackageAnnotator {
|
||||
* in the bytecode, so we need to look at the PSI to see if the class defines such a constructor.
|
||||
*/
|
||||
public static boolean isGeneratedDefaultConstructor(@Nullable final PsiClass aClass, String nameAndSig) {
|
||||
if (aClass == null) {
|
||||
return false;
|
||||
}
|
||||
if (DEFAULT_CONSTRUCTOR_NAME_SIGNATURE.equals(nameAndSig)) {
|
||||
return hasGeneratedOrEmptyPrivateConstructor(aClass);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasGeneratedOrEmptyPrivateConstructor(@Nullable final PsiClass aClass) {
|
||||
if (aClass == null) {
|
||||
return false;
|
||||
}
|
||||
private static boolean hasGeneratedOrEmptyPrivateConstructor(@NotNull final PsiClass aClass) {
|
||||
return ReadAction.compute(() -> {
|
||||
PsiMethod[] constructors = aClass.getConstructors();
|
||||
if (constructors.length == 1 && constructors[0].hasModifierProperty(PsiModifier.PRIVATE)) {
|
||||
@@ -563,6 +567,6 @@ public class PackageAnnotator {
|
||||
if (coverageSuite == null) return false;
|
||||
return SourceLineCounterUtil
|
||||
.collectNonCoveredClassInfo(classCoverageInfo, packageCoverageInfo, content, coverageSuite.isTracingEnabled(),
|
||||
psiClass);
|
||||
myIgnoreEmptyPrivateConstructors ? description -> !isGeneratedDefaultConstructor(psiClass, description) : Condition.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ 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;
|
||||
@@ -29,11 +30,10 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SourceLineCounterUtil {
|
||||
public static boolean collectNonCoveredClassInfo(final PackageAnnotator.ClassCoverageInfo classCoverageInfo,
|
||||
final PackageAnnotator.PackageCoverageInfo packageCoverageInfo,
|
||||
byte[] content,
|
||||
public static boolean collectNonCoveredClassInfo(final PackageAnnotator.ClassCoverageInfo classCoverageInfo,
|
||||
final PackageAnnotator.PackageCoverageInfo packageCoverageInfo, byte[] content,
|
||||
final boolean excludeLines,
|
||||
final PsiClass psiClass) {
|
||||
final Condition<String> includeDescriptionCondition) {
|
||||
if (content == null) return false;
|
||||
ClassReader reader = new ClassReader(content, 0, content.length);
|
||||
|
||||
@@ -42,13 +42,13 @@ public class SourceLineCounterUtil {
|
||||
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;
|
||||
});
|
||||
if (includeDescriptionCondition.value((String)description)) {
|
||||
classCoverageInfo.totalLineCount++;
|
||||
packageCoverageInfo.totalLineCount++;
|
||||
descriptions.add(description);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
classCoverageInfo.totalMethodCount += descriptions.size();
|
||||
packageCoverageInfo.totalMethodCount += descriptions.size();
|
||||
@@ -68,10 +68,16 @@ public class SourceLineCounterUtil {
|
||||
reader.accept(collector, 0);
|
||||
|
||||
String qualifiedName = reader.getClassName();
|
||||
PsiClass psiClass = ReadAction.compute(() -> ClassUtil.findPsiClassByJVMName(PsiManager.getInstance(project), qualifiedName));
|
||||
boolean ignoreEmptyPrivateConstructors = JavaCoverageOptionsProvider.getInstance(project).ignoreEmptyPrivateConstructors();
|
||||
PsiClass psiClass = ignoreEmptyPrivateConstructors
|
||||
? ReadAction.compute(() -> ClassUtil.findPsiClassByJVMName(PsiManager.getInstance(project), qualifiedName))
|
||||
: null;
|
||||
Condition<String> includeDescriptionCondition = ignoreEmptyPrivateConstructors
|
||||
? description -> !PackageAnnotator.isGeneratedDefaultConstructor(psiClass, description)
|
||||
: Condition.TRUE;
|
||||
TIntObjectHashMap<?> lines = collector.getSourceLines();
|
||||
lines.forEachEntry((line, description) -> {
|
||||
if (!PackageAnnotator.isGeneratedDefaultConstructor(psiClass, (String)description)) {
|
||||
if (includeDescriptionCondition.value((String)description)) {
|
||||
line--;
|
||||
uncoveredLines.add(line);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user