mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
-small refactoring (cherry picked from commit 90f8ebc2feae64cb504e0ada6a5625bd25d0b6c9) (cherry picked from commit 3077e1b9185fb214707c9ce20644ec0faa8b0de4) IJ-MR-169535 GitOrigin-RevId: 46ff90b6d78ace4f4246c6c3c2e5482686d0926e
98 lines
4.0 KiB
Java
98 lines
4.0 KiB
Java
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
|
package com.intellij.lang.jvm.util;
|
|
|
|
import com.intellij.lang.jvm.*;
|
|
import com.intellij.lang.jvm.types.*;
|
|
import com.intellij.psi.PsiClass;
|
|
import com.intellij.psi.PsiMethod;
|
|
import com.intellij.psi.util.PsiMethodUtil;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
import static com.intellij.lang.jvm.util.JvmUtil.resolveClass;
|
|
import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
|
|
import static com.intellij.util.containers.ContainerUtil.find;
|
|
import static java.util.Objects.requireNonNull;
|
|
|
|
// TODO support com.intellij.codeInsight.runner.JavaMainMethodProvider
|
|
|
|
/**
|
|
* @deprecated These methods are not supported for new features, please use original methods for languages
|
|
*/
|
|
@Deprecated
|
|
public final class JvmMainMethodUtil {
|
|
|
|
private static final String MAIN = "main";
|
|
|
|
private JvmMainMethodUtil() {}
|
|
|
|
public static boolean isMainMethod(@NotNull JvmMethod method) {
|
|
if (!MAIN.equals(method.getName())) return false;
|
|
final JvmClass containingClass = method.getContainingClass();
|
|
return containingClass != null && canBeMainClass(containingClass) && hasMainMethodSignature(method);
|
|
}
|
|
|
|
public static boolean hasMainMethodInHierarchy(@NotNull JvmClass clazz) {
|
|
if (!canBeMainClass(clazz)) return false;
|
|
//just to partially support instance methods for Java, these methods are abandoned,
|
|
//please use original methods
|
|
if (clazz instanceof PsiClass && PsiMethodUtil.hasMainMethod((PsiClass)clazz)) return true;
|
|
|
|
JvmMethod methodInHierarchy = JvmHierarchyUtil.traverseSupers(clazz, superClazz -> {
|
|
if (superClazz.getClassKind() == JvmClassKind.INTERFACE) {
|
|
return null;
|
|
}
|
|
return findMainMethodInClass(superClazz);
|
|
});
|
|
return methodInHierarchy != null;
|
|
}
|
|
|
|
private static boolean canBeMainClass(@NotNull JvmClass clazz) {
|
|
if (clazz.getQualifiedName() == null) return false; // anonymous and local classes
|
|
final JvmClassKind kind = clazz.getClassKind();
|
|
if (kind == JvmClassKind.ANNOTATION) return false;
|
|
return clazz.getContainingClass() == null || clazz.hasModifier(JvmModifier.STATIC);
|
|
}
|
|
|
|
private static @Nullable JvmMethod findMainMethodInClass(@NotNull JvmClass clazz) {
|
|
JvmMethod[] candidates = clazz.findMethodsByName(MAIN);
|
|
return find(candidates, JvmMainMethodUtil::hasMainMethodSignature);
|
|
}
|
|
|
|
/**
|
|
* @return {@code true} if the method matches {@code public static void xxx(String[] args) {}}, otherwise {@code false}.
|
|
* It also supports java instance methods.
|
|
* @see JvmMainMethodUtil
|
|
*/
|
|
private static boolean hasMainMethodSignature(@NotNull JvmMethod method) {
|
|
//just to partially support instance methods for Java, these methods are abandoned
|
|
//please use original methods
|
|
if (method instanceof PsiMethod &&
|
|
PsiMethodUtil.isMainMethod((PsiMethod)method)) return true;
|
|
|
|
if (method.isConstructor()) return false;
|
|
if (!method.hasModifier(JvmModifier.PUBLIC)) return false;
|
|
if (!method.hasModifier(JvmModifier.STATIC)) return false;
|
|
|
|
final JvmType returnType = requireNonNull(method.getReturnType(), () -> "Non-constructors should have return type: " + method);
|
|
if (!isVoid(returnType)) return false;
|
|
|
|
final JvmParameter[] parameters = method.getParameters();
|
|
if (parameters.length != 1) return false;
|
|
|
|
return isStringArray(parameters[0].getType());
|
|
}
|
|
|
|
private static boolean isVoid(@NotNull JvmType type) {
|
|
return type instanceof JvmPrimitiveType && ((JvmPrimitiveType)type).getKind() == JvmPrimitiveTypeKind.VOID;
|
|
}
|
|
|
|
private static boolean isStringArray(@NotNull JvmType type) {
|
|
if (!(type instanceof JvmArrayType)) return false;
|
|
final JvmType componentType = ((JvmArrayType)type).getComponentType();
|
|
if (!(componentType instanceof JvmReferenceType)) return false;
|
|
final JvmClass resolved = resolveClass((JvmReferenceType)componentType);
|
|
return resolved != null && JAVA_LANG_STRING.equals(resolved.getQualifiedName());
|
|
}
|
|
}
|