unused declaration: ensure refs on implicit constructor (IDEA-158585)

This commit is contained in:
Anna Kozlova
2016-08-24 21:16:13 +03:00
parent d876e1be0b
commit cd6878119f
7 changed files with 55 additions and 24 deletions
@@ -139,19 +139,24 @@ public class RefClassImpl extends RefJavaElementImpl implements RefClass {
}
}
RefMethod varargConstructor = null;
for (PsiMethod psiMethod : psiMethods) {
RefMethod refMethod = (RefMethod)getRefManager().getReference(psiMethod);
if (refMethod != null) {
if (psiMethod.isConstructor()) {
if (psiMethod.getParameterList().getParametersCount() > 0 || !psiMethod.hasModifierProperty(PsiModifier.PRIVATE)) {
final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
if (parameters.length > 0 || !psiMethod.hasModifierProperty(PsiModifier.PRIVATE)) {
setUtilityClass(false);
}
addConstructor(refMethod);
if (psiMethod.getParameterList().getParametersCount() == 0) {
if (parameters.length == 0) {
setDefaultConstructor((RefMethodImpl)refMethod);
}
else if (parameters.length == 1 && parameters[0].isVarArgs()) {
varargConstructor = refMethod;
}
}
else {
if (!psiMethod.hasModifierProperty(PsiModifier.STATIC)) {
@@ -161,6 +166,10 @@ public class RefClassImpl extends RefJavaElementImpl implements RefClass {
}
}
if (varargConstructor != null && getDefaultConstructor() == null) {
setDefaultConstructor((RefMethodImpl)varargConstructor);
}
if (getConstructors().isEmpty() && !isInterface() && !isAnonymous()) {
RefImplicitConstructorImpl refImplicitConstructor = new RefImplicitConstructorImpl(this);
setDefaultConstructor(refImplicitConstructor);
@@ -216,7 +216,7 @@ public class RefJavaUtilImpl extends RefJavaUtil{
if (defaultConstructorOnly) {
RefMethodImpl refDefaultConstructor = (RefMethodImpl)refClass.getDefaultConstructor();
if (refDefaultConstructor != null && !(refDefaultConstructor instanceof RefImplicitConstructor)) {
if (refDefaultConstructor != null) {
refDefaultConstructor.addInReference(refFrom);
refFrom.addOutReference(refDefaultConstructor);
hasConstructorsMarked = true;
@@ -475,26 +475,6 @@ public class VisibilityInspection extends GlobalJavaBatchInspectionTool {
return false;
}
});
if (entryPointsManager.isAddNonJavaEntries()) {
final RefClass ownerClass = refMethod.getOwnerClass();
if (refMethod.isConstructor() && ownerClass.getDefaultConstructor() != null) {
final PsiClass psiClass = ownerClass.getElement();
String qualifiedName = psiClass != null ? psiClass.getQualifiedName() : null;
if (qualifiedName != null) {
final Project project = manager.getProject();
PsiSearchHelper.SERVICE.getInstance(project)
.processUsagesInNonJavaFiles(qualifiedName, new PsiNonJavaFileReferenceProcessor() {
@Override
public boolean process(PsiFile file, int startOffset, int endOffset) {
entryPointsManager.addEntryPoint(refMethod, false);
ignoreElement(processor, refMethod);
return false;
}
}, GlobalSearchScope.projectScope(project));
}
}
}
}
}
@@ -515,6 +495,24 @@ public class VisibilityInspection extends GlobalJavaBatchInspectionTool {
return false;
}
});
final RefMethod defaultConstructor = refClass.getDefaultConstructor();
if (entryPointsManager.isAddNonJavaEntries() && defaultConstructor != null) {
final PsiClass psiClass = refClass.getElement();
String qualifiedName = psiClass != null ? psiClass.getQualifiedName() : null;
if (qualifiedName != null) {
final Project project = manager.getProject();
PsiSearchHelper.SERVICE.getInstance(project)
.processUsagesInNonJavaFiles(qualifiedName, new PsiNonJavaFileReferenceProcessor() {
@Override
public boolean process(PsiFile file, int startOffset, int endOffset) {
entryPointsManager.addEntryPoint(defaultConstructor, false);
ignoreElement(processor, defaultConstructor);
return false;
}
}, GlobalSearchScope.projectScope(project));
}
}
}
}
});
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems/>
@@ -0,0 +1,18 @@
class A {
public A(int... i) {
System.out.println(i);
}
}
class B extends A {
public static void main(String[] args) {
System.out.println(new B());
}
}
class C {}
class D extends C {
public static void main(String[] args) {
System.out.println(new D());
}
}
@@ -4,7 +4,7 @@
<file>A.java</file>
<line>3</line>
<problem_class>unused declaration</problem_class>
<description>Class is not instantiated.</description>
<description>Class has one instantiation but it is not reachable from entry points.</description>
</problem>
<problem>
<file>A.java</file>
@@ -74,6 +74,10 @@ public class UnusedDeclarationTest extends InspectionTestCase {
doTest();
}
public void testDefaultConstructor() throws Exception {
doTest();
}
public void testReachableFromMain() {
myTool.ADD_MAINS_TO_ENTRIES = true;
doTest();