ConversionResult (@NotNull PsiType targetType, @NotNull PsiType actualType, @NotNull Position position, @NotNull GroovyPsiElement context) { final PsiClassType objectType = TypesUtil.getJavaLangObject(context); boolean isCompileStatic = CompileStaticUtil.isCompileStatic(context); if (position == Position.RETURN_VALUE) { if (targetType.equals(objectType) && PsiTypes.voidType().equals(actualType)) { return OK; } } if (PsiTypes.voidType().equals(actualType)) { switch (position) { case RETURN_VALUE -> { // We can return void values from method. But it's very suspicious. return WARNING; } case ASSIGNMENT -> { if (targetType.equals(PsiTypes.booleanType())) return null; if (targetType.equals(PsiType.getJavaLangString(context.getManager(), context.getResolveScope()))) return WARNING; return isCompileStatic ? ERROR : WARNING; } default -> { } } } else if (actualType == PsiTypes.nullType()) { if (position == Position.RETURN_VALUE) { // We can return null from method returning primitive type, but runtime error will occur. if (targetType instanceof PsiPrimitiveType) return WARNING; } else { return targetType instanceof PsiPrimitiveType ? ERROR : OK; } } return null; }