diff --git a/.all-contributorsrc b/.all-contributorsrc index e26a244d2f..8a891884e5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7883,6 +7883,15 @@ "contributions": [ "code" ] + }, + { + "login": "VitaliiIevtushenko", + "name": "Vitalii Yevtushenko", + "avatar_url": "https://avatars.githubusercontent.com/u/11145125?v=4", + "profile": "https://github.com/VitaliiIevtushenko", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index b6ccbdf647..81690f91dc 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -820,299 +820,300 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Vincent Privat
Vincent Privat

๐Ÿ› Vishhwas
Vishhwas

๐Ÿ› Vishv_Android
Vishv_Android

๐Ÿ› + Vitalii Yevtushenko
Vitalii Yevtushenko

๐Ÿ› Vitaly
Vitaly

๐Ÿ› Vitaly Polonetsky
Vitaly Polonetsky

๐Ÿ› - Vojtech Polivka
Vojtech Polivka

๐Ÿ› + Vojtech Polivka
Vojtech Polivka

๐Ÿ› Vsevolod Zholobov
Vsevolod Zholobov

๐Ÿ› Vyom Yadav
Vyom Yadav

๐Ÿ’ป Wang Shidong
Wang Shidong

๐Ÿ› Waqas Ahmed
Waqas Ahmed

๐Ÿ› Wayne J. Earl
Wayne J. Earl

๐Ÿ› Wchenghui
Wchenghui

๐Ÿ› - Wener
Wener

๐Ÿ’ป + Wener
Wener

๐Ÿ’ป Will Winder
Will Winder

๐Ÿ› Willem A. Hajenius
Willem A. Hajenius

๐Ÿ’ป William Brockhus
William Brockhus

๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
Wilson Kurniawan

๐Ÿ› Wim Deblauwe
Wim Deblauwe

๐Ÿ› Woongsik Choi
Woongsik Choi

๐Ÿ› - XenoAmess
XenoAmess

๐Ÿ’ป ๐Ÿ› + XenoAmess
XenoAmess

๐Ÿ’ป ๐Ÿ› Yang
Yang

๐Ÿ’ป YaroslavTER
YaroslavTER

๐Ÿ› Yasar Shaikh
Yasar Shaikh

๐Ÿ’ป Young Chan
Young Chan

๐Ÿ’ป ๐Ÿ› YuJin Kim
YuJin Kim

๐Ÿ› Yuri Dolzhenko
Yuri Dolzhenko

๐Ÿ› - Yurii Dubinka
Yurii Dubinka

๐Ÿ› + Yurii Dubinka
Yurii Dubinka

๐Ÿ› Zoltan Farkas
Zoltan Farkas

๐Ÿ› Zustin
Zustin

๐Ÿ› aaronhurst-google
aaronhurst-google

๐Ÿ› ๐Ÿ’ป alexmodis
alexmodis

๐Ÿ› andreoss
andreoss

๐Ÿ› andrey81inmd
andrey81inmd

๐Ÿ’ป ๐Ÿ› - anicoara
anicoara

๐Ÿ› + anicoara
anicoara

๐Ÿ› arunprasathav
arunprasathav

๐Ÿ› asiercamara
asiercamara

๐Ÿ› astillich-igniti
astillich-igniti

๐Ÿ’ป avesolovksyy
avesolovksyy

๐Ÿ› avishvat
avishvat

๐Ÿ› avivmu
avivmu

๐Ÿ› - axelbarfod1
axelbarfod1

๐Ÿ› + axelbarfod1
axelbarfod1

๐Ÿ› b-3-n
b-3-n

๐Ÿ› balbhadra9
balbhadra9

๐Ÿ› base23de
base23de

๐Ÿ› bergander
bergander

๐Ÿ› ๐Ÿ’ป berkam
berkam

๐Ÿ’ป ๐Ÿ› breizh31
breizh31

๐Ÿ› - caesarkim
caesarkim

๐Ÿ› + caesarkim
caesarkim

๐Ÿ› carolyujing
carolyujing

๐Ÿ› cbfiddle
cbfiddle

๐Ÿ› cesares-basilico
cesares-basilico

๐Ÿ› chrite
chrite

๐Ÿ› ciufudean
ciufudean

๐Ÿ“– cobratbq
cobratbq

๐Ÿ› - coladict
coladict

๐Ÿ› + coladict
coladict

๐Ÿ› cosmoJFH
cosmoJFH

๐Ÿ› cristalp
cristalp

๐Ÿ› crunsk
crunsk

๐Ÿ› cwholmes
cwholmes

๐Ÿ› cyberjj999
cyberjj999

๐Ÿ› cyw3
cyw3

๐Ÿ› ๐Ÿ“– - d1ss0nanz
d1ss0nanz

๐Ÿ› + d1ss0nanz
d1ss0nanz

๐Ÿ› dague1
dague1

๐Ÿ“– dalizi007
dalizi007

๐Ÿ’ป danbrycefairsailcom
danbrycefairsailcom

๐Ÿ› dariansanity
dariansanity

๐Ÿ› darrenmiliband
darrenmiliband

๐Ÿ› davidburstrom
davidburstrom

๐Ÿ› - dbirkman-paloalto
dbirkman-paloalto

๐Ÿ› + dbirkman-paloalto
dbirkman-paloalto

๐Ÿ› deepak-patra
deepak-patra

๐Ÿ› dependabot[bot]
dependabot[bot]

๐Ÿ’ป ๐Ÿ› dinesh150
dinesh150

๐Ÿ› diziaq
diziaq

๐Ÿ› dreaminpast123
dreaminpast123

๐Ÿ› duanyanan
duanyanan

๐Ÿ› - dutt-sanjay
dutt-sanjay

๐Ÿ› + dutt-sanjay
dutt-sanjay

๐Ÿ› duursma
duursma

๐Ÿ’ป dylanleung
dylanleung

๐Ÿ› dzeigler
dzeigler

๐Ÿ› eant60
eant60

๐Ÿ› ekkirala
ekkirala

๐Ÿ› emersonmoura
emersonmoura

๐Ÿ› - emouty
emouty

๐Ÿ’ป ๐Ÿ› + emouty
emouty

๐Ÿ’ป ๐Ÿ› eugenepugach
eugenepugach

๐Ÿ› fairy
fairy

๐Ÿ› filiprafalowicz
filiprafalowicz

๐Ÿ’ป flxbl-io
flxbl-io

๐Ÿ’ต foxmason
foxmason

๐Ÿ› frankegabor
frankegabor

๐Ÿ› - frankl
frankl

๐Ÿ› + frankl
frankl

๐Ÿ› freafrea
freafrea

๐Ÿ› fsapatin
fsapatin

๐Ÿ› gearsethenry
gearsethenry

๐Ÿ› gracia19
gracia19

๐Ÿ› gudzpoz
gudzpoz

๐Ÿ› guo fei
guo fei

๐Ÿ› - gurmsc5
gurmsc5

๐Ÿ› + gurmsc5
gurmsc5

๐Ÿ› gwilymatgearset
gwilymatgearset

๐Ÿ’ป ๐Ÿ› haigsn
haigsn

๐Ÿ› hemanshu070
hemanshu070

๐Ÿ› henrik242
henrik242

๐Ÿ› hongpuwu
hongpuwu

๐Ÿ› hvbtup
hvbtup

๐Ÿ’ป ๐Ÿ› - igniti GmbH
igniti GmbH

๐Ÿ› + igniti GmbH
igniti GmbH

๐Ÿ› ilovezfs
ilovezfs

๐Ÿ› imax-erik
imax-erik

๐Ÿ› itaigilo
itaigilo

๐Ÿ› jakivey32
jakivey32

๐Ÿ› jbennett2091
jbennett2091

๐Ÿ› jcamerin
jcamerin

๐Ÿ› - jkeener1
jkeener1

๐Ÿ› + jkeener1
jkeener1

๐Ÿ› jmetertea
jmetertea

๐Ÿ› johnra2
johnra2

๐Ÿ’ป johnzhao9
johnzhao9

๐Ÿ› josemanuelrolon
josemanuelrolon

๐Ÿ’ป ๐Ÿ› kabroxiko
kabroxiko

๐Ÿ’ป ๐Ÿ› karthikaiyasamy
karthikaiyasamy

๐Ÿ“– - karwer
karwer

๐Ÿ› + karwer
karwer

๐Ÿ› kaulonline
kaulonline

๐Ÿ› kdaemonv
kdaemonv

๐Ÿ› kdebski85
kdebski85

๐Ÿ› ๐Ÿ’ป kenji21
kenji21

๐Ÿ’ป ๐Ÿ› kfranic
kfranic

๐Ÿ› khalidkh
khalidkh

๐Ÿ› - koalalam
koalalam

๐Ÿ› + koalalam
koalalam

๐Ÿ› krzyk
krzyk

๐Ÿ› lasselindqvist
lasselindqvist

๐Ÿ› lgemeinhardt
lgemeinhardt

๐Ÿ› lihuaib
lihuaib

๐Ÿ› liqingjun123
liqingjun123

๐Ÿ› lonelyma1021
lonelyma1021

๐Ÿ› - lpeddy
lpeddy

๐Ÿ› + lpeddy
lpeddy

๐Ÿ› lujiefsi
lujiefsi

๐Ÿ’ป lukelukes
lukelukes

๐Ÿ’ป lyriccoder
lyriccoder

๐Ÿ› marcelmore
marcelmore

๐Ÿ› matchbox
matchbox

๐Ÿ› matthiaskraaz
matthiaskraaz

๐Ÿ› - meandonlyme
meandonlyme

๐Ÿ› + meandonlyme
meandonlyme

๐Ÿ› mikesive
mikesive

๐Ÿ› milossesic
milossesic

๐Ÿ› mluckam
mluckam

๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
mohan-chinnappan-n

๐Ÿ’ป mriddell95
mriddell95

๐Ÿ› mrlzh
mrlzh

๐Ÿ› - msloan
msloan

๐Ÿ› + msloan
msloan

๐Ÿ› mucharlaravalika
mucharlaravalika

๐Ÿ› mvenneman
mvenneman

๐Ÿ› nareshl119
nareshl119

๐Ÿ› nicolas-harraudeau-sonarsource
nicolas-harraudeau-sonarsource

๐Ÿ› noerremark
noerremark

๐Ÿ› novsirion
novsirion

๐Ÿ› - nwcm
nwcm

๐Ÿ“– ๐Ÿ› ๐Ÿ’ป + nwcm
nwcm

๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
oggboy

๐Ÿ› oinume
oinume

๐Ÿ› orimarko
orimarko

๐Ÿ’ป ๐Ÿ› pablogomez2197
pablogomez2197

๐Ÿ› pacvz
pacvz

๐Ÿ’ป pallavi agarwal
pallavi agarwal

๐Ÿ› - parksungrin
parksungrin

๐Ÿ› + parksungrin
parksungrin

๐Ÿ› patpatpat123
patpatpat123

๐Ÿ› patriksevallius
patriksevallius

๐Ÿ› pbrajesh1
pbrajesh1

๐Ÿ› phoenix384
phoenix384

๐Ÿ› piotrszymanski-sc
piotrszymanski-sc

๐Ÿ’ป plan3d
plan3d

๐Ÿ› - poojasix
poojasix

๐Ÿ› + poojasix
poojasix

๐Ÿ› prabhushrikant
prabhushrikant

๐Ÿ› pujitha8783
pujitha8783

๐Ÿ› r-r-a-j
r-r-a-j

๐Ÿ› raghujayjunk
raghujayjunk

๐Ÿ› rajeshveera
rajeshveera

๐Ÿ› rajeswarreddy88
rajeswarreddy88

๐Ÿ› - recdevs
recdevs

๐Ÿ› + recdevs
recdevs

๐Ÿ› reudismam
reudismam

๐Ÿ’ป ๐Ÿ› rijkt
rijkt

๐Ÿ› rillig-tk
rillig-tk

๐Ÿ› rmohan20
rmohan20

๐Ÿ’ป ๐Ÿ› rnveach
rnveach

๐Ÿ› rxmicro
rxmicro

๐Ÿ› - ryan-gustafson
ryan-gustafson

๐Ÿ’ป ๐Ÿ› + ryan-gustafson
ryan-gustafson

๐Ÿ’ป ๐Ÿ› sabi0
sabi0

๐Ÿ› scais
scais

๐Ÿ› schosin
schosin

๐Ÿ› screamingfrog
screamingfrog

๐Ÿ’ต sebbASF
sebbASF

๐Ÿ› sergeygorbaty
sergeygorbaty

๐Ÿ’ป - shilko2013
shilko2013

๐Ÿ› + shilko2013
shilko2013

๐Ÿ› shiomiyan
shiomiyan

๐Ÿ“– simeonKondr
simeonKondr

๐Ÿ› snajberk
snajberk

๐Ÿ› sniperrifle2004
sniperrifle2004

๐Ÿ› snuyanzin
snuyanzin

๐Ÿ› ๐Ÿ’ป soloturn
soloturn

๐Ÿ› - soyodream
soyodream

๐Ÿ› + soyodream
soyodream

๐Ÿ› sratz
sratz

๐Ÿ› stonio
stonio

๐Ÿ› sturton
sturton

๐Ÿ’ป ๐Ÿ› sudharmohan
sudharmohan

๐Ÿ› suruchidawar
suruchidawar

๐Ÿ› svenfinitiv
svenfinitiv

๐Ÿ› - szymanp23
szymanp23

๐Ÿ› ๐Ÿ’ป + szymanp23
szymanp23

๐Ÿ› ๐Ÿ’ป tashiscool
tashiscool

๐Ÿ› test-git-hook
test-git-hook

๐Ÿ› testation21
testation21

๐Ÿ’ป ๐Ÿ› thanosa
thanosa

๐Ÿ› tiandiyixian
tiandiyixian

๐Ÿ› tobwoerk
tobwoerk

๐Ÿ› - tprouvot
tprouvot

๐Ÿ› ๐Ÿ’ป + tprouvot
tprouvot

๐Ÿ› ๐Ÿ’ป trentchilders
trentchilders

๐Ÿ› triandicAnt
triandicAnt

๐Ÿ› trishul14
trishul14

๐Ÿ› tsui
tsui

๐Ÿ› wangzitom12306
wangzitom12306

๐Ÿ› winhkey
winhkey

๐Ÿ› - witherspore
witherspore

๐Ÿ› + witherspore
witherspore

๐Ÿ› wjljack
wjljack

๐Ÿ› wuchiuwong
wuchiuwong

๐Ÿ› xingsong
xingsong

๐Ÿ› xioayuge
xioayuge

๐Ÿ› xnYi9wRezm
xnYi9wRezm

๐Ÿ’ป ๐Ÿ› xuanuy
xuanuy

๐Ÿ› - xyf0921
xyf0921

๐Ÿ› + xyf0921
xyf0921

๐Ÿ› yalechen-cyw3
yalechen-cyw3

๐Ÿ› yasuharu-sato
yasuharu-sato

๐Ÿ› zenglian
zenglian

๐Ÿ› zgrzyt93
zgrzyt93

๐Ÿ’ป ๐Ÿ› zh3ng
zh3ng

๐Ÿ› zt_soft
zt_soft

๐Ÿ› - ztt79
ztt79

๐Ÿ› + ztt79
ztt79

๐Ÿ› zzzzfeng
zzzzfeng

๐Ÿ› รrpรกd Magosรกnyi
รrpรกd Magosรกnyi

๐Ÿ› ไปป่ดตๆฐ
ไปป่ดตๆฐ

๐Ÿ› diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index c1d07eb028..34fb78e0c0 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -27,6 +27,7 @@ This is a {{ site.pmd.release_type }} release. * [#5329](https://github.com/pmd/pmd/issues/5329): \[java] Type inference issue with unknown method ref in call chain * java-bestpractices * [#5083](https://github.com/pmd/pmd/issues/5083): \[java] UnusedPrivateMethod false positive when method reference has no target type + * [#5318](https://github.com/pmd/pmd/issues/5318): \[java] PreserveStackTraceRule: false-positive on Pattern Matching with instanceof * java-performance * [#5314](https://github.com/pmd/pmd/issues/5314): \[java] InsufficientStringBufferDeclarationRule: Lack of handling for char type parameters diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceRule.java index 03d0d9faea..229e8a5da0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceRule.java @@ -4,11 +4,10 @@ package net.sourceforge.pmd.lang.java.rule.bestpractices; +import java.util.Collections; import java.util.HashSet; import java.util.Set; -import org.checkerframework.checker.nullness.qual.NonNull; - import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; import net.sourceforge.pmd.lang.java.ast.ASTCastExpression; @@ -17,13 +16,17 @@ import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; import net.sourceforge.pmd.lang.java.ast.ASTInitializer; import net.sourceforge.pmd.lang.java.ast.ASTList; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; +import net.sourceforge.pmd.lang.java.ast.ASTPatternExpression; import net.sourceforge.pmd.lang.java.ast.ASTThrowStatement; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTTypePattern; import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess; import net.sourceforge.pmd.lang.java.ast.ASTVariableId; +import net.sourceforge.pmd.lang.java.ast.BinaryOp; import net.sourceforge.pmd.lang.java.ast.InvocationNode; import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; @@ -64,7 +67,7 @@ public class PreserveStackTraceRule extends AbstractJavaRulechainRule { for (ASTThrowStatement throwStatement : catchStmt.getBody().descendants(ASTThrowStatement.class)) { ASTExpression thrownExpr = throwStatement.getExpr(); - if (!exprConsumesException(exceptionParam, thrownExpr, true)) { + if (!exprConsumesException(Collections.singleton(exceptionParam), thrownExpr, true)) { asCtx(data).addViolation(thrownExpr, exceptionParam.getName()); } } @@ -72,25 +75,39 @@ public class PreserveStackTraceRule extends AbstractJavaRulechainRule { return null; } - private boolean exprConsumesException(ASTVariableId exceptionParam, ASTExpression expr, boolean mayBeSelf) { + private boolean exprConsumesException(Set exceptionParams, ASTExpression expr, boolean mayBeSelf) { if (expr instanceof ASTConstructorCall) { // new Exception(e) - return ctorConsumesException(exceptionParam, (ASTConstructorCall) expr); + return ctorConsumesException(exceptionParams, (ASTConstructorCall) expr); } else if (expr instanceof ASTMethodCall) { - return methodConsumesException(exceptionParam, (ASTMethodCall) expr); + return methodConsumesException(exceptionParams, (ASTMethodCall) expr); } else if (expr instanceof ASTCastExpression) { ASTExpression innermost = JavaAstUtils.peelCasts(expr); - return exprConsumesException(exceptionParam, innermost, mayBeSelf); + return exprConsumesException(exceptionParams, innermost, mayBeSelf); } else if (expr instanceof ASTConditionalExpression) { ASTConditionalExpression ternary = (ASTConditionalExpression) expr; - return exprConsumesException(exceptionParam, ternary.getThenBranch(), mayBeSelf) - && exprConsumesException(exceptionParam, ternary.getElseBranch(), mayBeSelf); + Set possibleExceptionParams = new HashSet<>(exceptionParams); + + // Peel out a type pattern variable in case this conditional is an instanceof pattern + NodeStream.of(ternary.getCondition()) + .filterIs(ASTInfixExpression.class) + .filterMatching(ASTInfixExpression::getOperator, BinaryOp.INSTANCEOF) + .map(ASTInfixExpression::getRightOperand) + .filterIs(ASTPatternExpression.class) + .map(ASTPatternExpression::getPattern) + .filterIs(ASTTypePattern.class) + .map(ASTTypePattern::getVarId) + .firstOpt() + .ifPresent(possibleExceptionParams::add); + + return exprConsumesException(possibleExceptionParams, ternary.getThenBranch(), mayBeSelf) + && exprConsumesException(possibleExceptionParams, ternary.getElseBranch(), mayBeSelf); } else if (expr instanceof ASTVariableAccess) { JVariableSymbol referencedSym = ((ASTVariableAccess) expr).getReferencedSym(); @@ -99,7 +116,7 @@ public class PreserveStackTraceRule extends AbstractJavaRulechainRule { } ASTVariableId decl = referencedSym.tryGetNode(); - if (decl == exceptionParam) { + if (exceptionParams.contains(decl)) { return mayBeSelf; } else if (decl == null || decl.isFormalParameter() || decl.isField()) { return false; @@ -113,16 +130,16 @@ public class PreserveStackTraceRule extends AbstractJavaRulechainRule { // if any of the initializer and usages consumes the variable, // answer true. - if (exprConsumesException(exceptionParam, decl.getInitializer(), mayBeSelf)) { + if (exprConsumesException(exceptionParams, decl.getInitializer(), mayBeSelf)) { return true; } for (ASTNamedReferenceExpr usage : decl.getLocalUsages()) { - if (assignmentRhsConsumesException(exceptionParam, decl, usage)) { + if (assignmentRhsConsumesException(exceptionParams, decl, usage)) { return true; } - if (JavaAstUtils.followingCallChain(usage).any(it -> consumesExceptionNonRecursive(exceptionParam, it))) { + if (JavaAstUtils.followingCallChain(usage).any(it -> consumesExceptionNonRecursive(exceptionParams, it))) { return true; } } @@ -134,7 +151,7 @@ public class PreserveStackTraceRule extends AbstractJavaRulechainRule { } } - private boolean assignmentRhsConsumesException(ASTVariableId exceptionParam, ASTVariableId lhsVariable, ASTNamedReferenceExpr usage) { + private boolean assignmentRhsConsumesException(Set exceptionParams, ASTVariableId lhsVariable, ASTNamedReferenceExpr usage) { if (usage.getIndexInParent() == 0) { ASTExpression assignmentRhs = JavaAstUtils.getOtherOperandIfInAssignmentExpr(usage); boolean rhsIsSelfReferential = @@ -142,25 +159,25 @@ public class PreserveStackTraceRule extends AbstractJavaRulechainRule { .descendantsOrSelf() .filterIs(ASTVariableAccess.class) .any(it -> JavaAstUtils.isReferenceToVar(it, lhsVariable.getSymbol())); - return !rhsIsSelfReferential && exprConsumesException(exceptionParam, assignmentRhs, true); + return !rhsIsSelfReferential && exprConsumesException(exceptionParams, assignmentRhs, true); } return false; } - private boolean ctorConsumesException(ASTVariableId exceptionParam, ASTConstructorCall ctorCall) { - return ctorCall.isAnonymousClass() && callsInitCauseInAnonInitializer(exceptionParam, ctorCall) - || anArgumentConsumesException(exceptionParam, ctorCall); + private boolean ctorConsumesException(Set exceptionParams, ASTConstructorCall ctorCall) { + return ctorCall.isAnonymousClass() && callsInitCauseInAnonInitializer(exceptionParams, ctorCall) + || anArgumentConsumesException(exceptionParams, ctorCall); } - private boolean consumesExceptionNonRecursive(ASTVariableId exceptionParam, ASTExpression expr) { + private boolean consumesExceptionNonRecursive(Set exceptionParam, ASTExpression expr) { if (expr instanceof ASTConstructorCall) { return ctorConsumesException(exceptionParam, (ASTConstructorCall) expr); } return expr instanceof InvocationNode && anArgumentConsumesException(exceptionParam, (InvocationNode) expr); } - private boolean methodConsumesException(ASTVariableId exceptionParam, ASTMethodCall call) { - if (anArgumentConsumesException(exceptionParam, call)) { + private boolean methodConsumesException(Set exceptionParams, ASTMethodCall call) { + if (anArgumentConsumesException(exceptionParams, call)) { return true; } ASTExpression qualifier = call.getQualifier(); @@ -168,24 +185,24 @@ public class PreserveStackTraceRule extends AbstractJavaRulechainRule { return false; } boolean mayBeSelf = ALLOWED_GETTERS.anyMatch(call); - return exprConsumesException(exceptionParam, qualifier, mayBeSelf); + return exprConsumesException(exceptionParams, qualifier, mayBeSelf); } - private boolean callsInitCauseInAnonInitializer(ASTVariableId exceptionParam, ASTConstructorCall ctorCall) { + private boolean callsInitCauseInAnonInitializer(Set exceptionParams, ASTConstructorCall ctorCall) { return NodeStream.of(ctorCall.getAnonymousClassDeclaration()) .flatMap(ASTTypeDeclaration::getDeclarations) .map(NodeStream.asInstanceOf(ASTFieldDeclaration.class, ASTInitializer.class)) .descendants().filterIs(ASTMethodCall.class) - .any(it -> isInitCauseWithTargetInArg(exceptionParam, it)); + .any(it -> isInitCauseWithTargetInArg(exceptionParams, it)); } - private boolean isInitCauseWithTargetInArg(ASTVariableId exceptionSym, JavaNode expr) { - return INIT_CAUSE.matchesCall(expr) && anArgumentConsumesException(exceptionSym, (ASTMethodCall) expr); + private boolean isInitCauseWithTargetInArg(Set exceptionParams, JavaNode expr) { + return INIT_CAUSE.matchesCall(expr) && anArgumentConsumesException(exceptionParams, (ASTMethodCall) expr); } - private boolean anArgumentConsumesException(@NonNull ASTVariableId exceptionParam, InvocationNode thrownExpr) { + private boolean anArgumentConsumesException(Set exceptionParams, InvocationNode thrownExpr) { for (ASTExpression arg : ASTList.orEmptyStream(thrownExpr.getArguments())) { - if (exprConsumesException(exceptionParam, arg, true)) { + if (exprConsumesException(exceptionParams, arg, true)) { return true; } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/PreserveStackTrace.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/PreserveStackTrace.xml index 5292c61d64..637b6dffa6 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/PreserveStackTrace.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/PreserveStackTrace.xml @@ -1168,4 +1168,35 @@ public class Foo { ]]> + + #5318 [java] PreserveStackTraceRule: false-positive on Pattern Matching with instanceof + 0 + formatExceptionHandler = e -> { e.printStackTrace(); }; +} +]]> +