IG: add option to ignore cyclic dependencies from the same file (IDEA-210485)

in "Cyclic class dependency" inspection

GitOrigin-RevId: ba90567dbd2be793dd229defc4643d9814e71297
This commit is contained in:
Bas Leijdekkers
2021-06-30 21:43:21 +02:00
committed by intellij-monorepo-bot
parent b51823e83c
commit ce147dce1a
5 changed files with 90 additions and 16 deletions

View File

@@ -1439,6 +1439,7 @@ cyclic.class.dependency.display.name=Cyclic class dependency
cyclic.class.dependency.problem.descriptor=Class ''{0}'' is cyclically dependent on {1} other classes
cyclic.class.dependency.1.problem.descriptor=Class ''{0}'' is cyclically dependent on class ''{1}''
cyclic.class.dependency.2.problem.descriptor=Class ''{0}'' is cyclically dependent on classes ''{1}'' and ''{2}''
cyclic.class.dependency.ignore.in.same.file=Ignore cycles between classes located in the same file
cyclic.package.dependency.display.name=Cyclic package dependency
cyclic.package.dependency.problem.descriptor=Package ''{0}'' is cyclically dependent on {1} other packages
cyclic.package.dependency.1.problem.descriptor=Package ''{0}'' is cyclically dependent on package ''{1}''

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2016 Dave Griffith, Bas Leijdekkers
* Copyright 2006-2021 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,10 @@ import com.intellij.analysis.AnalysisScope;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.reference.RefClass;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.codeInspection.reference.RefPackage;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.codeInspection.util.RefEntityAlphabeticalComparator;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseGlobalInspection;
@@ -27,12 +30,22 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.uast.UDeclarationKt;
import javax.swing.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
public class CyclicClassDependencyInspection extends BaseGlobalInspection {
public boolean ignoreInSameFile = false;
@Override
public @Nullable JComponent createOptionsPanel() {
return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("cyclic.class.dependency.ignore.in.same.file"),
this, "ignoreInSameFile");
}
@Override
public CommonProblemDescriptor @Nullable [] checkElement(
@NotNull RefEntity refEntity,
@@ -48,6 +61,12 @@ public class CyclicClassDependencyInspection extends BaseGlobalInspection {
}
final Set<RefClass> dependencies = DependencyUtils.calculateTransitiveDependenciesForClass(refClass);
final Set<RefClass> dependents = DependencyUtils.calculateTransitiveDependentsForClass(refClass);
final VirtualFile vFile = refClass.getPointer().getVirtualFile();
if (ignoreInSameFile) {
final Predicate<RefClass> filter = aClass -> aClass.getPointer().getVirtualFile().equals(vFile);
dependencies.removeIf(filter);
dependents.removeIf(filter);
}
final Set<RefClass> mutualDependents = new HashSet<>(dependencies);
mutualDependents.retainAll(dependents);
final int numMutualDependents = mutualDependents.size();

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
</problems>

View File

@@ -0,0 +1,58 @@
package com.siyeh.igtest.dependency.cyclic_class_dependency.src;
/**
* @author Bas Leijdekkers
*/
public class Cyclic extends Base {
Cyclic() {
new Object() {{
foo();
}};
}
void foo() {}
}
class Base {
void a() {
Top.m();
}
}
class Top extends Cyclic {
public static void m() {}
}
interface FiveOClock {
void m(Coffee c);
}
interface Coffee extends FiveOClock {}
enum MyEnum {
ONE {
public int value() {
return 0;
}
},
TWO {
public int value() {
return ONE.value();
}
};
abstract int value();
}
class Outer {
void m() {
class Local {}
class Local2 extends Outer {}
}
class Inner1 {
Inner2 field;
}
class Inner2 {
Inner1 field;
}
}

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2013 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.
*/
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.siyeh.ig.dependency;
import com.siyeh.ig.IGInspectionTestCase;
@@ -25,4 +11,10 @@ public class CyclicClassDependencyInspectionTest extends IGInspectionTestCase {
public void test() {
doTest("com/siyeh/igtest/dependency/cyclic_class_dependency", new CyclicClassDependencyInspection());
}
public void testOption() {
final CyclicClassDependencyInspection inspection = new CyclicClassDependencyInspection();
inspection.ignoreInSameFile = true;
doTest("com/siyeh/igtest/dependency/cyclic_class_dependency2", inspection);
}
}