org.sonar.java.checks.design.ClassCouplingCheck Maven / Gradle / Ivy
/*
* SonarQube Java
* Copyright (C) 2012-2024 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the Sonar Source-Available License for more details.
*
* You should have received a copy of the Sonar Source-Available License
* along with this program; if not, see https://sonarsource.com/license/ssal/
*/
package org.sonar.java.checks.design;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nullable;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.java.checks.helpers.ExpressionsHelper;
import org.sonar.plugins.java.api.tree.ClassTree;
import org.sonar.plugins.java.api.tree.IdentifierTree;
import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree;
import org.sonar.plugins.java.api.tree.Tree;
@Rule(key = "S1200")
public class ClassCouplingCheck extends AbstractCouplingChecker {
private static final int DEFAULT_MAX = 20;
@RuleProperty(
key = "max",
description = "Maximum number of classes a single class is allowed to depend upon",
defaultValue = "" + DEFAULT_MAX)
public int max = DEFAULT_MAX;
@Override
public void visitClass(ClassTree tree) {
if (tree.is(Tree.Kind.CLASS) && tree.simpleName() != null) {
nesting.push(types);
types = new HashSet<>();
}
checkTypes(tree.superClass(), types);
checkTypes(tree.superInterfaces());
super.visitClass(tree);
if (tree.is(Tree.Kind.CLASS) && tree.simpleName() != null) {
if (types.size() > max) {
context.reportIssue(
this,
tree.simpleName(),
"Split this class into smaller and more specialized ones to reduce its dependencies on other classes from " +
types.size() + " to the maximum authorized " + max + " or less.");
}
types = nesting.pop();
}
}
@Override
public void checkTypes(@Nullable Tree type, @Nullable Set types) {
if (type == null || types == null) {
return;
}
if (type.is(Tree.Kind.IDENTIFIER)) {
types.add(((IdentifierTree) type).name());
} else if (type.is(Tree.Kind.MEMBER_SELECT)) {
MemberSelectExpressionTree mse = (MemberSelectExpressionTree) type;
String concatenated = ExpressionsHelper.concatenate(mse);
types.add(concatenated);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy