blob: eefdcef6949cffdd4f46e3431b8f8a489e3608d1 [file] [log] [blame]
/*
* Copyright 2003-2007 Dave Griffith
*
* 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.siyeh.ig.methodmetrics;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.siyeh.ig.psiutils.ClassUtils;
import com.siyeh.ig.psiutils.LibraryUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
class CouplingVisitor extends JavaRecursiveElementVisitor {
private boolean m_inClass = false;
private final PsiMethod m_method;
private final boolean m_includeJavaClasses;
private final boolean m_includeLibraryClasses;
private final Set<String> m_dependencies = new HashSet<String>(10);
CouplingVisitor(@NotNull PsiMethod method, boolean includeJavaClasses,
boolean includeLibraryClasses) {
super();
m_method = method;
m_includeJavaClasses = includeJavaClasses;
m_includeLibraryClasses = includeLibraryClasses;
}
@Override
public void visitVariable(@NotNull PsiVariable variable) {
super.visitVariable(variable);
final PsiType type = variable.getType();
addDependency(type);
}
@Override
public void visitMethod(@NotNull PsiMethod method) {
super.visitMethod(method);
final PsiType returnType = method.getReturnType();
addDependency(returnType);
addDependenciesForThrowsList(method);
}
private void addDependenciesForThrowsList(PsiMethod method) {
final PsiReferenceList throwsList = method.getThrowsList();
final PsiClassType[] throwsTypes = throwsList.getReferencedTypes();
for (PsiClassType throwsType : throwsTypes) {
addDependency(throwsType);
}
}
@Override
public void visitNewExpression(@NotNull PsiNewExpression exp) {
super.visitNewExpression(exp);
final PsiType classType = exp.getType();
addDependency(classType);
}
@Override
public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression exp) {
super.visitClassObjectAccessExpression(exp);
final PsiTypeElement operand = exp.getOperand();
addDependency(operand);
}
@Override
public void visitClass(@NotNull PsiClass aClass) {
final boolean wasInClass = m_inClass;
if (!m_inClass) {
m_inClass = true;
super.visitClass(aClass);
}
m_inClass = wasInClass;
final PsiType[] superTypes = aClass.getSuperTypes();
for (PsiType superType : superTypes) {
addDependency(superType);
}
}
@Override
public void visitTryStatement(@NotNull PsiTryStatement statement) {
super.visitTryStatement(statement);
final PsiParameter[] catchBlockParameters = statement.getCatchBlockParameters();
for (PsiParameter catchBlockParameter : catchBlockParameters) {
final PsiType catchType = catchBlockParameter.getType();
addDependency(catchType);
}
}
@Override
public void visitInstanceOfExpression(@NotNull PsiInstanceOfExpression exp) {
super.visitInstanceOfExpression(exp);
final PsiTypeElement checkType = exp.getCheckType();
addDependency(checkType);
}
@Override
public void visitTypeCastExpression(@NotNull PsiTypeCastExpression exp) {
super.visitTypeCastExpression(exp);
final PsiTypeElement castType = exp.getCastType();
addDependency(castType);
}
private void addDependency(PsiTypeElement typeElement) {
if (typeElement == null) {
return;
}
final PsiType type = typeElement.getType();
addDependency(type);
}
private void addDependency(PsiType type) {
if (type == null) {
return;
}
final PsiType baseType = type.getDeepComponentType();
if (ClassUtils.isPrimitive(type)) {
return;
}
final PsiClass containingClass = m_method.getContainingClass();
if (containingClass == null) {
return;
}
final String qualifiedName = containingClass.getQualifiedName();
if (qualifiedName == null) {
return;
}
if (baseType.equalsToText(qualifiedName)) {
return;
}
@NonNls final String baseTypeName = baseType.getCanonicalText();
if (!m_includeJavaClasses &&
(baseTypeName.startsWith("java.") ||
baseTypeName.startsWith("javax."))) {
return;
}
if (StringUtil.startsWithConcatenation(baseTypeName, qualifiedName, ".")) {
return;
}
if (!m_includeLibraryClasses) {
final Project project = m_method.getProject();
final GlobalSearchScope searchScope = GlobalSearchScope.allScope(project);
final PsiClass aClass = JavaPsiFacade.getInstance(project).findClass(baseTypeName, searchScope);
if (aClass == null) {
return;
}
if (LibraryUtil.classIsInLibrary(aClass)) {
return;
}
}
m_dependencies.add(baseTypeName);
}
public int getNumDependencies() {
return m_dependencies.size();
}
}