[lombok]: #2629 SneakyThrows permits missing 'catch' blocks in checked-exception-throwing try-with-resource blocks within lambdas

GitOrigin-RevId: 44f1a479a6c5a3152218bd2424216d76e52ce04d
This commit is contained in:
Oleksandr Zhelezniak
2024-10-06 14:01:02 +02:00
committed by intellij-monorepo-bot
parent b79a859047
commit 63e78ecf0b
4 changed files with 61 additions and 12 deletions

View File

@@ -44,7 +44,7 @@ Many features of the plugin (including warnings) could be disabled through per-p
- [**@juriad** Adam Juraszek](https://github.com/juriad) - [**@juriad** Adam Juraszek](https://github.com/juriad)
- [**@kuil09** Hwang, Geon Gu](https://github.com/kuil09) - [**@kuil09** Hwang, Geon Gu](https://github.com/kuil09)
- [**@krzyk** Krzysztof Krasoń](https://github.com/krzyk) - [**@krzyk** Krzysztof Krasoń](https://github.com/krzyk)
- [**@Lekanich** Aleksandr Zhelezniak](https://github.com/Lekanich) - [**@Lekanich** Oleksandr Zhelezniak](https://github.com/Lekanich)
- [**@mg6maciej** Maciej Górski](https://github.com/mg6maciej) - [**@mg6maciej** Maciej Górski](https://github.com/mg6maciej)
- [**@mlueders** Mike Lueders](https://github.com/mlueders) - [**@mlueders** Mike Lueders](https://github.com/mlueders)
- [**@RohanTalip** Rohan Talip](https://github.com/RohanTalip) - [**@RohanTalip** Rohan Talip](https://github.com/RohanTalip)

View File

@@ -22,20 +22,10 @@ public final class SneakyThrowsExceptionHandler extends CustomExceptionHandler {
@Override @Override
public boolean isHandled(@Nullable PsiElement element, @NotNull PsiClassType exceptionType, PsiElement topElement) { public boolean isHandled(@Nullable PsiElement element, @NotNull PsiClassType exceptionType, PsiElement topElement) {
PsiElement parent = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class, PsiTryStatement.class, PsiMethod.class); if (isHandledByParent(element, exceptionType)) {
if (parent instanceof PsiLambdaExpression) {
// lambda it's another scope, @SneakyThrows annotation can't neglect exceptions in lambda only on method, constructor
return false;
}
if (parent instanceof PsiTryStatement && isHandledByTryCatch(exceptionType, (PsiTryStatement)parent)) {
// that exception MAY be already handled by regular try-catch statement
return false; return false;
} }
if (topElement instanceof PsiTryStatement && isHandledByTryCatch(exceptionType, (PsiTryStatement)topElement)) {
// that exception MAY be already handled by regular try-catch statement (don't forget about nested try-catch)
return false;
}
if (!(topElement instanceof PsiCodeBlock)) { if (!(topElement instanceof PsiCodeBlock)) {
final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.class); final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
if (psiMethod != null) { if (psiMethod != null) {
@@ -49,6 +39,24 @@ public final class SneakyThrowsExceptionHandler extends CustomExceptionHandler {
return false; return false;
} }
private static boolean isHandledByParent(@Nullable PsiElement element, @NotNull PsiClassType exceptionType) {
PsiElement parent = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class, PsiTryStatement.class, PsiMethod.class);
if(parent == null) {
return false;
} else if (parent instanceof PsiMethod) {
// we out of the scope of the method, so the exception wasn't handled inside the method
return false;
} else if (parent instanceof PsiLambdaExpression) {
// lambda it's another scope, @SneakyThrows annotation can't neglect exceptions in lambda only on method, constructor
return true;
} else if (parent instanceof PsiTryStatement && isHandledByTryCatch(exceptionType, (PsiTryStatement) parent)) {
// that exception MAY be already handled by regular try-catch statement
return true;
}
// in case if the try block inside the lambda or inside another try-catch. GitHub issue: 1170
return isHandledByParent(parent, exceptionType);
}
private static boolean isConstructorMethodWithExceptionInSiblingConstructorCall(@NotNull PsiMethod containingMethod, private static boolean isConstructorMethodWithExceptionInSiblingConstructorCall(@NotNull PsiMethod containingMethod,
@NotNull PsiClassType exceptionTypes) { @NotNull PsiClassType exceptionTypes) {
final PsiMethodCallExpression thisOrSuperCallInConstructor = JavaPsiConstructorUtil.findThisOrSuperCallInConstructor(containingMethod); final PsiMethodCallExpression thisOrSuperCallInConstructor = JavaPsiConstructorUtil.findThisOrSuperCallInConstructor(containingMethod);

View File

@@ -30,4 +30,8 @@ public class SneakyThrowsHighlightTest extends AbstractLombokHighlightsTest {
public void testSneakThrowsDoesntCatchExceptionFromThisConstructor() { public void testSneakThrowsDoesntCatchExceptionFromThisConstructor() {
doTest(); doTest();
} }
public void testSneakyThrowsTryInsideLambda() {
doTest();
}
} }

View File

@@ -0,0 +1,37 @@
import lombok.SneakyThrows;
import java.io.Reader;
import java.io.FileReader;
public class SneakyThrowsTryInsideLambda {
@SneakyThrows
public static void m() {
Runnable r = () -> {
try (Reader reader = new <error descr="Unhandled exception: java.io.FileNotFoundException">FileReader</error>("")) {}
};
}
// everything is ok here
@SneakyThrows
void m2() {
try (Reader reader = new FileReader("")) {}
}
@SneakyThrows
public static void m3() {
try {
try (Reader reader = new FileReader("")) {
}
} catch (java.lang.NullPointerException e) {
}
}
@SneakyThrows
public static void m4() {
class A {
public void m() {
try (Reader reader = new <error descr="Unhandled exception: java.io.FileNotFoundException">FileReader</error>("")) {
}
}
}
}
}