[global inspections] accept top level functions

GitOrigin-RevId: 73b321f756acc62383b7bdd889db278a42ea13a1
This commit is contained in:
Anna Kozlova
2021-06-23 13:19:43 +00:00
committed by intellij-monorepo-bot
parent 4ded64a93c
commit 4966aa2d3c
8 changed files with 49 additions and 49 deletions
@@ -152,7 +152,7 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
}
}
private static boolean isExternalizableNoParameterConstructor(@NotNull UMethod method, RefClass refClass) {
private static boolean isExternalizableNoParameterConstructor(@NotNull UMethod method, @Nullable RefClass refClass) {
if (!method.isConstructor()) return false;
if (method.getVisibility() != UastVisibility.PUBLIC) return false;
final List<UParameter> parameterList = method.getUastParameters();
@@ -191,7 +191,7 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
return !(aClass != null && !isSerializable(aClass, refClass));
}
private static boolean isWriteReplaceMethod(@NotNull UMethod method, RefClass refClass) {
private static boolean isWriteReplaceMethod(@NotNull UMethod method, @Nullable RefClass refClass) {
final String name = method.getName();
if (!"writeReplace".equals(name)) return false;
List<UParameter> parameters = method.getUastParameters();
@@ -202,7 +202,7 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
return !(aClass != null && !isSerializable(aClass, refClass));
}
private static boolean isReadResolveMethod(@NotNull UMethod method, RefClass refClass) {
private static boolean isReadResolveMethod(@NotNull UMethod method, @Nullable RefClass refClass) {
final String name = method.getName();
if (!"readResolve".equals(name)) return false;
List<UParameter> parameters = method.getUastParameters();
@@ -426,14 +426,16 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
processedSuspicious.add(refMethod);
if (refMethod instanceof RefImplicitConstructor) {
RefClass ownerClass = refMethod.getOwnerClass();
LOG.assertTrue(ownerClass != null);
visitClass(ownerClass);
if (ownerClass != null) {
visitClass(ownerClass);
}
return;
}
if (refMethod.isConstructor()) {
RefClass ownerClass = refMethod.getOwnerClass();
LOG.assertTrue(ownerClass != null);
queryQualifiedNameUsages(ownerClass);
if (ownerClass != null) {
queryQualifiedNameUsages(ownerClass);
}
}
UMethod uMethod = (UMethod)refMethod.getUastElement();
if (uMethod != null && (isSerializablePatternMethod(uMethod, refMethod.getOwnerClass()) ||
@@ -504,7 +506,7 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
return true;
}
private static boolean isSerializablePatternMethod(@NotNull UMethod psiMethod, RefClass refClass) {
private static boolean isSerializablePatternMethod(@NotNull UMethod psiMethod, @Nullable RefClass refClass) {
return isReadObjectMethod(psiMethod, refClass) || isWriteObjectMethod(psiMethod, refClass) || isReadResolveMethod(psiMethod, refClass) ||
isWriteReplaceMethod(psiMethod, refClass) || isExternalizableNoParameterConstructor(psiMethod, refClass);
}
@@ -598,14 +600,6 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
else if (methodOwnerClass != null) {
addInstantiatedClass(methodOwnerClass);
}
else {
LOG.error("owner class is null for " + method.getPsiElement()
+ " is static ? " + method.isStatic()
+ "; is abstract ? " + method.isAbstract()
+ "; is main method ? " + method.isAppMain()
+ "; is constructor " + method.isConstructor()
+ "; containing file " + method.getPointer().getVirtualFile().getFileType());
}
myProcessedMethods.add(method);
makeContentReachable((RefJavaElementImpl)method);
makeClassInitializersReachable(methodOwnerClass);
@@ -616,7 +610,7 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
makeContentReachable((RefJavaElementImpl)method);
}
else {
addDelayedMethod(method);
addDelayedMethod(method, methodOwnerClass);
}
for (RefMethod refSub : method.getDerivedMethods()) {
@@ -676,8 +670,8 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
}
}
private void addDelayedMethod(@NotNull RefMethod refMethod) {
Set<RefMethod> methods = myClassIDtoMethods.computeIfAbsent(refMethod.getOwnerClass(), __ -> new HashSet<>());
private void addDelayedMethod(@NotNull RefMethod refMethod, @NotNull RefClass ownerClass) {
Set<RefMethod> methods = myClassIDtoMethods.computeIfAbsent(ownerClass, __ -> new HashSet<>());
methods.add(refMethod);
}
@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// 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.intellij.codeInspection.ex;
import com.intellij.codeInsight.AnnotationUtil;
@@ -233,7 +233,7 @@ public abstract class EntryPointsManagerBase extends EntryPointsManager implemen
if (newEntryPoint instanceof RefClass || newEntryPoint instanceof RefMethod) {
RefClass refClass = newEntryPoint instanceof RefMethod ? ((RefMethod)newEntryPoint).getOwnerClass()
: (RefClass)newEntryPoint;
if (!refClass.isAnonymous()) {
if (refClass != null && !refClass.isAnonymous()) {
final ClassPattern classPattern = new ClassPattern();
classPattern.pattern = new SmartRefElementPointerImpl(refClass, true).getFQName();
if (newEntryPoint instanceof RefMethod && !(newEntryPoint instanceof RefImplicitConstructor)) {
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2015 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.intellij.codeInspection.reference;
@@ -32,6 +18,11 @@ public class RefImplicitConstructorImpl extends RefMethodImpl implements RefImpl
super(JavaAnalysisBundle.message("inspection.reference.implicit.constructor.name", ownerClass.getName()), ownerClass);
}
@Override
public @NotNull RefClass getOwnerClass() {
return Objects.requireNonNull(super.getOwnerClass());
}
@Override
public void buildReferences() {
getRefManager().fireBuildReferences(this);
@@ -47,7 +38,6 @@ public class RefImplicitConstructorImpl extends RefMethodImpl implements RefImpl
public String getName() {
if (isValid()) {
RefClass ownerClass = getOwnerClass();
LOG.assertTrue(ownerClass != null);
return JavaAnalysisBundle.message("inspection.reference.implicit.constructor.name", ownerClass.getName());
}
return super.getName();
@@ -60,8 +50,7 @@ public class RefImplicitConstructorImpl extends RefMethodImpl implements RefImpl
@Override
public boolean isValid() {
RefClass ownerClass = getOwnerClass();
return ownerClass != null && ReadAction.compute(ownerClass::isValid).booleanValue();
return ReadAction.compute(getOwnerClass()::isValid).booleanValue();
}
@NotNull
@@ -88,8 +77,7 @@ public class RefImplicitConstructorImpl extends RefMethodImpl implements RefImpl
@Nullable
@Override
public PsiElement getPsiElement() {
RefClass ownerClass = getOwnerClass();
return ownerClass == null ? null : ownerClass.getPsiElement();
return getOwnerClass().getPsiElement();
}
@Override
@@ -228,7 +228,13 @@ public class RefMethodImpl extends RefJavaElementImpl implements RefMethod {
@Override
public boolean hasBody() {
return !isAbstract() && !getOwnerClass().isInterface() || !isBodyEmpty();
if (!isAbstract()) {
RefClass ownerClass = getOwnerClass();
if (ownerClass != null && !ownerClass.isInterface()) {
return true;
}
}
return !isBodyEmpty();
}
private void initializeSuperMethods(PsiMethod method) {
@@ -416,11 +422,7 @@ public class RefMethodImpl extends RefJavaElementImpl implements RefMethod {
@Nullable
@Override
public RefClass getOwnerClass() {
WritableRefEntity owner = getOwner();
if (owner != null && !(owner instanceof RefClass)) {
LOG.error("Unexpected owner: " + owner.getExternalName());
}
return ObjectUtils.tryCast(owner, RefClass.class);
return ObjectUtils.tryCast(getOwner(), RefClass.class);
}
@NotNull
@@ -1,4 +1,4 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// 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.intellij.codeInspection.deadCode;
@@ -14,6 +14,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class DeadHTMLComposer extends HTMLComposerImpl {
@@ -145,7 +146,7 @@ public class DeadHTMLComposer extends HTMLComposerImpl {
@Override public void visitMethod(@NotNull RefMethod method) {
RefClass refClass = method.getOwnerClass();
if (method.isExternalOverride()) {
String classOrInterface = HTMLJavaHTMLComposer.getClassOrInterface(refClass, false);
String classOrInterface = HTMLJavaHTMLComposer.getClassOrInterface(Objects.requireNonNull(refClass), false);
buf.append(AnalysisBundle.message("inspection.dead.code.problem.synopsis22", classOrInterface));
} else if (method.isStatic() || method.isConstructor()) {
int nRefs = method.getInReferences().size();
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>TC.kt</file>
<line>1</line>
<entry_point TYPE="method" FQNAME="TCKt void runApplication(java.lang.String args)" />
<description>Method is never used.</description>
</problem>
</problems>
@@ -0,0 +1,2 @@
inline fun <reified T : Any> runApplication(vararg args: String) {}
fun main(args: Array<String>) {}
@@ -87,4 +87,8 @@ public class UnusedDeclarationKtTest extends AbstractUnusedDeclarationTest {
public void testClassLiteralRef() {
doTest();
}
public void testTopLevelFunction() {
doTest();
}
}