diff --git a/FernFlower b/FernFlower index 62a2986..2545452 160000 --- a/FernFlower +++ b/FernFlower @@ -1 +1 @@ -Subproject commit 62a2986162ee98a4022089f1db4f0ae3c6e9e987 +Subproject commit 2545452a51edfbdbb35f46a6db75dc60530afb7a diff --git a/FernFlower-Patches/0001-Git-filter-and-setup-backport-to-Java-8.patch b/FernFlower-Patches/0001-Git-filter-and-setup-backport-to-Java-8.patch index 94d0de1..21b18ad 100644 --- a/FernFlower-Patches/0001-Git-filter-and-setup-backport-to-Java-8.patch +++ b/FernFlower-Patches/0001-Git-filter-and-setup-backport-to-Java-8.patch @@ -54,14 +54,12 @@ index f1df734f9f0bc7080a99140482eedf28bfe6b166..972529aebd1f5daa057f1fe9606c79be + \ No newline at end of file diff --git a/.gitignore b/.gitignore -index 3537b26a5b9d0579ae764825988f08a14d29517b..c52eb2e815432be8d1f1e6b61cffdcce68af85bb 100644 +index 2b5420b0d76d97d25c4de444bc669891fd9ea4f3..c52eb2e815432be8d1f1e6b61cffdcce68af85bb 100644 --- a/.gitignore +++ b/.gitignore -@@ -1,3 +1,231 @@ +@@ -1,4 +1,231 @@ -/.idea/ -/.gradle/ --/build/ -\ No newline at end of file + +# Created by https://www.gitignore.io/api/java,macos,linux,gradle,windows,eclipse,intellij + @@ -272,7 +270,9 @@ index 3537b26a5b9d0579ae764825988f08a14d29517b..c52eb2e815432be8d1f1e6b61cffdcce + +### Gradle ### +.gradle -+/build/ + /build/ +-/out/ +\ No newline at end of file + +# Ignore Gradle GUI config +gradle-app.setting @@ -295,10 +295,10 @@ index 3537b26a5b9d0579ae764825988f08a14d29517b..c52eb2e815432be8d1f1e6b61cffdcce +!testData/classes/** diff --git a/build.gradle b/build.gradle deleted file mode 100644 -index 9ce3662ad49f82511cfb2604752dac02d714325f..0000000000000000000000000000000000000000 +index efa9dfcfa2204db2314dc867ba995a6cfca37581..0000000000000000000000000000000000000000 --- a/build.gradle +++ /dev/null -@@ -1,25 +0,0 @@ +@@ -1,26 +0,0 @@ -// 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. -apply plugin: 'java' - @@ -314,2145 +314,577 @@ index 9ce3662ad49f82511cfb2604752dac02d714325f..00000000000000000000000000000000 - -repositories { mavenCentral() } -dependencies { -- testCompile 'junit:junit:4.12' -- testCompile 'org.assertj:assertj-core:3.12.2' +- implementation 'org.jetbrains:annotations:20.1.0' +- testImplementation 'junit:junit:4.12' +- testImplementation 'org.assertj:assertj-core:3.12.2' -} - -jar { -- archiveName 'fernflower.jar' +- archiveFileName = 'fernflower.jar' - manifest { - attributes 'Main-Class': 'org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler' - } -} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar -index cd13592d068005179bd9e3c58ef9024b2a14337f..490fda8577df6c95960ba7077c43220e5bb2c0d9 100644 +index 7454180f2ae8848c63b8b4dea2cb829da983f2fa..41d9927a4d4fb3f96a785543079b8df6723c946b 100644 GIT binary patch -literal 58694 -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 -z`k7=uf(h=gkivBw?57m%k^SPxZnYu@^F% -zKd`b)S#no`JLULZCFuP^y5ViChc;^3Wz#c|ehD+2MHbUuB3IH5+bJ_FChTdARM6Q2 -zdyuu9eX{WwRasK!aRXE+0j -zbTS8wg@ue{fvJ*=KtlWbrXl8YP88;GXto?_h2t@dY3F?=gX9Frwb8f1n!^xdOFDL7 -zbddq6he>%k+5?s}sy?~Ya!=BnwSDWloNT;~UF4|1>rUY!SSl^*F6NRs_DT-rn=t-p -z_Ga0p)`@!^cxW_DhPA=0O;88pCT*G9YL29_4fJ(b{| -zuR~VCZZCR97e%B(_F5^5Eifes$8!7DCO_4(x)XZDGO%dY9Pkm~-b1-jF#2H4kfl<3 -zsBes0sP@Zyon~Q&#<7%gxK{o+vAsIR>gOm$w+{VY8ul7OsSQ>07{|7jB6zyyeu+WU -zME>m2s|$xvdsY^K%~nZ^%Y`D7^PCO(&)eV-Qw|2_PnL=Nd=}#4kY)PS=Y62Dzz1e2 -z&*)`$OEBuC&M5f`I}A-pEzy^lyEEcd$n1mEgLj}u_b^d!5pg{v+>_FexoDxYj%X_F -z5?4eHVXurS%&n2ISv2&Eik?@3ry}0qCwS9}N)`Zc_Q8}^SOViB_AB&o6Eh#bG;NnL -zAhP2ZF_la`=dZv6Hs@78DfMjy*KMSExRZfccK=-DPGkqtCK%U1cUXxbTX-I0m~x$3 -z&Oc&aIGWtcf|i~=mPvR^u6^&kCj|>axShGlPG}r{DyFp(Fu;SAYJ}9JfF*x0k -zA@C(i5ZM*(STcccXkpV$=TznZKQVtec!A24VWu*oS0L(^tkEm2ZIaE4~~?#y9Z4 -zlU!AB6?yc(jiB`3+{FC -zl|IdP1Fdt#e5DI{W{d8^$EijTU(8FA@8V&_A*tO?!9rI -zhoRk`Q*riCozP>F%4pDPmA>R#Zm>_mAHB~Y5$sE4!+|=qK0dhMi4~`<6sFHb=x8Naml}1*8}K_Es3#oh3-7@0W}BJDREnwWmw<{wY9p)3+Mq2CLcX?uAvItguqhk*Po!RoP`kR)!OQy3Ayi -zL@ozJ!I_F2!pTC?OBAaOrJmpGX^O(dSR-yu5Wh)f+o5O262f6JOWuXiJS_Jxgl@lS -z6A9c*FSHGP4HuwS)6j3~b}t{+B(dqG&)Y}C;wnb!j#S0)CEpARwcF4Q-5J1NVizx7 -z(bMG>ipLI1lCq?UH~V#i3HV9|bw%XdZ3Q#c3)GB+{2$zoMAev~Y~(|6Ae -z^QU~3v#*S>oV*SKvA0QBA#xmq9=IVdwSO=m=4Krrlw>6t;Szk}sJ+#7=ZtX(gMbrz -zNgv}8GoZ&$=ZYiI2d?HnNNGmr)3I);U4ha+6uY%DpeufsPbrea>v!D50Q)k2vM=aF-zUsW*aGLS`^2&YbchmKO=~eX@k9B!r;d{G% -zrJU~03(->>utR^5;q!i>dAt)DdR!;<9f{o@y2f}(z(e)jj^*pcd%MN{5{J=K<@T!z -zseP#j^E2G31piu$O@3kGQ{9>Qd;$6rr1>t!{2CuT_XWWDRfp7KykI?kXz^{u_T2AZ -z-@;kGj8Iy>lOcUyjQqK!1OHkY?0Kz+_`V8$Q-V|8$9jR|%Ng;@c%kF_!rE3w>@FtX -zX1w7WkFl%Vg<mE0aAHX==DLjyxlfA}H|LVh;}qcWPd8pSE!_IUJLeGAW#ZJ?W}V7P -zpVeo|`)a<#+gd}dH%l)YUA-n_Vq3*FjG1}6mE;@A5ailjH*lJaEJl*51J0)Xecn6X -zz -zDr~lx5`!ZJ`=>>Xb$}p-!3w;ZHtu -zX@xB4PbX!J(Jl((<8K%)inh!-3o2S2sbI4%wu9-4ksI2%e=uS?Wf^Tp%(Xc&wD6lV -z*DV()$lAR&##AVg__A=Zlu(o$3KE|N7ZN{X8oJhG+FYyF!(%&R@5lpCP%A|{Q1cdr>x0<+;T`^onat<6tlGfEwRR?ZgMTD-H -zjWY?{Fd8=Fa6&d@0+pW9nBt-!muY@I9R>eD5nEDcU~uHUT04gH-zYB>Re+h4EX|IH -zp`Ls>YJkwWD3+}DE4rC3kT-xE89^K@HsCt6-d;w*o8xIHua~||4orJ<7@4w_#C6>W -z2X$&H38OoW8Y-*i=@j*yn49#_C3?@G2CLiJUDzl(6P&v`lW|=gQ&)DVrrx8Bi8I|$ -z7(7`p=^Lvkz`=Cwd<0%_jn&6k_a(+@)G^D04}UylQax*l(bhJ~;SkAR2q*4>ND5nc -zq*k9(R}Ijc1J8ab>%Tv{kb-4TouWfA?-r(ns#ghDW^izG3{ts{C7vHc5Mv?G;)|uX -zk&Fo*xoN`OG9ZXc>9(`lpHWj~9!hI;2aa_n!Ms1i;BFHx6DS23u^D^e(Esh~H@&f}y -z(=+*7I@cUGi`U{tbSUcSLK`S)VzusqEY)E$ZOokTEf2RGchpmTva?Fj! -z<7{9Gt=LM|*h&PWv6Q$Td!|H`q-aMIgR&X*;kUHfv^D|AE4OcSZUQ|1imQ!A$W)pJtk -z56G;0w?&iaNV@U9;X5?ZW>qP-{h@HJMt;+=PbU7_w`{R_fX>X%vnR&Zy1Q-A=7**t -zTve2IO>eEKt(CHjSI7HQ(>L5B5{~lPm91fnR^dEyxsVI-wF@82$~FD@aMT%$`usqNI=ZzH0)u>@_9{U!3CDDC#xA$pYqK4r~9cc_T@$nF1yODjb{=(x^({EuO?djG1Hjb{u -zm*mDO(e-o|v2tgXdy87*&xVpO-z_q)f0~-cf!)nb@t_uCict?p-L%v$_mzG`FafIV -zPTvXK4l3T8wAde%otZhyiEVVU^5vF -zQSR{4him-GCc-(U;tIi;qz1|Az0<4+yh6xFtqB-2%0@ -z&=d_5y>5s^NQKAWu@U#IY_*&G73!iPmFkWxxEU7f9<9wnOVvSuOeQ3&&HR<>$!b%J -z#8i?CuHx%la$}8}7F5-*m)iU{a7!}-m@#O}ntat&#d4eSrT1%7>Z?A-i^Y!Wi|(we -z$PBfV#FtNZG8N-Ot#Y>IW@GtOfzNuAxd1%=it -zDRV-dU|LP#v70b5w~fm_gPT6THi -zNnEw&|Yc9u5lzTVMAL} -zgj|!L&v}W(2*U^u^+-e?Tw#UiCZc2omzhOf{tJX*;i2=i=9!kS&zQN_hKQ|u7_3vo6MU0{U+h~` -zckXGO+XK9{1w3Z$U%%Fw`lr7kK8PzU=8%0O8ZkW`aQLFlR4OCb^aQgGCBqu6AymXk -zX!p(JDJtR`xB$j48h}&I2FJ*^LFJzJQJ0T>=z{*> -zWesZ#%W?fm`?f^B^%o~Jzm|Km5$LP#d7j9a{NCv!j14axHvO<2CpidW=|o4^a|l+- -zSQunLj;${`o%xrlcaXzOKp>nU)`m{LuUW!CXzbyvn;MeK#-D{Z4)+>xSC)km=&K%R -zsXs3uRkta6-rggb8TyRPnquv1>wDd)C^9iN(5&CEaV9yAt -zM+V+%KXhGDc1+N$UNlgofj8+aM*(F7U3=?grj%;Pd+p)U9}P3ZN`}g3`{N`bm;B(n -z12q1D7}$``YQC7EOed!n5Dyj4yl~s0lptb+#IEj|!RMbC!khpBx!H-Kul(_&-Z^OS -zQTSJA@LK!h^~LG@`D}sMr2VU#6K5Q?wqb7-`ct2(IirhhvXj?(?WhcNjJiPSrwL0} -z8LY~0+&7<~&)J!`T>YQgy-rcn_nf+LjKGy+w+`C*L97KMD%0FWRl`y*piJz2=w=pj -zxAHHdkk9d1!t#bh8Joi1hTQr#iOmt8v`N--j%JaO`oqV^tdSlzr#3 -zw70~p)P8lk<4pH{_x$^i#=~E_ApdX6JpR`h{@<Y;PC#{0uBTe -z1Puhl^q=DuaW}Gdak6kV5w);35im0PJ0F)Zur)CI*LXZxZQTh=4dWX}V}7mD#oMAn -zbxKB7lai}G8C){LS`hn>?4eZFaEw-JoHI@K3RbP_kR{5eyuwBL_dpWR>#bo!n~DvoXvX`ZK5r|$dBp6%z$H@WZ6Pdp&(zFKGQ -z2s6#ReU0WxOLti@WW7auSuyOHvVqjaD?kX;l)J8tj7XM}lmLxLvp5V|CPQrt6ep+t -z>7uK|fFYALj>J%ou!I+LR-l9`z3-3+92j2G`ZQPf18rst;qXuDk-J!kLB?0_=O}*XQ5wZMn+?ZaL5MKlZie- -z0aZ$*5~FFU*qGs|-}v-t5c_o-ReR@faw^*mjbMK$lzHSheO*VJY)tBVymS^5ol=ea -z)W#2z8xCoh1{FGtJA+01Hwg-bx`M$L9Ex-xpy?w-lF8e*xJXS4(I^=k1zFy|V)=ll -z#&yez3hRC5?@rPywJo2eOHWezUxZphm#wo`oyA-sP@|^+LV0^nzq|UJEZZM9wqa -z5Y}M0Lu@0Qd%+Q=3kCSb6q4J60t_s(V|qRw^LC>UL7I`=EZ -zvIO;P2n27=QJ1u;C+X)Si-P#WB#phpY3XOzK(3nEUF7ie$>sBEM3=hq+x<=giJjgS -zo;Cr5uINL%4k@)X%+3xvx$Y09(?<6*BFId+399%SC)d# -zk;Qp$I}Yiytxm^3rOxjmRZ@ws;VRY?6Bo&oWewe2i9Kqr1zE9AM@6+=Y|L_N^HrlT -zAtfnP-P8>AF{f>iYuKV%qL81zOkq3nc!_?K7R3p$fqJ?};QPz6@V8wnGX>3%U%$m2 -zdZv|X+%cD<`OLtC<>=ty&o{n-xfXae2~M-euITZY#X@O}bkw#~FMKb5vG?`!j4R_X%$ZSdwW -zUA0Gy&Q_mL5zkhAadfCo(yAw1T@}MNo>`3Dwou#CMu#xQKY6Z+9H+P|!nLI;4r9@k -zn~I*^*4aA(4y^5tLD+8eX;UJW;>L%RZZUBo(bc{)BDM!>l%t?jm~}eCH?OOF%ak8# -z*t$YllfyBeT(9=OcEH(SHw88EOH0L1Ad%-Q`N?nqM)<`&nNrp>iEY_T%M6&U>EAv3 -zMsvg1E#a__!V1E|ZuY!oIS2BOo=CCwK1oaCp#1ED_}FGP(~Xp*P5Gu(Pry_U -zm{t$qF^G^0JBYrbFzPZkQ;#A63o%iwe;VR?*J^GgWxhdj|tj`^@i@R+vqQWt~^ -z-dLl-Ip4D{U<;YiFjr5OUU8X^=i35CYi#j7R! -zI*9do!LQrEr^g;nF`us=oR2n9ei?Gf5HRr&(G380EO+L6zJD)+aTh_<9)I^{LjLZ} -z{5Jw5vHzucQ*knJ6t}Z6k+!q5a{DB-(bcN*)y?Sfete7Y}R9Lo2M|#nIDsYc({XfB!7_Db0Z99yE8PO6EzLcJGBlHe(7Q{uv -zlBy7LR||NEx|QyM9N>>7{Btifb9TAq5pHQpw?LRe+n2FV<(8`=R}8{6YnASBj8x}i -zYx*enFXBG6t+tmqHv!u~OC2nNWGK0K3{9zRJ(umqvwQ~VvD;nj;ihior5N$Hf@y0G -z$7zrb=CbhyXSy`!vcXK-T}kisTgI$8vjbuCSe7Ev*jOqI&Pt@bOEf>WoQ!A?`UlO5 -zSLDKE(-mN4a{PUu$QdGbfiC)pA}phS|A1DE(f<{Dp4kIB_1mKQ5!0fdA-K0h#_ -z{qMsj@t^!n0Lq%)h3rJizin0wT_+9K>&u0%?LWm<{e4V8W$zZ1w&-v}y -zY<6F2$6Xk>9v{0@K&s(jkU9B=OgZI(LyZSF)*KtvI~a5BKr_FXctaVNLD0NIIokM}S}-mCB^^Sgqo%e{4!Hp)$^S%q@ -zU%d&|hkGHUKO2R6V??lfWCWOdWk74WI`xmM5fDh+hy6>+e)rG_w>_P^^G!$hSnRFy -z5fMJx^0LAAgO5*2-rsN)qx$MYzi<_A=|xez#rsT9&K*RCblT2FLJvb?Uv3q^@Dg+J -zQX_NaZza4dAajS!khuvt_^1dZzOZ@eLg~t02)m2+CSD=}YAaS^Y9S`iR@UcHE%+L0 -zOMR~6r?0Xv#X8)cU0tpbe+kQ;ls=ZUIe2NsxqZFJQj87#g@YO%a1*^ -zJZ+`ah#*3dVYZdeNNnm8=XOOc<_l-b*uh -zJR8{yQJ#-FyZ!7yNxY|?GlLse1ePK!VVPytKmBwlJdG-bgTYW$3T5KinRY#^Cyu@& -zd7+|b@-AC67VEHufv=r5(%_#WwEIKjZ<$JD%4!oi1XH65r$LH#nHHab{9}kwrjtf= -zD}rEC65~TXt=5bg*UFLw34&*pE_(Cw2EL5Zl2i^!+*Vx+kbkT_&WhOSRB#8RInsh4 -z#1MLczJE+GAHR^>8hf#zC{pJfZ>6^uGn6@eIxmZ6g_nHEjMUUfXbTH1ZgT7?La;~e -zs3(&$@4FmUVw3n033!1+c9dvs&5g#a;ehO(-Z}aF{HqygqtHf=>raoWK9h7z)|DUJ -zlE0#|EkzOcrAqUZF+Wd@4$y>^0eh!m{y@qv6=C -zD(){00vE=5FU@Fs_KEpaAU1#$zpPJGyi0!aXI8jWaDeTW=B?*No-vfv=>`L`LDp$C -zr4*vgJ5D2Scl{+M;M(#9w_7ep3HY#do?!r0{nHPd3x=;3j^*PQpXv<~Ozd9iWWlY_ -zVtFYzhA<4@zzoWV-~in%6$}Hn$N;>o1-pMK+w$LaN1wA95mMI&Q6ayQO9 -zTq&j)LJm4xXjRCse?rMnbm%7E#%zk!EQiZwt6gMD=U6A0&qXp%yMa(+C~^(OtJ8dH -z%G1mS)K9xV9dlK>%`(o6dKK>DV07o46tBJfVxkIz#%VIv{;|)?#_}Qq(&| -zd&;iIJt$|`te=bIHMpF1DJMzXKZp#7Fw5Q0MQe@;_@g$+ELRfh-UWeYy%L*A@SO^J -zLlE}MRZt(zOi6yo!);4@-`i~q5OUAsac^;RpULJD(^bTLt9H{0a6nh0<)D6NS7jfB -ze{x#X2FLD2deI8!#U@5$i}Wf}MzK&6lSkFy1m2c~J?s=!m}7%3UPXH_+2MnKNY)cI -z(bLGQD4ju@^<+%T5O`#77fmRYxbs(7bTrFr=T@hEUIz1t#*ntFLGOz)B`J&3WQa&N -zPEYQ;fDRC-nY4KN`8gp*uO@rMqDG6=_hHIX#u{TNpjYRJ9ALCl!f%ew7HeprH_I2L -z6;f}G90}1x9QfwY*hxe&*o-^J#qQ6Ry%2rn=9G3*B@86`$Pk1`4Rb~}`P-8^V-x+s -zB}Ne8)A3Ex29IIF2G8dGEkK^+^0PK36l3ImaSv1$@e=qklBmy~7>5IxwCD9{RFp%q -ziejFT(-C>MdzgQK9#gC?iFYy~bjDcFA^%dwfTyVCk -zuralB)EkA)*^8ZQd8T!ofh-tRQ#&mWFo|Y3taDm8(0=KK>xke#KPn8yLCXwq -zc*)>?gGKvSK(}m0p4uL8oQ~!xRqzDRo(?wvwk^#Khr&lf9YEPLGwiZjwbu*p+mkWPmhoh0Fb(mhJEKXl+d68b6%U{E994D -z3$NC=-avSg7s{si#CmtfGxsijK_oO7^V`s{?x=BsJkUR4=?e@9# -z-u?V8GyQp-ANr%JpYO;3gxWS?0}zLmnTgC66NOqtf*p_09~M-|Xk6ss7$w#kdP8`n -zH%UdedsMuEeS8Fq0RfN}Wz(IW%D%Tp)9owlGyx#i8YZYsxWimQ>^4ikb-?S+G;HDT -zN4q1{0@|^k_h_VFRCBtku@wMa*bIQc%sKe0{X@5LceE`Uqqu7E9i9z-r}N2ypvdX1{P$*-pa$A8*~d0e5AYkh_aF|LHt7qOX>#d3QOp-iEO7Kq;+}w -zb)Le}C#pfmSYYGnq$Qi4!R&T{OREvbk_;7 -zHP<*B$~Qij1!9Me!@^GJE-icH=set0fF-#u5Z{JmNLny=S*9dbnU@H?OCXAr7nHQH -zw?$mVH^W-Y89?MZo5&q{C2*lq}sj&-3@*&EZaAtpxiLU==S@m_PJ6boIC9+8fKz@hUDw==nNm9? -z`#!-+AtyCOSDPZA)zYeB|EQ)nBq6!QI66xq*PBI~_;`fHEOor}>5jj^BQ;|-qS5}1 -zRezNBpWm1bXrPw3VC_VHd -z$B06#uyUhx)%6RkK2r8*_LZ3>-t5tG8Q?LU0Yy+>76dD(m|zCJ>)}9AB>y{*ftDP3 -z(u8DDZd(m;TcxW-w$(vq7bL&s#U_bsIm67w{1n|y{k9Ei8Q9*8E^W0Jr@M?kBFJE< -zR7Pu}#3rND;*ulO8X%sX>8ei7$^z&ZH45(C#SbEXrr3T~e`uhVobV2-@p5g9Of%!f -z6?{|Pt*jW^oV0IV7V76Pd>Pcw5%?;s&<7xelwDKHz(KgGL7GL?IZO%upB+GMgBd3ReR9BS -zL_FPE2>LuGcN#%&=eWWe;P=ylS9oIWY)Xu2dhNe6piyHMI#X4BFtk}C9v?B3V+zty -zLFqiPB1!E%%mzSFV+n<(Rc*VbvZr)iJHu(HabSA_YxGNzh -zN~O(jLq9bX41v{5C8%l%1BRh%NDH7Vx~8nuy;uCeXKo2Do{MzWQyblZsWdk>k0F~t -z`~8{PWc86VJ)FDpj!nu))QgHjl7a%ArDrm#3heEHn|;W>xYCocNAqX{J(tD!)~rWu -zlRPZ3i5sW;k^^%0SkgV4lypb -zqKU2~tqa+!Z<)!?;*50pT&!3xJ7=7^xOO0_FGFw8ZSWlE!BYS2|hqhQT8#x -zm2a$OL>CiGV&3;5-sXp>3+g+|p2NdJO>bCRs-qR(EiT&g4v@yhz(N5cU9UibBQ8wM -z0gwd4VHEs(Mm@RP(Zi4$LNsH1IhR}R7c9Wd$?_+)r5@aj+!=1-`fU(vr5 -z1c+GqAUKulljmu#ig5^SF#{ag10PEzO>6fMjOFM_Le>aUbw>xES_Ow|#~N%FoD{5!xir^;`L1kSb+I^f -z?rJ0FZugo~sm)@2rP_8p$_*&{GcA4YyWT=!uriu+ZJ%~_OD4N%!DEtk9SCh+A!w=< -z3af%$60rM%vdi%^X2mSb)ae>sk&DI_&+guIC88_Gq|I1_7q#}`9b8X -zGj%idjshYiq&AuXp%CXk>zQ3d2Ce9%-?0jr%6-sX3J{*Rgrnj=nJ2`#m`TaW-13kl -zS2>w8ehkYEx@ml2JPivxp -zIa2l^?)!?Y*=-+jk_t;IMABQ5Uynh&LM^(QB{&VrD7^=pXNowzD9wtMkH_;`H|d0V -z*rohM)wDg^EH_&~=1j1*?@~WvMG3lH=m#Btz?6d9$E*V5t~weSf4L%|H?z-^g>Fg` -zI_Q+vgHOuz31?mB{v#4(aIP}^+RYU}^%XN}vX_KN=fc{lHc5;0^F2$2A+%}D=gk-) -zi1qBh!1%xw*uL=ZzYWm-#W4PV(?-=hNF%1cXpWQ_m=ck1vUdTUs5d@2Jm -zV8cXsVsu~*f6=_7@=1 -zaV0n2`FeQ{62GMaozYS)v~i10wGoOs+Z8=g$F-6HH1qBbasAkkcZj-}MVz{%xf8`2 -z1XJU;&QUY4Hf-I(AG8bX -zhu~KqL}TXS6{)DhW=GFkCzMFMSf`Y00e{Gzu2wiS4zB|PczU^tjLhOJUv=i2KuFZHf-&`wi>CU0h_HUxCdaZ`s9J8|7F}9fZXg`UUL}ws7G=*n -zImEd-k@tEXU?iKG#2I13*%OX#dXKTUuv1X3{*WEJS41ci+uy=>30LWCv*YfX_A2(M -z9lnNAjLIzX=z;g;-=ARa<`z$x)$PYig1|#G;lnOs8-&rB2lT0#e;`EH8qZ_xNvwy7 -zo_9>P@SHK(YPu*8r86f==eshYjM3yAPOHDn- -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 -z=9I>I%97Y~G945O48YaAq6ENPUs%EJvyC! -zM4jMgJj}r~@D;cdaQ-j#`5zCRku}42aI<>CgraXuKDr19db~#|@UyM;f-uc!(KDsu -z5EA@CsN>^t@oH+0!SALi;ud>`P5mQta+Lh*-#RHJ)Gin%>EaFLSoU`(TG7c|yeFvl -zk|Yll%)h-*%WoI6M*j+4xw`OqiDVX{k-^V2{rzCIM9mzNHGP^D={!*P7T)%yDSI5- -zkGA4}r3`)#Vl6JFJ3xG)8K;FTtII9o7jNHof_Z_Zc<%@-H4RPpyXudpf)ky -zmTH$LFGxaIUGQ;l=>R>?+>ZSCU|@&+Gt@5Bj3w{L{KPpgQ<~)jqx0oNZSv9R&^A42 -zzqJr?C#D-n>=9FjM=D=7h_$QO$KQ8*%0%)rI(Npai_JjE9_lBk75BQMI -zkk4X5PATWgrub!fb5Hxi8{(Y<(GOO8^HECOA)eanyS{u%leQOkp;1W}_8eH?nPQxW -zd#Z+uJfTK>g-TR3WPu~2Ru9A+NkuIICM@PyPmJn(GBZt;xFZNDMbw8`xzl2`(?UC- -z#<*=*fo{UOvycb|b&4y0Nm!sHhFMI*Y$Olgh;BG#xBU+yxav82Ejj(ZvQ|64Wwy7I -zN=DXx7(V^NTH3YRB4HOu6T5=DW86P`L#Ng!SuT{%&>Cq8>|o8lF^^U%MRU41TT?h& -z!uJ$YdbM*2y?#`LJ2)XPoKq`hm$I3R{V5-;@u7!E9tH4sR(`Ab-Qh!|UN-a5fZ?P@2LWRvSv!hOk08;Yy!h&uEI-X}j+&v`X` -zkqY%*F@{}DHL*Jgjg2}a54hwEV`63bK4>mL%D^YT|>m1-kX{876BRm&`Y#{$&oz($qWJL}T*tj42k+yu8fa=4b7VUPq()Wb~=L?DU0U-4*Iu^KMZBRByWn-@=_f(4){Or#| -zpw}~Ajs6a=z!8_H59lqYlfnS77QY0pHpIz0#)}!EGhypupZeZe@%cv -z6Dngnl*SsUy^a`v?>lARi6Yps@%32JpGQvrcd*A8LPLEInBEU2vriGvMqG!jh^=Gj -zXvu5zpikqnt*e4&Un_e$2FAB?(yOS0JAzxh@nN?Blqc-)Pv`U}&E5|# -z)97-9utpqi*`hR+$;eS)A+KK)CO)V`b?*}z&*+28mDfWI31)sF)tBg6LVlxS -z225poL+O|x)5;skkj{rew<}TsDVqFMMLSgd;UK7^clMcObM~IgSq6!eJ($JP!KHPr -zBJ&SHi{wLsgMzn1^#kV#_!NO@RG@B5lxBO7WfIAi@o`{_XQg(*{R=@Z(0ij+*i7sK -zW5D%_fRN7l6qpytW2K1lUqP&W5jDT!AA9@q<;M!T=CKv*^MP)Er_uLL+Y53>**w7Y -zQ!2?^4$wC;Soc!+#~d?Yec;NLdR -z{~*hrSQS>UOMBe)1pHe0EsyO@d(IrU4ZiS&jL`wqv6Oqv=HbI^70qu9kn~wGkNL^> -z!Pd2)i--+&zp^`#4@*Myg;3r(jt*h@RWgRt70byZr;0Na8n4!bmpuX1&gK=QK!@j< -zH2fF7@2s0H0!9%VC-BIp(99@e@<%Ko?BB9uv*xPnZ5dQr -z8r7~9cZXv(AZPY^<(X@}GARv&_}mfYA7`vdl=)g2GIyN(<}(b_S_N2--NKp$SgO<3 -zRx|EabcjUSB44GaH3Kxmx3SW;E;Eia2Zs5SkbkQ8E%VQqr0J?tQjF~p;nbIXn+D;? -zg;t3Jg7A@9U**@aaqs}9;%??Scm{zBIY2ceYAQd*W-hB-!+H&4#yrm*GtT*&#`FXx -zGIVm}G<;Pj+h*KQ68S4rcIIGw-mkl039s@O4p9F%TC&&&xRL=N49v2PdBb$MxJoMo -zQk8+Sv+F5m{xP1prZvn1=x-Q -z&Yox|y&arZrLTm~<%o}VfPV#z+i&{)W5emXhx^g~8>eUe)|Vvwp8-x8d-MOj%@mSk -zZ9i{-Hu8m-rfO##y(_Rv;Y@?6%h4Id#6%`7ah+IaQ13o7o>bG&ScMj&KO~QoCmNT6()+oo%B -zugV3Da)t>unQq=tbD)FP{JmB~S5QCmb)lq9Fp(*|(UGeXr3kR?k35sKFs{{a*y+h0anA_K@iCi;BR6nFmKHC=@)rMmu=XWS1nVqD*=#${cFJ6<{e=U7!Rbg>Y0b~d#&viX+5m9aNAv=RAMt8=n6a&@t^|2LsKMR7xF -z;Cmw>t0<=W2II;doX`p#bcjPV9z&3dhAObzcB9xXMslqr(y!P6+2kG>Eh!rx&ZKmW)Wk~_xh`?neJqVhJk~1eTvRF#ehRwpS>s1{vUx*qf&Jm -z$)Wh|lmwYatW@U@*$<14>^|yYwmwFs)C5ke9hG42{gilSU#^ulO`M}`wJ_4*-3 -zGb?hfQj_AGQBI?4ghGijqfu>uAYkLK#!^uGUXuctdn8Ae5I7}o+j{9MJiM|sf9Nc{ -zuP&Ls@?rMe=IfJo!=iX?9&*4!Yjs5d?0Yx4cIFXrkSHRk17Fc@yM__fyFLLl6O9nT -zQqaDXunH;!PpQ7+-&#wJVtJXl8LjIkh)5qmcqhErYrP31w5~#!tS{LYTWGKEtbpE%(hH>qV(!2KMfs#a -z?ZzzbDB}(7+NWIiSBQ<_{3>;H;z}uZI;n2PKWJNxM=l;5-^zpu-}+1x|38lS-}6GX -z6F=M~bUtHg98X@of>mgCH-&5g6UpXGAla<+g`b&MQANW6D^;zfSzq0mQ)*J%;&tPOYin?J*G7GqmQ=>jvWvOn6E?! -z{$(CU7}zChEnl$(>xf`ZdeF2E9Bv=eH&T4HWAOQ!9gBs -z{gl^|(78q-ioBS^rR2PEGZLe_4Rl**H(bB?84RHquCEKi8N#29u=Eoh(DV`ZX{+8< -z3BIX<`sOFNBziFWS#-X%(e`0C_|Q8;Pw9izjNOF8h|kvmWCmDHM&pANC9MV<wEJ;W{-jXqm!zC+Y@Q1y_lLL -zfV^(1{A;L%TWmyI)RPknVUB<4r+d42S(W=%bXd@YB(~d>ABq-E;t)ie6%ouy(Fg`p -zuj<=I7^PDs5H+UsG}+GH}zoGt*{yKF&n23C7aW@ -z4ydrRtFW-uuAUu@RWe&0c!N4!H;`!n@@t#u -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 -zYEY{fj~P1Q -zY_vIx8j+W?nOTo{k7|A!vvlK?qYKZnTkm@qV7lWQf#;J@)(qh~m07vHwdQ@701t>}N2> -zYt=Q^?p;5oP%enrkvLCarS2rlJ;zjT@1)Ha_28t7T(IMcZi3U?D_dTzMKnR%{b7 -zXeWL6f-xfJvhsVNF_?I2^3gmv=2|f7azO~wc+o|=2cR+N_<9sF;vio2z;vtlV7U6o -z%q9XNPhjS1Fv)QuRq|0#HVGw&HG!!t0wQo=W>hP)uYZ7o;_qdM=-*`k-Z%4+>VGZ; -z{vGL`lv&#q*NFJmy`%{yAIPrAB%*freDk*5cHaNPB~B86YH -zIw9gNDz9H+n0&}J-c0V{E(`My-2Nkt0NBY-PjL5r*s48D&j)h7pIpJUb+0ol1F*~` -zp1!}vw0*&IA^z*SXZ}pIG9;ySrW01 -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 -z#PFWr7?X~=08GVa5;MFqMPt$8e*-l$h* -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 -zZHV-;f-^2epH -zxn#@~NOA -z11ZBV6tw5T5>Iz^Jb)0%OIlra;qJl^ufG156Ui{A2$qpZ_{^c1^R`+fbi*WT%;He@ -zyieltZ{6ivdgz6i=@iEldc;jVS!5E5$rymBrD?v#K?Mr`?ocG-n&lL`@;sMYaM2m6 -z)Tt641KSaR_(MIZi0J-0r(53x)8LPvfBwp-{yFxkKiTU)pdB)FGjC~7AfTS_$=v_Y -z*Z#MJ`R|V^X!eb+h*>&0yC}OF{rl;vioX)<^+YRtY&IVpwZx%m(G%kbE0AM%G$dMnxO@9U~x`$qY-b?f@fkQ`9pNJeiFRud6ZB~-h_kWX>mCgONAn%y8FDS -z1jJ5f3AGpr111cNW(=njoJxN_XIF;t1dO^e0km*ZO?76yVM(*B>Ix?cT=nC+o2XP$ -zo!&hK$H9sd8H07(XoY2&7QG(*iL;qrs4U*82`MFg4P0Dzw%rEFXuGLBslk;D|Cf}sL{Bdj9TpChAGEEN*DvCLV(j_N-e -zcLNc98=ZJ>3?UluoPSL2QwygpEHOrNp?KEVT77e1i3zzY%Y9lStpis{$m -zm(cz{%HDxH)4xj^O$Qy@?AW%`NjkP|cWgVkW81cE+qP}nZ)X0p&N}nVoOeCvGhF+3 -z?b@|#SADRMCTILsR4>rrHy4AU0PJ{|)~M^(@q-e3hLdj7_}OdzCb7?6jvhyQy!)3Gv3ELg)6!VjwA<}NC@GK%{NI0 -zJT}T#aRk{>TXHs_T?t5eRw>v2ntXC6^p*jkWo`a)WZ0?8&JFWArnx^e@#->FsW0`H -zaG;x(iE*;8ugY6Nhw%)c!hpKUyX3jhGA*i6J6@(fUBPL$z{4dz!^d6OL#hN?41I+g -z!KjR5!+yZ+z+Y#U0p;s{fV{jmnQyy>%`Eu5GUWo&fsZL97=D~-b_O#00NQ+zO>XS` -z6cn1v6jGixMb@=ItgwK*pbiAms3``uBok32wSnIF!(VPSH!Aca2(cTt_k_R -zo!iTIMT0nvu%dfM`Tm^UEy_oqiKOy5hANU5*kqB?bbwBoz>e&)X{#5b+bFeY#FB}p -zj#JFe|1ix8(itqE%U8Oe9{8p+lmPB#ITX?HhA~WU^`aMeLagZ?{J#$k1(<*Ga=!-# -z(r?kozXS&T@4ut}e53yWT>JmB5K8z*I`ZXC(_u$bUyRSI0_sa;;}c3a_~)8{7*#4- -z*hR0l-h`v$GUX!Y8S$OAGx`t7Oh5c~5aXowl-+DBh(YT4|& -zz2Q~Iz2(b(#FdLc$(X>h-N-=%K&sS{-j3KfIshl~vZ(yd@zZNg`=RANO&IW5GfVZE -zs6mU)V!n_RSxggdO;6lhUb4T6hUvzQ$bXz{bZkC4QCxql0E>+~jH^F@J~OC%bQSnw -z!dVcM*I_fSE>Yp7Ty9TQ8VjoGh>2rpcziKFwP#ZBOnF7Eb+fb#57*n=S;keHfwc -zH49H*3q*cDponQrD`v$M1l5b=n=zY6HiA!3d-3ZhDZ+LzKN9kDW#xrc^yy*`$5>{c -zL~=_5`{q}NdlgOp5;!td)>hv&2umQuUJip0G-qJ0O^3tqXGdqmn}Z9DTz4j33Oh6* -zRs?8e!2wbIsGfGP{9#WZD|RF{E86KJLEy$vz9KuntCBzNS(>A~j5a$SlK;1USU4_S -zB~S;>^=U+8Kqh5?r+Nbfvr>prvVolf25hJ>p9%wx5ew2uyC4l%vXv}jkoT5T@NOml -z^@+(g=Fks#f9@XKR3CWI`oEWac$gIO`*&M%ga!iQ{=d%2|J9ZRjEt@AzT>j~_r7Ge -zrikzvS+U<-JIh%phK;}dvq;P%#NIq@*-Ro -zG795&jLHtK3kt@gsFnVb^geyY&Q#0!O5NK<5l`92U6zg)2z^ixqqM;dD69k{pn5na -zjzCXM7%i#qTM&x#D|7;Cs8qI%RB+HS5}ROsznNr@l{c2b$1$=!oSc;%3db4qHN!gG -z%>$rEZM~8pIiTEB<|bT*mBLb{tT1uWu6OFJ)KF7(hj^P2rs5QyMx#q_*|BJuoXwJv -zyh%!-X{q#YM`heA8Hj!57>5|U9qR_sVak1r -z2ZH_d(s!DNqIuDZc5gkw(w^h@n7~LZ82aCz6|aG^n5bXeTCFdW -z7m@2Ej5B%8MSD2HAr*BPh~b^9^;NJ~HXJJX7VeGl(#=!DS?r0mNIH^}d}=~&Ui+B^ -z_wm)B4@6oIZ9FP|3#qxxW6-_;>b*pN_iexjXi=h}e`(krgGC?N9fbTnyYPYIO6K}B -zFA_P-suUrOEb6b`R1i9SkQ*s2Jb7^Y-tOTodB9(}j@~WUg#QJE`jW#~0+;?p-Oyv- -zf|?tPS8>)50*6Qh^}EqVu&_nQ+F^C-IvX6tCg-UDYg3UXsv^pjsXxyJD>pVkh$z=?hWh9Cyd8bJRGUUU{A@XK -zEFVF%XrUA0yYJ(VcELR{+rh(`Av6SI^lRD?z)AQ$gLvakWpQF`_zp{aqZKUt@U1H2uD*qV*seS(QQ2Dy-oc-O8X -zMKUd~h#|T^-6H}`fk?iJx;2kI2$Jj;QIf6%C{vhRVjqTvaHy7Wq*g(r%|c-3w(n|C -zr9N;Rs9JfUDeCWJFL}uP;Y0FDf(Wy};!IZ2zFjeU(d+_6MEJlaX*p=3D!D0b>op*k -zuYr23N1W0wly8w74c#W1LpXP|?)nWr(3eXs$E(c&PiERe!JWE^z0mm5cg@7F`_!@X -za8nQpF$jOM+JDY~nb?BoW=-xIQ22c3TFS?M{R<~rPg$le_1#FXz85*d|IS}UP|x1z -z+ey;M%HGW3JB?4_`{vKeW -ztvEN4bJui=CcnsQr$FVybke#RDpaIHY{GaczId-A9x@ -zD;Gi-lJ9Iau-2o;`eV1*3ztzN3!P`Jxrc)3ocRRAct^jD5E<^lS-Z2}IFL)oUQ<%h -z4?B_#BP>07`M}`7ywGkk}UQpFIOvRZx*v_~StXIsHv% -zk|F{D@%%dlD`92rZ1oTF`=>D~IOsVT{euA~R8PKHPL!_>)`|SN9}+Q?LbiX7V;y|` -zxRlL>%Ik$H(5Pr(Mxx>JnH-I0{je|Ff^ -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 -zw(m$e)>4rAZ2TKb((Vb1@C$)B -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 -zQj7D|**X2unoU|<->1K~fm%Nsb}uww1XK5 -zPTkQf9B`IX6+xXBtW=vbHP=GNFEGLjjx=4n!T8k>P0Dxgg)8?1odzkeL#&YQ#Ot0b -z=PB19V^dl>CF9vFxxuNE`{qHrf083@(u~2?E+QAb|ND4Ak^;V`^p(&%y!)wtA0#DI~1sjPy=Gl=Jk_LKV+s!Y^j?t@%~H!tX2)H -zm{hZ!i~RL`v`e690}D)}3FD}V(vmxXyhY%K5Guq{_Mv9?v2lT{bOWg4Zu^7y1ar8n -zmAHd)JADf~14}K&Kd>r_R}_x(PBD?%GkD@IDUklYfy|?y1BVdi#9312{)remsr!-H -zjW0tu#v*ygyWbLt^s5_5MkpYWOUgiCwk>cCafD`_APTvKBz%WJjzlS-G2A*dS)qkQzz504s~eJE&!(*U_>0mr$HykbwGNoNWwCEjL=c7M*D!Nb`PH -zx2NPxryn>XZ%|N7#-LQKLHw1-kG_2=QJ2=JLW=C*nydd_?z&Q5N}%86-u%7SV*Gb- -z@Bf(i5)`(qXJx-{k|yJdb?lP{@*FHb*?$CWe>MafB>S6?GqJ~&cUG(*a1pK4j -zcf{!2#D*VPQ_jByclkm!s~C_7tTThdil^s=WdwIgp0IA$=lH>9hCTx -z5Xr)>@*R|x(DjaQ$DHV74NS`Whn+KWt~fSy84>OBxriMf6kUU4Q-kS1l88`oJ;U37 -zBQ0WgFx`l;cSai&{i2YGMjA#*3na}+e^znG8aHDsy4bZf -z{#LURLOT3~vp8(Iz0R{4 -z(_8XLA)?)amfcWVTsCQ-sSBOwSm)13fLBY`sl!Db%2|ifT=q -zA}^pepW;deI;)PQ&|m^3N#3nC$*tDKC&*TfWst8|sxfW&I?b{?nN`JNk9Ca(mhRwR -z;e*YDD(uF0O__g-j`;qano_bd|GzAsI+Vubzr}$(&aq;>^uHkxZUTeJ#UKKb;6ZDm -zXJ;v)Dg@N3+lUox9T)|rNJr_O>1gvqMG~O-x)ZQ{39k$k* -zrcOGGtVyrDyF9^lp_*9wqZg(DHLU6pbt5$?+x}t^@`ZWLSOY9S8qUS0f_DMG--u2U -zVVx5|fL}q@Sl3A;632wqbUjvV!&-8wpc7-pG>olAC=&9uR9P+aLa{6Tryv9JHBdyU -z`QqpdCu5x$noe5^wes^G-+w6U9@E!NDHQLKi5hO!OIh=Gi{cttNKdQZov`>`$0}qW -zwz3-)$gk3`583rGJ_}20tDDcVxc&m|+f<1AbLy?n*OZa;*e5mRaNf1g%?~}~d-9qg -z)YnEg7G_l=&u9@fFIBKaalRbC<3=@@*feY>lRsNADQ15TvdRTJZ<)eCYVPqzdL=Ef -zN5(>Vd%-(d`|e!KyLWUEG);_E!J-fhAOl=zUcrgVX1&hj`Zz+wvF9Oz%X4gGuONcH -z%h?(;os*+5gzz&rd5$4ULvA`P^W&(9fPMjG4QPG?KhaXi@O6O|U0j#gaaIq8)g2TV -zw^p{f?V!a@N*#6eiN&o9wm34rAKw#f?N|a+zzc!gN;w?_aaFF$hD3`u9UipKy2=a?eobQF_M*REf$ -zj;+{$jx7^GXy!mmwnHMf3B}G*11Dl+ur+U$HV>=|*rWme??d4H)D^+~34-e<&T4fK -z9ektGZMEA`+wEVx>}pcQ8=?b3U&4M_&cEw^b7&G~t`IahA*>38X=Dd9PK+d+v5AchxFfgIsaho -z3^g-d&4HLt@zfMHx9?onm0BKMiye@&M25!d0|j0nObOP+ni%+TRkv7Sys6+6#71_3 -z=3c}|gh*XvU|-!JP`?&KXx|m7=3b=XOQhwATD=v29v@f&3!tGPuaC{Nnek)Hkat;U -z8D}L&CC7!O1(_;b_eTUDwOd6z&YPOQpDHX}OEqX&rqBLxbi6Y+6raWRuS~FCMLRMt -z&#=5pIeXB!uFvv)dfz7vM;+QgV~i`G1D= -z-T1{F=Svc>DCY7thwMnMEmQWBpxlHg7sL~EN*8FEl-J$-QY%K%J<1cYy3$KV -zG+EM%8p|KXJPMwGyQmer(9LR9MVP?GkZ=w}PhCJq%Z)LsM&!Gw6`W|6YLt|VXVknn -zG+d8xv`&o*XpcrIyO?E>GlQ59W6fo)hgdm&!us+gk&~Z(xzd@ocd|b&VXN{1iqTsr*tppm%|xZev}kgETo?Ip)PrPEKQ`fJY27Z?+iQ -zPb+`K9I8RYFXR$~Ml+_RwfhqjPI$G<^2eQukio^mMUAfca=8^`P$}-3av))0#reBX -zJO?KRoQN}PfKy6EWE<${E5oA4psTIXI5R3P!`afUEO#@F#cW6?SdJ)pjcBxn{HXms -zby#DnxcBA!a)&`0rbZD2SYTN$P0#hKE_J>aS6t>Fk>J=OkHFT(x{~rHi3m`WL<=kn -zYqLhsunHC_IFkJ)nD=}RTK!-#DyN3zk?9q}WQ|y1rKvmlPWbjHi7UlXup~E2|PJyPAGVueL7){V%z~!0G -zXAH|iVbtT<`S2``Tz}5WNHpQkL-$|7{gJQRQ -z{~K-@lS>`6>%9heUPf-y_RL%GwF=+XQ~OK*X5E^AVS9Hz$Yi?j*y$}A5lRJRSrKl( -z3QcA!z)W=;sR?}0Mz~&?X -z!oKp_GaPNka5j@l=_W8i_Ofa*C=4c}Wn{Tg&f#Kv>KXE-R$KfXiUCcU6VXc% -z=8i?pTr4YAqN+|9NHN6(T6PSGByZO+A&`CaMYXfh0S?fVLF)`1*NWI$0?QTU>kd1; -zGzWn5_-2B({Gn)x14cpGBq|78lCZr3xPjhMM!`-370O&|EV~3vDVO@igfR9m|9LnF``CmprMnO!UW=7QAFV7bZS -z&97u9G63r&&SVh|)l9V;7LLGCY8;X~D^VDNon%jj$@1u7VD2c4OvIF-u>sc%Ihq#3{;M1c1{1p*hfy2MCQDBv0zVR>fl{I|lfOf;-g+=$^M -zq0Rs#+yN#^6GhBtw92LZA^WH9cMTdqHT|aKv9`5>skD<(_o8oU-&XLEN{BSkLfhlzuyX9QH{N}qaK6~?EU{Kz -zFf*F$WS+nvgybofAOzsSJB2OZAEG_m7vlWn+^D;_jaN7gg(HGtYw~px -zw}w`idAI|sf^=i2^*GKT7v~wW-*+2JZJYOB6^uJwuw86RE7aIFD9F(*S)1|L=(x*R -zBloIwb9(ht1|YF%8f9femH5?zGAQAwWo -zyqo4TV2R=B`U<5m8wAeMHEHpWnOW5wp)I$xr(kkl)R;Oi0isun=y}c-l7LZ7m;lm$ -z$q4Iy6Sc&$7dUfcx*n3=`*`*UR -zN1JtLOUYS-=7UaFQks;9^B@e^CN+Pz{Jd$gh_F`j>;ZkK-Md1}-@#73aDFjIwBy*d -zTlwKK`nqGu3$(>F?Ap8A?q4y9mka`bxGNnAlZNNKWA&(V)8YwF5nmp7j%ul`_QG%4 -zaeXBNd7~ytMg3#Xf>6W<>tYbEa%-$6=;P^Sh>aUHZ+e~0RG)Xi3%`rEs8MS8uYqwNdw4SWVkOjZaf` -zG5VfUUiPoOG}N6 -z<{qp@h!mly6=>7I?*}czyF3Y!CUIt=0}iD^XE&VrDA?Dp@(yuX{qsEJgb&Q}SNvXl -zg?HrA?!MH-r4JN!Af3G9!#Qn(6l%OCA`)Ef2g8*M)Z!C4?WMK9NKh2jRTsnTgfut9 -zpcZ7xAHd%`iq|80efZ31m3pN9wwBIl#Hqv=X)1r?($L>(#BR+)^)pSgbo+7#q<^S1nr$1&0=q$@M&POX?y?3L&3X -z!%^Atu025LgEZ~|-)Cd0=o8K9A{$sT;SHj3M?l{!Er;st5w=T=K2^hJ<$(>&P!j2m -zy3~(Qm?r5vh*EGKNLnP31{fhbiIU~c2GX_wqmM}ik7)NF$bEYKH^bK?MD+uJ24Qa=6~Fg-o!gSX*ZYoo{fzTLs$371<;7oLD|PiS3s -zz;aIW1HVCV2r*#r`V-0hw_!s4!G4R|L@`u_;)KA?o(p8@$&bkWXV*taO%NC3k? -zok=*KA5vswZe|5QOQd*4kD7Db^c|__5C;&|S5MvKdkPtu)vo}DGqDpc097%52V*z( -zXp%Esq4?Rzj53SE6hKu;Xc!&LMZPPIj;O-Gnpq&!&u5db7Xi -z64ox137#@4w5it68EPn<8RO48KG_2>?+Aa}Qo7fR%&wXJNf2J;Kwm6Opddsyx$gY# -zU+b%y*{cBju|sw!wOcY_sMFWX9(C02d(;_YQh1*sH9?j$%`tKJyd(j0PtK#D+KLHI -zL;b*n{CZ7IBb}MUGdG3l2vFGJn3TOYJD$Hz2OOy*%!5a{!!0mvok+e+N -zaP?Ndm;SO(8-v%yvu#Rr;qFSgZrKJxV^uEnX@L(r4)dZeyh@yRqoi@3M|#Hz`hHN6 -zA|8#&oFv8+1F8t(#j1%Ywdn%N2uREt;@bFAF}2zeI2KE&uZr$?-SIwKu<5ThXn_}f -z`@RRcJ!3;pKi>mQe)VU5;c)zA@b#dd(J?}$sg0K5L^fIm8%TV4|>Q?qdfMwAh4AM8l8J|tiSF32B4q`!TYj_z!4Lowq99lipY?vlC -zJssf0Vy+@In|fg`2sUl$wDGr$XY+4g*%PhDjM^G!Z{H44gwY-ymOqXka)G3ulfWdY -ztNvx4oW*}=5^&NGhiS)Vzwb4;K`^*tjj8h$esujKb7&}?V_cU5kQElGgCL<358O^% -zcT-EwP>hqb1%_8C_5R4e#7RH -zp@tA$bVGG}q@TDR#-_^YT6}Zo5~p_5P%C_pRxwhgkor!;FtNFF#cncoEHm=#?xtY0 -z1dHK{(;)5CQJ`0upxdRV?(5PH{JISW%d+@v8FmbTh9n5TXGnM`Cs}{(AbDxaIg&O2 -zg<~{fKtj#r91u9PujPqhkFt7tid?IZ={dML<$3sh;A*Hw=VP++12;lVguAyio!na#kaYeX{|8h3_;g*K=UEf -zU*{ZR($$Bw*(h;CSO4{alBraU^)52&nxLKUxg=1N5MCBUJ+3a^`9#f?7=4#`&oz?k -zoz-#s4C)f8Uk@S*VF!Uc>X}9M`_*gkn0&GI2R*j -zUlHUy5b;rLro3?bBLIt%dRd~2lT@kjcfY~OL5ZmTl)ExZyt!)^K#1p>U~rdclk``e -z>=zHu6Qp^z%nX2U*RE14f{$U0*Cf)LfBz-c)t%iD%3wxsgHpRPvieqZgEC0IX_Vkd -zxh27*KXpXxYD=^PP&EtX{NlX -zC%v9)Wz6De((qH}Jqg-g`mwJ!IZ^L?eE2PE9@#9U0T>jD%e^K8-Phz7cZ-bP -zU%h91CvGtNYmE{gk=tex+96fK^!I7P7YI3Ma}h)ty%NEN -zn}d&kVV1DM4tPht`B!poikUOE396Uy+VE|E*eQuq -zoT8M0M&bcREYOX7Q)F5+d!xec;2;H!WO+!r;v#uo402OEt*q%vj)mC@8wg}HO02G( -zYG=<5*Vgl3R(5)N@{y+rvBY9CgUHeN`qQLm*3;$@Ez|2z2j3@V_m6j4Kc{5MTf}GG -zMS_qp%5n(5$y|Ke#!!7w$4KKAJmhA@sJLcoS}Mv+l^X$2DS9H)ezLP0LfVpNMIPwL2U@Y%%7Q7jPXmGSPlRwa7*y~EkqObIDtyFm)q -z-D~m~?At^+db`FvO2uEi2FuK@`RaSN*`T%G!}yA5f-hG1SYtty+Q}}`O^In~cgi>l -z=zXVDDNVH?QHtgup3*d46+OEicA^)pIn2`}B}8}{g`msSbzzvq5zHCIjU>OrtmbrG -zU26iOxr*A6%_LC(|3nH@ef$16q%glnTl}ob+(w=A9Uk48Pe(F^%ktv(oHC2Ve4|TE -zc6J5le1ZqXdLP~+(UY@`Y?r~{B6_Alh8Q{OmhufQSf94*GFtAi(lV<=!6wqxL;jck -zOnpR+=HK3Nh}Vv}%LXPzn;0b#^5Afk3y&G)X}NEkE`~TM%tU-P1@^=msCxOyP!IRO -zBegW5wZ@10CM!9*_|kF~ZSxrk>r^zyCL|dy9$~*`OX?>1)fL1l(|lW|G!``CEq!N$ -zMM)W~G2zDb6wA#)D5OmIMu_&UH_5B%DJ#NKl#R!?QVz>y5jLrK(-JpI6LIGVyD%W9 -zg+7;cE40;Rcv9 -zkCrUgZ-H}IaC=aY8~7*9+Ny?O=Ep;yso*#-SesEGSa3T&e&DQ`k!p#Zgb<6@KRjgn -zG+Z?LoNstww}#+R`Y(?d>>GG^ncorkoKX@REYSTD -zQTYHMwNiE~9MM(>u%!3KVR=O=by_thqeFR&Bm;D|lW@>^unOrb^k9yd-=S2LH0S7} -z>ae^bwruKEB*7m=)u$5MIo(`)Y+RR5o>9(DDDV623UMVck1##|b`7H%yjK9unoDGkVIKrG*dvN;2S3P_9>ckR6c?7n{s5v!i;dE&<_aDaPA_ -zi>Z&SHW^bWYJr-2sb7{WC|0k-a}7>k3)*YgZora(7dVnK7b6?Y7U|>t*u=-aLgC3` -zvnz>+QQ_%r^ePEJA5X6^`Ey@^#{dDW(QZr*A_L9Y+QI4?xFXAQ-JDe?&YmeAVN{2b -zK0DO+&S-fQWDg`ab0$mQodAEemrA3p{cHbqx{yVqz5Ns6)Rixse^k(i5spvs@22QF -zAhsD~>)rC%n(#M+D1!s?DFCBTRfNF~`N7kC8by+1samiHH9dbid%Masz0;p`l^GuF -z)taCc0FD9!#^qP3B`G>vZA2db%ma*@6WNWW{*kPq^|f^R%Ee|F-FM69H)u|#Qt{qt -zoi{%@b&~<}!vBf99Ef=ih~RNSh2LT6zvdLf+KCi=hu6#d5v7kpppM&Z;F3;`{0FxW -z@#nY=LnIjx1?~XD?48~y)>Y&odjWF%6G64~A_3<{rx6>R -zqF2ozPyJzzmcF+3AQwJQ@C?KEo|5k3xP%;^ZN*zpQBm5ho(*e)*zn8NzzzG6V?5V0 -z2<7tkys|TInay6or7^K(y0ZdwJz|6$blXL}SX7s2es~5{gYwS3d>6k|3V9vz-#G3! -zh@|-B?^JP~seJrS$&XAfp`RknZ!pFw@e!a9WgKijDz3K#6@`ifTCWHTa}Tr}n!~;0 -zh0~X4_sEKGZZ^}8+X9!T7NazNv{%@nJgpJ8M;Oa -zaYo_2Qbk6_j7W15!`+XKC!`+_)IGZ>r6X=buKUkQ*5wXs5}A2D@eYvF0{q(=wm -znxEYB{>rdO75{|gy2>`^UB!(y+9acVVRieAMG@Lhf)g>yr+Ccgf8oy1qUO@L$n8@A -z;nKV>muW=<*rD@Su=A?nhxTpx>?1>jYOk(ytb|TNwq8q1{;WERaWZi0ov0xFjiIm} -z)PkKhn`#2CSuR?p?4)9Vk#`#oL)#q8!B*j3s+x*6kQ~2Pog{K^{k(=xfv{IP9MecW -zCB_bMVE;HQS12k5L;tHHjhJ8m%07IN<1N(vQCG+8IilmMo{g$Y5nrPhSx`OH03*55 -z;^!ZP!KR|h3~K&8O?uAqKie(}FOYVMt}S-M;FF6%#pX@C<8P!jbk&G&a^_Oj+^2Ys -z*1tnnx4eOpd*hgE$xD+(iTw1TaGNs=4*;Pf#P`fd%_%)Jk|eeooma)pR9ka)Ek(PX -zq2N$R8sio=D*TQ0BaO+M*8wF-0cR8Bq6vZjr?NAFhjQ!V_)x?Yxmhd9T8#bPWJ^p2 -zVbs{=P2C~;GV>Zlkw%u3?OM9&TE|2xMT@t3uSiNEt`MOO*Q>52Wh>pfXJR}YW6XQ{ -zJfCN%^ZlJU=RD7Ip3^zMKT-4Q8#0faYOd#r>yK58)sH5XCS>Yj%p1^_p%gSNX4Iai -z%;dio52O@`qrWD0>K#6CJvdGFcB%`pA47@W5qIzGe`HRY=O5CK4bZvl6IkJj{#%r? -z|A5O4Uo8)Ng;t9f!sRAIsl1a8=TST_Vn(m0i`>XCa0r`>YP-LwxB%^wu8;8+GdQv( -zG^usXB?ocI0_)y0MR`T!?Us5ehia8>M~+$sXlUCRovE--QR@;Ys?Ozq9P(Q7ZQ43> -zpIo}_{z39UhS{5f8wKSDu+TKfi+#n{O-~4Uk -zh*EmSxYYrfwOxCYV}}!zL%2uIc%Oe$XRV@rFeWeka?;Z(XI{}`X?HJGyIgFm@ZX;w -zsc2~^A%MTLdqhpoV!jr)}36>dv>Px$jJImpFCzVcs)1b7l%&=qcE;^ -zEoSbtk#6sYkpC=iQX(3 -z5EUP%LDh0p49U2=$~DIZhi;dDRKwLN8`|PiC-Echa#PXZ|6)S}wWEA@3f!rX>G_!A -zphhlmxu@3JVRr3xOWD}*UYv04{*WHt*vT;0@pVLmuu52Mb_Vg9Wg9EUuA2 -zl8?Jv5GSU+*{PO$tBpirns`>?!VL-cX@gZO&q)OL%2_8U)8r*4jrGrH`p2zV!T-&| -zaf{j)uCI!{A{R9~aJ?$SZ?kk?jfE7FM%1sOCd&S0B(^ckufHtAOetsuspYrqyZ)x8Z8=dG=GG1lcFtKmoxl{>m -zAakHGc|f5ZKh>>}F8qu)Y29d2Op+uf?qK|dKPwE!pPkfGl#Sa#?TmJfv}jA5;1`#= -zQqplM=!3^!2QZeCx7wu8uWl9!IN85^zrmqGDxsj;TVs=EU)ubiDaD<*@ss- -zm%Y-l)9@TN+_0W7Ml5XnEz>_ep>fFIL{5V-n#cCKFhy#0p;!@D!D-=e{(8;*$#2G- -z-~F3cHNv>%;D819xg3-F_yHg8bD1W}{1-kQ-da2kMRP?r=@>BD^b5H6=`Lf3y6VPn$`%)-GW}O^kSon7EBP;q9?=n_7O67v9pc>!pQb -z)auPuaqG5v3l(E)_GSI_vFY2BtlPgw{(hIMip%d;>9vWnej@q%qMva4iRPI|N7n7w -z(!_tL^K*((d428fyiU(eFYzyaICWGnFx_T^a$3(A4p<5kwVtGjOSNa=ey -z3;wiIDZDmghb8BsMcSVyT9^W#{YkoGJ9As)0ccff5 -zB`U1^TKO@jql!utGX7_6ceT=$mJTWcQ+7_Fk7=jIE7Lu2Ja%~~6K=X$o@5Q7)=`Ao -z%Vptz#p~F$l82kO>0*a`LQ8HomkN}$Q0{w8GzfUMX3_$LbiUMT6?eJhshLtmT2m`2 -zrK@zuUt8C6$2Zb?u5HM~2xm~H)s1rOJ^3v#{cdG~?xM<+6Lrd(chPMthvmtIcgJoV -z-(H!YsUD=t^F)QFU+e|WYBXo`#ht!`&flPI?tga}(nLX13WI~;V?XO(57wx&_pbkw -zBgcA$g+wx2w|Xvakrlw=n~x7nWeO7*SwR2(p1`8M*~Ae34SZ&}#$zt|Z%!C%XpOXbpLFv5`sjlu|+#!Pgo9FXG>J~QZn(O%YH -zBWQs46dZC)E;!SviJp -zefD-koJ?SaKCq_$3t)wALZM_9CQK -zGw9iXX^iWLHTQFmME^y==>muB0FYBWAg>aJ#z};63aHSV~ -z^&BI1Xx6m%m3k8-P|$7QUIaSpT%uDW?OD?BB+n%~l7+?9t%+Q~hX?=}`?8pcPE~ed -z2_t~uEm#W0-QN{N#+ApD+=zZSaBm3ob`3@h+u^Gh4ttNN2s$sX!nzuwp?JOsGoHwj -z2@l5>ME8YD3`fUA=$RfY>9hSG4D8@onJ^lTK8T>xz1g7`#v+8NaNr$;IubZHjA0js -z2L>_#pi_KLjIjbU(W!eWi-1dyWY}RDad&1C;~9SzVCP+CjBSB%W;hBDGdrDHyErp5 -z5X#cSZWs?oRzdJKA&bh!#B=h>1`ELv5fGsjM;8grEB_Ml5nw!Q?T_Fy!`b1Xw-Oi& -zJK7`IPZ8{}^QU`YChTvFFb$*GF~83#Ejd(!t%MOOCWZs*(#FDY@nJtyM5ys3r$RH; -zGwY5D3&8G^h`_zm90;)SqJ))TM><4FJcR=#j{NChP1sZn(R`H3fhIePF<1&VWkIAq -zW^y3K#-asQg8eTLr4LygD9v;SEK4^GSPFI-K%^#fIhF$V7sl;-&O{IvfwyiWBC85G -z7MZzT=Na3;D)1g*L}lf9j#XxMO|l*@z#B0U0n~;6Q((CogEzq;QX^ml3_auK-QH(! -zYRlFYydetV8<%jvXTLoPZWwqE2_hCzy1W?cwt!a;Ak6maMa=Kjv3M;3Tu%5uArNL? -z-SSL!&nS5679sOBE+%t6kqdtVcsdc$>26x21CM6sb)#h-?QyJ +delta 8958 +zcmY+KWl$VIlZIh&f(Hri?gR<$?iyT!TL`X;1^2~W7YVSq1qtqM!JWlDxLm%}UESUM +zndj}Uny%^UnjhVhFb!8V3s(a#fIy>`VW15{5nuy;_V&a5O#0S&!a4dSkUMz_VHu3S +zGA@p9Q$T|Sj}tYGWdjH;Mpp8m&yu&YURcrt{K;R|kM~(*{v%QwrBJIUF+K1kX5ZmF +zty3i{d`y0;DgE+de>vN@yYqFPe1Ud{!&G*Q?iUc^V=|H%4~2|N +zW+DM)W!`b&V2mQ0Y4u_)uB=P@-2`v|Wm{>CxER1P^ +z>c}ZPZ)xxdOCDu59{X^~2id7+6l6x)U}C4Em?H~F`uOxS1?}xMxTV|5@}PlN%Cg$( +zwY6c}r60=z5ZA1L +zTMe;84rLtYvcm?M(H~ZqU;6F7Evo{P7!LGcdwO|qf1w+)MsnvK5^c@Uzj<{ +zUoej1>95tuSvDJ|5K6k%&UF*uE6kBn47QJw^yE&#G;u^Z9oYWrK(+oL97hBsUMc_^ +z;-lmxebwlB`Er_kXp2$`&o+rPJAN<`WX3ws2K{q@qUp}XTfV{t%KrsZ5vM!Q#4{V& +zq>iO$MCiLq#%wXj%`W$_%FRg_WR*quv65TdHhdpV&jlq<=K^K`&!Kl5mA6p4n~p3u +zWE{20^hYpn1M}}VmSHBXl1*-)2MP=0_k)EPr#>EoZukiXFDz?Di1I>2@Z^P$pvaF+ +zN+qUy63jek2m59;YG)`r^F3-O)0RDIXPhf)XOOdkmu`3SMMSW(g+`Ajt{=h1dt~ks +ztrhhP|L4G%5x79N#kwAHh5N){@{fzE7n&%dnisCm65Za<8r_hKvfx4Bg*`%-*-Mvn +zFvn~)VP@}1sAyD+B{{8l{EjD10Av&Mz9^Xff*t`lU=q=S#(|>ls520;n3<}X#pyh& +z*{CJf7$*&~!9jMnw_D~ikUKJ2+UnXmN6qak{xx%W;BKuXt7@ky!LPI1qk?gDwG@@o +zkY+BkIie>{{q==5)kXw(*t#I?__Kwi>`=+s?Gq6X+vtSsaAO&Tf+Bl$vKnzc&%BHM +z=loWOQq~n}>l=EL(5&6((ESsQC3^@4jlO5Od{qN#sWV)vqXw}aA>*uvwZopNN(|-T +zRTF%5Y_k1R$;(d-)n;hWex{;7b6KgdAVE@&0pd(*qDzBO#YZV%kh%pYt1`hnQ(Fa& +zYiDrOTDqk5M7hzp9kI2h!PxNnuJ&xl*zF8sx6!67bA49R1bmUF5bpK&&{eI0U~cH}PM +z3aW1$lRb|ItkG5~_eBNu$|I|vYIdAA9a!pVq<+UTx*M}fG`23zxXp&E=FfnY- +zEzKj;Cu_s4v>leO7M2-mE(UzKHL4c$c`3dS*19OpLV^4NI*hWWnJQ9lvzP4c;c?do +zqrcsKT*i~eIHl0D3r4N{)+RsB6XhrC^;sp2cf_Eq#6*CV;t8v=V!ISe>>9kPgh}NI +z=1UZutslxcT$Ad;_P^;Oouoa(cs!Ctpvi>%aQ+Zp=1d|h{W9Wmf7JWxa(~<#tSZ?C%wu4_5F!fc!<@PIBeJ)Nr^$bB6!_Gic_7}c3J{QI~Gg5g5jTp9}V6KYgrgaX>pJt}7$!wOht&KO|+z{Iw@YL|@~D +zMww}+lG}rm2^peNx>58ME||ZQxFQeVSX8iogHLq_vXb`>RnoEKaTWBF-$JD#Q4BMv +zt2(2Qb*x-?ur1Y(NsW8AdtX0#rDB?O(Vs4_xA(u-o!-tBG03OI!pQD+2UytbL5>lG +z*(F)KacHqMa4?dxa(Vcrw>IIAeB$3cx#;;5r2X;HE8|}eYdAgCw#tpXNy7C3w1q`9 +zGxZ6;@1G%8shz9e+!K2MO*{_RjO}Jo6eL3{TSZ>nY7)Qs`Dhi5><@oh0r)gT7H-?3 +zLDsd^@m%JvrS8sta5`QiZNs^*GT}Hiy^zjK2^Ni%`Z|ma)D2 +zuyumbvw$M8$haCTI~6M%d4+P)uX%u{Sfg4Al+F7c6;O-*)DKI7E8izSOKB#FcV{M+ +zEvY0FBkq!$J0EW$Cxl}3{JwV^ki-T?q6C30Y5e&p@8Rd?$ST-Ghn*-`tB{k54W<>F +z5I)TFpUC!E9298=sk>m#FI4sUDy_!8?51FqqW!9LN1(zuDnB3$!pEUjL>N>RNgAG~-9Xm|1lqHseW(%v&6K(DZ3Pano(1-Qe?3%J&>0`~w^Q-p&@ +zg@HjvhJk?*hpF7$9P|gkzz`zBz_5Z!C4_-%fCcAgiSilzFQef!@amHDrW!YZS@?7C +zs2Y9~>yqO+rkih?kXztzvnB^6W=f52*iyuZPv$c42$WK7>PHb +z6%MYIr5D32KPdwL1hJf{_#jn?`k(taW?mwmZVvrr=y~fNcV$`}v(8};o9AjOJumS4 +z`889O91^pkF+|@$d9wVoZ3;^j;^sUs&Ubo_qD&MTL%O +z&*SE0ujG~zm;?x)8TLC&ft))nyI +zcg44@*Q{cYT+qGrA=In_X{NNCD+B0w#;@g)jvBU;_8od6U>;7HIo@F*=g8CQUo(u^ +z3r4FJ7#<@)MXO&5+DgKE&^>^`r!loe7CWE*1k0*0wLFzSOV8jvlX~WOQ?$1v +zk$Or}!;ix0g78^6W;+<=J>z@CBs!<<)HvF(Ls-&`matpesJ5kkjC)6nGB@b{ii6-Uoho$BT%iJgugTOeZ$5Xo4D7Pd< +zC*LJh5V@2#5%aBZCgzlQi3@<_!VfiL07ywc)ZbwKPfcR|ElQoS(8x|a7#IR}7#Io= +zwg4$8S{egr-NffD)Fg&X9bJSoM25pF&%hf>(T&9bI}=#dPQyNYz;ZZ7EZ=u1n701SWKkZ9n(-qU +ztN`sdWL1uxQ1mKS@x11;O|@^AD9!NeoPx}?EKIr!2>1Qq4gjfGU)tr6?Z5l7JAS3j +zZeq{vG{rb%DFE4%$szK}d2UzB{4>L?Tv+NAlE*&Nq6g+XauaSI+N2Y8PJLw+aNg1p +zbxr|hI8wcMP&&+(Cu|%+Jq|r>+BHk@{AvfBXKiVldN)@}TBS0LdIpnANCVE26WL-} +zV}HJ^?m&$Rkq;Zf*i-hoasnpJVyTH__dbGWrB_R55d*>pTyl6(?$EO@>RCmTX1Hzr +zT2)rOng?D4FfZ_C49hjMV*UonG2DlG$^+k=Y%|?Dqae4}JOU=8=fgY4Uh!pa9eEqf +zFX&WLPu!jArN*^(>|H>dj~g`ONZhaaD%h_HHrHkk%d~TR_RrX{&eM#P@3x=S^%_6h +zh=A)A{id16$zEFq@-D7La;kTuE!oopx^9{uA3y<}9 +z^bQ@U<&pJV6kq7LRF47&!UAvgkBx=)KS_X!NY28^gQr27P=gKh0+E>$aCx&^vj2uc}ycsfSEP +zedhTgUwPx%?;+dESs!g1z}5q9EC+fol}tAH9#fhZQ?q1GjyIaR@}lGCSpM-014T~l +zEwriqt~ftwz=@2tn$xP&-rJt?nn5sy8sJ5Roy;pavj@O+tm}d_qmAlvhG(&k>(arz +z;e|SiTr+0<&6(-An0*4{7akwUk~Yf4M!!YKj^swp9WOa%al`%R>V7mi +z+5+UodFAaPdi4(8_FO&O!Ymb#@yxkuVMrog(7gkj$G@FLA#ENMxG)4f<}S%Fn?Up$+C%{02AgMKa^ +z4SFGWp6U>{Q6VRJV}yjxXT*e`1XaX}(dW1F&RNhpTzvCtzuu;LMhMfJ2LBEy?{^GHG!OF!! +zDvs64TG)?MX&9NCE#H3(M0K>O>`ca0WT2YR>PTe&tn?~0FV!MRtdb@v?MAUG&Ef7v +zW%7>H(;Mm)RJkt18GXv!&np +z?RUxOrCfs;m{fBz5MVlq59idhov21di5>WXWD-594L-X5;|@kyWi@N+(jLuh=o+5l +zGGTi~)nflP_G}Yg5Pi%pl88U4+^*ihDoMP&zA*^xJE_X*Ah!jODrijCqQ^{=&hD7& +z^)qv3;cu?olaT3pc{)Kcy9jA2E8I)#Kn8qO>70SQ5P8YSCN=_+_&)qg)OYBg|-k^d3*@jRAeB?;yd-O1A0wJ +z?K*RDm|wE<(PBz~+C%2CTtzCTUohxP2*1kE8Of~{KRAvMrO_}NN&@P7SUO{;zx0iK +z@or9R8ydYOFZf(cHASCAatL%;62IL27~SmASr(7F&NMr+#gNw@z1VM +z_ALFwo3)SoANEwRerBdRV`>y`t72#aF2ConmWQp(Xy|msN9$yxhZ1jAQ67lq{vbC5 +zujj|MlGo`6Bfn0TfKgi(k=gq0`K~W+X(@GzYlPI4g0M;owH3yG14rhK>lG8lS{`!K +z+Nc@glT-DGz?Ym?v#Hq|_mEdPAlHH5jZuh*6glq!+>Lk$S%ED2@+ea6CE@&1-9a?s +znglt|fmIK}fg<9@XgHe4*q!aO<-;Xj$T?IzB-{&2`#eA6rdtCi80mpP&vw(Uytxu$#YzNI_cB>LS +zmim>ys;ir;*Dzbr22ZDxO2s;671&J0U<9(n1yj)J +zHFNz=ufPcQVEG+ePjB<5C;=H0{>Mi*xD>hQq8`Vi7TjJ$V04$`h3EZGL|}a07oQdR +z?{cR(z+d>arn^AUug&voOzzi$ZqaS)blz-z3zr;10x;oP2)|Cyb^WtN2*wNn`YX!Y +z+$Pji<7|!XyMCEw4so}xXLU)p)BA~2fl>y2Tt}o9*BPm?AXA8UE8a;>rOgyCwZBFa +zyl42y`bc3}+hiZL_|L_LY29vVerM+BVE@YxK>TGm@dHi@Uw*7AIq?QA9?THL603J% +zIBJ4y3n8OFzsOI;NH%DZ!MDwMl<#$)d9eVVeqVl(5ZX$PPbt*p_(_9VSXhaUPa9Qu +z7)q4vqYKX7ieVSjOmVEbLj4VYtnDpe*0Y&+>0dS^bJ<8s*eHq3tjRAw^+Mu4W^-E= +z4;&namG4G;3pVDyPkUw#0kWEO1;HI6M51(1<0|*pa(I!sj}F^)avrE`ShVMKBz}nE +zzKgOPMSEp6M>hJzyTHHcjV%W*;Tdb}1xJjCP#=iQuBk_Eho6yCRVp&e!}4IBJ&?ksVc&u#g3+G$oNlJ?mWfADjeBS-Ph3`DKk-~Z70XugH8sq2eba@4 +zIC1H_J$`9b$K`J)sGX3d!&>OmC@@rx1TL~NinQOYy72Q_+^&Mg>Ku(fTgaXdr$p_V +z#gav1o{k~c>#)u3r@~6v^o)Lf=C{rAlL@!s457pq)pO;Cojx7U{urO4cvXP|E>+dV +zmr2?!-5)tk-&*ap^D^2x7NG6nOop2zNFQ9v8-EZ{WCz-h36C)<^|f{V#R_WE^@(T0+d-at5hXX{U?zak*ac-XnyINo+yBD~~3O1I=a +z99|CI>502&s-Qi5bv>^2#cQ%ut<4d7KgQ^kE|=%6#VlGiY8$rdJUH{sra;P~cyb_i +zeX(kS%w0C?mjhJl9TZp8RS;N~y3(EXEz13oPhOSE4WaTljGkVXWd~|#)vsG6_76I)Kb +z8ro?;{j^lxNsaxE-cfP;g(e;mhh3)&ba}li?woV2#7ByioiD>s%L_D;?#;C#z;a(N +z-_WY<=SH42m9bFQ>Nb +z@4K$@4l8pD7AKxCR>t0%`Qoy9=hA?<<^Vcj8;-E+oBe3ReW1`el8np8E$k{LgFQ}2 +z2t8a`wOXFdJ9!5$&mEfD1CnJ)TB+RJih88-Zos9@HZ# +zL#{qfbF0ARTXkR@G{lwlOH~nnL)1jcyu!qv2`57S&%oKz0}r{~l9U_UHaJ5!8#nrs +z?2FrL`mxnzu&{bweD&62)ilz*?pYIvt`T!XFVVA78})p1YEy7 +z8fK#s?b~Yo$n7&_a?EBdXH-_W)Z44?!;DFx6pZ?~RArtBI*Qm4~6nX6Z_T*i$bQPE;Qz?DAPstpGSqr-AJ +zo%m9cA`oDDm?&dTaoh_>@F>a?!y4qt_;NGN9Z<%SS;fX-cSu|>+Pba22`CRb#|HZa +z;{)yHE>M-pc1C0mrnT~80!u&dvVTYFV8xTQ#g;6{c<9d!FDqU%TK5T6h*w*p980D~ +zUyCb`y3{-?(mJFP)0*-Nt;mI$-gc4VQumh|rs&j_^R{sgTPF`1Xja2YWstsKFuQ(d +zmZMxV$p$|qQUXchu&8%J(9|)B?`~rIx&)LqDS>ob5%gTeTP#Sbny#y*rnJ&?(l=!( +zoV~}LJ1DPLnF8oyM(2ScrQ0{Q4m4-BWnS4wilgCW-~~;}pw=&<+HggRD_3c@3RQIr +z9+-%!%}u_{`YS=&>h%kPO3ce}>y!d-zqiniNR-b5r97u;+K6HA2tS>Z#cV{+eFI`* +zd8RMGAUtX1KWfPV;q<-5JAykS+2sY$2~UX+4461a(%{P#{rwFPu0xpIuYlbgD{C7C +z=U{FUarVTYX6ZUq3wE@G^QT4H2Re;n$Fz9cJ>hABl)9T8pozqbA1)H-%1=WKm^QMu +zjnUZ&Pu>q+X&6Co*y#@pxc-4waKMInEPGmE_>3@Ym3S*dedSradmc5mlJn`i0vMW6 +zhBnGQD^Z;&S0lnS0curqDO@({J7kTtRE+Ra?nl^HP9<)W&C>~`!258f$XDbyQOQXG +zP8hhySnarOpgu8xv8@WlXnm(Uk~)_3$Sg0vTbU3 +z{W!5B(L3{Yy3K5PN<@jEarAtja`}@KYva&zFRF*s+_%jIXh$T(S=an8?=Ry3H*NRqWgsM`&!#|@kf1>=4q%bFw7^Rhz!z5I +zyI^zU8_R1WN9`88Z=n>pIZQ`Ixr~_9G%Q}@A7rd#*%y7G +zXl^Id=^ZL?Rx}}gWXCqzj9C6;x(~mAH|$JteXa1MH<6UQig@!Hf~t}B%tP0I|H&;y +zO6N0}svOa1a^PyP9N5?4W6VF%=Bj{qHUgc8@siw4bafT=UPFSoQqKgyUX>sXTBZ=x +zOh^Ad!{kOM9v{%5y}`-8u*T&C7Vq6mD%GR}UeU(*epO&qgC-CkD;%=l)ZuinSzHM` +z{@`j&_vC6dDe{Yb9k@1zeV_K6!l(@=6ucoI=R^cH=6{i71%4W3$J-?<8Qn#$-DMtA +z6Qqi)t?4ifrt%3jSA#6ji#{f(($KBL-iQh-xrC||3U3lq`9>r)>X%oLvtimuHW-)} +zy}>9~|M>w4eES`g7;iBM%Se5-OP%1U6gNWp3AZqT8C6OlFFfQ$|7LL;tBV)(qlp4K +zruar^K8FnJN3@_}B;G`a~H`t|3+6d>q3#`ctTkE-D^1#d9NalQ04lH*qUW2!V +zhk7#z8OwHhSl8w14;KctfO8ubZJ4$dEdpXE78wABz=n5*=q9ex3S}`e7x~~V-jmHOhtX2*n+pBslo3uosdE7xABK=V#-t{1Hd~?i +z{i~%Bw6NYF+F$aK$M`r#xe=NxhA5=p%i7!$);sd>Q}#`G?Q~fygrMXmZw?0#5#17W}6Tj+&kFexG{!mYl5FoA99}3G9l;3lVQ^ +z48^~gsVppE*x91WheqI(A%F0Z#$#1UJP1R12Mj9r)y(A?a+iquX+d8WD4WAQJ_!oq +z9rTISr7bPd(GTP57xm$}C}&kjMivi;zi^Y9g3&X0A;ovdJ?{%_wHgt%%9P&N4H +z^XzV(uNA4 +zAP`hgP6BEN5`YXh|DF~6Pud?~gWfhUKoPX4>z|}0aocC&K+AoV%|SX*N!wGq3|y< +zg4lP(04XIPmt6}$N!dTk+pZv>u;MTB{L4hp9uXk7>aS!6jqM2lVr%{)H3$O127TSZ +z0x9hi0k-P?nWFdQ0K`pykqUIT&jD~B0tHP{ffS(}fZ(aW$oBWTSfHO!A^><6vj?q^^Y^VFp)SH8qbSJ)2BQ2giV^Jq -zFM+=b>VM_0`Twt|AfhNEDWRs$s33W-FgYPF$G|v;Ajd#EJvq~?%Dl+7b9gt&@JnV& -zVTw+M{u}HWz&!1sM3<%=i=ynH#PrudYu5LcJJ)ajHr(G4{=a#F|NVAywfaA%^uO!C -z{g;lFtBJY2#s8>^_OGg5t|rdT7Oww?$+fR;`t{$TfB*e04FB0g)XB-+&Hb;vf{Bfz -zn!AasyM-&GnZ1ddTdbyz*McVU7y3jRnK-7^Hz;X%lA&o+HCY=OYuI)e@El@+psx3!=-AyGc9CR8WqtQ@!W)xJzVvOk|6&sHFY -z{YtE&-g+Y@lXBV#&LShkjN{rv6gcULdlO0UL}?cK{TjX9XhX2&B|q9JcRNFAa5lA5 -zoyA7Feo41?Kz(W_JJUrxw|A`j`{Xlug(zFpkkOG~f$xuY$B0o&uOK6H7vp3JQ2oS; -zt%XHSwv2;0QM7^7W5im{^iVKZjzpEs)X^}~V2Ite6QA3fl?64WS)e6{P0L!)*$Xap -zbY!J-*@eLHe=nYET{L*?&6?FHPLN(tvqZNvh_a-_WY3-A -zy{*s;=6`5K!6fctWXh6=Dy>%05iXzTDbYm_SYo#aT2Ohks>^2D#-XrW*kVsA>Kn=Y -zZfti=Eb^2F^*#6JBfrYJPtWKvIRc0O4Wmt8-&~XH>_g78lF@#tz~u8eWjP~1=`wMz -zrvtRHD^p1-P@%cYN|dX#AnWRX6`#bKn(e3xeqVme~j5#cn`lVj9g=ZLF$KMR9LPM3%{i9|o -z;tX+C!@-(EX#Y -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 -z96f>mFU6(2ZK~iL=5Y~> -z&ryAHkcfNJui`m9avzVTRp8E&&NNlL0q?&}4(Eko)|zB0rfcBT_$3Oe!sAzYKCfS8 -z$9hWMiKyFq$TYbw-|zmt(`ISX4NRz9m#ALcDfrdZrkTZ1dW@&be5M(qUFL_@jRLPP -z%jrzr-n%*PS$iORZf3q$r5NdW2Lxrz$y}rf#An?TDv~RXWVd6QQrr<*?nACs -zR0}+JYDXvI!F@(1(c!(Cm?L)^dvV8Uo&Fm8iXNv!r99BZuhY+ucdb*PN9(h#xWo?D -z$XvQfR?*b3vVpg~rQ4=86quZy4ryWEe_Ja@QAa)84|>i(S*0tQ6q)e;0(W+&t?|9{ -zyIvIQxU3VI!#mWa4PEkHPh;Z&p{`{46SLes*}jskiBHK`EFN6?v}!Cy7GJ)!uZ_lP -zE@f{(dZ`G^p{h=6nTLe~mQAhx0sU#xu~o_(wqlS>Y-6GPP!noZ=^ZSJj9JVol9e_$ -z)Ab&U=p`(dTudZ$av8LhWL|4!%{Z^G`dK#+b;Nry -z+Hjt#iX+S4Ss7LHK6mW3G9^2W1BC!PJFC^gaBf9tuk2IbDFudUySc>3<4MunKGV%& -zhw!c@lSiX;s*l9DHV5b9PvaO{sI@I!D&xIz?@cPn+ADze=3|OBTD8x+am=ksPDR&O -z%IC9-3yYAVwE_MH!+e;vqhk;Bl93=AtND|US`V2%K!f@dNqvW>Ii%b@9V0&SaoaKW -zNr4w@<34mq0OP{1EM$yMK&XV|9n=5SPDZX2ZQRRp{cOdgy9-O>rozh0?vJftN`<~} -zbZD7@)AZd$oN~V^MqEPq046yz{5L!j`=2~HRzeU3ux|K#6lPc^uj0l+^hPje=f{2i -zbT@VhPo#{E20PaHBH%BzHg;G9xzWf>6%K?dp&ItZvov3RD|Qnodw#b8XI|~N6w(!W -z=o+QIs@konx7LP3X!?nL8xD?o;u?DI8tQExh7tt~sO?e4dZQYl?F9^DoA9xhnzHL7 -zpTJ_mHd6*iG4R@zPy*R>gARh|PJ70)CLMxi*+>4;=nI)z(40d#n)=@)r4$XEHAZ4n -z2#ZGHC|J=IJ&Au6;B6#jaFq^W#%>9W8OmBE65|8PO-%-7VWYL}UXG*QDUi3wU -z{#|_So4FU)s_PPN^uxvMJ1*TCk=8#gx?^*ktb~4MvOMKeLs#QcVIC-Xd(<5GhFmVs -zW(;TL&3c6HFVCTu@3cl+6GnzMS)anRv`T?SYfH)1U(b;SJChe#G?JkHGBs0jR-iMS -z_jBjzv}sdmE(cmF8IWVoHLsv=8>l_fAJv(-VR8i_Pcf0=ZY2#fEH`oxZUG}Mnc5aP -zmi2*8i>-@QP7ZRHx*NP&_ghx8TTe3T;d;$0F0u-1ezrVloxu$sEnIl%dS`-RKxAGr -zUk^70%*&ae^W3QLr}G$aC*gST=99DTVBj=;Xa49?9$@@DOFy2y`y*sv&CWZQ(vQGM -zV>{Zl?d{dxZ5JtF#ZXgT2F`WtU4mfzfH&^t@Sw-{6s7W@(LIOZ2f9BZk_ -z8Z+@(W&+j_Di?gEpWK$^=zTs}fy)Bd87+d4MmaeBv!6C_F(Q -ztdP$1$=?*O(iwV?cHS|94~4%`t_hmb%a -zqNK?G^g)?9V4M2_K1pl{%)iotGKF5-l-JPv<^d}4`_kjCp||}A-uI$chjdR -z-|u5N>K;|U^A;yqHGbEu>qR*CscQL8<|g>ue}Q>2jcLd?S1JQiMIQyIW+q{=9)6)01GH26 -z!VlQ)__&jLd){l;+5; -zi)pW|lD!DKXoRDN*yUR?s~oHw0_*|5ReeEKfJPRSp$kK#dxHeA4b_S?rfQ -zk1-frOl4gW6l={Z6(u@s{bbqlpFsf<9TU93c%+c=gxyKO?4mcvw^Yl-2dNTJOh)un -z#i90#nE$@SqPW0Xg>%i{Y#%XpSdX7ATz#-F7kq?2OOSm5UHt|Q{{V<7*x8s?iFpA$67#;R!jG47UmO-r|Ai2)W9 -zemGX2^de)r>GIFD=VPn^X7$uK@AM=249B1|m1^;377<%|teW&%8Exv^2=NJSD-}DP -zw3=a|Fy^6&z4n+P)7!G+`?s~E~ -z8U&+-#37zmACcO!_1mH>BULJ_#TyR}ef2>K1g5q@)d?H|0qRqBjV0oB7oAZ}ie8Ln -z-Xr7cY&zbf-In5_i;l}1UX@`k_m_%OXk{hgPY -zWqwbay^j^`U5MbVJ&g0JR1bPDPCk?uARiz7Z0hrdu5m|y%Hd+Eu#~Y@i5Aj`9cU48 -zL**HdVn0Gj&~Mj86W1Zn%bf^eQUhx9GVnd0dimk2qRVl$$MKj4s#+W=+91O**E0HT -z&G#b{{)}cD3cZJq)r%UZRD#T&BfZ~M56z=>={dery|knDQgLarO`3RZ`gWRc;8`sL -zV8L_l=;41|P@DtM_??CZ7qHl+j&zxy5p;x?idVF=OW%>qf>ARM2C$ -zviG2Tq$25_a&BqovgMe(#_0F7Doq#!Xw9f$QIl13lUIL!NEH~oM#tD2>Iyo&iyzTQ -z3-lhQ^~jq&f)p -zt^oDS1}g))iuXk#qRh!!g@?o$^{QVo0J3HQx*syEE*qZs!|6bGKNq68dGKc-J~ML!7^tM3 -zHDqs?6C8iB)@F%-6qjn@)X$b?!Ik$+HeAKr_Bu61Wo`}#S6w{{c(g>Kh -zX5a7RScv6K*tgGk*c(#F@F -zOlDyuMGBfnI?EAXOaOz4I*1L=wbnGioWjpyHjbG}sJj@9Nf>(rB<#!6lu0I!=&#Zf -z&J!#?E_CBM(4azW&l!XGmZgh)28zraGP{gE@u|e7ajZna!r4n{EY9(*X@qR3+JS*A`ZJPit{@_h1S#6enu&Zey<}cXlBi*|4ikYwGvS{XrhN*&lqVw_>8b>i$8*^gj -zp9b)}z8W(-om#C3(=J;GBonv9UJEHUYWX+8e8^zyLgMzuqv6(mLh6F(Rl___ZW})k -zFNP^E1{e5Q$T<87jUocULLJ51RpU(cgHVi$&^L$1r3>JYXXr@9x6dqv(}G`MqE5-0G92TJJ>av!>b;W55c&_|f`c -zt*gQyvd?+mGXneGchD?M8-70`zNs_fuB>)NpMTOBD%r6mssj(u~F93hu@ywi=I#(LUXoXL=%=OG} -zHAxWM$FWqo%wzc=U%@BiTbr@cVf+NX65#k)Y*LbZVW_-XNm=a={jv6o`d3U{u-^*R -z4ddSMvk!i`G1jK!(OUwvktROV?FXq7s(@9s3Wh9&%gT`BA|KDGq@_Rk~k4y2d)Dyn5Y^CMU0j -zgaSde2dY9;Cda&sc4+csB50tE4JGwoB9SEP| -zL}-oH#_F6(ALd0AXVN?u^4$T>XDi$s>=O;uy3=k7U7h31o3V5jO{Xz=Q&@6-zKJH* -z3ypYrCVmiuwyt}9Vav~Og6!>0o)dY -zwAghtAD+xR1epi`@o|@G-QOIvn9G7)l0DM~4&{f0?Co9Wi{9fdidi1E0qtujR@kvr -z9}HP>KnL9%<~!Y0Td&fCoHD&5(_oUdXf~Q84RK}>eLDC!WC7MwbC2?p2+Ta%S^%^%nY1JX~Ju0BJ2!-Nwn{(|K{(i3>a23{a_GM2+g -z#ocB*=3U6=N(t$O&Y!f$o%>Y%)|b -zdaJR?3DYg7iqBhgn||?sy7(rV+`k8XLI`cXZ?!GI8|Hn?490(3A?B=H0d#5D56Kqz+XLoFDGusdu9|soq#( -za3H=g&;s{slaAL9?mRoX#fAgg|I+!eTc@L4cgWqE*SYg -z(O?BDchqQsJ2DvgBUT?TH6^b(MEP1b5U;NiJ})W!A4%p9DMUtTF}-`ES{VKcYp!kj -zy;q|Ich7i%{%XT*Hx3ZnxBFd5f6waPc%om2;k1FFMAa`afmJ(Jw2-%M!D|Gcm$`{` -zV(*ZhZ%CIH=cl}jZB`9k^;*QpJXJ)?gDwI*xP%R=jR)4*!V=+`@_N4WxbyosV#Mm= -zTdN!^TLhUwW*)sT? -zsz2U#+euQ{i+%m2m4*+tAl_;kwRMdRhU8-bQfhC~8_@aEr~CVowB3VSS6-e1zVtH1 -z{xDy#^mRho_Du{1O0h{st)q?K&s?`k%fV?0Vlr^H2&3`%Yw?vb`CCjSbw$BbQfzc{ -zS@zQ6&MRB`b?wPTol@QbgxO5UAB^b#BVOk;Gtn9y$Y_J(A}SK@tFCYk7N$O@wFSZwrtj1;eNLH1?^i)?`AW?7F^f -znFV^vo(oieB~(=s>%1i;2FKdM5X(d8&!Qa1&9U2puMx&_y3&qp7?! -zV0+>%PJ{cpHpviwnQox(tbTZtMHz!E@E&7#K|GTBcj!O_tdItpMSHHpfi8frRkDCT -zU%aA7f8NF(%kA_ws$y2Wv_f?VRDmA-n}oVuktDt9kg39A6ovbmk8RRd-dOsV{CpHe -z%toO)Sw%!?R=f1sIiDySN25GF*2+>LRdN{yF3U+AI2s9h?D^>fw*VfmX_;tUC&?Cm -zAsG!DO4MBvUrl+e^5&Ym!9)%FC7=Idgl?8LiKc8Mi9$`%UWiFoQns2R&CK1LtqY6T -zx*fniB_SF$>k3t!BpJUj1-Cw}E|SBvmU1bQH+bUL;3Y?4$)>&NsS6n{A1a%qXyXCT -zOB;2OAsRw^+~sO<53?(QCBVH|fc+9p%P^W9sDh%9rOlM36BlAXnAHy6MrZn?CSLC} -z)QuBOrbopP>9*a+)aY)6e4@bVZC+b#n>jtYZPER)XTy!38!5W?RM0mMxOmLUM6|GQ -zSve;^Agzm~$}p-m4K8I`oQV!+=b*CAz$t0yL-Dl8qGiWF8p6-ob$UyS%Te>8=Q8#X -ztHDoAeT7fv{D{vO#m{&V`WV*E?)exd1w%WbyJ6(r%(rRlHYd$o -zzG@D%fOytxTH6x9>0t~z9l7@5tsY$mMIQu)lo36QBPpRw_w4%|c`&WG -zGCtu?!5Yk-^f%q)ZH}o&PTZDf@p$jzG;sg8*!Znh!$);w(b3aQk5H|ZK3JH>IDuKrF?u;9MMP+eZlFtt)@x>V^*f;e2q -zEd#1J*FqWpyv}~#Q-{oaL+aFd7ys)6owbL+# -zkK7-hTnM9YIZ7Dh^zUAB1}yk=#ISyN~{z00W#qhK7(x<89H_-!^5-By8oZiHe(q54!M+K*%$*OaMJ?umW -zq^7*-A-JfTHV6KLlJO%rW8MI+t8VsiCr+0a$xjc4&F;9gr8xtH3JJ2bVwmhkLcY0> -z9``kl72$3B5RnrZeZYDHgjWFu(|~5qNGf-<=epN^Tu_A95aJe@KWE%rzD0&`j1em_ -z((N}Mz-!7qh@*Ipwx0=UFnK^A*dMmB(iD8eJ#1BF>gwFVW9*LO5k&|Oa@c~DCpU1-i`WXNZ>=Dg61AJ5OJS6K*m<_SA#8jB7YEB~EzAaYw -zqG3Qm9rS5gWu021H`E|Fz0*fS(Nkf%j}2n=cW%1DA<#$|v+Y2;rOUe&IG|H=Y~)rz -zfjqsJ1Y=KazMMQ-$2l5T@1DN->7Kjjr^Uf(*+>&TrK6uUY|(WsCSeY%2gs&$9@ZJR -zMrg5Ud^Ds_{P{DrSE|v$J8=Ied0o~|w&~9C7NwmtHee0J!_;9NB^@;wHnDxgtjMA< -zk(!lI@(Hfy^*6miWP#4_L2bJ_8^4*oXGYw9+3;i;WEl0v8`S1oGRwX2iPwS==(t}w -z`h#KsEe+y$*E5IsNEH@stkeqlq74Mj%UL|-Vjg?=quBFpQd`ks-lngBGrl@E0ajxH -z6l*88r&oyYSnW|3vxCtOm_ -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 -zh{d?sxv2q%V&yE -z7sNFCepye_X;G5W-1!0rPwz@;cIJmiWJEuE;aCjbRHb&diNhibHKBCN`P@{e#kg1J -zf|FO~&4#?v^j@|#`h55rgIHUvFPjZp?rvp2<}*yVXGSiKT-%hmzeMG^JDUmvCyG{! -zRXkg29y5(K`ZvD`d%3Y^O1g3OEeay8i!%j0T$WO1KUul-UhC7QH1!x8Rdx0H8C>-j -zTX(M5D@$EheYzREX4o8zU418AoI-$yCc%;3l;bOaAsDS#FO34@3v?r-|4AMFXbRQa -zaZH-F)NpS9oYgmTWypw(e|0xuCX$5QvST4x(r=vgviGd@C+T->Cr?}%Jx$Mu1voZ- -z-2F`&Ja+^EfC>Ny)S)sCG1zw+s1X4K3VIv0d6e-pdr%l>aY|NcOw-P0tlF%!-u|*2 -zWaWEna%d$<1OZ^i%sbWiniZ&}T(0|)tvY6I)=hk%EQIi)ZDL@@YjS1A<*7-D_SXAB -zKdn`CSj8OxRhO<@EtI5;4ASR%*=TxobXhgm_HBRsR5z`|G8XIER6JD~UGNzbAGhVg -z=Rd~l*_7;Z5YI_8UJOH5U+CUVsI4+;tMP$Oawxt$ipO<YI*=!sJgS(0Vg^3FY!Tul0SP`GHNvf} -zTj_``#*I`Es%Er$Jdh-un4Yo)CtoEH?5lWoXq4EaAOjnwI}<_V&w^%{)7sU;t$akTX1y3>xI -z8W2y3+F&9y>r&TrdySH4=Diz~Rp5}eNJHoP+=Vtp=aJ|}$19z;cUVL$p%!ZRu(kjZ -znG9*8XM}=>sj{`)e6f(+bSU*Tb6UEZi!CA+?~<1^G26ILHzc~V^0X)x)P3^|l~2Lm -z{8Ha+giG@mnACl<@>EW7-}qAN%9tu1parVt340-9l&S_&BnoaNIu%Pd-D?NBGHNWf$7XaKPKC(tRpUnc^Ji1?8I? -zRw>D|HEa-0bG4e$bfKEsEgwviOJ&e=v&^| -zwL6u(JEW`S$!ci@5L-EDbUD~y_O*-1@X-<}vK&QP+&RG{@jXuub;DC5Y&tFVDoa)- -z7z(PySs1$J7nRk1TMv)zy(sH0mf)w5wDFnUKDj$+?Q_GLx9FA&G=M=NsDM=Tklb-yHr$E86dcog#XU8$T#AmAA~)k;HfV20)+AT@~Cm>w6;&L&DX+62r*tTksz -zK!4JP0H#_p`Q*KDV5a&5^qMGYjYR{0`h)Pjg|F-``XfpDv5CDtra`%ETxZex -z2T9|@+H6bW@2v6qiI&xT!v>br-xR8I5ol*)`_vJ&z5$D~$sueCiv6g`&b*}47tYKp -z#iI_9Bj`uaU-Kx&PWLnFf#KT{ -z2xmI)6%Tx09Rq#JuL2^YOs}6La`BaO>R%ZClYN*MllYf09%NB%Hmfu|e$pQ|!R-)w -zvqYz8VM6M!T>i1+eTVCbdhtC}1y2NLi3w7VZ6^mxV`6z88|jB^i{q-rY3!WiZeK8l -z&;_lp8QFHIBF|s-v -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 -zGMag^=DoR4VXf5;(XX{L^JahaU3;+(! -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 -zE?FfxUUnr5^wV1gN6sa -z`)bnaE5W2;Ux}pAm(|pN-J+>GIHDK{qN@U5azmFYu{x2P_>(P=Hjh4Y=dDG6wK`Ze -zZKScYpM)AG7dMYil1Frsedc}sHj&&9n$gAmE`q)#xBo-9{vT!{)c2tgXM%6e)8X7V-YP!W{Pq1IK~GjN9mj_W*W0%G8^W&-61a|6T17|YgrDbRuiK7HHyv`n)D -zcsnr+Tk5fL$&C;C$6M?k*KH0*TbsN-KA&K=p@hH?7bh#s@V(K1IMYeb0&eU$ZaAPg -z!ojYCk6P-+p+|Qm&>EZ9w!w?R=eG&^HIu^Q7A_Ftte)#<*&2Py?+~S<(^tNE3pYWA -z9DQewZRRf84NJIU`m6O<&+f^~@-6OT<_IoBs7LP;tWTEr}yxP;Kd -zZ9{2JHfh@94ihcN`D){gE5DyGT8!E8g2f_;vFGZWL;b78=PYR!xv55?o~h|~{Pit$ -zdM0|ef6ya$o+Kt=RFVgsv->rZnH$mRc-6V-ws*14)D7EKoN{Cnhxk`t=$W(RkNt4O -zqo~@i4YxpV7mzCb=3nDMW^_9%<29&0TI()~_w`r@PdF_n2|>Jzr?QFd;lg5sv!=oa -zFLaOuUlI!ijZX+I1~OjQ$;xC1z~mwPIpE+Ibaq&t_I;Z(=$)YJ&|+(Rb&LPmz$hr} -z@=2mZf!(z5V5$B_NyH~`vWrw_)^jiKt -z7u|ImqLcbY_>RBDUpW7FL0>P`KCBQW4<&XXuy6pX -zs7ZV_Q2`4EO&ZkP@`4DXZ^npZN{a3e#J2Xhi|%@gyq2VD&IisXtW%D-7!t``BC&d= -z!&A1`>(iF$bsF#2=OrA#bpie^A`j|qSYU+M{b6*V@qM*$kWd6oR1gRslZmAE6yHwMT5C9hW-WyH&eH -z6nD^lj}oqaRmm%5fD3aKpB**USFhMO`M6$sKAp0-%hW!f$$eiJd;<{5IU7I#y?|&I}O?pN-2SH`N -z@GPY5CoEiKR!kxMLK2eYr7L`^yPUQ3XkE)8l7@A+ZrzW+gO7Ae`0k&yvESb6%Ykx-o7o -zp4p{?D>=FsjABCKM;|ldR>?2-%#Zt*2-8B)LuX@*l|2l^PPH( -zgXv(lTB-qP_91_Qdos1YTUqApbB=Zdye7|Lioct8V?zCb-LCfO_2X@!oFO^D23gvN -z1zXw|3Wo)A(Q$_n$aM<$m6^Y0=sSobOf}cAB(Rm$e={Xwl|UjBSc`;%i{IP&BDe-_ -zJT}~@3Bdm`M<0yAQjH^M@`7OL*xGXg)TP;12#;+?*NzPi>fPs>IZ|gB`CfO=SR8s6 -z0tD-yAVBt$%kDhvYDafGHq5n>|8SpO&Gy -z14?ny>;U5W5o-ykx)&%ZHgImvf@X#Bd&!KhyOzjNll -z$(R4*NaD9Qb+Z08WBHZ0 -z06*&{aAzQe;z2-o7~$SO)FXuJzxB>2nD35YeK1~y6txTZG5E+Fi}3xP#`GxK1LPc!h5oNTxiU& -zxm5_t?E}i>kZ%G6M?34$F?;^^{FM~H&c#P~G;sxs(;=+NV;OzL+*^7P8=0XtBXk9W -z>E;QBTj%e~saxc>oLcV9#$WnB8tOqOvic{=!eK1!=AD;${#H|wf`~z5d|wsQ@2m2? -zO8NJq=YL$4zf~_$^3sz1eDGfLOG67a<)qUDOpqcq(&S?D$Uu+~TP>&UR^qJnn~9$+ -zaGwA^iLKIkAPE9!$ysg<*WX@X$Is_jJ={|`jyRc!nM8_E)i8P6P$gEqe-g=eyV0vx -z*$(+3JaA;)41j7N5jbMT1AQ>l%Gv@L{jtRJQb(CdHx?n_B-D%=l?c$m?66&*5VJk> -zi-TyHG72|j6;8Y9xsMa%Su*IEA&S=88qRSFS-PsThC+~q*Huvr!W7I-dOS!U!0fs$ -zxGJ+05)V0cWf_{@(1_b+-66ELtJMO>FQ+nU03UMGwQJ+O=W)7KDb0~IK-P!7C>Pt3PaTrgL-PFYkbPD}l0 -z?!EH^s^g*Run4YEv9EB#@ohlR^o{gQaLrp(#b~u&vN$1ZDtj?|^Os9E_Z^LC+lOE^RNe{G1&_l871hFmfJ;cTU^{uPq&^p9MFohw%2v79XS($$< -z6MiRQVZJNXQ0}m;DA{&YFMK(%-4ZgKq=@*C2cl8M!AY`u@(i=LXlKO{MYPR9F_Wp9 -zz;L1tlX8iHCF0XkH%^%i%p%oMF}5aaL_evUfc&L_u{dMa=?`MuHTYUg<^}sSk_=2I -zLJT_w`I#{{O_yFVvEWTb^%;rgWYwV2N{fsIiO_SCu6n+#6){%ub~DYSxymal3APRJ -zwfcy*{3=vv>J-+8jnbyZ!t@}!%>|Op5gWu=gw2Jl1Vn{XfJl1LhDA_8EZo#Mc#I~< -zbTSNC8Kq=YCJ&7cq@Jn{i;2=^nx||A3pewo(+_VzExBsN;d%__J*u;dzHBtZ%9^|w -zNdZ|e+vXnN8LAjmoQdjHl?8mAh0IZ9AZszWK(fXf`DFqt19|G4r&dCJG8}@b9*r}5 -zE=QSIOKH*fc}oUGAhtAn(tBPkqO0OX&+{^@rY8GAJrhlVU(-sC1-TGlj&m+q4F#vQ -zHOzTZh)d@EwO62Z%_TqBa5XV(rW8Ldsu!MyVj_&r^UFt2?UQUnkwO2 -zkgN}%kXr~fzLZ?~8`Jsz{&&Fk8(F-+v0g!|WkHuT{N(oYeNLwBA@J5%wSzPy&6~5j -z_Yg6nTkIXag|{dtfflWCw!j#d;QEGQBQHPEJ>wELe`9f617)aqtGz8K4kE4rR#5A} -zeOTB8Z76g#pLzd9fzRh#*w$Lyz5|?r=T+esa{EjK?ooY)T5#AQR}sBNhfoAGb#UCy -zb=n74+EIq8ZR$%Xq$nLo>zoWW@tt8JO11K&9dC^)c~)+Ug$nys;3Nm&Wu0ZLLj+mk -z`$n!Z>3Ii$GAZFgXK+Gxf~6KHIC}z0lIz7WipwG}SEilzqtc{jW&Ls*rb^!Fb6vK5 -zf5%h_xI-kS{(RhO=zv9TGhePCS2mR1)eVq1+vdXPn~4nU@0WCT_5k_m(Hxz=HAct! -zQ|%&IYjO2uJFl+C%JGq;5yHaoqy6pkp;|5QDZ6 -z&c|9nnZuy8O^Urb&LQQDy*e_@Cq=0gyB7qn8cxoAl+LUUk@hlOA=qw#V(&39LK%OK4ZwyfhL{fvcHtwA*fLx9lBBH$05y9P-^z#34vKTAS}I5DiQ~*U6TuOJ%Bi -z5NYue7VChNC0(tMi-g22zQnXI`eEh5vA3OC~T -z$%?qbt~z|n3UXydRHK4ibh~<7Rp!NxVYA6QUK5Kl -z{8mY4G+`iTuEE}0oJFaN7Lt2IJGgnkQjwlSxj@gPStUFcdM>hQ{PsHG~*L<64Io3b}Nj`)Y_#=KmU -zR)^Ny@r4@(%j-^Z6t=7u2Cf(TW<6<%gn%TP@nTn}H4@rQEFko`>D_Kte}wwrt~=VH -zWF&0>w4cTleJF<4_y|P;MNMinLk3_rE`)bx!j52tuP7o3J+YofA2cqbBfD{c{={sY -z=~{d7FU#RXK2zePK*`n#oQ#4srw+YlAWu)Nd#q2W5sGJ$<-actjffCfTGF?^E!ELIx_h=lc&-&GF+OAdpvn~Wox1g -z385v*+Sc2KHPA+OLI%_d(GpYefT}H}X!fU2Z*T(Eu=+S;RRE&Z7Jw!F|$#V^xy1?ELq}##am0`3V>nS?DyB -zKOac`ZO%PhK{x|0alZcXzqj=-i -zz2!E|!@f9oBdH&nG7T+Ne8zXKK|^#uxrlIzkS){XJvC!#VBr3NGBnliwmm2{hmV -zS14R%X=eCrCN&6XRb>5&Y!3up0&)C=JuD8qU8vweK>?4m68eC6Bb+`FRuF%@ES5gF -z0bw7ZD))rUQ}nGZ&qqYUWaar3pcVs2(s~)T79Oz3F`6jo;Jy_-?^=Y}GTy>dSY*4z -z!af+nNS!jdd6?X@e`y&7+u=00wl&h~ive7yce -z3s7jMJET65m2aXWg6@Egfq{r>Otqr{AlW)~8+G^pTGp;4~2sHoncq8PQAX=B!+Tv4r#AwYW; -zY(q<5DeK;^E6R4X$)aUqk-oK6e~m -zXZ9*1xw%-=>Gup7vljyyR&bvBYPm*@B}m3S5ys_Ns0=0<9^dcKc{kKx{&}*Ma^qvX -z)pm1R&ndct=uNdovxJ(g(GB3oAI!?iQ4-~Pn(gwVjvB=sWiBryu-=R1;HMmaW?L9> -zxWW!#H$c;m;G`8h!ED%ZEfOfUBki?LzR~2rveZenU3jf)1xZhOg*{x{8DqqS2A4d5y#Ka`ev$H8alG=LDsYATUVVEkBN9iD8?ueFoi4IqOeit@zOiZ!bv0t3rKA -zmsfylBJ16Is^eC2UKh6SkIv#jA<(Hqp-!FBbNCv4Csh!$1$qW6n&(#thxZQdYCTM$oEz*l?thY?mWbDv?NXFrB~6ERl5 -zXzR+u8!On1XlFBA8M0I^ef-Lx@AkC0DW+;M= -zTYF5e!Aau-=M?hCXdffUGu?wdUS9r69Cn-z{(*bt}3ww2T^M0T$OIy -ze$*^FdbBynetO9>MpMVpS;FOr1gU -zGX!j3R~l1%+)s$&86>giOB!u3=!0KFc!CQ -zFt%|pcl>rEQv6;evoZayYHjtuX@vi26eS)kGGzgUQsz#WS96 -z7m(S`fNylXUnGZuYkqVI2dr{yWkGpCalurqjks#Cb+AyI{Z#CQt6*>KY*Mu=XVycI -z&(J%pFr@aco-BteNvD{A(VI?a^d}B3_+~6{*4Vrb#Lk(NtJZyKnzm`dX;V7uWfbq> -zUH+eByH3mZ!%Hj2f}(1`q8fo&wl1aRUHjfY|IA^Ikp%FB+AIv|w|Vr|v>w{JSWU)F -z9*PYXV_!2QX0OY+Cj&$blNMT$i4uaDZ0qq}>W1>KXhkbo;Y_2$?=F{HGA-6N!3{$f -z`S3FudDvgv*_J;ve=f{0B}PA5id7j$S?4pjZ!O@3vMO};?J2YoCK>hhP$P-fN@4dK -zjBFP&)P+&wFpZ^ry)*b2=0F*&XcUF+>U}h#v+OUj-Cxw5zX~jxuISW}SdiC4G4+3P -zxTgop;Gr1LnkEMp9|^H0*r2Mf0ThAOgQ -zu`;fwt%6((N@!kg>ddgHc+`Qfx%){V3Un;!)aE}f<;#9OxxI0Dy=~`IahsYre~ZD^ -zhVi~1XMFFzZFD)jPhAauW%~f~ac(8mfx1-Z65|&j86rwy;HyQ7-`%vdogtR{kj`% -zG5TI>)9HA4jrp0gtbhadCW6^z -z!$sT@f@TEi!;)H`*=60(5EJ8;Y3iHzq_g91k_?{^zP1|vowM=UH!dM#H=dIJla -zF_K -zL&QMw?QDO+ovLTHZ%XdQ6IypP-p}=pqv~+Dt&Vx=K^Tzf0jrEfpR%H79-ZHrX|S0= -zKIN+R!nDTak%BBugw(G$Hx+D{zML#WI_HV@s#vMo;y9D7gvF4b2(vV)cd-ZqjEv8B}fX|wXHRa0f)wLPk(r;WNJ!P$bJoM+^5Q;o` -z{H}1y)ciQ^D%vU9LRINS*jpYK9df{Sxd4*eRJ_jm5STa*#+EmW8HqI?TZc!S*)wZQ -z^d6)_!d03}FboiSfu;h3QH1o5|=T9 -zCNy~3e7MVkbkZSt#a2E9utvLm+^b4}HDO1;HA3!gFYM?fAE4D?JyF2?XtGzmfl42Nw%w&}_f(q7FEc{;6gs0xXQTL#Zv&4t;;Qg$0}`QlAYY -zye9fC=pozLfb7#gUp(q^C1UvN3)3A2lL)kE4;rK1PhU@$g~3x-O{_eHz24dlY@Xe2 -z6ogtf@|g-6K1La*>S%vuGSQFyaIF$~eMJgO>Wk5Bz9P@GOqhDo?_ZxF^NlRu%b~N= -zHrlw!;MHReDyKZYbD863b;S-8d#xB3D7>iwO!h?;Do#V&-tw`tXP>cE&18Q9G)?@^ -zeauxAt!d&@MeLCAUNO#7@~ieDu6YC$U5bI%`JG+&QA$y -z4lqIIx+OWn6QR`eDKOnak;>5r&!6NB2r_xY7WmzC8YR#49HndW+XRY=NC^~m<{8PV -z$U%IRX%EjUb)HbFGYq!S*aoRIp)yyTh)t*qL|O77HNGo-{B=P~mk$tCJNbA$b-_F# -zW%R@cS6hmh*rXrZ__-oNgDcJ8hinav_S{Ob=pr%#S#04|N3y>6_L-H+;fsI&2t{X; -z)|-L^8=X~K$XvfLfcIKn5J^7vvam`$O)$|Ft#z~1#owvzY6R}?%nUZl3K+uHL3iu5 -zy8ITKxumo!mU8STW6#fOk(5I-IvkLkF;d@iFKf!0S2=ycVY|~{zr3}? -z&zW?>!oTtv50uNZ@iO89Rz;2Mpjkn7Pc=S6RM8aenDsNRu(-ocEmUy$_UL`9Z%&`( -zpB3Yn4F0ys6V9X;P*aovs(6c{PZ-4Z;e~05F#*O+ixB^tMI4xwAY&8kI -zeoa+TBbSmk8;G5;U=sdW&GFejlX}tm>)HC#EVVa!(3^sRloS5YinhV3dax0?GY1es -zg&Pcf-$>Ot>ozdT1H(T~Un3JfVIN``c|uti(o=P-$*)!TKAUj|^$UG}8O--q2nzQT -zVE%dy{+nxHSu+O*z>M{eIRap3{ZA8w^muLgXI7?7%RKpp6MVu9d(b#K(us -zkDgJErBl~W6`?elbwzOsZH>O=tPlH0jQ{q+sZu(A+ao^vn5nWNeL#Rl%pby*uAXay^Bt8(jtug3>OQrnYK%lM{tSF -zT>e)AkSjXOjaz&0-CAF&OL~h(sS9+L86!4RluPUsD6xgEAITyG5-5j431P3%x`pcS -z1*~HUtBsW@G6l^V+Ekb3jtV`N@?tltYr98ft+C%Cz!M+C_)p=w8FEAt7V~|t(}pY7 -zILr_gm!~3C-m)s(r|IX(%Yx2 -z5WV6=H0F`3Re>OxYi9--JOd7|T!SEo2H|4%Q*FgWJ>zO#`tWbH`V|E*iG(Yom}YlA -zy@aY}YI6Q0V1%56T$n^hd}f62$-W-~WqWLpcira&4d58!k&U}x=$>R(BXCHXIEl2exk5xgzD-=-iNx5N{1vs4=4uofZv)U|J(Fk^z4oP -zHb*W~K9WNQEZpj~n~t2TP_w<(A@mWOP@q`{3Zao0N#IguSUSDyk2KKho4+2^8o~bX(nh)rHF23j*X2ZI~2HlJ$`z)e1!0ED3O7j>=4B%u2#gsIMa$O{ngWDtkO5onXKeo~SiR!2(*bWSniR8Q8DoYV3KA -zU>r~QmA}5_Pz&D?ygY_hMc1KFf#SZ)9;>9W5LST>t9m1YB%;U3S!*|hz^(Ml{o`I2H{WW3 -zinC^pv9&)^`b1|z?#Ukh%v{z6O1(Leq%u5G^ -zcT`vdQk*K}4Ic5vaG -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 -zFlIdFhTGJk#^RJH!Z+y -zKunFVq!o?m&Jl-&j_q3XZz?TB+G0CHs2^XV6r*g3evwM?L|8X>4@`NDWJ#F}75An=>g6@2F-AEdS& -z*$1dR%(wGy%$5(kBM%9s(=y=1Isq12sh0?QP^-Ir^^=i+Sl5y80%ap%t9L -zi&?s#samWIWOSx5j3MqG9X6_rzh+;|)NRpE3_*wDooJ)tk@bc?Re(KbG`!{bdIS31 -z1BsL`P&wlRWSLW_GnAPXk|N?D?lNHna-*`LZQ`C$bT{u*_zXPaxbp{_3Aym?386EX -z5z#w3hJ~l${a~)%w~HD3WM4=Io68K?>*-crX)#7@y)riA4+=))3l@(~>&6&_1t_)Z -z#?_d`NWe{5p}rCM%Kg{Dn-&4A4}rr#O7|F&L>S6us{GWsM(i2~!$v8=>` -z%#Opr_RWJCLzW~ZDas1U7{R?+pt~tf(_xABj{kNujEwIF;zk^E-0F*=Kd9MM2L5&0 -ziN|i*(weu|6R<5%zZljM8`HvAj`?SR -z__19CQxm3*49)@_0DS+2x?r -z>06*Bp;)JAOg15@ebab{qn#S$QH|jO -z(iO^O!CvjVSk&s{t1WD5aLXs-n%JR%stkExwQ^uGWR>66vFQ!#pe%Gszy(&jJXv@D12#52Sz0~r4#z{%96Lg -zqhwyNX0l{tAr$En{g-%G;be1BuMpu>5tk@L$wtfyvc#H)*7;o|bHm<(RW^a*Uu?UXa -z3lppsw2?c)CtnqrNe~S-&DJUk&g+?0#VP3CYchw~H7pk$dVoe*5kMRgX2)lXNm|?+hTKYN~hxY7X(b -z7H{yjak-+Rh*JGzn4b`t?m+`R#n|ut_^wb3_hd?tbb(BOyh-T{pQN-XZ>bezLUK&( -z=o+}Bbqpmp=4;)Fh`QQtTg)$6){Qtmb^;~CL{-;)97rWzKXKA+1aA`^y?~uq3twTz;S>&bPA=`232aMarn%@dCRTVj$@T68BtT%6%u{0gRcnVRGNQQ9c-; -znX5e*jBTVHM3{4pB;F^NuBhjCS!t<|AE -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 -z;#-4Dh6*2q)td!Z$($`kRqj? -zW+I>W(D>r^ftlL5YB{B~py>iw8^BV*2?yoDWdATY{PjkX!YNsBqrYQLGW2+cVYeBio|=nX5!<-4LD -z?0^9zbb@_#uuo5koW|r%u)tH6U5-(Mbz~@ulh+--(sSS8C!cR&{DwP+SgX9`8cc2x(v*I$pF#<# -z69O{mURS_exUF*ixxB>t;P%i7^&0<_kOAqfd{;4gaqE+w3(?tj+-JLJ)kptg+BkPU -zg(r?i>dkA4iOt2xlf+XC#>UBRQ+0l~l*pL+#2TINyk!{6VHJ@Hrj!wR4*Pr;u&HUs -zg%BYqB@oD^Y_Z~#ax@3|T9wnO?RPZgnT9jZ*nEA&zS3G%M` -zsAB!O`vRjepy+_$VjKk9g@1?rQc+Ox%jfNHxk3dxT)By2^VflN<%Y9&g`!71&JNV95urO$(dgZIVA^bV2d5oW0(;p3Wmv=W5)5TnpRS#N#@6 -z9RZQQ2C_-X%Tn8SaD6qw^7`;qr=#eb{p)S|XghOY -zDnBXFa!F4%@j|_=ymW7&Y#J0VI%GigZNixermV;WK2_=sQv=Sys<2!-Im#Wv5gEbQ -z*pZb`TAXZ#T4hbinL&!Xr@AYG4mU;{`7xrIu>Izm2ruyBYYGwkw-D($3?H)~KjzD2NN_hKVf)GPa&ppC_pIjJ{kBj6|3f@r{H9mOzk} -z>rL2FI8q>Vv|w5g>FV3C`gZhc%ex)=_%V;9sbJ07jX_nie%P%wS#2%Zn}Jh!P1fmL&=)Ab8Oi4$sd7MWEv}pn9`J@+9hY<)!gCYGJd?evvqGGwIt5Aj -zuK8F~Q`C|;2Iesbtdhw33hdzheoIg&O54?>eNs;5SnxjGCp%RNiy5G9q$>`})&Rj4 -zwp5tFQRqqqiIDJiiotDt2K5gkbCz_CPs^Z*PE*nXHFN}TkGy;eZan2Mro}IHodd`a -zWaKe;JijTlS5$6rl=-22s?=C$lX45a)|-N!*X=kOzdZ1C{2;w&LPW5gWg5pD=Bxt+ -zp1(q}Pg*k_%Ht$8wB$Y$7LDaS%7QVA;vWpV@;PhhXE90DfqArsdK1Nej{JY>k#3+sVCtZjI_Pu-nx -zxz)PEo1eUHj9A^!zMxx^;@?)?>wn;S43PJeMp}i>(dVGl6`co4A~kd%yk~q5)50pz -zp57*GL(H>QXa>|w&UnuqaCJQsIy-Sm(X}GYYA75BQ4I&?g(d&i%no*90leXvuQjZS -zb^TKx$){K|-&KUYV8~l7uVgO~elet*TlG6A7TZb7Hi*SlG3&!au)88DX2}#zQ!8HY -zgsJmgAZ5)tdIsZjSK{6+-n@J|`r!|EyNRaR5ZW{HsvXJ3t?rVy7TdI1pQ}qh))k-jV-yO69_rjL3l`4{f6272Y#^mK(mn -zc_szeGfe!FjVY&RR!bG=BIq0IN9srHtFPkxukJXgyd#|Q-k)^W0izG^@plkIEC-IK -z?`Ku)dHc@=-5~%~i|^M%MOg(K8P1ar9e|K0G!(Ch9)CcXEEkA&ca9JzEFo72ySXo_ -zEvlrA2FmE$npu?=RN{!)UWz$i`n>z`tpv^Vr0_;JREh-Ks24lXeV>=cGD*G(z0({7 -z%1z$ZbzZ0vRdc+~u>jJmRTx+t`dJp>HU3G{J7$7M;S_mqUn{ko=LuDSK$}ziM=9 -zLOXK8$P94iUmVYA#XA=@ITbQ`OgP -z+{{?ga}A92%m59(YwleSlg26jr~7_>kQ;_o`7GohSZ3eX;b_|m33imepPDOsa*4X- -zvU*pF$f^Q{CAB)MU3rMN)G;%qvrxr=m(H}1G670|^wwU-bHSqo_Q&owvfqrv3{u7s8;jR2J#T@JFshs7C>lA?n!l(-t&;=X`{un -z8N7)MI5Pe+C!1?;=r&j9m^+YO6!tBKORe^DYQ07SFM5Kh1RZX+Tq7kQHsYQ5ijgF1 -zs6SoDK%5yWL|B3bg_-|3spqNPY_Vw|l!KiDE3{%$cDg-HWH=(Ha$QZR@xrl6{^U)m -zvEoi=UpkOKd{jPdinK;2gp`@8r8I7R=&b0bLvAg+iBtvTUMqGTTW4ehAX4$8dekk-#Xtog2YFyP_2Y_UyL1oaV3-B)~DZ#2U;QX_%>u5adkxyMB>OY -zRjF03V8DpW-!mj|SK* -zE+$jwz-CJtr>zU43GlGl6D-J^tDV5O^%A5OTe|BxT3Zd#3TsHqwy#aZE2{&v)`Mk% -z@geIlaqb%7L;$KP?;&bYS?~9P8e__pOHRUi-Dypvm+!lI-TO%M2{|j15Yge7`|M -zeLXNo7wA5f&-RqM#Rh?bBLD>HSpAvHTK!u!fm)~dsRE`dYKy;%k%wyM^{FQqe+L4o -z;qg~?<~mjtlm|%ugfnEe97JsyY$sj -zs3Yrfey9(As^ese{w|_?x$B8HsKH_tew2Vj9zeH`tSUwiVx8oSh3oYwehf}8mrq{Jkh1AxIFb=;?%0F57ww}PXee0cQbBDAE<}02D;eEpV3pI3AK_Ke1P{zZ;3tgh(&LWlR&@VsQCDBI1{RFrHBdE_^&5 -zZUu)8XQ4tG!7+VrTZh@=Mn2)c05+|m^nnp&qE6n6Vc>2wCt)~6K@Hy{!r$_|gp|() -ztFAa~&jqxH0MZg6B@ecRVs8Q6k%D4GX=`E2O^#;6HJd?)O2JkdAK_HhoZMSPJPHjL -z0m@%1@RYFp%ihx+!F(`V>5m&il3TuT!l7;-79R$~_$zKL -zZ6`*#szCis@R&!7HzYE<^Odq)%4vB~F{i4QnT-)D-)i8*!L5l}gWO4A#hY_7bi^bg -z_3v$IuK9?xtI7wkoCEBfcgEUPj$2&P#{w9;c3)9=I5ThKK9sEq7RB<9x-f0KGk&;d -z2-B{t!lvK!Y6*bVA(PDIu}gdPMPfrQoG_?xGEDrG@u@$Fbdw|UwN12wV}TCg(rtn1pB)eh -z$#5B|dKz9o`;=S2heJ;BE^cugr+m9!hWudn)fnn|gBy@yXlakE{#s7FPwOd|*pD~( -zi?Go5q=@795Fb45+EN#s*fLj-TAFg4N=_Gs(%W}!HlHl`R_@b>_JnabN%lk&P!mnc -za1AHANj%e>oYPR`>`hWw$#~E}O{yS1Duz~1iQzC2cPVC$Oy{XZVeSr2%Ls++^`C*7 -z!OSDl)QsJLX6E+@9wK`9aT5tzH9n;dq@f-%-9ZScU7E>oKzF5!xey4)ZHoFVvF85NlH5q5N}D^>7lRC-ap5@t5~c-*7KDuP-qh%N5>&&rqfLa -z#3NJIm72D`-Z@XYPQr3b0?EmdWUCV?Dksgs%fc4*m5&fxp}@PW{sj42EZXQ&Yb~mS -zN&5b+HZba%Aed;sAOp~fFiQ*QvGuxpRZV?&)uik2Wbh7bpur-P=`UgxiLNBXfy_Ng*80y#Km^8=KyO+5*_X -zB>i -zZG^eigMOUmqDAzE9w%$N$@(A_CE^JPz8ycL%SVy)NKWUxPe1Wk<794s_IQ4!i%3mr -z_~wm*456P8!W~0q&Q4Hhsw7Qblut$fx)T)$ajCssRVI)O$tH-TFGi8_>p0UWtC62Wf;W-bYr3?=a<)NOd9Us0*^ZTTptf -zS$hz-tcr-{J!x*~u#39HMj2DKz-nyGBtGDP5$?wA7q?AaXRsI4{f%tiqF~}3Q~%DT -za`U9FiuPM87G6C~B|0-(8%3-)3`z89i6VG%uSL>$eH~NMc+p!rG*V^{s3RxMZHE;Z -z;`l$tM8=lF4L(WB+Xpvh>zhwvgB2C8*qc8zM&V*KcYO0RoMH&j0|O~ESH%fFk{-mm -zi=MT`{R~YeS5lrz#-5~pnbbeOI@d5R8sfvETHl!Z*^<7#`^q&^{hsrgiDp1ZkqXb; -z6*Ptit4q?Ye3FTGlEux(5lW-WpowQijy3K~q+5~F^y<0KEy&2gJ#qe1aN<~G&~XU$ -zDp;##VSEs^c-1QB9YMUKxS6iDKlJlpTS=F;1xu@^%v9>&gny3jAl;OUj~pT_k(|3Z -zXIUcUTd_E2fdW^^eAn=SIl`QGi1&xN6%$lzgcQVLoWwQLz&z#pGrRcRwNWLQ_JG_t -zgkC80!P|s4TWONU&o+!3ZiWwI~wrGy`(>T{IoC|DD=qrG(sx$@Au-z=bR>g}` -z1|Q)#Lw-RnXCKp$<{D`?kPA+#>EO15TyD#^mL?$)uO%|oUPoQ;;g<=q~fxVNA+U1RjsmJuZP*6aGdD&%$ -z*vOUo-WS|5k-g--v5$MC^D;Nfq;be|;E_mYk%5soRKf2)eA;Q{znlx4Amilx$u8=kvt#(>A@JzxRX)#(i% -zVaws4?gF7vwZ@^uU~sN=}^doS*iiU -z| -zjx);7t**MxOU<2v(!o|nm)(f25>#4+2JS{l&2=y*^s+t9SOiQd3rG|=Pdp2!=S{yV -zitpAdDXVf*uj;Zsd=^f@BXifX+Q~||vT28IQ$PTt$xL#N^=poYe%7KT?JPPmUzC}c -zc85v`&dYU$Vc-vAIh)m3$yCVk4)^o|fMqX~6xCOQDtIGQY6t%zYQ{F`S -z8Xvay>|}aJTCh=?9PT1hz`t}k8qmdj7Ka+opnv^XAv|}hq5xhc;K;+jLd8u|Ey&%O-nU4GJZ}yDl0`> -z%{mD<{`^K70&+R^8Vev700dYQ1O9#mi~B_M{rIUr%MXdz|9ebUP)<@zR8fgeR_rChk0$^o|E~f#?DwaV1h}`c -zH~AaqkN@(YCjk0Be=042`yWsITZ{jnsD8A=&$0`+{nLa0&J*xA=9Bjti6?+c&H`HK -zNB*#%1q;w~e*qw5W8?Tk+}~DK&&(PSPx({Q|7G1w{S1wB0eG{3i})ul;7$n;%JU0o -z5rCY7rH!89e*^(Z8IWax@GlI>fcE(ZhCilbFX3k7=vT4G@@sIQ5=k%NN_ -zAbYow^?!0EyoC1(VL;RYH02J!WPXGL{4Dc;uJnuA0yL#9og4r{E@EbuMuG+g00vn- -zYrX$VWB-x>wCMec7NEfu01f_E;|Rk4C4soT9w2q5GC=fE!p6!-#>U3N$@bSxb5Lp? -zTL4h(X93g{aQ5m?g_h_apj82e2T0TT!}flSyL+hSPz*p@0$c!~KNW1iFZe~9NdCv_ -zevOx2f^jngXk#`&QjEXifzkaM&)UIJ&(iY0*>E~cqW}q@r(OXD6M{e04hRU7^`G#5 -zUAufYh9(uj3jzYH9RP3SPsLs0muNCJCja$qzf3Uy6Ad0PO#hdNU*q0LQKVds<{t5QaUWS*LF9m>qVkSEM6XqXBX#d;D_)=>3 -zC#t{mZ=n8n;oXZRVtPb$Rl-=O*j^^ccKFLf1uG9iEb4W>WL -zLGYI<3oof&#8@V -z#GlBA?SDu9eedGme!&YL*H4~~&cE@zoOb?cmheA5<1hU#KWSpS|8Gk7-@GvYsq=q) -oE`N5K{P4N_EZYFE|K@>tBMk;v2mOd$WCD5z@VD^x{P^qt0dz#mIsgCw +delta 8722 +zcmY*;Wn2_c*XJ;R(j_4+E#1=H-QC^YIm8gsFf@+D&?(ZAlF}t5odeR+{krb6yU*TF +z|2X&D{M`@d*32TNOe20l5=0ho#^2I~pbD~q^aFzN{Rm#3zYeiL5N6aRiR|+XoxRvM +znZSLLlAJDh@2J2?#n2A?qar%tzN-5NQO +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 +z;W_|SPk^G}!M9_^pO +zA3bt3-tca%^42sHeDtfcC0S3w3H1ny!Bxpa=*k?XRPpx9Bb-gx1J9Yvx)4J(8cG+q +z(iCPZ9dsf3#QVyZgD_MW#G#qgV)olu$59&3(PzQfw@%4uZ~<5J=ABvdY43(Qnp{;G +zHg3>@T#>DbTuhFl3)fb3TFqdh)V2aq7!;&JOHseTWukvA7}(iGUq;v-{2J0iHSNHq +z;+)h!p6Ok^+Sp8-jgL($n6Qu47xyE`cFO5SdZR6;R!FET`tm#0D37z339Suxjpv+s +z*=%2-N$N?X&0?x_uut3erF@aBGj;9$k9?3FlbDO{RQa1_qtxrh4!4#fjp4x~akvdTp@ +zos?^Q&XE;3N93s4rHQGPrV7+au1$$aB6$hLy*Yz_kN$~dweb9PcB!eYVQTGjFuJP> +zZCEwBtb>TIgIO^qAzq@Bv-qud_ZD-2W<_at&ml-gv`tPt$@DF5`HlA +zM>DmmMkpv&Zm-8)Y#0bLQf4MpD4_-7M8eu6rh(tL8dq8onHs#R9J~dGd2IaXXMC~h +z91pKhnQa%Fsn29nAA1;x(%oC +zhca~qQDJaMf?wFrl-Pj;e$bZMYmMF!Y3Lv&Sb?Sjn#!NVx&NDyc^$b4uYyo2OmERa +zRz;yDGd@JTykzFLe|Wk-y7#3x`6$wt$zR8r48mdUvfbeL+4D|Z``~7$PrE@qc7rZe +zVsIoIbCwzjLZ@_M1*bD{HaYn();Z1-q*-I{tEnTZ(}Zmk&%MXSNBX>o| +z-u*RNkAyKC-Srp7c-=@5f)xMWg>o2WWl}j6j9=8+D8;T +z>0*0q#;qw8%U8i;6s0fu#I*%(g*@@a2Er@@nyI}{=@W{Z-;`=wN4N~>6Xrh&z#g}l +zN1g5}0-#(nHUTv_rl2{yUZ;h#t&Fd?tY!7L%ClY)>uH-Ny2ET$lW$S)IQiN79H)D^ +zb&0AXYkupy0~w8)*>Sj_p9}4L?lGTq%VG|2p`nWGhnM^!g|j-|O{%9Q%swOq63|*W +zw$(N_laI}`ilB+o!a-wl?er~;;3+)$_akSQ!8YO_&-e*SI7n^(QQ;X0ZE`{4f!gAl +z5$d+9CKVNonM!NO_frREICIAxOv)wm>}-k?iRisM`R7;=lyo|E_YR~FpS&PS`Lg0f +zl-ON<0S%Uix8J%#yZdkCz4YNhcec<|7*P(JsM#>-L>+tYg_71q9~70FAc^6KW5jql +zw!crdgVLH1G_eET=|SEc977;)ezVC|{PJZfra|}@rD;0s&@61mTEBJtILllg{%{vN +zfhb&lq0yChaLhnJ-Qb62MB7`>M;|_ceHKZAeeh@#8tbrK!ArP6oXIhMK;dhEJTY`@ +z0Tq>MIe0`7tGv)N*F0IGYSJv0vN?Az8g+4K9S!pW2~9F4W(_U_T=jCZrzuZ3*|__T +zONp_UWmyePv8C~rckc?Xji;Z5OEqg +zC*Um)i;Wh4TEwqReQdVVbUKT^2>Tpi6z_^-uF*adUFug4i@JhzpWT^Sk&E>CyP2?H +zWf6x}ehuTs6wvzCnTU&gYzT029Nz19(In1WC +z`(1IGmi!O%2AR|BjQa4Q0~u)kM%}?xQyjWuQ16^Gp++;`vr7!k--UZWM*~7Zl|ceO@I3`OpaRhD;YoCuo5IC0uHx>9 +z478hu@H|e0Zlo)Zj@01#;8BDs@991xe~^9uG2}UXLM(m7fa}AMwX*tjioBeV&Q8Gx +zSq$6wZFkRBK`cMI>R(@W@+lo2t)L+4q-negWRLWZBz*|%=W4v62JrmzNuOtA*x)QE +z5L%=OH#@KMdB%Jp^r?0tE}5-*6oP`-lO7Sf)0)n*e<{HA=&qhLR)oD8-+V}Z4=md) +z+k9lKf64DB2hAT)UaCP~di?-V3~JBH7itYyk~L6hrnxM%?RKntqd`=!b|e7eFnAcu +z3*V;g{xr7TSTm$}DY%~SMpl>m{Sj!We+WfxSEor?YeiAxYUy25pn(?T()E>ByP^c@ +zipwvWrhIK((R((VU+;@LmOnDu)ZXB3YArzzin!Z^0;PyJWnlfflo|q8(QY;o1*5CO +z##hnkO{uynTMdk`~DOC#1 +zdiYxQoy}=@7(ke#A8$YZZVtk4wo$8x28&I;cY3Ro-|kW=*yiiHgCLZeAr)UtVx>Tu +z|LvL0hq|1-jC0I4x#>&QZCfrVB=zT!nR|~Uz`9%~2 +znl{uZ{VEszW`Fad^q_HB!K9*|U-stK%?~;g?&&+12A}Rq$z($Bzuk^2X(Y=hF?-dQ +ztc3DsQKI;qhWIV`99Q#R3xnU0AvY!i*BECj-z9l74|%O=V@nlv|qqC^r^-~C?E +zGW%c|uYgnfJ(gjsTm_cIqcv*mYM{+i+&@F@+69ZQOK&u#v4oxUSQJ=tvqQ3W=*m;| +z>SkBi8LYb-qRY7Sthh*0%3XAC%$z1rhOJzuX=PkTOa=DlocZUpE#KxVNH5)_4n=T( +zGi3YrH7e~sPNYVBd~Grcq#CF~rN{p9Zza-Ntnwfma@TB)=3g36*0lSZg#ixEjFe%+ +zX=&LDZ5zqculZ`=RYc^ln(~;nN|Qh6gN=!6f9-N2h+3NWbIxYud&;4SX*tWf5slk4 +z{q@@l71UAZgj~*6edXb57fBUxvAS7s(RI=X868JM0+^DCn2yC>;v%S;qPOjB>YVsz(Zx9a>>BK&M +zIQK>7_n)4ud0X5YM}^i*keH{ehLsiy9@NvOpsFeQjdI6anLGvVbBw_*fU1TzdVS$i +z*4j7z!I5RF#rSz|8ibi$;qE{4`aqWYik7QB5U&F5C*;TO_x+gtzPGpzNt!7~nsBT7)Ckc(K~%uv&{{6A`mmBJVAk-{s~52Vu|HbCH7_W1~ZCX^RflOakGg=jo2Z +z<*s;5-J+2@^LRDZ-7EV&Pq+FTErw@pfFqvx^i%E7Fx#^n(E`m2(c>K-O5`M`Yek9el +zzTGs5qD6*G;y#~xu3>qWuO?-amKYtvRA}I9z#UspEeM;wOERYeot_n_EUMJf$4_u?E!6X~?q)tPoZb^_;8Y_Ox2h1m<+Le-fsRd|T8db<8#$bqez +zua^Z|>h%zdnuU^ww$#-dZ9NTM`FN+!IlLkz*FqWb!x^Z|C{KyGjZ+>G;;7Mb@LY|H +zc+Gp`L((Dw7pnDlHNm&;SfHedhx*kad$I^uGz{`0BYelq0yEUHpNKSkvj$|dpvY3{7*YGyhXA^LP0&wOw9oNoC=QoVx1<2Dne8qqZL +zm>nFh5DX(-RnQwvHCZQwn^#Z=E!SPVlaRJ78Bo@}!!9dRt^qZy?-*`Pt4WSmgucJv +zV1yFkcjlEM^uz-;b#Q7ZCP@Lk)m}uPX={R4B=56k7WNh11BN~0T*vr@!!ow^B0hOR +zQ)4)&(e%>bNNL%bm<&8H{*l_L7s0$2GUgX2Vd;=4d9Dm2v3TaL+;L>{K7h7 +zV#k?xDPm(NDE31$ +z<}|X)pEY6myjK+^gaIMk&Yj2~F0rSKemNqlsVm4c|N7mp_C*L01s;GNx#D-*&gk!qQr}^?_r@q!8fuXw!)fA7xkd} +zb>vHvdx~H$5qqAWrow7}+8zBM65-JOt5z +za=T6f7MK`XJuQog8kIEboPdhcaVJeHy)5z7EBLK5NRr()E|#K0L0N^JD@pUA^Czb` +zbUZ_558y+vqAGeyHCbrvOvLD67Ph}06959VzQ_|>RrXQAqE+AQ(-AaKdxoWaF8hdt +z{O3W@b^*o#-f1VuU>YMV03ELF7zkCN4Q&b#prz%3Nne0lSbRo@@ +z^ihv%oIl~Qyl6Q;a#$*jOC%x0_;eis*)J7=f@Ct*)xF5 +zo}u~@-I}2|$b%5L7>@+Z?4o+1r&v6ceIy+vroK&jCQ<4q&45HP2wCol4hVm3pZtjf +zHz1D7oyaSKJ~T{Gx}7ONLA)D5k(%%`WswrDyzX*rn}i}}TB4^y#@mAwPzoC)`?rYv +zHgx|trUN#mu*VzUV~8TnJM2Qh*ZM5B{x&y>5An`(M7=Z*Q>TdiH@j*2=moNuOtvpz +z+G`@~-`%~+AgPKgke@XiRPgndh@bp*-HRsh;HTtz@-y_uhb%7ylVOTqG0#u?Vn5c5 +zEp*XRo|8hcgG^$#{$O9CJ&NE;TrfRpSnLmes&MO{m=N%zc`}gb!eQ7odl$oy1%PI} +z#AIxx%oRVy&{O~9xnK4$EY>(eQj}!HKIV$Fz*H=-=Kn)N0D6u`(;iO|VraI4fu_W` +z;b5{7;Lyx4za}DU#+U7}=H0dAS#YJJ&g2!P@Htu-AL&w=-)*%P9h2{wR|@?Ff9~)b +z^+e_3Hetq7W%ls{!?<6&Y$Z;NNB41pvrv)|MET6AZXFXJeFqbFW5@i5WGzl?bP+~? +z*&_puH;wKv2)9T_d+P`bLvJFqX#j&xa*-;0nGBbQf0DC>o~=J_Wmtf*2SZQr?{i~X +z9-IbRH8{iy?<0v9Ir1?$66+igy|yDQ5J~A9sFX@Pe<*kCY8+MwH?I +z`P}zfQ6l^AO8ehZ=l^ZR;R%uu4;BK*=?W9t|0{+-at(MQZ(CtG=EJFNaFMlKCMXu30(gJUqj5+ +z`GM|!keqcj;FKTa_qq;{*dHRXAq157hlB@kL#8%yAm2AgfU|*rDKX@FLlp=HL8ddv +zAWLCHe@DcDeB2}fl7#=0+#<05c3=VqM*O3bkr@9X4nO|)q0hU;Gye{L8ZN*NH8Id@mP-u;Fmb8YuorjLrW&ndip8CN%_qp982r +w1WEnz9^$&s1hkp_3#lPJQ~!HI7WYYjA7>z!`?f%npAh2%rB@vD|Lau$2O)#1n*aa+ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties -index 56a6b165675b7de0752a0777092b4f34e36ec445..a4b4429748d92848a3d820c7b099fbeb941066ae 100644 +index 2e6e5897b5285c749d75662c65ac5d2904c37bc6..41dfb87909a877d96c3af4adccce4c7a301b55a2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties -@@ -1,6 +1,5 @@ --#Tue Nov 28 14:11:56 CET 2017 +@@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip +-distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip ++distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists --distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-all.zip -diff --git a/gradlew b/gradlew -index cccdd3d517fc5249beaefa600691cf150f2fa3e6..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3 100755 ---- a/gradlew -+++ b/gradlew -@@ -1,5 +1,21 @@ - #!/usr/bin/env sh +diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +index 939863351be0544adc7c4079dc2dbb18be877fb9..f7addc6af8928ee2b2d1b9a09d13750413d4721f 100644 +--- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java ++++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +@@ -40,11 +40,12 @@ public class ExprProcessor implements CodeConstants { + public static final String UNKNOWN_TYPE_STRING = ""; + public static final String NULL_TYPE_STRING = ""; -+# -+# Copyright 2015 the original author or authors. -+# -+# 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 -+# -+# https://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. -+# -+ - ############################################################################## - ## - ## Gradle start up script for UN*X -@@ -28,7 +44,7 @@ APP_NAME="Gradle" - APP_BASE_NAME=`basename "$0"` +- private static final Map functionMap = Map.of( +- opc_arraylength, FunctionExprent.FUNCTION_ARRAY_LENGTH, +- opc_checkcast, FunctionExprent.FUNCTION_CAST, +- opc_instanceof, FunctionExprent.FUNCTION_INSTANCEOF +- ); ++ private static final Map functionMap = new HashMap<>(); ++ static { ++ functionMap.put(opc_arraylength, FunctionExprent.FUNCTION_ARRAY_LENGTH); ++ functionMap.put(opc_checkcast, FunctionExprent.FUNCTION_CAST); ++ functionMap.put(opc_instanceof, FunctionExprent.FUNCTION_INSTANCEOF); ++ } - # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. --DEFAULT_JVM_OPTS="" -+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + private static final VarType[] constants = { + VarType.VARTYPE_INT, VarType.VARTYPE_FLOAT, VarType.VARTYPE_LONG, VarType.VARTYPE_DOUBLE, VarType.VARTYPE_CLASS, VarType.VARTYPE_STRING +@@ -266,7 +267,7 @@ public class ExprProcessor implements CodeConstants { + for (int i = 0; i < seq.length(); i++) { + Instruction instr = seq.getInstr(i); + Integer offset = block.getOriginalOffset(i); +- Set offsets = offset >= 0 ? Set.of(offset) : null; ++ Set offsets = offset >= 0 ? Collections.singleton(offset) : null; - # Use the maximum available, or set MAX_FD != -1 to use that value. - MAX_FD="maximum" -@@ -109,8 +125,8 @@ if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" - fi + switch (instr.opcode) { + case opc_aconst_null: +@@ -764,7 +765,7 @@ public class ExprProcessor implements CodeConstants { + ClassesProcessor.ClassNode enclosingClass = (ClassesProcessor.ClassNode) DecompilerContext.getProperty( + DecompilerContext.CURRENT_CLASS_NODE + ); +- List enclosingClassList = new ArrayList<>(List.of(enclosingClass)); ++ List enclosingClassList = new ArrayList<>(Collections.singletonList(enclosingClass)); + while (enclosingClass.parent != null) { + enclosingClass = enclosingClass.parent; + enclosingClassList.add(0, enclosingClass); +diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java +index ed57b52d919ea3c2cb774f28a04b0893e1eb5c7f..3aa5956fbb79de630c5e9e600c9fd27ae7da0091 100644 +--- a/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java ++++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java +@@ -14,6 +14,7 @@ import org.jetbrains.java.decompiler.struct.gen.VarType; --# For Cygwin, switch paths to Windows format before running java --if $cygwin ; then -+# For Cygwin or MSYS, switch paths to Windows format before running java -+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` -@@ -138,19 +154,19 @@ if $cygwin ; then - else - eval `echo args$i`="\"$arg\"" - fi -- i=$((i+1)) -+ i=`expr $i + 1` - done - case $i in -- (0) set -- ;; -- (1) set -- "$args0" ;; -- (2) set -- "$args0" "$args1" ;; -- (3) set -- "$args0" "$args1" "$args2" ;; -- (4) set -- "$args0" "$args1" "$args2" "$args3" ;; -- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; -- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; -- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; -- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; -- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; -+ 0) set -- ;; -+ 1) set -- "$args0" ;; -+ 2) set -- "$args0" "$args1" ;; -+ 3) set -- "$args0" "$args1" "$args2" ;; -+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;; -+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; -+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; -+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; -+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; -+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac - fi + import java.util.ArrayList; + import java.util.Arrays; ++import java.util.HashMap; + import java.util.List; + import java.util.Map; -@@ -159,14 +175,9 @@ save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " - } --APP_ARGS=$(save "$@") -+APP_ARGS=`save "$@"` +@@ -30,14 +31,15 @@ public final class SecondaryFunctionsHelper { + FunctionExprent.FUNCTION_CADD + }; - # Collect all arguments for the java command, following the shell quoting and substitution rules - eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +- private static final Map mapNumComparisons = Map.of( +- FunctionExprent.FUNCTION_EQ, new Integer[]{FunctionExprent.FUNCTION_LT, FunctionExprent.FUNCTION_EQ, FunctionExprent.FUNCTION_GT}, +- FunctionExprent.FUNCTION_NE, new Integer[]{FunctionExprent.FUNCTION_GE, FunctionExprent.FUNCTION_NE, FunctionExprent.FUNCTION_LE}, +- FunctionExprent.FUNCTION_GT, new Integer[]{FunctionExprent.FUNCTION_GE, FunctionExprent.FUNCTION_GT, null}, +- FunctionExprent.FUNCTION_GE, new Integer[]{null, FunctionExprent.FUNCTION_GE, FunctionExprent.FUNCTION_GT}, +- FunctionExprent.FUNCTION_LT, new Integer[]{null, FunctionExprent.FUNCTION_LT, FunctionExprent.FUNCTION_LE}, +- FunctionExprent.FUNCTION_LE, new Integer[]{FunctionExprent.FUNCTION_LT, FunctionExprent.FUNCTION_LE, null} +- ); ++ private static final Map mapNumComparisons = new HashMap<>(); ++ static { ++ mapNumComparisons.put(FunctionExprent.FUNCTION_EQ, new Integer[]{FunctionExprent.FUNCTION_LT, FunctionExprent.FUNCTION_EQ, FunctionExprent.FUNCTION_GT}); ++ mapNumComparisons.put(FunctionExprent.FUNCTION_NE, new Integer[]{FunctionExprent.FUNCTION_GE, FunctionExprent.FUNCTION_NE, FunctionExprent.FUNCTION_LE}); ++ mapNumComparisons.put(FunctionExprent.FUNCTION_GT, new Integer[]{FunctionExprent.FUNCTION_GE, FunctionExprent.FUNCTION_GT, null}); ++ mapNumComparisons.put(FunctionExprent.FUNCTION_GE, new Integer[]{null, FunctionExprent.FUNCTION_GE, FunctionExprent.FUNCTION_GT}); ++ mapNumComparisons.put(FunctionExprent.FUNCTION_LT, new Integer[]{null, FunctionExprent.FUNCTION_LT, FunctionExprent.FUNCTION_LE}); ++ mapNumComparisons.put(FunctionExprent.FUNCTION_LE, new Integer[]{FunctionExprent.FUNCTION_LT, FunctionExprent.FUNCTION_LE, null}); ++ } --# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong --if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then -- cd "$(dirname "$0")" --fi -- - exec "$JAVACMD" "$@" -diff --git a/gradlew.bat b/gradlew.bat -index f9553162f122c71b34635112e717c3e733b5b212..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d 100644 ---- a/gradlew.bat -+++ b/gradlew.bat -@@ -1,3 +1,19 @@ -+@rem -+@rem Copyright 2015 the original author or authors. -+@rem -+@rem Licensed under the Apache License, Version 2.0 (the "License"); -+@rem you may not use this file except in compliance with the License. -+@rem You may obtain a copy of the License at -+@rem -+@rem https://www.apache.org/licenses/LICENSE-2.0 -+@rem -+@rem Unless required by applicable law or agreed to in writing, software -+@rem distributed under the License is distributed on an "AS IS" BASIS, -+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+@rem See the License for the specific language governing permissions and -+@rem limitations under the License. -+@rem -+ - @if "%DEBUG%" == "" @echo off - @rem ########################################################################## - @rem -@@ -13,8 +29,11 @@ if "%DIRNAME%" == "" set DIRNAME=. - set APP_BASE_NAME=%~n0 - set APP_HOME=%DIRNAME% + public static boolean identifySecondaryFunctions(Statement stat, VarProcessor varProc) { + if (stat.getExprents() == null) { +diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchHelper.java +index 49a305a923ba34513b719efc45e15943f84bfba7..19d80e848b2f679926885439536c53f28429545c 100644 +--- a/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchHelper.java ++++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchHelper.java +@@ -447,7 +447,7 @@ public final class SwitchHelper { + } + List newExprents; + if (lastExprentIndex > 0) { +- newExprents = List.copyOf(firstSwitchExprents.subList(0, lastExprentIndex)); ++ newExprents = new ArrayList<>(firstSwitchExprents.subList(0, lastExprentIndex)); + } + else { + newExprents = Collections.emptyList(); +diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +index a7033f507fd9667d773977803718c08810f0d750..3882cfd68af7f55938311363a69a2dded3fffbab 100644 +--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java ++++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +@@ -36,15 +36,16 @@ public class ConstExprent extends Exprent { + private static final String E = "E"; + private static final String PI = "PI"; -+@rem Resolve any "." and ".." in APP_HOME to make it shorter. -+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi -+ - @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. --set DEFAULT_JVM_OPTS= -+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" +- private static final Map CHAR_ESCAPES = Map.of( +- 0x8, "\\b", /* \u0008: backspace BS */ +- 0x9, "\\t", /* \u0009: horizontal tab HT */ +- 0xA, "\\n", /* \u000a: linefeed LF */ +- 0xC, "\\f", /* \u000c: form feed FF */ +- 0xD, "\\r", /* \u000d: carriage return CR */ +- 0x27, "\\'", /* \u0027: single quote ' */ +- 0x5C, "\\\\" /* \u005c: backslash \ */ +- ); ++ private static final Map CHAR_ESCAPES = new HashMap<>(); ++ static { ++ CHAR_ESCAPES.put(0x8, "\\b"); /* \u0008: backspace BS */ ++ CHAR_ESCAPES.put(0x9, "\\t"); /* \u0009: horizontal tab HT */ ++ CHAR_ESCAPES.put(0xA, "\\n"); /* \u000a: linefeed LF */ ++ CHAR_ESCAPES.put(0xC, "\\f"); /* \u000c: form feed FF */ ++ CHAR_ESCAPES.put(0xD, "\\r"); /* \u000d: carriage return CR */ ++ CHAR_ESCAPES.put(0x27, "\\'"); /* \u0027: single quote ' */ ++ CHAR_ESCAPES.put(0x5C, "\\\\"); /* \u005c: backslash \ */ ++ } + + private StructMember parent; + private VarType constType; +diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +index 4e6eb0cb06362df98589932c67a22c3b6741fc27..5489465076ce772ad91d6c05ce6bb8b150f1747b 100644 +--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java ++++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +@@ -451,16 +451,17 @@ public class InvocationExprent extends Exprent { + return null; + } + +- private static final Map UNBOXING_METHODS = Map.of( +- "booleanValue", "java/lang/Boolean", +- "byteValue", "java/lang/Byte", +- "shortValue", "java/lang/Short", +- "intValue", "java/lang/Integer", +- "longValue", "java/lang/Long", +- "floatValue", "java/lang/Float", +- "doubleValue", "java/lang/Double", +- "charValue", "java/lang/Character" +- ); ++ private static final Map UNBOXING_METHODS = new HashMap<>(); ++ static { ++ UNBOXING_METHODS.put("booleanValue", "java/lang/Boolean"); ++ UNBOXING_METHODS.put("byteValue", "java/lang/Byte"); ++ UNBOXING_METHODS.put("shortValue", "java/lang/Short"); ++ UNBOXING_METHODS.put("intValue", "java/lang/Integer"); ++ UNBOXING_METHODS.put("longValue", "java/lang/Long"); ++ UNBOXING_METHODS.put("floatValue", "java/lang/Float"); ++ UNBOXING_METHODS.put("doubleValue", "java/lang/Double"); ++ UNBOXING_METHODS.put("charValue", "java/lang/Character"); ++ } + + private boolean isUnboxingCall() { + return !isStatic && parameters.size() == 0 && className.equals(UNBOXING_METHODS.get(name)); +diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java +index 8a73c2655aa12ecfd26df4e2f4eae17145f8f3e6..f10f59b946137e13a7f6e12d9b61099ce109768c 100644 +--- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java ++++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java +@@ -98,13 +98,13 @@ public class VarTypeProcessor { + CheckTypesResult exprentTypeBounds = currentExprent.checkExprTypeBounds(); + if (exprentTypeBounds == null) return true; + +- for (var entry : exprentTypeBounds.getMaxTypeExprents()) { ++ for (CheckTypesResult.ExprentTypePair entry : exprentTypeBounds.getMaxTypeExprents()) { + if (entry.type.getTypeFamily() != CodeConstants.TYPE_FAMILY_OBJECT) { + changeExprentType(entry.exprent, entry.type, false); + } + } + boolean result = true; +- for (var entry : exprentTypeBounds.getMinTypeExprents()) { ++ for (CheckTypesResult.ExprentTypePair entry : exprentTypeBounds.getMinTypeExprents()) { + result &= changeExprentType(entry.exprent, entry.type, true); + } + return result; +diff --git a/src/org/jetbrains/java/decompiler/struct/StructMember.java b/src/org/jetbrains/java/decompiler/struct/StructMember.java +index 2802eeb66f3144e8b552bd0f14674f768de51219..f03613981dd7c48929db77e550c194e072c0e76b 100644 +--- a/src/org/jetbrains/java/decompiler/struct/StructMember.java ++++ b/src/org/jetbrains/java/decompiler/struct/StructMember.java +@@ -54,7 +54,7 @@ public abstract class StructMember { + Set typeAnnotations = TargetInfo.EmptyTarget.extract(getPossibleTypeAnnotationCollisions(getType())) + .stream() + .map(typeAnnotation-> typeAnnotation.getAnnotationExpr()) +- .collect(Collectors.toUnmodifiableSet()); ++ .collect(Collectors.toSet()); + return typeAnnotations.contains(typeAnnotationExpr); + } + +@@ -62,7 +62,7 @@ public abstract class StructMember { + Set typeAnnotations = TargetInfo.FormalParameterTarget + .extract(getPossibleTypeAnnotationCollisions(type), param).stream() + .map(typeAnnotation-> typeAnnotation.getAnnotationExpr()) +- .collect(Collectors.toUnmodifiableSet()); ++ .collect(Collectors.toSet()); + return typeAnnotations.contains(typeAnnotationExpr); + } - @rem Find java.exe - if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java -index 3280038cb409ed7f96e99da714dc5127b74fd1ca..1dedf68f53090579fc197d85800b4f7b62d9a1e6 100644 +index 037cb437ee5e93941364d73e3d88c1c9f14ac517..2133783e40306b0c7a78db9f04ff079e341ece6a 100644 --- a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java +++ b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java -@@ -213,7 +213,12 @@ public class ConstantPool implements NewClassNameBuilder { +@@ -221,7 +221,12 @@ public class ConstantPool implements NewClassNameBuilder { if (newName != null) { StringBuilder buffer = new StringBuilder(); - if (vt.arrayDim > 0) { -- buffer.append("[".repeat(vt.arrayDim)).append('L').append(newName).append(';'); + if (vt.getArrayDim() > 0) { +- buffer.append("[".repeat(vt.getArrayDim())).append('L').append(newName).append(';'); + // No functional change, just a revert for J8 compatibility -+ for (int i = 0; i < vt.arrayDim; i++) { ++ for (int i = 0; i < vt.getArrayDim(); i++) { + buffer.append('['); + } + @@ -2460,6 +892,150 @@ index 3280038cb409ed7f96e99da714dc5127b74fd1ca..1dedf68f53090579fc197d85800b4f7b } else { buffer.append(newName); +diff --git a/src/org/jetbrains/java/decompiler/struct/match/MatchEngine.java b/src/org/jetbrains/java/decompiler/struct/match/MatchEngine.java +index aa04e9f12c2af4332c6e1fe6e50ae18c5f56808f..0395a67d814678eb0bcc7edcc4574b0dd64f3a4b 100644 +--- a/src/org/jetbrains/java/decompiler/struct/match/MatchEngine.java ++++ b/src/org/jetbrains/java/decompiler/struct/match/MatchEngine.java +@@ -12,72 +12,81 @@ import org.jetbrains.java.decompiler.struct.match.MatchNode.RuleValue; + + import java.util.*; + +-import static java.util.Map.entry; +- + public class MatchEngine { + @SuppressWarnings("SpellCheckingInspection") +- private static final Map stat_properties = Map.of( +- "type", MatchProperties.STATEMENT_TYPE, +- "ret", MatchProperties.STATEMENT_RET, +- "position", MatchProperties.STATEMENT_POSITION, +- "statsize", MatchProperties.STATEMENT_STATSIZE, +- "exprsize", MatchProperties.STATEMENT_EXPRSIZE, +- "iftype", MatchProperties.STATEMENT_IFTYPE); ++ private static final Map stat_properties = new HashMap<>(); + + @SuppressWarnings("SpellCheckingInspection") +- private static final Map expr_properties = Map.ofEntries( +- entry("type", MatchProperties.EXPRENT_TYPE), +- entry("ret", MatchProperties.EXPRENT_RET), +- entry("position", MatchProperties.EXPRENT_POSITION), +- entry("functype", MatchProperties.EXPRENT_FUNCTYPE), +- entry("exittype", MatchProperties.EXPRENT_EXITTYPE), +- entry("consttype", MatchProperties.EXPRENT_CONSTTYPE), +- entry("constvalue", MatchProperties.EXPRENT_CONSTVALUE), +- entry("invclass", MatchProperties.EXPRENT_INVOCATION_CLASS), +- entry("signature", MatchProperties.EXPRENT_INVOCATION_SIGNATURE), +- entry("parameter", MatchProperties.EXPRENT_INVOCATION_PARAMETER), +- entry("index", MatchProperties.EXPRENT_VAR_INDEX), +- entry("name", MatchProperties.EXPRENT_FIELD_NAME)); ++ private static final Map expr_properties = new HashMap<>(); + + @SuppressWarnings("SpellCheckingInspection") +- private static final Map stat_type = Map.of( +- "if", StatementType.IF, +- "do", StatementType.DO, +- "switch", StatementType.SWITCH, +- "trycatch", StatementType.TRY_CATCH, +- "basicblock", StatementType.BASIC_BLOCK, +- "sequence", StatementType.SEQUENCE); +- +- private static final Map expr_type = Map.ofEntries( +- entry("array", Exprent.EXPRENT_ARRAY), +- entry("assignment", Exprent.EXPRENT_ASSIGNMENT), +- entry("constant", Exprent.EXPRENT_CONST), +- entry("exit", Exprent.EXPRENT_EXIT), +- entry("field", Exprent.EXPRENT_FIELD), +- entry("function", Exprent.EXPRENT_FUNCTION), +- entry("if", Exprent.EXPRENT_IF), +- entry("invocation", Exprent.EXPRENT_INVOCATION), +- entry("monitor", Exprent.EXPRENT_MONITOR), +- entry("new", Exprent.EXPRENT_NEW), +- entry("switch", Exprent.EXPRENT_SWITCH), +- entry("var", Exprent.EXPRENT_VAR), +- entry("annotation", Exprent.EXPRENT_ANNOTATION), +- entry("assert", Exprent.EXPRENT_ASSERT)); +- +- private static final Map expr_func_type = Map.of("eq", FunctionExprent.FUNCTION_EQ); +- +- private static final Map expr_exit_type = Map.of( +- "return", ExitExprent.EXIT_RETURN, +- "throw", ExitExprent.EXIT_THROW); ++ private static final Map stat_type = new HashMap<>(); + +- @SuppressWarnings("SpellCheckingInspection") +- private static final Map stat_if_type = Map.of( +- "if", IfStatement.IFTYPE_IF, +- "ifelse", IfStatement.IFTYPE_IFELSE); ++ private static final Map expr_type = new HashMap<>(); ++ ++ private static final Map expr_func_type = new HashMap<>(); + +- private static final Map expr_const_type = Map.of( +- "null", VarType.VARTYPE_NULL, +- "string", VarType.VARTYPE_STRING); ++ private static final Map expr_exit_type = new HashMap<>(); ++ ++ @SuppressWarnings("SpellCheckingInspection") ++ private static final Map stat_if_type = new HashMap<>(); ++ ++ private static final Map expr_const_type = new HashMap<>(); ++ ++ static { ++ stat_properties.put("type", MatchProperties.STATEMENT_TYPE); ++ stat_properties.put("ret", MatchProperties.STATEMENT_RET); ++ stat_properties.put("position", MatchProperties.STATEMENT_POSITION); ++ stat_properties.put("statsize", MatchProperties.STATEMENT_STATSIZE); ++ stat_properties.put("exprsize", MatchProperties.STATEMENT_EXPRSIZE); ++ stat_properties.put("iftype", MatchProperties.STATEMENT_IFTYPE); ++ ++ expr_properties.put("type", MatchProperties.EXPRENT_TYPE); ++ expr_properties.put("ret", MatchProperties.EXPRENT_RET); ++ expr_properties.put("position", MatchProperties.EXPRENT_POSITION); ++ expr_properties.put("functype", MatchProperties.EXPRENT_FUNCTYPE); ++ expr_properties.put("exittype", MatchProperties.EXPRENT_EXITTYPE); ++ expr_properties.put("consttype", MatchProperties.EXPRENT_CONSTTYPE); ++ expr_properties.put("constvalue", MatchProperties.EXPRENT_CONSTVALUE); ++ expr_properties.put("invclass", MatchProperties.EXPRENT_INVOCATION_CLASS); ++ expr_properties.put("signature", MatchProperties.EXPRENT_INVOCATION_SIGNATURE); ++ expr_properties.put("parameter", MatchProperties.EXPRENT_INVOCATION_PARAMETER); ++ expr_properties.put("index", MatchProperties.EXPRENT_VAR_INDEX); ++ expr_properties.put("name", MatchProperties.EXPRENT_FIELD_NAME); ++ ++ stat_type.put("if", StatementType.IF); ++ stat_type.put("do", StatementType.DO); ++ stat_type.put("switch", StatementType.SWITCH); ++ stat_type.put("trycatch", StatementType.TRY_CATCH); ++ stat_type.put("basicblock", StatementType.BASIC_BLOCK); ++ stat_type.put("sequence", StatementType.SEQUENCE); ++ ++ expr_type.put("array", Exprent.EXPRENT_ARRAY); ++ expr_type.put("assignment", Exprent.EXPRENT_ASSIGNMENT); ++ expr_type.put("constant", Exprent.EXPRENT_CONST); ++ expr_type.put("exit", Exprent.EXPRENT_EXIT); ++ expr_type.put("field", Exprent.EXPRENT_FIELD); ++ expr_type.put("function", Exprent.EXPRENT_FUNCTION); ++ expr_type.put("if", Exprent.EXPRENT_IF); ++ expr_type.put("invocation", Exprent.EXPRENT_INVOCATION); ++ expr_type.put("monitor", Exprent.EXPRENT_MONITOR); ++ expr_type.put("new", Exprent.EXPRENT_NEW); ++ expr_type.put("switch", Exprent.EXPRENT_SWITCH); ++ expr_type.put("var", Exprent.EXPRENT_VAR); ++ expr_type.put("annotation", Exprent.EXPRENT_ANNOTATION); ++ expr_type.put("assert", Exprent.EXPRENT_ASSERT); ++ ++ expr_func_type.put("eq", FunctionExprent.FUNCTION_EQ); ++ ++ expr_exit_type.put("return", ExitExprent.EXIT_RETURN); ++ expr_exit_type.put("throw", ExitExprent.EXIT_THROW); ++ ++ stat_if_type.put("if", IfStatement.IFTYPE_IF); ++ stat_if_type.put("ifelse", IfStatement.IFTYPE_IFELSE); ++ ++ expr_const_type.put("null", VarType.VARTYPE_NULL); ++ expr_const_type.put("string", VarType.VARTYPE_STRING); ++ } + + private final MatchNode rootNode; + private final Map variables = new HashMap<>(); diff --git a/src/org/jetbrains/java/decompiler/util/SFormsFastMapDirect.java b/src/org/jetbrains/java/decompiler/util/SFormsFastMapDirect.java index bb8b4dd9b866ec54491da50310b09b6fcb0bdf3f..7143281598c9273e847cc8aa5d86178c3b2b6bab 100644 --- a/src/org/jetbrains/java/decompiler/util/SFormsFastMapDirect.java diff --git a/FernFlower-Patches/0002-Test-Framework-upgrades.patch b/FernFlower-Patches/0002-Test-Framework-upgrades.patch index dc3a0c7..6118697 100644 --- a/FernFlower-Patches/0002-Test-Framework-upgrades.patch +++ b/FernFlower-Patches/0002-Test-Framework-upgrades.patch @@ -20,10 +20,10 @@ index bb303e84f33161a4b4fd40a73aa48d29981d9ef2..cc1f537e71af0748b7b97d7d8489198e throw new RuntimeException("not implemented"); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java -index b5e82131dd20ea45a02ff62e085695417111adfe..b905da55c9b3bd7dc48123559809a1d7ed9eaf9c 100644 +index c870c683cad7935d7aba141c0310ec0f0a2fdeda..272601270ea32fb5ccc4a822cd9d1b959bae9c35 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java -@@ -469,6 +469,10 @@ public class Statement implements IMatchable { +@@ -430,6 +430,10 @@ public abstract class Statement implements IMatchable { return false; } @@ -71,18 +71,21 @@ index 4c5641fec76837a51094d4a54800d5b7475446ca..7d29c198014cbfee8092fd31461208ce private static boolean isTestDataDir(File dir) { return dir.isDirectory() && new File(dir, "classes").isDirectory() && new File(dir, "results").isDirectory(); diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -index feea5aad81ebdff6221e13cfc8472b4b5c2d78c0..1e8014083efc7c0fdfad40747cccbcd0bf33c608 100644 +index e64cf91c0674163f5c81b874e21e84da83fd264e..721a3606e209f4f803dcb6b513a5768c9c437c48 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -@@ -1,37 +1,20 @@ - // 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. +@@ -2,26 +2,14 @@ package org.jetbrains.java.decompiler; + import org.jetbrains.java.decompiler.main.DecompilerContext; -import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler; + import org.jetbrains.java.decompiler.main.extern.ClassFormatException; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; -import org.junit.After; -import org.junit.Before; + import org.junit.Rule; import org.junit.Test; + import org.junit.rules.Timeout; -import java.io.File; -import java.io.IOException; @@ -95,7 +98,15 @@ index feea5aad81ebdff6221e13cfc8472b4b5c2d78c0..1e8014083efc7c0fdfad40747cccbcd0 - -public class SingleClassesTest { - private DecompilerTestFixture fixture; -- ++public class SingleClassesTest extends SingleClassesTestBase { ++ protected DecompilerTestFixture fixture; + + /* + * Set individual test duration time limit to 60 seconds. +@@ -30,19 +18,14 @@ public class SingleClassesTest { + @Rule + public Timeout globalTimeout = Timeout.seconds(60); + - @Before - public void setUp() throws IOException { - fixture = new DecompilerTestFixture(); @@ -109,9 +120,6 @@ index feea5aad81ebdff6221e13cfc8472b4b5c2d78c0..1e8014083efc7c0fdfad40747cccbcd0 - public void tearDown() { - fixture.tearDown(); - fixture = null; -+public class SingleClassesTest extends SingleClassesTestBase { -+ protected DecompilerTestFixture fixture; -+ + @Override + protected String[] getDecompilerOptions() { + return new String[] { @@ -123,10 +131,10 @@ index feea5aad81ebdff6221e13cfc8472b4b5c2d78c0..1e8014083efc7c0fdfad40747cccbcd0 } @Test public void testPrimitiveNarrowing() { doTest("pkg/TestPrimitiveNarrowing"); } -@@ -134,45 +117,4 @@ public class SingleClassesTest { - @Test public void testRecordVararg() { doTest("records/TestRecordVararg"); } - @Test public void testRecordGenericVararg() { doTest("records/TestRecordGenericVararg"); } - @Test public void testRecordAnno() { doTest("records/TestRecordAnno"); } +@@ -226,45 +209,4 @@ public class SingleClassesTest { + + @Test(expected = ClassFormatException.class) + public void testUnsupportedConstantPoolEntry() { doTest("java11/TestUnsupportedConstantPoolEntry"); } - - private void doTest(String testFile, String... companionFiles) { - ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/FernFlower-Patches/0003-Fix-initializers-for-anon-and-synthetic-classes.patch b/FernFlower-Patches/0003-Fix-initializers-for-anon-and-synthetic-classes.patch index 479be4f..d0c089a 100644 --- a/FernFlower-Patches/0003-Fix-initializers-for-anon-and-synthetic-classes.patch +++ b/FernFlower-Patches/0003-Fix-initializers-for-anon-and-synthetic-classes.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix initializers for anon and synthetic classes diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -index 2d57c02d34e186e440ee0afccac79545b5a190cf..16a7cfebe26dfe0f6244a46f9af271758be274da 100644 +index 959ff51c479db3f0144df9f0de5b3ef863dcdff6..0dc28bc9d8e3b622f691939b1c8fcce9a09c11fe 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -@@ -39,6 +39,7 @@ public class ClassWriter { +@@ -46,6 +46,7 @@ public class ClassWriter { StructClass cl = wrapper.getClassStruct(); InitializerProcessor.extractInitializers(wrapper); @@ -17,10 +17,10 @@ index 2d57c02d34e186e440ee0afccac79545b5a190cf..16a7cfebe26dfe0f6244a46f9af27175 if (node.type == ClassNode.CLASS_ROOT && !cl.isVersion5() && diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java -index 7bb50aaeb939930ea8c9679d88cf9a2cc5f0b4af..e380664d46356ec909049293a89bc4be6823dca8 100644 +index 804443bf66c6cc2a9cadf5ef11c44827257aaf53..a45067feeedaece4546ae2dbc5148fbf9b2c0309 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java -@@ -87,6 +87,31 @@ public class ClassesProcessor implements CodeConstants { +@@ -88,6 +88,31 @@ public class ClassesProcessor implements CodeConstants { rec.type = entry.simpleNameIdx == 0 ? ClassNode.CLASS_ANONYMOUS : entry.outerNameIdx == 0 ? ClassNode.CLASS_LOCAL : ClassNode.CLASS_MEMBER; rec.accessFlags = entry.accessFlags; @@ -53,7 +53,7 @@ index 7bb50aaeb939930ea8c9679d88cf9a2cc5f0b4af..e380664d46356ec909049293a89bc4be String enclClassName = entry.outerNameIdx != 0 ? entry.enclosingName : cl.qualifiedName; if (enclClassName == null || innerName.equals(enclClassName)) { diff --git a/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java -index d3696ddeda3a7df15242d613d6cde5c936642509..55badb664d4a52620710e97e040929ce5414eb9e 100644 +index bc8992ff40bf8655077d2c01a7038bfbbfe999c0..4930acdf38046e1dfe3f04a7e68b4ff88c4ed594 100644 --- a/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java @@ -13,6 +13,9 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.Statements; @@ -70,10 +70,10 @@ index d3696ddeda3a7df15242d613d6cde5c936642509..55badb664d4a52620710e97e040929ce Exprent exprent = firstData.getExprents().get(0); if (exprent.type == Exprent.EXPRENT_INVOCATION) { InvocationExprent invExpr = (InvocationExprent)exprent; -- if (Statements.isInvocationInitConstructor(invExpr, method, wrapper, false) && invExpr.getLstParameters().isEmpty()) { +- if (Statements.isInvocationInitConstructor(invExpr, method, wrapper, false) && invExpr.getParameters().isEmpty()) { - firstData.getExprents().remove(0); + if (Statements.isInvocationInitConstructor(invExpr, method, wrapper, false)) { -+ List mask = ExprUtil.getSyntheticParametersMask(invExpr.getClassname(), invExpr.getStringDescriptor(), invExpr.getLstParameters().size()); ++ List mask = ExprUtil.getSyntheticParametersMask(invExpr.getClassName(), invExpr.getStringDescriptor(), invExpr.getParameters().size()); + boolean hideSuper = true; + + //searching for non-synthetic params @@ -82,8 +82,8 @@ index d3696ddeda3a7df15242d613d6cde5c936642509..55badb664d4a52620710e97e040929ce + continue; + } + VarType type = invExpr.getDescriptor().params[i]; -+ if (type.type == CodeConstants.TYPE_OBJECT) { -+ ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(type.value); ++ if (type.getType() == CodeConstants.TYPE_OBJECT) { ++ ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(type.getValue()); + if (node != null && (node.type == ClassNode.CLASS_ANONYMOUS || (node.access & CodeConstants.ACC_SYNTHETIC) != 0)) { + break; // Should be last + } @@ -112,8 +112,8 @@ index d3696ddeda3a7df15242d613d6cde5c936642509..55badb664d4a52620710e97e040929ce + MethodDescriptor md = MethodDescriptor.parseDescriptor(desc); + if (md.params.length > 0) { + VarType type = md.params[md.params.length - 1]; -+ if (type.type == CodeConstants.TYPE_OBJECT) { -+ ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(type.value); ++ if (type.getType() == CodeConstants.TYPE_OBJECT) { ++ ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(type.getValue()); + if (node != null && (node.type == ClassNode.CLASS_ANONYMOUS) || (node.access & CodeConstants.ACC_SYNTHETIC) != 0) { + //TODO: Verify that the body is JUST a this([args]) call? + wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(name, desc)); diff --git a/FernFlower-Patches/0004-Fix-field-initalizers.patch b/FernFlower-Patches/0004-Fix-field-initalizers.patch index 484c156..3da1af7 100644 --- a/FernFlower-Patches/0004-Fix-field-initalizers.patch +++ b/FernFlower-Patches/0004-Fix-field-initalizers.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix field initalizers diff --git a/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java -index 55badb664d4a52620710e97e040929ce5414eb9e..f1e02d4a1232fe1e98d554e034ec49601fa2be70 100644 +index 4930acdf38046e1dfe3f04a7e68b4ff88c4ed594..169a613c8b6e84a80895acdc18dfe0aa576c2af6 100644 --- a/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java @@ -3,6 +3,7 @@ package org.jetbrains.java.decompiler.main; @@ -213,7 +213,7 @@ index 55badb664d4a52620710e97e040929ce5414eb9e..f1e02d4a1232fe1e98d554e034ec4960 + private static void makeLaterFieldsInLambdaQualified(NewExprent nexpr, StructClass cl, int fidx) { + boolean isStatic = cl.getFields().get(fidx).hasModifier(CodeConstants.ACC_STATIC); + if (isStatic && nexpr.isLambda() && !nexpr.isMethodReference()) { -+ ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(nexpr.getNewType().value); ++ ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(nexpr.getNewType().getValue()); + MethodWrapper wrapper = child.parent.getWrapper().getMethods().getWithKey(child.lambdaInformation.content_method_key); + + Set s = new HashSet<>(); @@ -241,10 +241,10 @@ index 55badb664d4a52620710e97e040929ce5414eb9e..f1e02d4a1232fe1e98d554e034ec4960 + } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java -index 642a86be9a791759e04cc74ad12ffca4436dfbf6..c79f1a6fc6d13c3e61d877624c18b117a5567ce6 100644 +index ec3a8668a94c7da89091a09a3002fd14346cc684..0f99c8891a4bc70626b2383b22384a1b212fe8da 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java -@@ -31,18 +31,24 @@ public class FieldExprent extends Exprent { +@@ -29,18 +29,24 @@ public class FieldExprent extends Exprent { private final boolean isStatic; private Exprent instance; private final FieldDescriptor descriptor; @@ -269,16 +269,16 @@ index 642a86be9a791759e04cc74ad12ffca4436dfbf6..c79f1a6fc6d13c3e61d877624c18b117 addBytecodeOffsets(bytecodeOffsets); } -@@ -89,7 +95,7 @@ public class FieldExprent extends Exprent { +@@ -87,7 +93,7 @@ public class FieldExprent extends Exprent { if (isStatic) { ClassNode node = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE); - if (node == null || !classname.equals(node.classStruct.qualifiedName) || isAmbiguous()) { + if (node == null || !classname.equals(node.classStruct.qualifiedName) || isAmbiguous() || forceQualified) { - buf.append(DecompilerContext.getImportCollector().getShortNameInClassContext(ExprProcessor.buildJavaClassName(classname))); + buf.append(DecompilerContext.getImportCollector().getNestedNameInClassContext(ExprProcessor.buildJavaClassName(classname))); buf.append("."); } -@@ -185,6 +191,10 @@ public class FieldExprent extends Exprent { +@@ -183,6 +189,10 @@ public class FieldExprent extends Exprent { return name; } diff --git a/FernFlower-Patches/0005-Fix-output-discrepancies-based-on-running-JVM.patch b/FernFlower-Patches/0005-Fix-output-discrepancies-based-on-running-JVM.patch index 5c3cc93..a69f1c4 100644 --- a/FernFlower-Patches/0005-Fix-output-discrepancies-based-on-running-JVM.patch +++ b/FernFlower-Patches/0005-Fix-output-discrepancies-based-on-running-JVM.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix output discrepancies based on running JVM diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java -index e380664d46356ec909049293a89bc4be6823dca8..3dc1f5130dcd0889690078da5bb718256e0780d9 100644 +index a45067feeedaece4546ae2dbc5148fbf9b2c0309..7db5b328969a6dac49054e57b5c00c672ca4ea85 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java -@@ -229,6 +229,7 @@ public class ClassesProcessor implements CodeConstants { +@@ -249,6 +249,7 @@ public class ClassesProcessor implements CodeConstants { stack.add(nestedClass); } } @@ -16,7 +16,7 @@ index e380664d46356ec909049293a89bc4be6823dca8..3dc1f5130dcd0889690078da5bb71825 } } } -@@ -434,7 +435,7 @@ public class ClassesProcessor implements CodeConstants { +@@ -454,7 +455,7 @@ public class ClassesProcessor implements CodeConstants { } @@ -25,8 +25,8 @@ index e380664d46356ec909049293a89bc4be6823dca8..3dc1f5130dcd0889690078da5bb71825 public static final int CLASS_ROOT = 0; public static final int CLASS_MEMBER = 1; public static final int CLASS_ANONYMOUS = 2; -@@ -516,6 +517,12 @@ public class ClassesProcessor implements CodeConstants { - return node.wrapper; +@@ -545,6 +546,12 @@ public class ClassesProcessor implements CodeConstants { + isNonSealed = nonSealed; } + @Override @@ -39,10 +39,18 @@ index e380664d46356ec909049293a89bc4be6823dca8..3dc1f5130dcd0889690078da5bb71825 public String method_name; public String method_descriptor; diff --git a/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java -index 2ad5b20116396973442a5e956a9c30f0a1bada13..77371c62159055cb97cfdd207ece9d852f38a441 100644 +index 05e6e2d720aa5812ef12c4741eab06b8ea477e0f..f9c8c6a0334512699c545c881207194745427c96 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java -@@ -107,6 +107,8 @@ public class LambdaProcessor { +@@ -19,6 +19,7 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; + + import java.io.IOException; + import java.util.BitSet; ++import java.util.Collections; + import java.util.HashMap; + import java.util.List; + import java.util.Map; +@@ -110,6 +111,8 @@ public class LambdaProcessor { mt.releaseResources(); } @@ -51,7 +59,7 @@ index 2ad5b20116396973442a5e956a9c30f0a1bada13..77371c62159055cb97cfdd207ece9d85 // build class hierarchy on lambda for (ClassNode nd : node.nested) { if (nd.type == ClassNode.CLASS_LAMBDA) { -@@ -116,6 +118,7 @@ public class LambdaProcessor { +@@ -119,6 +122,7 @@ public class LambdaProcessor { parent_class.nested.add(nd); nd.parent = parent_class; @@ -60,10 +68,10 @@ index 2ad5b20116396973442a5e956a9c30f0a1bada13..77371c62159055cb97cfdd207ece9d85 } } diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -index da175324e5b04e7980225f97d1b30d729d5d46a2..3625c482744fe98f41fda3736355c50b7ed514e6 100644 +index 7a8655702381a23063c06594aa07bdd9b5c0a8fe..bc116db0c8ad1b1312f220b9b9e22c5d7cdddad8 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -@@ -217,6 +217,7 @@ public class NestedClassProcessor { +@@ -218,6 +218,7 @@ public class NestedClassProcessor { if (setEnclosing.contains(node.classStruct.qualifiedName)) { node.nested.add(child); child.parent = node; @@ -72,10 +80,10 @@ index da175324e5b04e7980225f97d1b30d729d5d46a2..3625c482744fe98f41fda3736355c50b return true; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java -index 7ef6d2f64c10d9543977690f19ff0f6bea2a3615..8d0100d6e80a3b8dd743a6c21139348217d742b7 100644 +index fe2d3b14c6e48dc08831123ef80902bc3126ceca..86cac9e08f0f0d3ebd43353b64eba9560279de55 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java -@@ -193,7 +193,7 @@ public final class DomHelper { +@@ -194,7 +194,7 @@ public final class DomHelper { RootStatement root = graphToStatement(graph); @@ -84,7 +92,7 @@ index 7ef6d2f64c10d9543977690f19ff0f6bea2a3615..8d0100d6e80a3b8dd743a6c211393482 // try { // DotExporter.toDotFile(root.getFirst().getStats().get(13), new File("c:\\Temp\\stat1.dot")); -@@ -203,7 +203,7 @@ public final class DomHelper { +@@ -204,7 +204,7 @@ public final class DomHelper { throw new RuntimeException("parsing failure!"); } @@ -93,7 +101,7 @@ index 7ef6d2f64c10d9543977690f19ff0f6bea2a3615..8d0100d6e80a3b8dd743a6c211393482 SequenceHelper.condenseSequences(root); root.buildMonitorFlags(); -@@ -466,11 +466,11 @@ public final class DomHelper { +@@ -467,11 +467,11 @@ public final class DomHelper { boolean same = (post == head); @@ -107,7 +115,7 @@ index 7ef6d2f64c10d9543977690f19ff0f6bea2a3615..8d0100d6e80a3b8dd743a6c211393482 setHandlers.add(head); while (true) { -@@ -615,7 +615,7 @@ public final class DomHelper { +@@ -616,7 +616,7 @@ public final class DomHelper { set.removeAll(setOldNodes); if (setOldNodes.contains(key)) { @@ -117,10 +125,10 @@ index 7ef6d2f64c10d9543977690f19ff0f6bea2a3615..8d0100d6e80a3b8dd743a6c211393482 } else { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -index 966cd442c8b991aeae0055a114f01426debb59da..010566ba18cc005e72ddcbf7eea17f0f533a87d9 100644 +index f7addc6af8928ee2b2d1b9a09d13750413d4721f..79dceb558c4b99591e87d917739bcf4c66bda292 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -@@ -797,6 +797,7 @@ public class ExprProcessor implements CodeConstants { +@@ -933,6 +933,7 @@ public class ExprProcessor implements CodeConstants { } TextBuffer buf = new TextBuffer(); @@ -129,10 +137,10 @@ index 966cd442c8b991aeae0055a114f01426debb59da..010566ba18cc005e72ddcbf7eea17f0f for (Exprent expr : lst) { if (buf.length() > 0 && expr.type == Exprent.EXPRENT_VAR && ((VarExprent)expr).isClassDef()) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java -index 9f5289507e7d8f25b4f2f269ee239643b3cd7698..3682bbb940e6855019cb5b10b7a7de6d703e5b62 100644 +index 13d747a5ec6b961763f70b9174efeaf976336dbc..5428c1d1b10e0fbaa7c3b62725acd34d0632f37c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java -@@ -481,10 +481,17 @@ public class FinallyProcessor { +@@ -480,10 +480,17 @@ public class FinallyProcessor { // so remove dummy exit startBlocks.remove(graph.getLast()); startBlocks.removeAll(tryBlocks); @@ -151,7 +159,7 @@ index 9f5289507e7d8f25b4f2f269ee239643b3cd7698..3682bbb940e6855019cb5b10b7a7de6d Area arr = compareSubgraphsEx(graph, start, catchBlocks, first, finallytype, mapLast, skippedFirst); if (arr == null) { -@@ -507,8 +514,17 @@ public class FinallyProcessor { +@@ -506,8 +513,17 @@ public class FinallyProcessor { // DotExporter.toDotFile(graph, new File("c:\\Temp\\fern5.dot"), true); // } catch(Exception ex){ex.printStackTrace();} @@ -171,10 +179,10 @@ index 9f5289507e7d8f25b4f2f269ee239643b3cd7698..3682bbb940e6855019cb5b10b7a7de6d if (entry.getValue()) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/LabelHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/LabelHelper.java -index bf4d889cea52307dede26a398ac9a81ec4577934..05e945fa82190610c0147389204d579d3d1d61e4 100644 +index fba6145dd11f851b2487c11ad2b529c94ef72c35..d7397455f8a67bb220e3236da77d0c4b14aeb1e5 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/LabelHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/LabelHelper.java -@@ -19,7 +19,7 @@ public final class LabelHelper { +@@ -23,7 +23,7 @@ public final class LabelHelper { liftClosures(root); @@ -183,7 +191,7 @@ index bf4d889cea52307dede26a398ac9a81ec4577934..05e945fa82190610c0147389204d579d lowClosures(root); } -@@ -117,7 +117,7 @@ public final class LabelHelper { +@@ -120,7 +120,7 @@ public final class LabelHelper { lowContinueLabels(st, edges); } else { @@ -193,10 +201,10 @@ index bf4d889cea52307dede26a398ac9a81ec4577934..05e945fa82190610c0147389204d579d } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorTreeExceptionFilter.java b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorTreeExceptionFilter.java -index d8b587fff8b748fd4187453c31a5b39e43bc8ecb..318d95cd5427cda3ec721797c181fe68cb95b6db 100644 +index 09e36dc4686d5e445a48325295ace392a79182f7..da65e74c53d2dc8f0e5f5ab538fe7b9defc5b135 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorTreeExceptionFilter.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorTreeExceptionFilter.java -@@ -13,10 +13,10 @@ public class DominatorTreeExceptionFilter { +@@ -14,10 +14,10 @@ public class DominatorTreeExceptionFilter { private final Statement statement; // idom, nodes @@ -209,7 +217,7 @@ index d8b587fff8b748fd4187453c31a5b39e43bc8ecb..318d95cd5427cda3ec721797c181fe68 // handler, head dom private Map mapExceptionDoms = new HashMap<>(); -@@ -66,7 +66,7 @@ public class DominatorTreeExceptionFilter { +@@ -67,7 +67,7 @@ public class DominatorTreeExceptionFilter { for (int index = lstKeys.size() - 1; index >= 0; index--) { Integer key = lstKeys.get(index); Integer idom = orderedIDoms.get(index); @@ -218,8 +226,8 @@ index d8b587fff8b748fd4187453c31a5b39e43bc8ecb..318d95cd5427cda3ec721797c181fe68 } Integer firstid = statement.getFirst().id; -@@ -78,7 +78,7 @@ public class DominatorTreeExceptionFilter { - List lstPreds = stat.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_BACKWARD); +@@ -79,7 +79,7 @@ public class DominatorTreeExceptionFilter { + List lstPreds = stat.getNeighbours(EdgeType.EXCEPTION, EdgeDirection.BACKWARD); if (!lstPreds.isEmpty()) { - Set set = new HashSet<>(); @@ -228,7 +236,7 @@ index d8b587fff8b748fd4187453c31a5b39e43bc8ecb..318d95cd5427cda3ec721797c181fe68 for (Statement st : lstPreds) { set.add(st.id); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/FastExtendedPostdominanceHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/FastExtendedPostdominanceHelper.java -index 71ef24b4bf403112f7c5438c135ec06c7e452c80..e8568f4a93c65c6ac1f7b102ac800724531d9d05 100644 +index 82ae0a25a20d2727f611d359e699d6666d1e0ae4..a86f0d2887c6c19cb1d911ec43830eb69f8aaada 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/FastExtendedPostdominanceHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/FastExtendedPostdominanceHelper.java @@ -14,9 +14,9 @@ public class FastExtendedPostdominanceHelper { @@ -264,50 +272,39 @@ index 71ef24b4bf403112f7c5438c135ec06c7e452c80..e8568f4a93c65c6ac1f7b102ac800724 return res; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -index 9fa58125289555ee7a4c565574acf74afcc413d0..691d613050f89cce24136dc957a38b65cc51fc4c 100644 +index 3882cfd68af7f55938311363a69a2dded3fffbab..48d38ff8657fd6d237fe2d75677d89b8bbd8852d 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -@@ -177,15 +177,15 @@ public class ConstExprent extends Exprent { - } - } - else if (Float.isNaN(floatVal)) { -- return new TextBuffer("0.0F / 0.0"); -+ return new TextBuffer("0.0F / 0.0F"); - } - else if (floatVal == Float.POSITIVE_INFINITY) { -- return new TextBuffer("1.0F / 0.0"); -+ return new TextBuffer("1.0F / 0.0F"); - } +@@ -220,7 +220,7 @@ public class ConstExprent extends Exprent { else if (floatVal == Float.NEGATIVE_INFINITY) { -- return new TextBuffer("-1.0F / 0.0"); -+ return new TextBuffer("-1.0F / 0.0F"); + return new TextBuffer("-1.0F / 0.0F"); } - return new TextBuffer(value.toString()).append('F'); + return new TextBuffer(trimZeros(value.toString())).append('F'); case CodeConstants.TYPE_DOUBLE: double doubleVal = (Double)value; -@@ -207,15 +207,15 @@ public class ConstExprent extends Exprent { +@@ -251,15 +251,15 @@ public class ConstExprent extends Exprent { } } else if (Double.isNaN(doubleVal)) { -- return new TextBuffer("0.0D / 0.0"); +- return new TextBuffer("0.0 / 0.0"); + return new TextBuffer("0.0D / 0.0D"); } else if (doubleVal == Double.POSITIVE_INFINITY) { -- return new TextBuffer("1.0D / 0.0"); +- return new TextBuffer("1.0 / 0.0"); + return new TextBuffer("1.0D / 0.0D"); } else if (doubleVal == Double.NEGATIVE_INFINITY) { -- return new TextBuffer("-1.0D / 0.0"); +- return new TextBuffer("-1.0 / 0.0"); + return new TextBuffer("-1.0D / 0.0D"); } -- return new TextBuffer(value.toString()).append('D'); +- return new TextBuffer(value.toString()); + return new TextBuffer(trimZeros(value.toString())).append('D'); case CodeConstants.TYPE_NULL: return new TextBuffer("null"); -@@ -233,6 +233,18 @@ public class ConstExprent extends Exprent { +@@ -277,6 +277,18 @@ public class ConstExprent extends Exprent { throw new RuntimeException("invalid constant type: " + constType); } @@ -324,8 +321,8 @@ index 9fa58125289555ee7a4c565574acf74afcc413d0..691d613050f89cce24136dc957a38b65 + return value.substring(0, i + 1); + } - public boolean isNull() { - return CodeConstants.TYPE_NULL == constType.type; + private boolean inConstantVariable(String classSignature, String variableName) { + ClassesProcessor.ClassNode node = (ClassesProcessor.ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java index cc1f537e71af0748b7b97d7d8489198e2a677cc9..0994d9466eda95b46d3f234bf977e8e9aa0e0899 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java @@ -381,7 +378,7 @@ index cc1f537e71af0748b7b97d7d8489198e2a677cc9..0994d9466eda95b46d3f234bf977e8e9 // IMatchable implementation // ***************************************************************************** diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java -index 29e7030a24be3d75161885ae1adf38cf5a94a001..6efce5e4b043b2dcb58b4dc21f85da9ac9081a7a 100644 +index 53afa148cf8ae11ceeacf454673a1963d4892212..a1f931b79adb35660ee0f29b1d522214384a044f 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java @@ -22,6 +22,7 @@ import org.jetbrains.java.decompiler.util.SFormsFastMapDirect; @@ -390,9 +387,9 @@ index 29e7030a24be3d75161885ae1adf38cf5a94a001..6efce5e4b043b2dcb58b4dc21f85da9a import java.util.List; +import java.util.ArrayList; import java.util.Map.Entry; + import java.util.Objects; - public class SSAConstructorSparseEx { -@@ -56,7 +57,7 @@ public class SSAConstructorSparseEx { +@@ -57,7 +58,7 @@ public class SSAConstructorSparseEx { // DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr12_my.dot")); // } catch(Exception ex) {ex.printStackTrace();} @@ -402,10 +399,10 @@ index 29e7030a24be3d75161885ae1adf38cf5a94a001..6efce5e4b043b2dcb58b4dc21f85da9a setInit.add(i); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java -index 4edec05872a22da324cb24961825b9d66811a5e2..f5719d1a14fc0fd41393e44fe84e0d3c9370d323 100644 +index c6287d302d83548e19f51260e1e984dc991e7f86..80d6d34d3329f831e8add4a0617b8e8bf8a86006 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java -@@ -71,7 +71,7 @@ public class SSAUConstructorSparseEx { +@@ -68,7 +68,7 @@ public class SSAUConstructorSparseEx { FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.buildDirectGraph(root); @@ -415,7 +412,7 @@ index 4edec05872a22da324cb24961825b9d66811a5e2..f5719d1a14fc0fd41393e44fe84e0d3c setInit.add(i); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/GeneralStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/GeneralStatement.java -index 0891a4758e43affe4c8f7df991a79bd9475cafc8..c098f3be7e2b67de21ea499ca5e12f120b47572e 100644 +index 58f94462caa7a8212c3e9e36e343e2f4c55582f5..d355e63f8a3252bf58f0cdf18f42e6732132efef 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/GeneralStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/GeneralStatement.java @@ -5,7 +5,8 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; @@ -438,31 +435,32 @@ index 0891a4758e43affe4c8f7df991a79bd9475cafc8..c098f3be7e2b67de21ea499ca5e12f12 for (Statement st : set) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java -index a5b9d3aa23c0f50d4504ab67de8ccf01d072ae73..28c2f2c8bf29d0d12f2a63be231399adf9030935 100644 +index 133d87f45ab3b057e78589a53529821e5a6a6dea..119949c8bd35082b95cbfde2b185aa2d23034224 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java -@@ -63,7 +63,15 @@ public final class SwitchStatement extends Statement { - - default_edge = head.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL).get(0); - -- for (Statement st : lstNodes) { +@@ -46,7 +46,16 @@ public final class SwitchStatement extends Statement { + regularSuccessors.remove(post); + } + defaultEdge = head.getSuccessorEdges(EdgeType.DIRECT_ALL).get(0); +- for (Statement successor : regularSuccessors) { ++ + //We need to use set above in case we have multiple edges to the same node. But HashSets iterator is not ordered, so sort -+ List sorted = new ArrayList<>(lstNodes); ++ List sorted = new ArrayList<>(regularSuccessors); + Collections.sort(sorted, new Comparator() { + @Override + public int compare(Statement o1, Statement o2) { + return o1.id - o2.id; + } + }); -+ for (Statement st : sorted) { - stats.addWithKey(st, st.id); ++ for (Statement successor : sorted) { + stats.addWithKey(successor, successor.id); } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java -index adbb6fd39f8dca8e6ef97916354e3cb4e59340c9..c211d680fe9d488b302c92e0ad1ba37f233675ec 100644 +index 0bdf9048e55b5d8873959ce3146b913805406fab..f9ffa3a3279fd8c3639489260a0dc4a01950c1a2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java -@@ -215,7 +215,10 @@ public class VarVersionsProcessor { +@@ -277,7 +277,10 @@ public class VarVersionsProcessor { Map mapOriginalVarIndices = new HashMap<>(); // map var-version pairs on new var indexes @@ -475,40 +473,32 @@ index adbb6fd39f8dca8e6ef97916354e3cb4e59340c9..c211d680fe9d488b302c92e0ad1ba37f if (pair.version >= 0) { int newIndex = pair.version == 1 ? pair.var : counters.getCounterAndIncrement(CounterContainer.VAR_COUNTER); diff --git a/testData/results/MoreAnnotations.dec b/testData/results/MoreAnnotations.dec -index 37302cc3db53fe0bbcfdab2e7a9653812a320235..069c0334a1df23c17159f8f199045438559b7687 100644 +index 7ea22e010e25dae99314be45985743c85da03b33..8a16a352f46a45a57f5dd2cbb8fbd14161178022 100644 --- a/testData/results/MoreAnnotations.dec +++ b/testData/results/MoreAnnotations.dec -@@ -34,8 +34,8 @@ public @interface MoreAnnotations { - @MoreAnnotations( +@@ -35,7 +35,7 @@ public @interface MoreAnnotations { intArray = {1, 0, 2147483647, -2147483648}, byteArray = {1, 0, 127, -128, -1}, -- floatArray = {1.0F, 0.0F, 3.4028235E38F, 1.4E-45F, 0.0F / 0.0, 1.0F / 0.0, -1.0F / 0.0}, -- doubleArray = {1.0D, 0.0D, 1.7976931348623157E308D, 4.9E-324D, 0.0D / 0.0, 1.0D / 0.0, -1.0D / 0.0}, -+ floatArray = {1.0F, 0.0F, 3.4028235E38F, 1.4E-45F, 0.0F / 0.0F, 1.0F / 0.0F, -1.0F / 0.0F}, + floatArray = {1.0F, 0.0F, 3.4028235E38F, 1.4E-45F, 0.0F / 0.0F, 1.0F / 0.0F, -1.0F / 0.0F}, +- doubleArray = {1.0, 0.0, 1.7976931348623157E308, 4.9E-324, 0.0 / 0.0, 1.0 / 0.0, -1.0 / 0.0}, + doubleArray = {1.0D, 0.0D, 1.7976931348623157E308D, 4.9E-324D, 0.0D / 0.0D, 1.0D / 0.0D, -1.0D / 0.0D}, booleanArray = {true, false}, shortArray = {1, 0, 32767, -32768, -1}, longArray = {1L, 0L, 9223372036854775807L, -9223372036854775808L}, -@@ -51,9 +51,9 @@ public @interface MoreAnnotations { +@@ -53,7 +53,7 @@ public @interface MoreAnnotations { - byte byteValue() default 1; + float floatValue() default 1.0F / 0.0F; -- float floatValue() default 1.0F / 0.0; -+ float floatValue() default 1.0F / 0.0F; - -- double doubleValue() default 0.0D / 0.0; +- double doubleValue() default 0.0 / 0.0; + double doubleValue() default 0.0D / 0.0D; boolean booleanValue() default true; -@@ -75,9 +75,9 @@ public @interface MoreAnnotations { - - byte[] byteArray() default {1, 0, 127, -128, -1}; +@@ -77,7 +77,7 @@ public @interface MoreAnnotations { -- float[] floatArray() default {1.0F, 0.0F, 3.4028235E38F, 1.4E-45F, 0.0F / 0.0, 1.0F / 0.0, -1.0F / 0.0}; -+ float[] floatArray() default {1.0F, 0.0F, 3.4028235E38F, 1.4E-45F, 0.0F / 0.0F, 1.0F / 0.0F, -1.0F / 0.0F}; + float[] floatArray() default {1.0F, 0.0F, 3.4028235E38F, 1.4E-45F, 0.0F / 0.0F, 1.0F / 0.0F, -1.0F / 0.0F}; -- double[] doubleArray() default {1.0D, 0.0D, 1.7976931348623157E308D, 4.9E-324D, 0.0D / 0.0, 1.0D / 0.0, -1.0D / 0.0}; +- double[] doubleArray() default {1.0, 0.0, 1.7976931348623157E308, 4.9E-324, 0.0 / 0.0, 1.0 / 0.0, -1.0 / 0.0}; + double[] doubleArray() default {1.0D, 0.0D, 1.7976931348623157E308D, 4.9E-324D, 0.0D / 0.0D, 1.0D / 0.0D, -1.0D / 0.0D}; boolean[] booleanArray() default {true, false}; @@ -532,7 +522,7 @@ index 37302cc3db53fe0bbcfdab2e7a9653812a320235..069c0334a1df23c17159f8f199045438 } diff --git a/testData/results/TestAnonymousClass.dec b/testData/results/TestAnonymousClass.dec -index 924b7641e3454daf3ce738de750dfcfa587fa18d..14c92f960012ea63747096f9237fca7ee5e70ced 100644 +index 9cd9f538a6a53faa511ceac028001ccef418c3aa..3ea3c7058eadc696e538c72e018bd4076b07a397 100644 --- a/testData/results/TestAnonymousClass.dec +++ b/testData/results/TestAnonymousClass.dec @@ -67,15 +67,8 @@ public abstract class TestAnonymousClass { @@ -540,9 +530,9 @@ index 924b7641e3454daf3ce738de750dfcfa587fa18d..14c92f960012ea63747096f9237fca7e }// 40 - static class InnerRecursive { -- TestAnonymousClass.InnerRecursive r; +- InnerRecursive r; - -- public InnerRecursive(TestAnonymousClass.InnerRecursive var1) { +- public InnerRecursive(InnerRecursive var1) { - this.r = var1;// 105 - }// 106 - @@ -636,7 +626,7 @@ index 924b7641e3454daf3ce738de750dfcfa587fa18d..14c92f960012ea63747096f9237fca7e 18 104 diff --git a/testData/results/TestAnonymousClassConstructor.dec b/testData/results/TestAnonymousClassConstructor.dec -index 66960ce40f72703d3577549847d033f011007834..63abd4acbe8cf73eb9628724b632af1a9ca231a3 100644 +index e4d02ffde3166e0b22f82550fa73bdea4c6d02ac..e48e5bc934ccd1ed1aedd0fcde645026bbb4e3fe 100644 --- a/testData/results/TestAnonymousClassConstructor.dec +++ b/testData/results/TestAnonymousClassConstructor.dec @@ -65,16 +65,16 @@ class TestAnonymousClassConstructor { @@ -780,7 +770,7 @@ index 66960ce40f72703d3577549847d033f011007834..63abd4acbe8cf73eb9628724b632af1a 57 63 diff --git a/testData/results/TestClassSimpleBytecodeMapping.dec b/testData/results/TestClassSimpleBytecodeMapping.dec -index 8883fab6ffd4b5f8b8b656b96e9a5c45d0e1bfb9..d5f7070f5b6618b11ea075941af29d4278059b59 100644 +index 5b26ef8b403a0cc1c2b9858ed3c9ce84108c7562..7c03120a91f0fc0a5cecbbff4cd7b2c0d0da2c94 100644 --- a/testData/results/TestClassSimpleBytecodeMapping.dec +++ b/testData/results/TestClassSimpleBytecodeMapping.dec @@ -33,17 +33,17 @@ public class TestClassSimpleBytecodeMapping { @@ -841,33 +831,8 @@ index 8883fab6ffd4b5f8b8b656b96e9a5c45d0e1bfb9..d5f7070f5b6618b11ea075941af29d42 +55 <-> 45 Not mapped: 39 -diff --git a/testData/results/TestConstants.dec b/testData/results/TestConstants.dec -index 28df2c294ca1c0818ffad43052919c61c262c16a..1170f1a5876121e55bc5c58a2d10afeac8d1527f 100644 ---- a/testData/results/TestConstants.dec -+++ b/testData/results/TestConstants.dec -@@ -16,14 +16,14 @@ public class TestConstants { - static final int IMax = 2147483647; - static final long LMin = -9223372036854775808L; - static final long LMax = 9223372036854775807L; -- static final float FNan = 0.0F / 0.0; -- static final float FNeg = -1.0F / 0.0; -- static final float FPos = 1.0F / 0.0; -+ static final float FNan = 0.0F / 0.0F; -+ static final float FNeg = -1.0F / 0.0F; -+ static final float FPos = 1.0F / 0.0F; - static final float FMin = 1.4E-45F; - static final float FMax = 3.4028235E38F; -- static final double DNan = 0.0D / 0.0; -- static final double DNeg = -1.0D / 0.0; -- static final double DPos = 1.0D / 0.0; -+ static final double DNan = 0.0D / 0.0D; -+ static final double DNeg = -1.0D / 0.0D; -+ static final double DPos = 1.0D / 0.0D; - static final double DMin = 4.9E-324D; - static final double DMax = 1.7976931348623157E308D; - diff --git a/testData/results/TestExtendingSubclass.dec b/testData/results/TestExtendingSubclass.dec -index 5e13985808328287c750d776eee29041bec8e3fe..2caf74011a7beee7fd2a9fdebe1873be625a8f1a 100644 +index f7be1b46d3058aba92f7a21ffc9558068dd26226..6bab8435926e1c10171fc97b61075ec58dba2572 100644 --- a/testData/results/TestExtendingSubclass.dec +++ b/testData/results/TestExtendingSubclass.dec @@ -1,35 +1,35 @@ @@ -879,7 +844,7 @@ index 5e13985808328287c750d776eee29041bec8e3fe..2caf74011a7beee7fd2a9fdebe1873be + }// 9 + } + - class Subclass2 extends TestExtendingSubclass.Subclass1 { + class Subclass2 extends Subclass1 { Subclass2(String name) { super(name);// 14 }// 15 @@ -920,11 +885,11 @@ index 5e13985808328287c750d776eee29041bec8e3fe..2caf74011a7beee7fd2a9fdebe1873be 8 13 diff --git a/testData/results/TestInnerLocal.dec b/testData/results/TestInnerLocal.dec -index af4fb30496706a46dcc578948b4c66ef90b6d65e..f728ad7e3493b296f88d919a028b646096f733c7 100644 +index b270e4eea9caf36d5c66b64d18e33ca8d8fcae10..9009b85453ba2aae2ac4e32f94fb082dcd6d3c81 100644 --- a/testData/results/TestInnerLocal.dec +++ b/testData/results/TestInnerLocal.dec @@ -30,6 +30,14 @@ public class TestInnerLocal { - new TestInnerLocal.Inner1Static.Inner2Static("test");// 26 + new Inner1Static.Inner2Static("test");// 26 }// 27 + class Inner1 { @@ -1225,7 +1190,7 @@ index 21f0f129d1bc260e2dbc7ce77f07ece57711bf75..af7ce865f5d946980010ee02c3e5be38 37 <-> 19 39 <-> 22 diff --git a/testData/results/TestSwitchOnEnum.dec b/testData/results/TestSwitchOnEnum.dec -index b6984c399ceff5434ddf72837649389341a00ea5..34064819cc6a520a13bc3fd718a046861414ae4c 100644 +index e63cfe50c3d0c9fddd4f3051d7bda5df33523cbb..6e1f77fa247005cb8bb012a91aff96ed78103204 100644 --- a/testData/results/TestSwitchOnEnum.dec +++ b/testData/results/TestSwitchOnEnum.dec @@ -36,15 +36,15 @@ public class TestSwitchOnEnum { diff --git a/FernFlower-Patches/0006-Convert-Exprent.bytecode-to-a-BitMap.patch b/FernFlower-Patches/0006-Convert-Exprent.bytecode-to-a-BitMap.patch index 5a04936..331144b 100644 --- a/FernFlower-Patches/0006-Convert-Exprent.bytecode-to-a-BitMap.patch +++ b/FernFlower-Patches/0006-Convert-Exprent.bytecode-to-a-BitMap.patch @@ -102,19 +102,19 @@ index 61810d96bea8e35006df80630e9caf029b33b41c..6379ccadaf4d0b7bf2a4001481b408dd \ No newline at end of file +} diff --git a/src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java b/src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java -index 265ffca9a139bd0cb7a4a2e1e68a8f3032939b9a..e89d9e45ac59e28e49a82c1838f24d57f029406b 100644 +index 28c4f50ec90546100a5f16e9c6d60aa931a00e0d..9eb4fbab0ede1b19bfaa9a433c182e00b4f07a0b 100644 --- a/src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java +++ b/src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java -@@ -190,4 +190,19 @@ public class BasicBlock implements IGraphNode { - public List getPredExceptions() { - return predExceptions; +@@ -149,4 +149,19 @@ public class BasicBlock implements IGraphNode { + public String toString() { + return id + ":" + DecompilerContext.getNewLineSeparator() + seq.toString(0); } + + public int getStartInstruction() { + if (seq.isEmpty()) { + return 0; + } -+ return instrOldOffsets.get(0); ++ return originalOffsets.get(0); + } + + public int getEndInstruction() { @@ -122,10 +122,9 @@ index 265ffca9a139bd0cb7a4a2e1e68a8f3032939b9a..e89d9e45ac59e28e49a82c1838f24d57 + return 0; + } + int end = seq.getLastInstr().length; -+ return end + instrOldOffsets.get(size() -1); ++ return end + originalOffsets.get(size() -1); + } } -\ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java b/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java index c6a23b3277c3a93be621d6686b1554d51be01c9b..32ca965883f26cd8944bfb5e838d5cf584142f68 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java @@ -145,10 +144,10 @@ index c6a23b3277c3a93be621d6686b1554d51be01c9b..32ca965883f26cd8944bfb5e838d5cf5 } } diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -index 3625c482744fe98f41fda3736355c50b7ed514e6..5606e91f5ea92b921d73ea9d85360a8d924c14fc 100644 +index bc116db0c8ad1b1312f220b9b9e22c5d7cdddad8..b274560fadc6911d272c5c9358d1cdf7eb808357 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -@@ -532,7 +532,7 @@ public class NestedClassProcessor { +@@ -533,7 +533,7 @@ public class NestedClassProcessor { if (mapParamsToNewVars.containsKey(varIndex)) { VarVersionPair newVar = mapParamsToNewVars.get(varIndex); method.varproc.getExternalVars().add(newVar); @@ -157,7 +156,7 @@ index 3625c482744fe98f41fda3736355c50b7ed514e6..5606e91f5ea92b921d73ea9d85360a8d } } else if (exprent.type == Exprent.EXPRENT_FIELD) { -@@ -543,7 +543,7 @@ public class NestedClassProcessor { +@@ -544,7 +544,7 @@ public class NestedClassProcessor { // mapFieldsToNewVars.containsKey(key)) { VarVersionPair newVar = mapFieldsToNewVars.get(key); method.varproc.getExternalVars().add(newVar); @@ -167,10 +166,10 @@ index 3625c482744fe98f41fda3736355c50b7ed514e6..5606e91f5ea92b921d73ea9d85360a8d } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java -index 3b255bed5f2a158d9caa676784e4cdf78d81875d..a41e8de55f8edf43d7271ec02b6bca1e14138a1b 100644 +index 228a7b835307d950e030fe16bcb2e8a41c0fafb3..f1f3e7c7e903dd0571c2a18f1ed976999cff99da 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java -@@ -10,8 +10,8 @@ import org.jetbrains.java.decompiler.struct.gen.VarType; +@@ -11,8 +11,8 @@ import org.jetbrains.java.decompiler.struct.gen.VarType; import java.util.ArrayList; import java.util.Arrays; @@ -190,101 +189,69 @@ index 3b255bed5f2a158d9caa676784e4cdf78d81875d..a41e8de55f8edf43d7271ec02b6bca1e Exprent func = lstOperands.get(0); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -index 010566ba18cc005e72ddcbf7eea17f0f533a87d9..6aa061689f525158f31aee3fdcc114ac89f11ae5 100644 +index 79dceb558c4b99591e87d917739bcf4c66bda292..80d5dab3d3f0101ba5907e6a8e31d275834a73b2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -@@ -282,7 +282,15 @@ public class ExprProcessor implements CodeConstants { - +@@ -267,7 +267,15 @@ public class ExprProcessor implements CodeConstants { + for (int i = 0; i < seq.length(); i++) { Instruction instr = seq.getInstr(i); - Integer bytecode_offset = block.getOldOffset(i); -- Set bytecode_offsets = bytecode_offset >= 0 ? Collections.singleton(bytecode_offset) : null; -+ BitSet bytecode_offsets = null; -+ if (bytecode_offset >= 0) { -+ bytecode_offsets = new BitSet(); -+ bytecode_offsets.set(bytecode_offset); -+ int end_offset = block.getOldOffset(i+1); -+ if (end_offset > bytecode_offset) { -+ bytecode_offsets.set(bytecode_offset, end_offset); + Integer offset = block.getOriginalOffset(i); +- Set offsets = offset >= 0 ? Collections.singleton(offset) : null; ++ BitSet offsets = null; ++ if (offset >= 0) { ++ offsets = new BitSet(); ++ offsets.set(offset); ++ int end_offset = block.getOriginalOffset(i+1); ++ if (end_offset > offset) { ++ offsets.set(offset, end_offset); + } + } switch (instr.opcode) { case opc_aconst_null: -@@ -322,7 +330,7 @@ public class ExprProcessor implements CodeConstants { +@@ -308,7 +316,7 @@ public class ExprProcessor implements CodeConstants { case opc_fload: case opc_dload: case opc_aload: -- pushEx(stack, exprlist, new VarExprent(instr.operand(0), varTypes[instr.opcode - opc_iload], varProcessor, bytecode_offset)); -+ pushEx(stack, exprlist, new VarExprent(instr.operand(0), varTypes[instr.opcode - opc_iload], varProcessor, bytecode_offsets)); +- pushEx(stack, exprList, new VarExprent(instr.operand(0), varTypes[instr.opcode - opc_iload], varProcessor, offset)); ++ pushEx(stack, exprList, new VarExprent(instr.operand(0), varTypes[instr.opcode - opc_iload], varProcessor, offsets)); break; case opc_iaload: case opc_laload: -@@ -352,8 +360,11 @@ public class ExprProcessor implements CodeConstants { - case opc_astore: - Exprent expr = stack.pop(); - int varindex = instr.operand(0); -+ if (bytecode_offsets != null) { //TODO: Figure out why this nulls in some cases -+ bytecode_offsets.set(bytecode_offset, bytecode_offset + instr.length); +@@ -331,7 +339,10 @@ public class ExprProcessor implements CodeConstants { + case opc_astore: { + Exprent value = stack.pop(); + int varIndex = instr.operand(0); +- VarExprent left = new VarExprent(varIndex, varTypes[instr.opcode - opc_istore], varProcessor, nextMeaningfulOffset(block, i)); ++ if (offsets != null) { //TODO: Figure out why this nulls in some cases ++ offsets.set(offset, offset + instr.length); + } - AssignmentExprent assign = new AssignmentExprent( -- new VarExprent(varindex, varTypes[instr.opcode - opc_istore], varProcessor, nextMeaningfulOffset(block, i)), expr, bytecode_offsets); -+ new VarExprent(varindex, varTypes[instr.opcode - opc_istore], varProcessor, bytecode_offsets), expr, bytecode_offsets); - exprlist.add(assign); ++ VarExprent left = new VarExprent(varIndex, varTypes[instr.opcode - opc_istore], varProcessor, offsets); + exprList.add(new AssignmentExprent(left, value, offsets)); break; - case opc_iastore: -@@ -415,7 +426,7 @@ public class ExprProcessor implements CodeConstants { - pushEx(stack, exprlist, new FunctionExprent(FunctionExprent.FUNCTION_NEG, stack, bytecode_offsets)); + } +@@ -393,7 +404,7 @@ public class ExprProcessor implements CodeConstants { + pushEx(stack, exprList, new FunctionExprent(FunctionExprent.FUNCTION_NEG, stack, offsets)); break; - case opc_iinc: -- VarExprent vevar = new VarExprent(instr.operand(0), VarType.VARTYPE_INT, varProcessor); -+ VarExprent vevar = new VarExprent(instr.operand(0), VarType.VARTYPE_INT, varProcessor, bytecode_offsets); - exprlist.add(new AssignmentExprent(vevar, new FunctionExprent( - instr.operand(1) < 0 ? FunctionExprent.FUNCTION_SUB : FunctionExprent.FUNCTION_ADD, Arrays - .asList(vevar.copy(), new ConstExprent(VarType.VARTYPE_INT, Math.abs(instr.operand(1)), null)), -@@ -614,23 +625,6 @@ public class ExprProcessor implements CodeConstants { - } - } - -- private static int nextMeaningfulOffset(BasicBlock block, int index) { -- InstructionSequence seq = block.getSeq(); -- while (++index < seq.length()) { -- switch (seq.getInstr(index).opcode) { -- case opc_nop: -- case opc_istore: -- case opc_lstore: -- case opc_fstore: -- case opc_dstore: -- case opc_astore: -- continue; -- } -- return block.getOldOffset(index); -- } -- return -1; -- } -- - private void pushEx(ExprentStack stack, List exprlist, Exprent exprent) { - pushEx(stack, exprlist, exprent, null); - } -@@ -932,4 +926,4 @@ public class ExprProcessor implements CodeConstants { - return VarType.VARTYPE_INT.isStrictSuperset(type) || - type.equals(VarType.VARTYPE_BYTE_OBJ) || type.equals(VarType.VARTYPE_SHORT_OBJ); - } --} -\ No newline at end of file -+} + case opc_iinc: { +- VarExprent varExpr = new VarExprent(instr.operand(0), VarType.VARTYPE_INT, varProcessor); ++ VarExprent varExpr = new VarExprent(instr.operand(0), VarType.VARTYPE_INT, varProcessor, offsets); + int type = instr.operand(1) < 0 ? FunctionExprent.FUNCTION_SUB : FunctionExprent.FUNCTION_ADD; + List operands = Arrays.asList(varExpr.copy(), new ConstExprent(VarType.VARTYPE_INT, Math.abs(instr.operand(1)), null)); + exprList.add(new AssignmentExprent(varExpr, new FunctionExprent(type, operands, offsets), offsets)); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java -index 3682bbb940e6855019cb5b10b7a7de6d703e5b62..171d9bdba69a4701bb7396f2bbe6b5f53cb3bb2b 100644 +index 5428c1d1b10e0fbaa7c3b62725acd34d0632f37c..f0d3f8516357d7bae44b0ad0e5f24903a717268f 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java -@@ -313,6 +313,7 @@ public class FinallyProcessor { +@@ -315,6 +315,7 @@ public class FinallyProcessor { } } + final int store_length = var <= 3 ? 1 : var <= 128 ? 2 : 4; // disable semaphore at statement exit points for (BasicBlock block : setTry) { - List lstSucc = block.getSuccs(); -@@ -322,8 +323,8 @@ public class FinallyProcessor { + List lstSucc = block.getSuccessors(); +@@ -324,8 +325,8 @@ public class FinallyProcessor { if (dest != graph.getLast() && !setCopy.contains(dest)) { // disable semaphore SimpleInstructionSequence seq = new SimpleInstructionSequence(); @@ -294,8 +261,8 @@ index 3682bbb940e6855019cb5b10b7a7de6d703e5b62..171d9bdba69a4701bb7396f2bbe6b5f5 + seq.addInstruction(Instruction.create(CodeConstants.opc_istore, false, CodeConstants.GROUP_GENERAL, bytecode_version, new int[]{var}, store_length), -1); // build a separate block - BasicBlock newblock = new BasicBlock(++graph.last_id); -@@ -352,8 +353,8 @@ public class FinallyProcessor { + BasicBlock newBlock = new BasicBlock(++graph.last_id, seq); +@@ -353,8 +354,8 @@ public class FinallyProcessor { // enable semaphore at the statement entrance SimpleInstructionSequence seq = new SimpleInstructionSequence(); @@ -304,25 +271,25 @@ index 3682bbb940e6855019cb5b10b7a7de6d703e5b62..171d9bdba69a4701bb7396f2bbe6b5f5 + seq.addInstruction(Instruction.create(CodeConstants.opc_bipush, false, CodeConstants.GROUP_GENERAL, bytecode_version, new int[]{1}, 1), -1); + seq.addInstruction(Instruction.create(CodeConstants.opc_istore, false, CodeConstants.GROUP_GENERAL, bytecode_version, new int[]{var}, store_length), -1); - BasicBlock newhead = new BasicBlock(++graph.last_id); - newhead.setSeq(seq); + BasicBlock newHead = new BasicBlock(++graph.last_id, seq); + @@ -362,8 +363,8 @@ public class FinallyProcessor { - // initialize semaphor with false + // initialize semaphore with false seq = new SimpleInstructionSequence(); - seq.addInstruction(Instruction.create(CodeConstants.opc_bipush, false, CodeConstants.GROUP_GENERAL, bytecode_version, new int[]{0}), -1); - seq.addInstruction(Instruction.create(CodeConstants.opc_istore, false, CodeConstants.GROUP_GENERAL, bytecode_version, new int[]{var}), -1); + seq.addInstruction(Instruction.create(CodeConstants.opc_bipush, false, CodeConstants.GROUP_GENERAL, bytecode_version, new int[]{0}, 1), -1); + seq.addInstruction(Instruction.create(CodeConstants.opc_istore, false, CodeConstants.GROUP_GENERAL, bytecode_version, new int[]{var}, store_length), -1); - BasicBlock newheadinit = new BasicBlock(++graph.last_id); - newheadinit.setSeq(seq); + BasicBlock newHeadInit = new BasicBlock(++graph.last_id, seq); + diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/MergeHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/MergeHelper.java -index 77c3dc3caaffad0430a400d7342c63b199e7c9b5..c9ca96373685aa74c10f79b1050cca012484bfb2 100644 +index 545a7766f6ed6dca92f29f6317503ae8852bb9e0..ba131586bc96dc3522a1db41814102d8bdf62c8c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/MergeHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/MergeHelper.java -@@ -89,6 +89,12 @@ public final class MergeHelper { - if (ifedge.getType() == StatEdge.TYPE_BREAK) { +@@ -94,6 +94,12 @@ public final class MergeHelper { + if (ifedge.getType() == EdgeType.BREAK) { ifexpr.negateIf(); } + @@ -334,7 +301,7 @@ index 77c3dc3caaffad0430a400d7342c63b199e7c9b5..c9ca96373685aa74c10f79b1050cca01 stat.setConditionExprent(ifexpr.getCondition()); lastif.getFirst().removeSuccessor(ifedge); lastif.removeSuccessor(elseedge); -@@ -143,6 +149,12 @@ public final class MergeHelper { +@@ -148,6 +154,12 @@ public final class MergeHelper { // negate condition (while header) IfExprent ifexpr = (IfExprent)firstif.getHeadexprent().copy(); ifexpr.negateIf(); @@ -347,8 +314,8 @@ index 77c3dc3caaffad0430a400d7342c63b199e7c9b5..c9ca96373685aa74c10f79b1050cca01 stat.setConditionExprent(ifexpr.getCondition()); // remove edges -@@ -181,7 +193,12 @@ public final class MergeHelper { - stat.setLooptype(DoStatement.LOOP_WHILE); +@@ -186,7 +198,12 @@ public final class MergeHelper { + stat.setLoopType(LoopType.WHILE); // no need to negate the while condition - stat.setConditionExprent(((IfExprent)firstif.getHeadexprent().copy()).getCondition()); @@ -361,9 +328,9 @@ index 77c3dc3caaffad0430a400d7342c63b199e7c9b5..c9ca96373685aa74c10f79b1050cca01 // remove edges StatEdge ifedge = firstif.getIfEdge(); -@@ -333,9 +350,17 @@ public final class MergeHelper { +@@ -338,9 +355,17 @@ public final class MergeHelper { - stat.setLooptype(DoStatement.LOOP_FOR); + stat.setLoopType(LoopType.FOR); if (hasinit) { - stat.setInitExprent(preData.getExprents().remove(preData.getExprents().size() - 1)); + Exprent exp = preData.getExprents().remove(preData.getExprents().size() - 1); @@ -382,11 +349,11 @@ index 77c3dc3caaffad0430a400d7342c63b199e7c9b5..c9ca96373685aa74c10f79b1050cca01 if (lastData.getExprents().isEmpty()) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java -index 72c845f20473ef66ad68ed0a30dbefd8597a6bb6..26f82b92d1b4a972032c05203e8bb642aaba493e 100644 +index 82d12b891da94538ca844e4964e71908ed146a9b..1af6fc576e1528f6c06b0e493bd912b9b37edff6 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java -@@ -638,7 +638,7 @@ public class SimplifyExprentsHelper { - if (stat.type == Statement.TYPE_IF && stat.getExprents() == null) { +@@ -640,7 +640,7 @@ public class SimplifyExprentsHelper { + if (stat.type == StatementType.IF && stat.getExprents() == null) { IfStatement statement = (IfStatement)stat; Exprent ifHeadExpr = statement.getHeadexprent(); - Set ifHeadExprBytecode = (ifHeadExpr == null ? null : ifHeadExpr.bytecode); @@ -395,11 +362,11 @@ index 72c845f20473ef66ad68ed0a30dbefd8597a6bb6..26f82b92d1b4a972032c05203e8bb642 if (statement.iftype == IfStatement.IFTYPE_IFELSE) { Statement ifStatement = statement.getIfstat(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java b/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java -index c0a7769b59177a3b9d2bb72ec1cfd0d59df277fc..d9185f455a983685f9f5ef2a31b3d8d0bd676dcb 100644 +index ae166cc9ea414d5a0b698d8d06c7a24836c21316..478a3aef4cbc9d555abd82e38200a62ba7aa9a23 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java -@@ -409,8 +409,8 @@ public final class ExceptionDeobfuscator { - +@@ -404,8 +404,8 @@ public final class ExceptionDeobfuscator { + for (ExceptionRangeCFG range : ranges) { // add some dummy instructions to prevent optimizing away the empty block SimpleInstructionSequence seq = new SimpleInstructionSequence(); - seq.addInstruction(Instruction.create(CodeConstants.opc_bipush, false, CodeConstants.GROUP_GENERAL, bytecode_version, new int[]{0}), -1); @@ -407,23 +374,23 @@ index c0a7769b59177a3b9d2bb72ec1cfd0d59df277fc..d9185f455a983685f9f5ef2a31b3d8d0 + seq.addInstruction(Instruction.create(CodeConstants.opc_bipush, false, CodeConstants.GROUP_GENERAL, bytecode_version, new int[]{0}, 1), -1); + seq.addInstruction(Instruction.create(CodeConstants.opc_pop, false, CodeConstants.GROUP_GENERAL, bytecode_version, null, 1), -1); - BasicBlock dummyBlock = new BasicBlock(++graph.last_id); - dummyBlock.setSeq(seq); + BasicBlock dummyBlock = new BasicBlock(++graph.last_id, seq); + diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java -index c1d755183f276c66f087e86b0cf8b0aa4c198f75..a6601eee39bde738f840f01806a13b907583af50 100644 +index 84de9258ddf94a35d4b1b1854e6a9bb4755214c5..982b660190ba9488c3ff62022aca0dfecbefab48 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java -@@ -9,6 +9,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; - import org.jetbrains.java.decompiler.util.InterpreterUtil; +@@ -6,6 +6,7 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; + import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.util.TextBuffer; +import java.util.BitSet; import java.util.List; + import java.util.Objects; - public class AnnotationExprent extends Exprent { -@@ -95,4 +96,10 @@ public class AnnotationExprent extends Exprent { - InterpreterUtil.equalLists(parNames, ann.parNames) && - InterpreterUtil.equalLists(parValues, ann.parValues); +@@ -98,4 +99,10 @@ public class AnnotationExprent extends Exprent { + parNames.equals(ann.parNames) && + parValues.equals(ann.parValues); } + + @Override @@ -434,19 +401,18 @@ index c1d755183f276c66f087e86b0cf8b0aa4c198f75..a6601eee39bde738f840f01806a13b90 } \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java -index 753a0a60059ba84b3cb42edf782ab312a18791ca..bf5ff14382c3d5e655778298c87fbe6a8b6592c3 100644 +index c5bce7deb9b3ddee4adb41e356838979c2508fac..47303b872ca4353b1954d8b3c56d99a0693e095a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java -@@ -9,15 +9,15 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; +@@ -5,6 +5,7 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; + import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; + import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult; + import org.jetbrains.java.decompiler.struct.gen.VarType; ++import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.jetbrains.java.decompiler.util.TextBuffer; - import java.util.ArrayList; -+import java.util.BitSet; - import java.util.List; --import java.util.Set; - - public class ArrayExprent extends Exprent { - private Exprent array; + import java.util.*; +@@ -14,7 +15,7 @@ public class ArrayExprent extends Exprent { private Exprent index; private final VarType hardType; @@ -455,7 +421,7 @@ index 753a0a60059ba84b3cb42edf782ab312a18791ca..bf5ff14382c3d5e655778298c87fbe6a super(EXPRENT_ARRAY); this.array = array; this.index = index; -@@ -109,4 +109,11 @@ public class ArrayExprent extends Exprent { +@@ -106,4 +107,11 @@ public class ArrayExprent extends Exprent { public Exprent getIndex() { return index; } @@ -492,20 +458,10 @@ index 0dcb63d34c036a9cd21e21d77c2ea01f6f5b9266..097c10a32ed819368c48efa51866420c + } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java -index c590ac5a15ba65b7dfc90cac27e1b34e5d1ffefd..e2768f5f53f670e2189454970d66524b4446021a 100644 +index 13faa7fd16307e584d00bdf9f990e7cc7245babd..6cc60fd5314369cef21bd56c12e2af8e4c56292d 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java -@@ -15,8 +15,8 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; - import org.jetbrains.java.decompiler.util.TextBuffer; - - import java.util.ArrayList; -+import java.util.BitSet; - import java.util.List; --import java.util.Set; - - public class AssignmentExprent extends Exprent { - -@@ -40,7 +40,7 @@ public class AssignmentExprent extends Exprent { +@@ -36,7 +36,7 @@ public class AssignmentExprent extends Exprent { private Exprent right; private int condType = CONDITION_NONE; @@ -514,7 +470,7 @@ index c590ac5a15ba65b7dfc90cac27e1b34e5d1ffefd..e2768f5f53f670e2189454970d66524b super(EXPRENT_ASSIGNMENT); this.left = left; this.right = right; -@@ -170,6 +170,13 @@ public class AssignmentExprent extends Exprent { +@@ -166,6 +166,13 @@ public class AssignmentExprent extends Exprent { condType == as.getCondType(); } @@ -529,10 +485,10 @@ index c590ac5a15ba65b7dfc90cac27e1b34e5d1ffefd..e2768f5f53f670e2189454970d66524b // getter and setter methods // ***************************************************************************** diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -index 691d613050f89cce24136dc957a38b65cc51fc4c..e97be6c82f048e553b0e24b9311169ea5626e263 100644 +index 48d38ff8657fd6d237fe2d75677d89b8bbd8852d..6542c5adf793250866d9b1d46403084c8db8bc97 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -@@ -36,15 +36,15 @@ public class ConstExprent extends Exprent { +@@ -52,20 +52,20 @@ public class ConstExprent extends Exprent { private final Object value; private final boolean boolPermitted; @@ -546,12 +502,18 @@ index 691d613050f89cce24136dc957a38b65cc51fc4c..e97be6c82f048e553b0e24b9311169ea this(constType, value, false, bytecodeOffsets); } +- public ConstExprent(VarType constType, Object value, Set bytecodeOffsets, StructMember parent) { ++ public ConstExprent(VarType constType, Object value, BitSet bytecodeOffsets, StructMember parent) { + this(constType, value, bytecodeOffsets); + this.parent = parent; + } + - private ConstExprent(VarType constType, Object value, boolean boolPermitted, Set bytecodeOffsets) { + private ConstExprent(VarType constType, Object value, boolean boolPermitted, BitSet bytecodeOffsets) { super(EXPRENT_CONST); this.constType = constType; this.value = value; -@@ -403,6 +403,11 @@ public class ConstExprent extends Exprent { +@@ -454,6 +454,11 @@ public class ConstExprent extends Exprent { return boolPermitted; } @@ -564,15 +526,16 @@ index 691d613050f89cce24136dc957a38b65cc51fc4c..e97be6c82f048e553b0e24b9311169ea // IMatchable implementation // ***************************************************************************** diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java -index b3cc07de2a2ef613de320e120e2f0957aed4cbbd..61b29a83579f85aaba32dd0e432de825a106457d 100644 +index 8dfa6cb4ad9ff9e465a1b42ca206e55ac07aabf8..b0c626320205e7e6fac1f8ceafdffbe89a5daf41 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java -@@ -17,8 +17,8 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; +@@ -16,9 +16,9 @@ import org.jetbrains.java.decompiler.struct.match.MatchNode; import org.jetbrains.java.decompiler.util.TextBuffer; import java.util.ArrayList; +import java.util.BitSet; import java.util.List; + import java.util.Objects; -import java.util.Set; public class ExitExprent extends Exprent { @@ -670,20 +633,21 @@ index 0994d9466eda95b46d3f234bf977e8e9aa0e0899..7183241d331031e66f1afca8bce8feff } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java -index c79f1a6fc6d13c3e61d877624c18b117a5567ce6..45b9f87924ca6d651fb2ab0a4671eb95cdb696fd 100644 +index 0f99c8891a4bc70626b2383b22384a1b212fe8da..3c1c333b45528adaaf63d149436a4cefa30ad905 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java -@@ -22,8 +22,8 @@ import org.jetbrains.java.decompiler.util.TextBuffer; +@@ -19,9 +19,9 @@ import org.jetbrains.java.decompiler.util.TextBuffer; import org.jetbrains.java.decompiler.util.TextUtil; import java.util.ArrayList; +import java.util.BitSet; import java.util.List; + import java.util.Objects; -import java.util.Set; public class FieldExprent extends Exprent { private final String name; -@@ -33,15 +33,15 @@ public class FieldExprent extends Exprent { +@@ -31,15 +31,15 @@ public class FieldExprent extends Exprent { private final FieldDescriptor descriptor; private boolean forceQualified = false; @@ -702,7 +666,7 @@ index c79f1a6fc6d13c3e61d877624c18b117a5567ce6..45b9f87924ca6d651fb2ab0a4671eb95 super(EXPRENT_FIELD); this.name = name; this.classname = classname; -@@ -195,6 +195,12 @@ public class FieldExprent extends Exprent { +@@ -193,6 +193,12 @@ public class FieldExprent extends Exprent { this.forceQualified = value; } @@ -716,10 +680,10 @@ index c79f1a6fc6d13c3e61d877624c18b117a5567ce6..45b9f87924ca6d651fb2ab0a4671eb95 // IMatchable implementation // ***************************************************************************** diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java -index 6bdd8dbe64e8fc562952e63f424b562d9bbc17b0..53b7403a24707b5719aeec34bfba8391c664b502 100644 +index 8bdade633e911e8cabe2ef7deacc56da3508fc78..f2efd6b594b700b20814c620328753a66aea22a4 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java -@@ -186,7 +186,7 @@ public class FunctionExprent extends Exprent { +@@ -183,7 +183,7 @@ public class FunctionExprent extends Exprent { private VarType implicitType; private final List lstOperands; @@ -728,7 +692,7 @@ index 6bdd8dbe64e8fc562952e63f424b562d9bbc17b0..53b7403a24707b5719aeec34bfba8391 this(funcType, new ArrayList<>(), bytecodeOffsets); if (funcType >= FUNCTION_BIT_NOT && funcType <= FUNCTION_PPI && funcType != FUNCTION_CAST && funcType != FUNCTION_INSTANCEOF) { -@@ -202,7 +202,7 @@ public class FunctionExprent extends Exprent { +@@ -199,7 +199,7 @@ public class FunctionExprent extends Exprent { } } @@ -737,7 +701,7 @@ index 6bdd8dbe64e8fc562952e63f424b562d9bbc17b0..53b7403a24707b5719aeec34bfba8391 super(EXPRENT_FUNCTION); this.funcType = funcType; this.lstOperands = operands; -@@ -210,7 +210,7 @@ public class FunctionExprent extends Exprent { +@@ -207,7 +207,7 @@ public class FunctionExprent extends Exprent { addBytecodeOffsets(bytecodeOffsets); } @@ -746,7 +710,7 @@ index 6bdd8dbe64e8fc562952e63f424b562d9bbc17b0..53b7403a24707b5719aeec34bfba8391 this(funcType, new ArrayList<>(1), bytecodeOffsets); lstOperands.add(operand); } -@@ -600,6 +600,12 @@ public class FunctionExprent extends Exprent { +@@ -598,6 +598,12 @@ public class FunctionExprent extends Exprent { this.implicitType = implicitType; } @@ -760,17 +724,17 @@ index 6bdd8dbe64e8fc562952e63f424b562d9bbc17b0..53b7403a24707b5719aeec34bfba8391 // IMatchable implementation // ***************************************************************************** diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java -index 32dd0ba62d28eb445ccae63f8d688b6a3d41404f..f9177d5f5f7991637bb793cdf479b6af63dcf414 100644 +index d5a743fd1a4e068616a82e8f23d119a8ba2b1d59..36e528ae73df7a893d4f50dd2bc8660b803953d8 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java -@@ -10,6 +10,7 @@ import org.jetbrains.java.decompiler.util.ListStack; +@@ -9,6 +9,7 @@ import org.jetbrains.java.decompiler.util.ListStack; import org.jetbrains.java.decompiler.util.TextBuffer; import java.util.ArrayList; +import java.util.BitSet; import java.util.List; + import java.util.Objects; import java.util.Set; - @@ -64,7 +65,7 @@ public class IfExprent extends Exprent { private Exprent condition; @@ -803,7 +767,7 @@ index 32dd0ba62d28eb445ccae63f8d688b6a3d41404f..f9177d5f5f7991637bb793cdf479b6af + } +} diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -index 3fe26b38b93b72d776e506b6158cb7968270d7c2..87522af363670f27a69bf5dee95a954ae14ed594 100644 +index 5489465076ce772ad91d6c05ce6bb8b150f1747b..bfae94c3dd24e9fbf624310591ae33ccb454ecff 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -65,7 +65,7 @@ public class InvocationExprent extends Exprent { @@ -815,13 +779,13 @@ index 3fe26b38b93b72d776e506b6158cb7968270d7c2..87522af363670f27a69bf5dee95a954a this(); name = cn.elementname; -@@ -618,6 +618,13 @@ public class InvocationExprent extends Exprent { +@@ -623,6 +623,13 @@ public class InvocationExprent extends Exprent { return bootstrapArguments; } + @Override + public void getBytecodeRange(BitSet values) { -+ measureBytecode(values, lstParameters); ++ measureBytecode(values, parameters); + measureBytecode(values, instance); + measureBytecode(values); + } @@ -830,15 +794,16 @@ index 3fe26b38b93b72d776e506b6158cb7968270d7c2..87522af363670f27a69bf5dee95a954a // IMatchable implementation // ***************************************************************************** diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/MonitorExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/MonitorExprent.java -index 4172874fff5ab1323bb477bbf3cdd5710a197945..380f47a9de0e1b9d342d5c8557175d7e5a6b1e8a 100644 +index 5c4b2f37b57ec1f084e4147f2d9605e89d895b91..3ad223c61453159d096405bb73184644595b75a9 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/MonitorExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/MonitorExprent.java -@@ -8,8 +8,8 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; +@@ -7,9 +7,9 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.util.TextBuffer; import java.util.ArrayList; +import java.util.BitSet; import java.util.List; + import java.util.Objects; -import java.util.Set; public class MonitorExprent extends Exprent { @@ -864,21 +829,10 @@ index 4172874fff5ab1323bb477bbf3cdd5710a197945..380f47a9de0e1b9d342d5c8557175d7e + } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java -index e946c9a285276d946475add0803bfa789ccdd155..7914279296b8aaa495f85bed6439676c15963411 100644 +index 6257de67e8acd4b4882c758befa3c1e5223ddc0c..6df45768b067fd2e01ffd61bb157158cb369ad7e 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java -@@ -20,8 +20,9 @@ import org.jetbrains.java.decompiler.util.ListStack; - import org.jetbrains.java.decompiler.util.TextBuffer; - - import java.util.ArrayList; -+import java.util.BitSet; -+import java.util.Collections; - import java.util.List; --import java.util.Set; - - public class NewExprent extends Exprent { - private InvocationExprent constructor; -@@ -34,11 +35,11 @@ public class NewExprent extends Exprent { +@@ -31,11 +31,11 @@ public class NewExprent extends Exprent { private boolean lambda; private boolean enumConst; @@ -892,8 +846,8 @@ index e946c9a285276d946475add0803bfa789ccdd155..7914279296b8aaa495f85bed6439676c super(EXPRENT_NEW); this.newType = newType; this.lstDims = lstDims; -@@ -438,6 +439,14 @@ public class NewExprent extends Exprent { - InterpreterUtil.equalLists(lstArrayElements, ne.getLstArrayElements()); +@@ -436,6 +436,14 @@ public class NewExprent extends Exprent { + Objects.equals(lstArrayElements, ne.lstArrayElements); } + @Override @@ -908,15 +862,16 @@ index e946c9a285276d946475add0803bfa789ccdd155..7914279296b8aaa495f85bed6439676c return constructor; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java -index 3a97175bf6ff44f745e9d4738a34aae2b4d05437..81f7546312493c244636b50fa972c0a3817b9aed 100644 +index 3b77fa20c3bfe1790e5f9386b5a38f02ca9c51fe..105c4d951f806fffb8d42386933a7629fa61d76c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java -@@ -10,15 +10,15 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; +@@ -9,16 +9,16 @@ import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.util.TextBuffer; import java.util.ArrayList; +import java.util.BitSet; import java.util.List; + import java.util.Objects; -import java.util.Set; public class SwitchExprent extends Exprent { @@ -930,7 +885,7 @@ index 3a97175bf6ff44f745e9d4738a34aae2b4d05437..81f7546312493c244636b50fa972c0a3 this.value = value; @@ -100,6 +100,22 @@ public class SwitchExprent extends Exprent { - return InterpreterUtil.equalObjects(value, sw.getValue()); + return Objects.equals(value, sw.getValue()); } + @Override @@ -953,17 +908,17 @@ index 3a97175bf6ff44f745e9d4738a34aae2b4d05437..81f7546312493c244636b50fa972c0a3 return value; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java -index d0a2260b1c5b597bab6caec1cb616aaeb70351a4..c6f0eaccf94c55175c19bfc6a4beee9569ab9dc0 100644 +index eb0ef2bf829f55541711e24e483b68890735320a..4c40e5152ffca092883170401453525093da011a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java -@@ -27,6 +27,7 @@ import org.jetbrains.java.decompiler.util.TextBuffer; - import org.jetbrains.java.decompiler.util.TextUtil; +@@ -26,6 +26,7 @@ import org.jetbrains.java.decompiler.util.TextUtil; import java.util.ArrayList; + import java.util.Collections; +import java.util.BitSet; import java.util.List; + import java.util.Objects; - public class VarExprent extends Exprent { @@ -37,21 +38,20 @@ public class VarExprent extends Exprent { private VarType varType; private boolean definition = false; @@ -1016,7 +971,7 @@ index d0a2260b1c5b597bab6caec1cb616aaeb70351a4..c6f0eaccf94c55175c19bfc6a4beee95 // first try from signature if (DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES)) { @@ -181,6 +182,11 @@ public class VarExprent extends Exprent { - InterpreterUtil.equalObjects(getVarType(), ve.getVarType()); // FIXME: varType comparison redundant? + Objects.equals(getVarType(), ve.getVarType()); // FIXME: varType comparison redundant? } + @Override @@ -1028,7 +983,7 @@ index d0a2260b1c5b597bab6caec1cb616aaeb70351a4..c6f0eaccf94c55175c19bfc6a4beee95 return index; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/BasicBlockStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/BasicBlockStatement.java -index 262a01f7e3d64235423a7b2e5ed915ff057c9355..cf79818c542c47c6c1e128197dce3061002dcdb8 100644 +index 6510e1dca6733eb28ceb0a774a658f893b3a8935..98e1c189d302ac71e01949511dc9f9c035b85e5a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/BasicBlockStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/BasicBlockStatement.java @@ -10,6 +10,7 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; @@ -1038,8 +993,8 @@ index 262a01f7e3d64235423a7b2e5ed915ff057c9355..cf79818c542c47c6c1e128197dce3061 +import org.jetbrains.java.decompiler.util.StartEndPair; public class BasicBlockStatement extends Statement { - -@@ -84,4 +85,13 @@ public class BasicBlockStatement extends Statement { + private final BasicBlock block; +@@ -58,4 +59,13 @@ public class BasicBlockStatement extends Statement { public BasicBlock getBlock() { return block; } @@ -1054,7 +1009,7 @@ index 262a01f7e3d64235423a7b2e5ed915ff057c9355..cf79818c542c47c6c1e128197dce3061 + } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DummyExitStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DummyExitStatement.java -index c1d4530d9264e3ab97563ab0541d9d674c7c130d..5fc00b45371c373f2a60cff44e04e9e2b789981d 100644 +index b0cca026cbe68b2741a6ca01a50c6a46be128bc8..b1c9165f9a4a2135128d22a3971303cc4d763a94 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DummyExitStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DummyExitStatement.java @@ -1,25 +1,21 @@ @@ -1071,7 +1026,7 @@ index c1d4530d9264e3ab97563ab0541d9d674c7c130d..5fc00b45371c373f2a60cff44e04e9e2 + public BitSet bytecode = null; // offsets of bytecode instructions mapped to dummy exit public DummyExitStatement() { - type = Statement.TYPE_DUMMYEXIT; + super(StatementType.DUMMY_EXIT); } - public void addBytecodeOffsets(Collection bytecodeOffsets) { @@ -1089,10 +1044,10 @@ index c1d4530d9264e3ab97563ab0541d9d674c7c130d..5fc00b45371c373f2a60cff44e04e9e2 } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java -index c6a01d51adac8696e27122b7f355f3ac23e894cc..2c79ef6d43f569ac91342a08753da1a74f50c992 100644 +index 0d0cb081dcbf15a11c42ac5d586459b8ac35d384..6420052a9215a0ab826a4d955e8d3d662f5ba563 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java -@@ -11,6 +11,7 @@ import org.jetbrains.java.decompiler.struct.match.IMatchable; +@@ -12,6 +12,7 @@ import org.jetbrains.java.decompiler.struct.match.IMatchable; import org.jetbrains.java.decompiler.struct.match.MatchEngine; import org.jetbrains.java.decompiler.struct.match.MatchNode; import org.jetbrains.java.decompiler.util.TextBuffer; @@ -1100,7 +1055,7 @@ index c6a01d51adac8696e27122b7f355f3ac23e894cc..2c79ef6d43f569ac91342a08753da1a7 import org.jetbrains.java.decompiler.util.TextUtil; import java.util.ArrayList; -@@ -408,6 +409,13 @@ public final class IfStatement extends Statement { +@@ -409,6 +410,13 @@ public final class IfStatement extends Statement { return elseedge; } @@ -1115,7 +1070,7 @@ index c6a01d51adac8696e27122b7f355f3ac23e894cc..2c79ef6d43f569ac91342a08753da1a7 // IMatchable implementation // ***************************************************************************** diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/RootStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/RootStatement.java -index 61eca33c037cb575b1b6df2addd1ffcdf2aa671b..8649444b62e0d98aa08ecc1276fc8602ea42dcdc 100644 +index 0946904c8610c2d21de597361e0adf377e88a675..163efe83fdfd94ccb945509fe4593f8495f467bb 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/RootStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/RootStatement.java @@ -4,6 +4,7 @@ package org.jetbrains.java.decompiler.modules.decompiler.stats; @@ -1139,19 +1094,19 @@ index 61eca33c037cb575b1b6df2addd1ffcdf2aa671b..8649444b62e0d98aa08ecc1276fc8602 + } +} diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java -index b905da55c9b3bd7dc48123559809a1d7ed9eaf9c..74f44c077c0985fa23145f39d617976f94571f55 100644 +index 272601270ea32fb5ccc4a822cd9d1b959bae9c35..9d5fcfd4c907e69c52965517dfe69e3a2f82c5df 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java -@@ -16,6 +16,7 @@ import org.jetbrains.java.decompiler.struct.match.IMatchable; +@@ -19,6 +19,7 @@ import org.jetbrains.java.decompiler.struct.match.IMatchable; import org.jetbrains.java.decompiler.struct.match.MatchEngine; import org.jetbrains.java.decompiler.struct.match.MatchNode; import org.jetbrains.java.decompiler.struct.match.MatchNode.RuleValue; +import org.jetbrains.java.decompiler.util.StartEndPair; + import org.jetbrains.java.decompiler.util.TextBuffer; import org.jetbrains.java.decompiler.util.VBStyleCollection; - import java.util.*; -@@ -835,6 +836,40 @@ public class Statement implements IMatchable { - return id.toString(); +@@ -796,6 +797,40 @@ public abstract class Statement implements IMatchable { + return Integer.toString(id); } + //TODO: Cleanup/cache? @@ -1192,18 +1147,18 @@ index b905da55c9b3bd7dc48123559809a1d7ed9eaf9c..74f44c077c0985fa23145f39d617976f // IMatchable implementation // ***************************************************************************** diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java -index 28c2f2c8bf29d0d12f2a63be231399adf9030935..3a809094b3852f05db829f8fef729dd87749324e 100644 +index 119949c8bd35082b95cbfde2b185aa2d23034224..18e40f99948e63d8e1d6136b4d1d5eadefd97330 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java -@@ -16,6 +16,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.exps.FieldExprent; +@@ -19,6 +19,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; + import org.jetbrains.java.decompiler.modules.decompiler.exps.FieldExprent; import org.jetbrains.java.decompiler.modules.decompiler.exps.SwitchExprent; import org.jetbrains.java.decompiler.struct.gen.VarType; - import org.jetbrains.java.decompiler.util.TextBuffer; +import org.jetbrains.java.decompiler.util.StartEndPair; + import org.jetbrains.java.decompiler.util.TextBuffer; import java.util.*; - -@@ -208,6 +209,17 @@ public final class SwitchStatement extends Statement { +@@ -170,6 +171,17 @@ public final class SwitchStatement extends Statement { sortEdgesAndNodes(); } @@ -1218,14 +1173,14 @@ index 28c2f2c8bf29d0d12f2a63be231399adf9030935..3a809094b3852f05db829f8fef729dd8 + return StartEndPair.join(sepairs); + } + - // ***************************************************************************** - // private methods - // ***************************************************************************** + public void sortEdgesAndNodes() { + Map edgeIndicesMapping = new HashMap<>(); + List firstSuccessors = first.getSuccessorEdges(EdgeType.DIRECT_ALL); diff --git a/src/org/jetbrains/java/decompiler/struct/StructMethod.java b/src/org/jetbrains/java/decompiler/struct/StructMethod.java -index a71559379c0aecb53fe8d6d43b8630fa3c16cb10..2336000ea054e5f2e0ef88d30f4a7bc8ee04494f 100644 +index b0b41808499ab657c8ae799dd253d9410f1b001b..f58ee71d23ded6d1fe495b5872bd7965b4c6e61e 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMethod.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMethod.java -@@ -297,11 +297,11 @@ public class StructMethod extends StructMember { +@@ -299,11 +299,11 @@ public class StructMethod extends StructMember { } } @@ -1516,15 +1471,15 @@ index b697e795761f0f254e341663f4934e06ae3af8ef..e873e7e3cc488b036a46c332bd724e3f } } diff --git a/testData/results/TestAnonymousClass.dec b/testData/results/TestAnonymousClass.dec -index 14c92f960012ea63747096f9237fca7ee5e70ced..b86b5fdcf18f733f846dd2cb4d5796d8046cf965 100644 +index 3ea3c7058eadc696e538c72e018bd4076b07a397..044b1f23b7027c7317fba97b760993a45c70115d 100644 --- a/testData/results/TestAnonymousClass.dec +++ b/testData/results/TestAnonymousClass.dec @@ -46,12 +46,12 @@ public abstract class TestAnonymousClass { void foo(int var1) throws Exception { if (var1 > 0) {// 10 -- TestAnonymousClass.I var2 = new TestAnonymousClass.I() { -+ TestAnonymousClass.I var2 = new TestAnonymousClass.I() {// 11 +- I var2 = new I() { ++ I var2 = new I() {// 11 public void foo() throws Exception { boolean var1 = true;// 13 boolean var2 = true;// 14 @@ -1576,7 +1531,7 @@ index 14c92f960012ea63747096f9237fca7ee5e70ced..b86b5fdcf18f733f846dd2cb4d5796d8 14 <-> 52 15 <-> 53 diff --git a/testData/results/TestAnonymousClassConstructor.dec b/testData/results/TestAnonymousClassConstructor.dec -index 63abd4acbe8cf73eb9628724b632af1a9ca231a3..e0ab2c8e78b4489495c36623c734ca58c68fccd4 100644 +index e48e5bc934ccd1ed1aedd0fcde645026bbb4e3fe..08e25fc143aae82531a9e493c328a5606aef9f02 100644 --- a/testData/results/TestAnonymousClassConstructor.dec +++ b/testData/results/TestAnonymousClassConstructor.dec @@ -117,139 +117,207 @@ class TestAnonymousClassConstructor { @@ -2455,7 +2410,7 @@ index cae1518889f1af8977a574de616e37574b3b2c16..9bb7d48e1531f3ac1e467ba8eac25de0 +89 <-> 87 +90 <-> 88 diff --git a/testData/results/TestClassLoop.dec b/testData/results/TestClassLoop.dec -index 55e369b4cb9d39272293f42d72f62fb60dea4f35..82e549f8076ccb6adf4989e71127c70b223922cc 100644 +index 4c2e9ff65a838ba16edbb9a178d11a0c3f85841a..137a4edd73da81f3150da42957bbaa266321a69f 100644 --- a/testData/results/TestClassLoop.dec +++ b/testData/results/TestClassLoop.dec @@ -78,41 +78,68 @@ public class TestClassLoop { @@ -2641,7 +2596,7 @@ index 0576e74a1d8f22a9dee2d72ba7dc984e269abe9d..f2617df3c17a6b9caa908148f7d612a4 23 <-> 12 24 <-> 13 diff --git a/testData/results/TestClassSimpleBytecodeMapping.dec b/testData/results/TestClassSimpleBytecodeMapping.dec -index d5f7070f5b6618b11ea075941af29d4278059b59..c033983370f38dda5935716026b9d339e9eac24a 100644 +index 7c03120a91f0fc0a5cecbbff4cd7b2c0d0da2c94..706965c11a037c3dd1726371d6b9bd9224269ddb 100644 --- a/testData/results/TestClassSimpleBytecodeMapping.dec +++ b/testData/results/TestClassSimpleBytecodeMapping.dec @@ -49,8 +49,13 @@ public class TestClassSimpleBytecodeMapping { @@ -2765,7 +2720,7 @@ index d5f7070f5b6618b11ea075941af29d4278059b59..c033983370f38dda5935716026b9d339 } } diff --git a/testData/results/TestClassSwitch.dec b/testData/results/TestClassSwitch.dec -index d8cb7242db570634da4bf4dfde39371dbd0676f3..a42bfc86fd3fa9948233d709ba8358f1b8ec7908 100644 +index 3f42b35767b44c7cb2b0eaf31dbbf61d9c3b315a..6a2b156f9ad0e29aad668542ee090d63130d2182 100644 --- a/testData/results/TestClassSwitch.dec +++ b/testData/results/TestClassSwitch.dec @@ -15,12 +15,20 @@ public class TestClassSwitch { @@ -2790,7 +2745,7 @@ index d8cb7242db570634da4bf4dfde39371dbd0676f3..a42bfc86fd3fa9948233d709ba8358f1 29 6 2c 8 diff --git a/testData/results/TestClassTypes.dec b/testData/results/TestClassTypes.dec -index 1b76bbb2e89b84dd33fbda862787f8a9d68ef8c0..cc61ae7e238d542e26bde5062a31523003d1b313 100644 +index 07980cc103b3434bdefc78de045120dd6babaa51..a90e113aaabede0b4df7e1e8bcd9f06699a8e061 100644 --- a/testData/results/TestClassTypes.dec +++ b/testData/results/TestClassTypes.dec @@ -53,29 +53,41 @@ class 'pkg/TestClassTypes' { @@ -2896,7 +2851,7 @@ index 1b76bbb2e89b84dd33fbda862787f8a9d68ef8c0..cc61ae7e238d542e26bde5062a315230 } } diff --git a/testData/results/TestClassVar.dec b/testData/results/TestClassVar.dec -index 14e8b9e377dae1246dad22afec036b2e410c3dd9..a1c44f7954ab14e9caa6c85d098fc6d83c70ba82 100644 +index 9beaab18d63a04c8da209347ef10ffdd32dd6800..6de2af6b7b05a4e6c53c7fd9103e0baf839548d2 100644 --- a/testData/results/TestClassVar.dec +++ b/testData/results/TestClassVar.dec @@ -42,20 +42,32 @@ class 'pkg/TestClassVar' { @@ -2988,10 +2943,10 @@ index fefd4212a729bcafc87860b0ed02969149e019f7..2e422b84f097ceb4f923d2cafe9a0c84 12 10 } diff --git a/testData/results/TestDebugSymbols.dec b/testData/results/TestDebugSymbols.dec -index e96eb3328706553b4bd8c131f5c1708a348531c1..1300ffd36f0d85b2334ff9b30d0dc824b0215caa 100644 +index 1010becabda4cb15ee6daeba50f2c4935aefa56d..a405885e6b5a53c8cefbfe9db0f045d562e43d42 100644 --- a/testData/results/TestDebugSymbols.dec +++ b/testData/results/TestDebugSymbols.dec -@@ -13,22 +13,44 @@ class TestDebugSymbols { +@@ -23,22 +23,44 @@ class TestDebugSymbols { class 'pkg/TestDebugSymbols' { method 'm ()I' { 0 4 @@ -3035,9 +2990,9 @@ index e96eb3328706553b4bd8c131f5c1708a348531c1..1300ffd36f0d85b2334ff9b30d0dc824 + 42 8 43 8 } - } + diff --git a/testData/results/TestEnum.dec b/testData/results/TestEnum.dec -index 6fabfaebda76ddd7136b9d8a9f8c354a398e9a0a..069e4efe131ecd59c97e979a3ab4f1fcb8170cfc 100644 +index 40f54d7f0c4ce8b4984d26fac0b13aa1d1dfb145..5248b0236ee49381488c6c5fd3ca8efd4571ba0e 100644 --- a/testData/results/TestEnum.dec +++ b/testData/results/TestEnum.dec @@ -50,13 +50,20 @@ class 'pkg/TestEnum' { @@ -3062,7 +3017,7 @@ index 6fabfaebda76ddd7136b9d8a9f8c354a398e9a0a..069e4efe131ecd59c97e979a3ab4f1fc } } diff --git a/testData/results/TestExtendingSubclass.dec b/testData/results/TestExtendingSubclass.dec -index 2caf74011a7beee7fd2a9fdebe1873be625a8f1a..20f40571d8d00eee74650de2bf483f9ce2a1a1a5 100644 +index 6bab8435926e1c10171fc97b61075ec58dba2572..b9e66bb809b5c7c37a5c04dd08e074e5e3c607b2 100644 --- a/testData/results/TestExtendingSubclass.dec +++ b/testData/results/TestExtendingSubclass.dec @@ -21,7 +21,10 @@ class 'pkg/TestExtendingSubclass$Subclass1' { @@ -3077,7 +3032,7 @@ index 2caf74011a7beee7fd2a9fdebe1873be625a8f1a..20f40571d8d00eee74650de2bf483f9c } } diff --git a/testData/results/TestIffSimplification.dec b/testData/results/TestIffSimplification.dec -index 595c4cb3560eb0e2892ad78d4d1e09624972288f..f9e97f1441516c6c91781d0481182641c468eb2a 100644 +index 0c3a1c421353fe2b9c3f652d999a2c26633511e4..1598c234401e462f4a189cf17bcf3e13c5fbda1b 100644 --- a/testData/results/TestIffSimplification.dec +++ b/testData/results/TestIffSimplification.dec @@ -32,54 +32,91 @@ public class TestIffSimplification { @@ -3197,7 +3152,7 @@ index 3eb1ea54a6080827d3022ea409fdbdc84febf881..5178d8421eb80d2f354cf156bb0ada67 } } diff --git a/testData/results/TestInnerClassConstructor.dec b/testData/results/TestInnerClassConstructor.dec -index f15701a8cc1a757ed8689f40ab375bc52e094be1..2c64a2779e6178a1059af45478e8b15d11ada2aa 100644 +index e37f5014eb173ea82ba61f3a863cc7b5c2ff936b..99ab820bb84ed0fb45bcc7a92dd6c371de0eaa91 100644 --- a/testData/results/TestInnerClassConstructor.dec +++ b/testData/results/TestInnerClassConstructor.dec @@ -29,6 +29,7 @@ class TestInnerClassConstructor { @@ -3255,7 +3210,7 @@ index f15701a8cc1a757ed8689f40ab375bc52e094be1..2c64a2779e6178a1059af45478e8b15d } } diff --git a/testData/results/TestInnerLocal.dec b/testData/results/TestInnerLocal.dec -index f728ad7e3493b296f88d919a028b646096f733c7..5873a128dea3f646318c14f11822d08005c8673e 100644 +index 9009b85453ba2aae2ac4e32f94fb082dcd6d3c81..cf53952d828695bf661720d580e84c4d07273299 100644 --- a/testData/results/TestInnerLocal.dec +++ b/testData/results/TestInnerLocal.dec @@ -57,52 +57,79 @@ public class TestInnerLocal { @@ -3728,7 +3683,7 @@ index 1e3a41c0f8acf669d79049228dc72f63fc387528..72d29afee0f95f9b75898720f39cb051 9 13 } diff --git a/testData/results/TestMethodReferenceSameName.dec b/testData/results/TestMethodReferenceSameName.dec -index 2592d18d569d40e672ddbeee8d07b498a3596626..beaf26ef7981bb1d125430c4e3c41c10511d81e2 100644 +index 0dfbeebf93f70504be97a4d5c5487f7b631d5b61..22e9d9213fbd9f82adfe184c960591209f633155 100644 --- a/testData/results/TestMethodReferenceSameName.dec +++ b/testData/results/TestMethodReferenceSameName.dec @@ -14,9 +14,19 @@ public class TestMethodReferenceSameName { @@ -3754,7 +3709,7 @@ index 2592d18d569d40e672ddbeee8d07b498a3596626..beaf26ef7981bb1d125430c4e3c41c10 } diff --git a/testData/results/TestPrimitives.dec b/testData/results/TestPrimitives.dec -index bc930a51035d6d89803c5c618fb2f2934c45eb63..a7d1557e6814e071df65c610fbdae860c8ff93bc 100644 +index 701f2bb3c5f0ba5c2bc18d2f3ee89bc7e901eced..dcbf031b69cc65b108a2cba8f894d02027372032 100644 --- a/testData/results/TestPrimitives.dec +++ b/testData/results/TestPrimitives.dec @@ -172,143 +172,178 @@ public class TestPrimitives { @@ -4167,7 +4122,7 @@ index c5afe1865540afe457073567009b4b96132d0a07..644701c21beb2a80ed07fc6ed7b2873f } } diff --git a/testData/results/TestSwitchOnEnum.dec b/testData/results/TestSwitchOnEnum.dec -index 34064819cc6a520a13bc3fd718a046861414ae4c..5afdee0f6dc9f35169315b838d25991b0dd8dd20 100644 +index 6e1f77fa247005cb8bb012a91aff96ed78103204..43c9a50f4312736e64116221bfe9140270a81929 100644 --- a/testData/results/TestSwitchOnEnum.dec +++ b/testData/results/TestSwitchOnEnum.dec @@ -50,6 +50,7 @@ public class TestSwitchOnEnum { @@ -4546,15 +4501,3 @@ index 6cdcd8fc638ceeec823172b2859ee8f970f61327..db4cb49cc7816f05dd2e3d82a6b79a74 e 24 } } -diff --git a/testData/results/TypeAnnotations.dec b/testData/results/TypeAnnotations.dec -index 590d89477cde2bc61395393b10827c7b5b180e7d..f743fc88a30f344f033bbde656589afee1e49bf7 100644 ---- a/testData/results/TypeAnnotations.dec -+++ b/testData/results/TypeAnnotations.dec -@@ -31,6 +31,7 @@ class TypeAnnotations { - class 'pkg/TypeAnnotations' { - method 'm1 ()I' { - 0 13 -+ 1 13 - 2 13 - } - diff --git a/FernFlower-Patches/0007-Enhance-switch-on-enum-and-string-output.patch b/FernFlower-Patches/0007-Enhance-switch-on-enum-and-string-output.patch deleted file mode 100644 index f9c6d53..0000000 --- a/FernFlower-Patches/0007-Enhance-switch-on-enum-and-string-output.patch +++ /dev/null @@ -1,974 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: LexManos -Date: Sat, 15 Apr 2017 17:32:28 -0700 -Subject: [PATCH] Enhance switch on enum and string output - - -diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java -index 3dc1f5130dcd0889690078da5bb718256e0780d9..f1dc102772e3cb5aa227057276c95b4402447fab 100644 ---- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java -+++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java -@@ -13,6 +13,7 @@ import org.jetbrains.java.decompiler.main.rels.ClassWrapper; - import org.jetbrains.java.decompiler.main.rels.LambdaProcessor; - import org.jetbrains.java.decompiler.main.rels.NestedClassProcessor; - import org.jetbrains.java.decompiler.main.rels.NestedMemberAccess; -+import org.jetbrains.java.decompiler.modules.decompiler.SwitchHelper; - import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent; - import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; - import org.jetbrains.java.decompiler.struct.StructClass; -@@ -401,16 +402,35 @@ public class ClassesProcessor implements CodeConstants { - return; - } - -+ List nestedCopy = new ArrayList<>(node.nested); -+ -+ for (ClassNode nd : node.nested) { -+ if (shouldInitEarly(nd)) { -+ initWrappers(nd); -+ nestedCopy.remove(nd); -+ } -+ } -+ - ClassWrapper wrapper = new ClassWrapper(node.classStruct); - wrapper.init(); - - node.wrapper = wrapper; - -- for (ClassNode nd : node.nested) { -+ for (ClassNode nd : nestedCopy) { - initWrappers(nd); - } - } - -+ private static boolean shouldInitEarly(ClassNode node) { -+ if (node.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { -+ if (node.classStruct.getMethods().size() == 1 && node.classStruct.getMethods().get(0).getName().equals(CodeConstants.CLINIT_NAME)) { -+ return node.classStruct.getFields().stream() -+ .allMatch( stField -> stField.getDescriptor().equals("[I") && stField.hasModifier(SwitchHelper.STATIC_FINAL_SYNTHETIC)); -+ } -+ } -+ return false; -+ } -+ - private static void addClassNameToImport(ClassNode node, ImportCollector imp) { - if (node.simpleName != null && node.simpleName.length() > 0) { - imp.getShortName(node.type == ClassNode.CLASS_ROOT ? node.classStruct.qualifiedName : node.simpleName, false); -diff --git a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java -index d9de3d584a63ba323914e165410ba8c63a118d2c..a5fe09983d491f671fdbb80ebc1c570c81c77c0c 100644 ---- a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java -+++ b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java -@@ -177,6 +177,11 @@ public class MethodProcessorRunnable implements Runnable { - //} - } - -+ // this has to be done after all inlining is done so the case values do not get reverted -+ if (SwitchHelper.simplifySwitches(root)) { -+ SequenceHelper.condenseSequences(root); // remove empty blocks -+ } -+ - ExitHelper.removeRedundantReturns(root); - - SecondaryFunctionsHelper.identifySecondaryFunctions(root, varProc); -diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -index 5606e91f5ea92b921d73ea9d85360a8d924c14fc..983298ea03a14f6b1911b5e43be3538d7e768ddc 100644 ---- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -+++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -@@ -2,6 +2,7 @@ - package org.jetbrains.java.decompiler.main.rels; - - import org.jetbrains.java.decompiler.code.CodeConstants; -+import org.jetbrains.java.decompiler.code.cfg.BasicBlock; - import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; - import org.jetbrains.java.decompiler.main.DecompilerContext; - import org.jetbrains.java.decompiler.main.collectors.CounterContainer; -@@ -11,8 +12,11 @@ import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; - import org.jetbrains.java.decompiler.modules.decompiler.exps.*; - import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectGraph; - import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectNode; -+import org.jetbrains.java.decompiler.modules.decompiler.stats.BasicBlockStatement; -+import org.jetbrains.java.decompiler.modules.decompiler.stats.CatchStatement; - import org.jetbrains.java.decompiler.modules.decompiler.stats.DoStatement; - import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; -+import org.jetbrains.java.decompiler.modules.decompiler.stats.SequenceStatement; - import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; - import org.jetbrains.java.decompiler.modules.decompiler.vars.VarTypeProcessor; - import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; -@@ -85,6 +89,125 @@ public class NestedClassProcessor { - processClass(root, child); - } - } -+ /** -+ * When Java introduced Enums they aded the ability to use them in Switch statements. -+ * This was done in a purely syntax sugar way using the old switch on int methods. -+ * The compiler creates a synthetic class with a static int array field. -+ * To support enums changing post compile, It initializes this field with a length of the current enum length. -+ * And then for every referenced enum value it adds a mapping in the form of: -+ * try { -+ * field[Enum.VALUE.ordinal()] = 1; -+ * } catch (FieldNotFoundException e) {} -+ * -+ * If a class has multiple switches on multiple enums, the compiler adds the init and try list to the BEGINNING of the static initalizer. -+ * But they add the field to the END of the fields list. -+ */ -+ /* -+ private void gatherEnumSwitchMaps(ClassNode node) { -+ for (ClassNode child : node.nested) { -+ gatherEnumSwitchMaps(child); -+ } -+ -+ MethodWrapper clinit = node.getWrapper().getMethodWrapper("", "()V"); -+ if (clinit == null || clinit.root == null || clinit.root.getFirst().type != Statement.TYPE_SEQUENCE) { -+ return; -+ } -+ -+ final int STATIC_FINAL_SYNTHETIC = CodeConstants.ACC_STATIC | CodeConstants.ACC_STATIC | CodeConstants.ACC_FINAL | CodeConstants.ACC_SYNTHETIC; -+ Set potentialFields = new HashSet(); -+ for (StructField fd : node.classStruct.getFields()) { -+ if ((fd.getAccessFlags() & STATIC_FINAL_SYNTHETIC) == STATIC_FINAL_SYNTHETIC && "[I".equals(fd.getDescriptor())) { -+ potentialFields.add(fd.getName()); -+ } -+ } -+ -+ if (potentialFields.size() == 0) { -+ return; -+ } -+ -+ SequenceStatement seq = (SequenceStatement)clinit.root.getFirst(); -+ for (int x = 0; x < seq.getStats().size();) { -+ Statement stat = seq.getStats().get(x); -+ if (stat.type != Statement.TYPE_BASICBLOCK || stat.getExprents() == null || stat.getExprents().size() != 1 || stat.getExprents().get(0).type != Exprent.EXPRENT_ASSIGNMENT) { -+ break; -+ } -+ AssignmentExprent ass = (AssignmentExprent)stat.getExprents().get(0); -+ if (ass.getLeft().type != Exprent.EXPRENT_FIELD || ass.getRight().type != Exprent.EXPRENT_NEW) { -+ break; -+ } -+ FieldExprent mapField = (FieldExprent)ass.getLeft(); -+ NewExprent _new = ((NewExprent)ass.getRight()); -+ if (!mapField.getClassname().equals(node.classStruct.qualifiedName) || !potentialFields.contains(mapField.getName()) || -+ _new.getNewType().type != CodeConstants.TYPE_INT || _new.getNewType().arrayDim != 1 || -+ _new.getLstDims().size() != 1 || _new.getLstDims().get(0).type != Exprent.EXPRENT_FUNCTION) { -+ break; -+ } -+ FunctionExprent func = (FunctionExprent)_new.getLstDims().get(0); -+ if (func.getFuncType() != FunctionExprent.FUNCTION_ARRAY_LENGTH || func.getLstOperands().size() != 1 || func.getLstOperands().get(0).type != Exprent.EXPRENT_INVOCATION) { -+ break; -+ } -+ InvocationExprent invoc = (InvocationExprent)func.getLstOperands().get(0); -+ if (!"values".equals(invoc.getName()) || !("()[L" + invoc.getClassname() + ";").equals(invoc.getStringDescriptor())) { -+ break; -+ } -+ -+ String fieldName = mapField.getName(); -+ String enumName = invoc.getClassname(); -+ Map idToName = new HashMap(); -+ -+ boolean replace = false; -+ int y = x; -+ while (++y < seq.getStats().size()) { -+ if (seq.getStats().get(y).type != Statement.TYPE_TRYCATCH) { -+ break; -+ } -+ CatchStatement _try = (CatchStatement)seq.getStats().get(y); -+ Statement first = _try.getFirst(); -+ List exprents = first.getExprents(); -+ if (_try.getVars().size() != 1 || !"java/lang/NoSuchFieldError".equals(_try.getVars().get(0).getVarType().value) || -+ first.type != Statement.TYPE_BASICBLOCK || exprents == null || exprents.size() != 1 || exprents.get(0).type != Exprent.EXPRENT_ASSIGNMENT) { -+ break; -+ } -+ ass = (AssignmentExprent)exprents.get(0); -+ if (ass.getRight().type != Exprent.EXPRENT_CONST || (!(((ConstExprent)ass.getRight()).getValue() instanceof Integer)) || -+ ass.getLeft().type != Exprent.EXPRENT_ARRAY){ -+ break; -+ } -+ ArrayExprent array = (ArrayExprent)ass.getLeft(); -+ if (array.getArray().type != Exprent.EXPRENT_FIELD || !array.getArray().equals(mapField) || array.getIndex().type != Exprent.EXPRENT_INVOCATION) { -+ break; -+ } -+ invoc = (InvocationExprent)array.getIndex(); -+ if (!enumName.equals(invoc.getClassname()) || !"ordinal".equals(invoc.getName()) || !"()I".equals(invoc.getStringDescriptor()) || -+ invoc.getInstance().type != Exprent.EXPRENT_FIELD) { -+ break; -+ } -+ -+ FieldExprent enumField = (FieldExprent)invoc.getInstance(); -+ if (!enumName.equals(enumField.getClassname()) || !enumField.isStatic()) { -+ break; -+ } -+ -+ idToName.put((Integer)((ConstExprent)ass.getRight()).getValue(), enumField.getName()); -+ seq.replaceStatement(_try, getNewEmptyStatement()); -+ replace = true; -+ } -+ -+ if (replace) { -+ seq.replaceStatement(seq.getStats().get(x), getNewEmptyStatement()); -+ node.classStruct.getEnumSwitchMap().put(fieldName, idToName); -+ node.getWrapper().getHiddenMembers().add(InterpreterUtil.makeUniqueKey(fieldName, "[I")); -+ } -+ x = y; -+ } -+ }*/ -+ -+ private Statement getNewEmptyStatement() { -+ BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock( -+ DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.STATEMENT_COUNTER))); -+ bstat.setExprents(new ArrayList()); -+ return bstat; -+ } - - private static void setLambdaVars(ClassNode parent, ClassNode child) { - if (child.lambdaInformation.is_method_reference) { // method reference, no code and no parameters -diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchHelper.java -index 1e08a6d935a9c292f836d542a98914d209a62a38..5e9a0d721e8826694c7ba005bcf89127f22b0900 100644 ---- a/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchHelper.java -+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchHelper.java -@@ -7,15 +7,37 @@ import org.jetbrains.java.decompiler.main.DecompilerContext; - import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; - import org.jetbrains.java.decompiler.main.rels.MethodWrapper; - import org.jetbrains.java.decompiler.modules.decompiler.exps.*; -+import org.jetbrains.java.decompiler.modules.decompiler.stats.IfStatement; -+import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; - import org.jetbrains.java.decompiler.modules.decompiler.stats.SwitchStatement; -- -+import org.jetbrains.java.decompiler.struct.StructField; - import java.util.ArrayList; - import java.util.HashMap; - import java.util.List; - import java.util.Map; -+import java.util.stream.Collectors; - - public final class SwitchHelper { -- public static void simplify(SwitchStatement switchStatement) { -+ public static boolean simplifySwitches(Statement stat) { -+ boolean ret = false; -+ if (stat.type == Statement.TYPE_SWITCH) { -+ ret = simplify((SwitchStatement)stat); -+ } -+ -+ for (int i = 0; i < stat.getStats().size(); ++i) { -+ ret |= simplifySwitches(stat.getStats().get(i)); -+ } -+ -+ return ret; -+ } -+ -+ private static boolean simplify(SwitchStatement switchStatement) { -+ SwitchStatement following = null; -+ List edges = switchStatement.getSuccessorEdges(StatEdge.TYPE_REGULAR); -+ if (edges.size() == 1 && edges.get(0).getDestination().type == Statement.TYPE_SWITCH) { -+ following = (SwitchStatement)edges.get(0).getDestination(); -+ } -+ - SwitchExprent switchExprent = (SwitchExprent)switchStatement.getHeadexprent(); - Exprent value = switchExprent.getValue(); - if (isEnumArray(value)) { -@@ -55,7 +77,7 @@ public final class SwitchHelper { - DecompilerContext.getLogger() - .writeMessage("Unable to simplify switch on enum: " + exprent + " not found, available: " + mapping, - IFernflowerLogger.Severity.ERROR); -- return; -+ return false; - } - values.add(realConst.copy()); - } -@@ -64,17 +86,177 @@ public final class SwitchHelper { - caseValues.clear(); - caseValues.addAll(realCaseValues); - switchExprent.replaceExprent(value, ((InvocationExprent)array.getIndex()).getInstance().copy()); -+ return true; - } -+ else if (isSwitchOnString(switchStatement, following)) { -+ Map caseMap = new HashMap<>(); -+ -+ int i = 0; -+ for (; i < switchStatement.getCaseStatements().size(); ++i) { -+ -+ Statement curr = switchStatement.getCaseStatements().get(i); -+ -+ while (curr != null && curr.type == Statement.TYPE_IF) { -+ IfStatement ifStat = (IfStatement)curr; -+ Exprent condition = ifStat.getHeadexprent().getCondition(); -+ -+ if (condition.type == Exprent.EXPRENT_FUNCTION && ((FunctionExprent)condition).getFuncType() == FunctionExprent.FUNCTION_NE) { -+ condition = ((FunctionExprent)condition).getLstOperands().get(0); -+ } -+ -+ if (condition.type == Exprent.EXPRENT_INVOCATION && ((InvocationExprent)condition).getLstParameters().size() == 1) { -+ Exprent assign = ifStat.getIfstat().getExprents().get(0); -+ int caseVal = ((ConstExprent)((AssignmentExprent)assign).getRight()).getIntValue(); -+ caseMap.put(caseVal, ((InvocationExprent)condition).getLstParameters().get(0)); -+ } -+ -+ curr = ifStat.getElsestat(); -+ } -+ } -+ -+ List> realCaseValues = following.getCaseValues().stream() -+ .map(l -> l.stream() -+ .map(e -> e instanceof ConstExprent ? ((ConstExprent)e).getIntValue() : null) -+ .map(caseMap::get) -+ .collect(Collectors.toList())) -+ .collect(Collectors.toList()); -+ -+ following.getCaseValues().clear(); -+ following.getCaseValues().addAll(realCaseValues); -+ -+ Exprent followingVal = ((SwitchExprent)following.getHeadexprent()).getValue(); -+ following.getHeadexprent().replaceExprent(followingVal, ((InvocationExprent)value).getInstance()); -+ -+ switchStatement.getFirst().getExprents().remove(switchStatement.getFirst().getExprents().size() - 1); -+ switchStatement.getFirst().getAllPredecessorEdges().forEach(switchStatement.getFirst()::removePredecessor); -+ switchStatement.getFirst().getAllSuccessorEdges().forEach(switchStatement.getFirst()::removeSuccessor); -+ switchStatement.getParent().replaceStatement(switchStatement, switchStatement.getFirst()); -+ return true; -+ } -+ return false; - } - -+ public static final int STATIC_FINAL_SYNTHETIC = CodeConstants.ACC_STATIC | CodeConstants.ACC_FINAL | CodeConstants.ACC_SYNTHETIC; -+ /** -+ * When Java introduced Enums they added the ability to use them in Switch statements. -+ * This was done in a purely syntax sugar way using the old switch on int methods. -+ * The compiler creates a synthetic class with a static int array field. -+ * To support enums changing post compile, It initializes this field with a length of the current enum length. -+ * And then for every referenced enum value it adds a mapping in the form of: -+ * try { -+ * field[Enum.VALUE.ordinal()] = 1; -+ * } catch (FieldNotFoundException e) {} -+ * -+ * If a class has multiple switches on multiple enums, the compiler adds the init and try list to the BEGINNING of the static initalizer. -+ * But they add the field to the END of the fields list. -+ * -+ * Note: SOME compilers name the field starting with $SwitchMap, so if we do not have full context this can be a guess. -+ * But Obfuscated/renamed code could cause issues -+ */ - private static boolean isEnumArray(Exprent exprent) { - if (exprent instanceof ArrayExprent) { -- Exprent field = ((ArrayExprent)exprent).getArray(); -- Exprent index = ((ArrayExprent)exprent).getIndex(); -- return field instanceof FieldExprent && -- (((FieldExprent)field).getName().startsWith("$SwitchMap") || -- (index instanceof InvocationExprent && ((InvocationExprent)index).getName().equals("ordinal"))); -+ ArrayExprent arr = (ArrayExprent) exprent; -+ Exprent tmp = arr.getArray(); -+ if (tmp instanceof FieldExprent) { -+ FieldExprent field = (FieldExprent)tmp; -+ Exprent index = arr.getIndex(); -+ ClassesProcessor.ClassNode classNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(field.getClassname()); -+ -+ if (classNode == null || !"[I".equals(field.getDescriptor().descriptorString)) { -+ return field.getName().startsWith("$SwitchMap") || //This is non-standard but we don't have any more information so.. -+ (index instanceof InvocationExprent && ((InvocationExprent) index).getName().equals("ordinal")); -+ } -+ -+ StructField stField = classNode.getWrapper().getClassStruct().getField(field.getName(), field.getDescriptor().descriptorString); -+ if ((stField.getAccessFlags() & STATIC_FINAL_SYNTHETIC) != STATIC_FINAL_SYNTHETIC) { -+ return false; -+ } -+ -+ if ((classNode.getWrapper().getClassStruct().getAccessFlags() & CodeConstants.ACC_SYNTHETIC) == CodeConstants.ACC_SYNTHETIC) { -+ return true; //TODO: Find a way to check the structure of the initalizer? -+ //Exprent init = classNode.getWrapper().getStaticFieldInitializers().getWithKey(InterpreterUtil.makeUniqueKey(field.getName(), field.getDescriptor().descriptorString)); -+ //Above is null because we haven't preocess the class yet? -+ } -+ } - } - return false; - } -+ -+ /** -+ * Switch on string gets compiled into two sequential switch statements. -+ * The first is a switch on the hashcode of the string with the case statement -+ * being the actual if equal to string literal check. Hashcode collisions result in -+ * an else if chain. The body of the if block sets the switch variable for the -+ * following switch. -+ * -+ * The second switch block has the case statements of the original switch on string. -+ * -+ * byte b1 = -1; -+ * switch (stringVar.hashcode()) { -+ * case -390932093: -+ * if (stringVar.equals("foo") { -+ * b1 = 0; -+ * } -+ * } -+ * -+ * switch(b1) { -+ * case 0 : -+ * // code for case "foo" -+ * } -+ */ -+ private static boolean isSwitchOnString(SwitchStatement first, SwitchStatement second) { -+ if (second != null) { -+ Exprent firstValue = ((SwitchExprent)first.getHeadexprent()).getValue(); -+ Exprent secondValue = ((SwitchExprent)second.getHeadexprent()).getValue(); -+ -+ if (firstValue.type == Exprent.EXPRENT_INVOCATION && secondValue.type == Exprent.EXPRENT_VAR && first.getCaseStatements().get(0).type == Statement.TYPE_IF) { -+ InvocationExprent invExpr = (InvocationExprent)firstValue; -+ VarExprent varExpr = (VarExprent)secondValue; -+ -+ if (invExpr.getName().equals("hashCode") && invExpr.getClassname().equals("java/lang/String")) { -+ boolean matches = true; -+ -+ for (int i = 0; matches && i < first.getCaseStatements().size(); ++i) { -+ if (!first.getCaseEdges().get(i).contains(first.getDefault_edge())) { -+ Statement curr = first.getCaseStatements().get(i); -+ while (matches && curr != null) { -+ if (curr.type == Statement.TYPE_IF) { -+ IfStatement ifStat = (IfStatement)curr; -+ Exprent condition = ifStat.getHeadexprent().getCondition(); -+ -+ if (condition.type == Exprent.EXPRENT_FUNCTION && ((FunctionExprent)condition).getFuncType() == FunctionExprent.FUNCTION_NE) { -+ condition = ((FunctionExprent)condition).getLstOperands().get(0); -+ } -+ -+ if (condition.type == Exprent.EXPRENT_INVOCATION) { -+ InvocationExprent condInvocation = (InvocationExprent)condition; -+ -+ if (condInvocation.getName().equals("equals") && condInvocation.getInstance().equals(invExpr.getInstance())) { -+ List block = ifStat.getIfstat().getExprents(); -+ -+ if (block != null && block.size() == 1 && block.get(0).type == Exprent.EXPRENT_ASSIGNMENT) { -+ AssignmentExprent assign = (AssignmentExprent)block.get(0); -+ -+ if (assign.getRight().type == Exprent.EXPRENT_CONST && varExpr.equals(assign.getLeft())) { -+ -+ curr = ifStat.getElsestat(); -+ continue; -+ } -+ } -+ } -+ } -+ } -+ -+ matches = false; -+ } -+ } -+ } -+ -+ return matches; -+ } -+ } -+ } -+ -+ return false; -+ } - } -diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java -index 3a809094b3852f05db829f8fef729dd87749324e..ace61bee430c2afb9ffd11b3e7af2dcc5fdd5b46 100644 ---- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java -+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java -@@ -106,7 +106,6 @@ public final class SwitchStatement extends Statement { - - @Override - public TextBuffer toJava(int indent, BytecodeMappingTracer tracer) { -- SwitchHelper.simplify(this); - - TextBuffer buf = new TextBuffer(); - buf.append(ExprProcessor.listToJava(varDefinitions, indent, tracer)); -diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -index 1e8014083efc7c0fdfad40747cccbcd0bf33c608..dc34cc358594ff94e5abab1733336c1eb1f4d30e 100644 ---- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java -+++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -@@ -81,6 +81,7 @@ public class SingleClassesTest extends SingleClassesTestBase { - "pkg/SharedName2", "pkg/SharedName3", "pkg/SharedName4", "pkg/NonSharedName", - "pkg/TestClashNameParent", "ext/TestClashNameParent","pkg/TestClashNameIface", "ext/TestClashNameIface"); } - @Test public void testSwitchOnEnum() { doTest("pkg/TestSwitchOnEnum");} -+ @Test public void testSwitchOnStrings() { doTest("pkg/TestSwitchOnStrings");} - @Test public void testVarArgCalls() { doTest("pkg/TestVarArgCalls"); } - @Test public void testLambdaParams() { doTest("pkg/TestLambdaParams"); } - @Test public void testInterfaceMethods() { doTest("pkg/TestInterfaceMethods"); } -@@ -101,7 +102,6 @@ public class SingleClassesTest extends SingleClassesTestBase { - @Test public void testPackageInfo() { doTest("pkg/package-info"); } - - // TODO: fix all below -- //@Test public void testSwitchOnStrings() { doTest("pkg/TestSwitchOnStrings");} - //@Test public void testUnionType() { doTest("pkg/TestUnionType"); } - //@Test public void testInnerClassConstructor2() { doTest("pkg/TestInner2"); } - //@Test public void testInUse() { doTest("pkg/TestInUse"); } -diff --git a/testData/classes/pkg/TestEnum$1.class b/testData/classes/pkg/TestEnum$1.class -index fb5c29f40e2fe3fd9b19075f906072fc4b546339..cfff174c14e68acae8ae05607147141d86ade3ef 100644 -GIT binary patch -delta 261 -zcmaFOw2xWz)W2Q(7#J8#7(}@km>C4w8HCswgeQvH+6ejNCnx5FB^G5SCgr4tfCxqg -zmXeIjVnzlY&%C_UBIlgM;^I^wSHPzrJ6%5{wYbDJuQXT1(0XEkt&j*K10SmJ#C3u7 -zMhq-KYZw?fw6tXyw=*zq1hSbJ*nuP)10#?WVc-CgJYY5l11AGFkO#Dnffq=!0omGM -rK2Qu@qZpD#MyN(+20oy2CI)^60U!;sSdf8%3&`XGn#KgA85}qOgYPD_ - -delta 178 -zcmdnT{F+Jh)W2Q(7#J8#7=*YOm>GE48Ti;41SX2wPMlz^D9FgbSCE~qACg*J;+j{Q -zt76E=z~h;hms;eUlUQ7wT0HS?V2%O<3s55i1BaHj4C8hN#*IKWBLh2-WCPL+3?e|1 -sgMkxBvH^LLU|FCFbY)^dL%4vFObpx%JU|*^C_j+J1=Pv}q!}DI01Rpu)c^nh - -diff --git a/testData/classes/pkg/TestEnum$2.class b/testData/classes/pkg/TestEnum$2.class -index 3dedba7752417dc953984d6750c47d95d9ff7410..8503c8571788def2ab045dd16661d4dcca7909f3 100644 -GIT binary patch -delta 343 -zcmeyxJcU*9)W2Q(7#J8#805GZm>I;`86?;lBpDglY%=pQOYGPgq$VonCkXlECnx5F -zB^G5SCgr4tfCxqgmXeIjVnzl5pMvak{gBk+64$)aToog0Mg~Tpu#ityVp*boPGVlV -zesD=qW?ni-qJ)t_7*%~pWkIU-#6DX_nTco2SY#O)yeC>&PPS*XsrO`HV_*e3jay4w -zMpu%BaXSO!Mj)4ofeT2oF)#v2Nd|5psQ`31P#FUc122#UvG^GHp<)6If($G`wL%QS -zK#~(Es|~~;y%>f`gAL<>NHXwPfK6j&5CN)XVi08z1JW#DQ`vzmDIkj#h}j&ZfU-c~ -Jz`-C5p#eGAGZz2= - -delta 145 -zcmbQj`ioid)W2Q(7#J8#7{s|4m>C4v83frGgcupvY%=pQOYGPggeNNIPyA%fC^}h> -z(Tqimk->YSmF47xj5dtQlkYK#IWRJC0kyL+Fak+QAj!?Z10*@YJO;2R<3=C{S(!A@ -YB3_^v69XRu|KuDdMRpM&kHLWh0DhMfjsO4v - -diff --git a/testData/classes/pkg/TestEnum$3.class b/testData/classes/pkg/TestEnum$3.class -new file mode 100644 -index 0000000000000000000000000000000000000000..dc94a7b9fa9a1f1cdebf3289cef7bf02a494d872 -GIT binary patch -literal 867 -zcmZ`&YflqF6g{)ucH4CeZBdG~D%Dk6MarXEu?9(?BxoNW+SC|~$#lDE7na>-yT$m6 -z{46Gf7{d?H|3tjAKmZ@f%)R%Vxn~}CW`3T0KL$`jMa6C0i6M@=F^Xmd%qh61B8&Ti -z)?*Ys5HKgAhr&D(Ca<8N;0Z%oZ+)_SV^HTqeYo4#+vdoxI^#VCX?u$y`=4RG{ds6I -zL|+-UOKX7{r<`g{DP{e|UBoZ1Hv7})cC5DWU -z6m9PGiw(CmHU^uPY4@t0=Xyf$Ov9uQJV#l>3t?7-d5JQ^1QnuqzO=r~plvyh>8;y* -zG%`mFiHoV5-5t~LDdVz)A$b{|)k;1sS!AEvV=>EgzOY^UE3ZP8Y;J5YO#O3AalM}9 -za670s-B0q*Nk}hM7wHUF=RhUhd>wUn5p$1y=~NJ`9zIsoLUfW*+HB84gP*9rYX -zh$7(Q5!mq$^&6xE(L#ri<>nX2Z;ucOc;x`pqKAl`@&Qx{hJ&;KULzQ}fEqz1fL{?t -zjMht&&tZz9~BbWGG>s+G(`fXso#S7P9e4CGTDLur6a-vD?_Jw@_3c_gCrfwGui%lroClCh2e - -literal 0 -HcmV?d00001 - -diff --git a/testData/classes/pkg/TestEnum$Type.class b/testData/classes/pkg/TestEnum$Type.class -index 1e27737076d4e4680d1239e46a3aed67e3e065a4..92f267523f644eaaaab02638df6cd69940b59640 100644 -GIT binary patch -delta 338 -zcmZvWJx;?w5QX158?Uj|dYD=v0nEc^3IzCJa2512VIJDQ~3{$vALMl2I53DQAr$PcFi7 -z+GLTnhpxarLuq&wIG#UFj^dkv<=qW^11mT%u!d?nVPE$y6findH@W?c;v4uQbqbbA -z)tppOrrMaMu!>5~X`WI`RCiIJ2MD`WnLvHY@&DrjH7pQc&ogysC~Tmf{wT+_>DMN# -R95pacuG3DA9n2k;{{XgWF;oBm - -delta 229 -zcmX@i{+!L`)W2Q(7#J8#7z{WWSQwPJ7?c@Q*cpV`8PvEKco@_{ga!u#FBec!1EfNe -zgFz5PYq2wEPqaBb*@97Naw20En+}66JA>Zji;NO%`aBF$4APU|Gd_w_Vqjum1RBpJ -z#Gf%O0b%LX8ikwF|tvVmpffGU8hfutBvOrC)m2pJgIwX|inGq7#MP%Hx!VPcSF -k;9!trkewXN94HSFk!Mf<%P2DN18FXx(JTzA415k!05YH%f&c&j - -diff --git a/testData/classes/pkg/TestEnum.class b/testData/classes/pkg/TestEnum.class -index 036f3e623b9467f49e9ec677abc19ea8c9156cb2..12bb8932e0bdf70f6b5d82adc8b325376e6abfcd 100644 -GIT binary patch -literal 2479 -zcmZ`*ZBr9h6n-{uyIB_vi=t3$0i%W>Ac}1*6hj4D6veton_6v`u;Oai&}8FF-#_)Q -zbf*2%hADLFwBzUgfc~6LpK}u+fi#)D=iYPAdCvRJ{{8PCe*u`l_a+i>WLZjbxoct> -zAL$s=@v(_P9fguA~1H*E^lEi5gOfL5gtO};5 -zQ_2p3J9gd@y#9f6LL25UYDyzSw3f<5z1&pe@ -z$){OwqwE#j&|773%#a0jp7~+nk%kT@bPG>zx*LrgooVC6e5)JdDv-$Y^X!7>>=JEW -zHf)U4emM;{+QJ>^m{vuVtX9^J&5L4+oo7rHijAW6H^nJ!I@O{%IV}-8rE0n0UGt@r -zI(GVbRNSyIiD_A;ER4!Dj#>BuWllzO>suUPrc}FP;T%RRgs570if1~WTX=ylb$n&v -zYkXtjTe(?9jxDx0J8R)AGMuAktn|2rA>nES${xICBDG-)-yvsVSY7X>OXAxP$CPxo -z;MWH@UMQ9VhI=$K)RdsbmB(HoWJ)eI7e>whWRqB9kef9dZ-C?JdgriX(zKf1Nha%Z -zkA0w*%Bz0h7S)9DoZ9oH8NE`KGjObK%`c7J<~t*#LC=*pOqWtdvP81THn?Cx|B+rk%+C4*eApA|Gjyf0G=m -zE`_(mHurDiGFP!Utj^^9%1yIkKlT(gywh-=?Mx|AoIo5=QZqZ;XB*n~L4$q-(c?d=Cs1I913)bjQN(A#H!jJLk=OdYs6wK7nVISVYksmQ2+mzaN%eGT( -z56RZ%wuY`6j&9-D=+D&a;UjqRbc#qfMI^4MD$ghmai8Ho%LW)GZ-hA+WmeAP8XIDs -zoDW&BA{`HTvsaC3BmOz+C!uFd)6{$Q6ex6!)+D8iG$L{6Dy5PA*|Zf}wl1=pO&#yk -z2XR-&2ecniyX&}tr~+STfInol61XA`~ZrZaB8#v0J4P4vCQ$-HeR -z?AL2}V;lXO7|{QudbEb)PCiycual40(C6e6H4HeLh)SO7!`7`jvI`wJie7&CoMSns -oVKc4u4!h0TNL$@OnsktvJVlC>!LOkN&g6ReLBwCqpsu3-0aPyDs{jB1 - -literal 1652 -zcmZ`(>r&HD5dKatNg9JdfJ!S0)T%8PD+1n%P=ujZ2IusL2TEoI!U`$igW7?E*801VqgT+({GLUMyzPq -z2eGVEvFroF$>H33dM}w}7<}2CLwau%YrMp8B--QjY?NOUnZdMWo7=V0zFFBd_KReZ -zMO5YuLnzW)G1^^(l^EQSXpTWzv24p(W$^cjOL2rRYaQ5zQ>##!ct22Yy^eBWKEOE7 -z6zLQFA82T&W;<5N%vn{78hmP0jFRb?m37-LJBDMGZJLn3t@5UMSTPHRW4@;OUg=XP -z)mdplFxu)1>^ZT{P|;7PshLe#DHL1NoNA-Smt&;^A73SsYPMXf6wC(}Kfi&0TXc;V -z*Ki$+Tr6m~!uR{Ch8@tlXzdH9VGg^rWosJ3xU69kQ?!%qh%m)Zb1R$Iu!o$6P%nm7 -zmd$E-&fS-U`?P;foi?!}XY)RI3&pZc#7861wpKIyZ_R>3%`LYNR@|C+8?1E^+9O*x -z$er2TWEkm~R&#;qCMI*q?Zh-)&hzv;kP-pjF+iGn6q>pdn%V&1;$s1Zf_#Sbt-yx} -zqF|VzuMlbesCBr%!t)E>PxQqwOHvX(o$zy*Kf$|%Rn?`LZ;*dM>cul$L#%}lh-{Sc -zb646aB1R`mvPr`WHzCxS*$G`?N4@wkZjj$aiFw>2p?O@Gw3oC-aYyjY%zuH}UFmWw -zatX_X^l|<-=>dv7H@a+~jL^UM>bGGvVPan2Ajrq>W5Izbt -z@ah;+UO(eLf~x`T7z26zEJY7CFeE&~UR|$agz_~odW^BW?w9m)b&MY&&_GcBLE-K? -zv~1o}$51x!tz$Hsm+A;+8*ra;_KTT}(9eDpL5$P!1+WU8T5QhnF5<-Ag%w;R9VGh% -RF}#on(r=%hghG)*{{0aTzB}L`}p@Oqz%rIB#G|K)+FI)ZCnaKbg8G5V*bh*b(Sosx_RIohKz{d(|%0 -zSutIw=@tvc%L2p6rFHw6ovquAO19{3*BX_D)Lns4(Y4DP%l4LPF>s;VHQ&8n5wMDz -zJKJUFPE8ITU6q5M*W7Zo(D0@;=j8k#&LYSuK};h-eXUk2h>Muvb$54{QWx!fUWG-Q -zA)l8avb9mk{$rxRKv#32wC5g4*_E38h7E)`N!Wr&a -zS^z>SrVlZTF$zX4{TbpDF9Ln^x+?nV`!PT-U)_U`&A_8e%f4LZ0KSh*XxDgr5Z_yj -zQHUQ87}J@s{{Vs481(1fqc0QIRHg-TG1WDxdgy55JW@hbYX{o?Hg7(qA*{Zp;XVwk -zQT{{9KF6m6&<~L?5Edb8T>NIQz~HgUUmcb2dQ?`}Ngky#(NQ^%I9{-R>qzZQsrLGj -z+H8OsNpz*%G?+y*VZ+OGkIVG9v|Q{12hrxdptL7=pW#XJq|q#h5Wzmi@D>w_c?7{jWE68K6tWV6=8+E_lmG0H@Bcq?kM4-Pvxg43w+F3D -sE(xW{f8->&q)$rnQ`95SSdWu>iqzAjo+Wik(GJ1tq4ijY+2O;;U){p8_W%F@ - -delta 329 -zcmXYr%}#?*5QWcx1>{F7YOz>r)w*FJ8+Tp1!?>VvX>x6vijvy2Xy7rhFJOEFlO`s{ -z_yE3GBO5q2@12?)Ak0MOPcofFjG#QT=a^g%3 -z?#{)eI-+C0dq)l3=Ygw#R=N$iOmA{phqgpl#}+xJ -NPv4vpwmDbO_yrE&GXnqs - -diff --git a/testData/results/TestEnum.dec b/testData/results/TestEnum.dec -index 069e4efe131ecd59c97e979a3ab4f1fcb8170cfc..ce2511cc9f80e7162f6d7d3e8d061757a38ba125 100644 ---- a/testData/results/TestEnum.dec -+++ b/testData/results/TestEnum.dec -@@ -21,10 +21,32 @@ public enum TestEnum { - this("?", (TestEnum.Type)null);// 36 - } - -- private TestEnum(@Deprecated String var3, TestEnum.Type var4) { -- this.s = var3;// 37 -+ private TestEnum(@Deprecated String s, TestEnum.Type t) { -+ this.s = s;// 37 - } - -+ private void testSwitch() { -+ switch(this) {// 40 -+ case E1: -+ System.out.println("E1");// 42 -+ break;// 43 -+ case E2: -+ System.out.println("E2");// 45 -+ break;// 46 -+ case E3: -+ System.out.println("E3");// 48 -+ break;// 49 -+ case E4: -+ System.out.println("E4");// 51 -+ } -+ -+ switch(TestEnum.Type.ODD) {// 55 -+ case ODD: -+ System.out.println("ODD");// 57 -+ default: -+ } -+ }// 59 -+ - private static enum Type { - ODD, - EVEN; -@@ -66,6 +88,67 @@ class 'pkg/TestEnum' { - a 24 - b 25 - } -+ -+ method 'testSwitch ()V' { -+ 0 28 -+ 1 28 -+ 2 28 -+ 3 28 -+ 4 28 -+ 5 28 -+ 6 28 -+ 8 28 -+ 28 30 -+ 29 30 -+ 2a 30 -+ 2b 30 -+ 2c 30 -+ 2d 30 -+ 2e 30 -+ 2f 30 -+ 30 31 -+ 33 33 -+ 34 33 -+ 35 33 -+ 36 33 -+ 37 33 -+ 38 33 -+ 39 33 -+ 3a 33 -+ 3b 34 -+ 3e 36 -+ 3f 36 -+ 40 36 -+ 41 36 -+ 42 36 -+ 43 36 -+ 44 36 -+ 45 36 -+ 46 37 -+ 49 39 -+ 4a 39 -+ 4b 39 -+ 4c 39 -+ 4d 39 -+ 4e 39 -+ 51 42 -+ 52 42 -+ 53 42 -+ 54 42 -+ 55 42 -+ 56 42 -+ 57 42 -+ 58 42 -+ 59 42 -+ 5b 42 -+ 6c 44 -+ 6d 44 -+ 6e 44 -+ 6f 44 -+ 70 44 -+ 71 44 -+ 74 47 -+ } - } - - Lines mapping: -@@ -74,3 +157,14 @@ Lines mapping: - 32 <-> 18 - 36 <-> 21 - 37 <-> 25 -+40 <-> 29 -+42 <-> 31 -+43 <-> 32 -+45 <-> 34 -+46 <-> 35 -+48 <-> 37 -+49 <-> 38 -+51 <-> 40 -+55 <-> 43 -+57 <-> 45 -+59 <-> 48 -diff --git a/testData/results/TestSwitchOnStrings.dec b/testData/results/TestSwitchOnStrings.dec -index cd120e8f6e93c1a3fe1366cac12f5b874233eae3..1b322a7f6e77eb5bc9ee16677fff9aa8b5469af1 100644 ---- a/testData/results/TestSwitchOnStrings.dec -+++ b/testData/results/TestSwitchOnStrings.dec -@@ -1,13 +1,131 @@ - package pkg; - - public class TestSwitchOnStrings { -- public int testSOE(String s) { -- switch (s) { -+ public int testSOS1(String var1) { -+ switch(var1) {// 5 - case "xxx": -- return 2; -+ return 2;// 7 - case "yyy": -- return 1; -- } -- return 0; -- } -+ return 1;// 9 -+ default: -+ return 0;// 11 -+ } -+ } -+ -+ public int testSOS2(String var1) { -+ switch(var1) {// 15 -+ case "xxx": -+ return 2;// 17 -+ case "yyy": -+ return 1;// 19 -+ case "BBAa": -+ return 5;// 21 -+ case "AaAa": -+ return 4;// 23 -+ case "AaBB": -+ return 3;// 25 -+ default: -+ return 0;// 27 -+ } -+ } -+ -+ public int testSOS3(String var1) { -+ switch(var1) {// 31 -+ case "xxx": -+ return 2;// 33 -+ case "yyy": -+ return 1;// 35 -+ case "AaAa": -+ case "AaBB": -+ case "BBAa": -+ return 3;// 39 -+ default: -+ return 0;// 41 -+ } -+ } - } -+ -+class 'pkg/TestSwitchOnStrings' { -+ method 'testSOS1 (Ljava/lang/String;)I' { -+ 0 4 -+ 25 5 -+ 26 5 -+ 33 7 -+ 34 7 -+ 3e 4 -+ 58 6 -+ 59 6 -+ 5a 8 -+ 5b 8 -+ 5c 10 -+ 5d 10 -+ } -+ -+ method 'testSOS2 (Ljava/lang/String;)I' { -+ 0 15 -+ 2d 16 -+ 2e 16 -+ 3b 18 -+ 3c 18 -+ 49 24 -+ 4a 24 -+ 57 22 -+ 58 22 -+ 65 20 -+ 66 20 -+ 70 15 -+ 94 17 -+ 95 17 -+ 96 19 -+ 97 19 -+ 98 21 -+ 99 21 -+ 9a 23 -+ 9b 23 -+ 9c 25 -+ 9d 25 -+ 9e 27 -+ 9f 27 -+ } -+ -+ method 'testSOS3 (Ljava/lang/String;)I' { -+ 0 32 -+ 2d 33 -+ 2e 33 -+ 3b 35 -+ 3c 35 -+ 49 39 -+ 4a 39 -+ 57 38 -+ 58 38 -+ 65 37 -+ 66 37 -+ 70 32 -+ 94 34 -+ 95 34 -+ 96 36 -+ 97 36 -+ 98 40 -+ 99 40 -+ 9a 42 -+ 9b 42 -+ } -+} -+ -+Lines mapping: -+5 <-> 5 -+7 <-> 7 -+9 <-> 9 -+11 <-> 11 -+15 <-> 16 -+17 <-> 18 -+19 <-> 20 -+21 <-> 22 -+23 <-> 24 -+25 <-> 26 -+27 <-> 28 -+31 <-> 33 -+33 <-> 35 -+35 <-> 37 -+39 <-> 41 -+41 <-> 43 -diff --git a/testData/src/pkg/TestEnum.java b/testData/src/pkg/TestEnum.java -index e474d341d406981b924706ac065121f2a9603ed4..974898e766f59086aa471ea2ca48352478bece3a 100644 ---- a/testData/src/pkg/TestEnum.java -+++ b/testData/src/pkg/TestEnum.java -@@ -35,4 +35,26 @@ public enum TestEnum { - - private TestEnum() { this("?", null); } - private TestEnum(@Deprecated String s, Type t) { this.s = s; } -+ -+ private void testSwitch() { -+ switch (this) { -+ case E1: -+ System.out.println("E1"); -+ break; -+ case E2: -+ System.out.println("E2"); -+ break; -+ case E3: -+ System.out.println("E3"); -+ break; -+ case E4: -+ System.out.println("E4"); -+ break; -+ } -+ -+ switch (Type.ODD) { -+ case ODD: -+ System.out.println("ODD"); -+ } -+ } - } -diff --git a/testData/src/pkg/TestSwitchOnStrings.java b/testData/src/pkg/TestSwitchOnStrings.java -index cd120e8f6e93c1a3fe1366cac12f5b874233eae3..796e2b36a3dec636af63a354aedd8631d176169a 100644 ---- a/testData/src/pkg/TestSwitchOnStrings.java -+++ b/testData/src/pkg/TestSwitchOnStrings.java -@@ -1,7 +1,7 @@ - package pkg; - - public class TestSwitchOnStrings { -- public int testSOE(String s) { -+ public int testSOS1(String s) { - switch (s) { - case "xxx": - return 2; -@@ -10,4 +10,34 @@ public class TestSwitchOnStrings { - } - return 0; - } -+ -+ public int testSOS2(String s) { -+ switch (s) { -+ case "xxx": -+ return 2; -+ case "yyy": -+ return 1; -+ case "BBAa": -+ return 5; -+ case "AaAa": -+ return 4; -+ case "AaBB": -+ return 3; -+ } -+ return 0; -+ } -+ -+ public int testSOS3(String s) { -+ switch (s) { -+ case "xxx": -+ return 2; -+ case "yyy": -+ return 1; -+ case "AaAa": -+ case "AaBB": -+ case "BBAa": -+ return 3; -+ } -+ return 0; -+ } - } diff --git a/FernFlower-Patches/0008-Make-methods-hold-a-reference-to-their-declaring-cla.patch b/FernFlower-Patches/0007-Make-methods-hold-a-reference-to-their-declaring-cla.patch similarity index 84% rename from FernFlower-Patches/0008-Make-methods-hold-a-reference-to-their-declaring-cla.patch rename to FernFlower-Patches/0007-Make-methods-hold-a-reference-to-their-declaring-cla.patch index 9fc739b..9984e1b 100644 --- a/FernFlower-Patches/0008-Make-methods-hold-a-reference-to-their-declaring-cla.patch +++ b/FernFlower-Patches/0007-Make-methods-hold-a-reference-to-their-declaring-cla.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Make methods hold a reference to their declaring class This is used in several later commits. diff --git a/src/org/jetbrains/java/decompiler/struct/StructMethod.java b/src/org/jetbrains/java/decompiler/struct/StructMethod.java -index 2336000ea054e5f2e0ef88d30f4a7bc8ee04494f..3b14d7fc755a2d9c33a022aaa2ab728c4a12a4e8 100644 +index f58ee71d23ded6d1fe495b5872bd7965b4c6e61e..4e5c7b4da350020f4f69da956eda4384b86df2aa 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMethod.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMethod.java -@@ -39,7 +39,7 @@ public class StructMethod extends StructMember { +@@ -41,7 +41,7 @@ public class StructMethod extends StructMember { attributes.putAll(code.codeAttributes); } @@ -18,7 +18,7 @@ index 2336000ea054e5f2e0ef88d30f4a7bc8ee04494f..3b14d7fc755a2d9c33a022aaa2ab728c } private static final int[] opr_iconst = {-1, 0, 1, 2, 3, 4, 5}; -@@ -55,13 +55,15 @@ public class StructMethod extends StructMember { +@@ -57,13 +57,15 @@ public class StructMethod extends StructMember { private final int codeFullLength; private InstructionSequence seq = null; private boolean expanded = false; @@ -35,7 +35,7 @@ index 2336000ea054e5f2e0ef88d30f4a7bc8ee04494f..3b14d7fc755a2d9c33a022aaa2ab728c super(accessFlags, attributes); this.name = name; this.descriptor = descriptor; -@@ -74,6 +76,7 @@ public class StructMethod extends StructMember { +@@ -76,6 +78,7 @@ public class StructMethod extends StructMember { else { this.localVariables = this.codeLength = this.codeFullLength = -1; } @@ -43,7 +43,7 @@ index 2336000ea054e5f2e0ef88d30f4a7bc8ee04494f..3b14d7fc755a2d9c33a022aaa2ab728c } public void expandData(StructClass classStruct) throws IOException { -@@ -371,4 +374,8 @@ public class StructMethod extends StructMember { +@@ -378,4 +381,8 @@ public class StructMethod extends StructMember { public String toString() { return name; } diff --git a/FernFlower-Patches/0009-Reintroduce-DotExporter-for-debugging-purposes.patch b/FernFlower-Patches/0008-Reintroduce-DotExporter-for-debugging-purposes.patch similarity index 89% rename from FernFlower-Patches/0009-Reintroduce-DotExporter-for-debugging-purposes.patch rename to FernFlower-Patches/0008-Reintroduce-DotExporter-for-debugging-purposes.patch index cde2bec..c2c3bb5 100644 --- a/FernFlower-Patches/0009-Reintroduce-DotExporter-for-debugging-purposes.patch +++ b/FernFlower-Patches/0008-Reintroduce-DotExporter-for-debugging-purposes.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Reintroduce DotExporter for debugging purposes diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -index 983298ea03a14f6b1911b5e43be3538d7e768ddc..5c7be12a1097a6464fe674cf62823418d2644e99 100644 +index b274560fadc6911d272c5c9358d1cdf7eb808357..575759dabaea87058a5a615c05cb91932cb5873b 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -@@ -27,6 +27,7 @@ import org.jetbrains.java.decompiler.struct.attr.StructEnclosingMethodAttribute; +@@ -24,6 +24,7 @@ import org.jetbrains.java.decompiler.struct.attr.StructEnclosingMethodAttribute; import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; @@ -16,7 +16,7 @@ index 983298ea03a14f6b1911b5e43be3538d7e768ddc..5c7be12a1097a6464fe674cf62823418 import org.jetbrains.java.decompiler.util.InterpreterUtil; import java.util.*; -@@ -383,6 +384,7 @@ public class NestedClassProcessor { +@@ -261,6 +262,7 @@ public class NestedClassProcessor { // iterate enclosing class for (MethodWrapper method : node.getWrapper().getMethods()) { if (method.root != null) { // neither abstract, nor native @@ -25,18 +25,18 @@ index 983298ea03a14f6b1911b5e43be3538d7e768ddc..5c7be12a1097a6464fe674cf62823418 List lst = exprent.getAllExprents(true); lst.add(exprent); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java -index 6efce5e4b043b2dcb58b4dc21f85da9ac9081a7a..8e57cd727302fe608f178c51ba4a7fb4c8971448 100644 +index a1f931b79adb35660ee0f29b1d522214384a044f..3917ae87c6d147e808768ffc717cc24b08b3f433 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java -@@ -14,6 +14,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; +@@ -15,6 +15,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement.Statemen import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.struct.StructMethod; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; +import org.jetbrains.java.decompiler.util.DotExporter; import org.jetbrains.java.decompiler.util.FastSparseSetFactory; import org.jetbrains.java.decompiler.util.FastSparseSetFactory.FastSparseSet; - import org.jetbrains.java.decompiler.util.InterpreterUtil; -@@ -53,9 +54,7 @@ public class SSAConstructorSparseEx { + import org.jetbrains.java.decompiler.util.SFormsFastMapDirect; +@@ -54,9 +55,7 @@ public class SSAConstructorSparseEx { FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.buildDirectGraph(root); @@ -47,7 +47,7 @@ index 6efce5e4b043b2dcb58b4dc21f85da9ac9081a7a..8e57cd727302fe608f178c51ba4a7fb4 List setInit = new ArrayList<>(); for (int i = 0; i < 64; i++) { -@@ -68,20 +67,19 @@ public class SSAConstructorSparseEx { +@@ -69,20 +68,19 @@ public class SSAConstructorSparseEx { setCatchMaps(root, dgraph, flatthelper); @@ -73,18 +73,18 @@ index 6efce5e4b043b2dcb58b4dc21f85da9ac9081a7a..8e57cd727302fe608f178c51ba4a7fb4 for (DirectNode node : dgraph.nodes) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java -index f5719d1a14fc0fd41393e44fe84e0d3c9370d323..3607a8dc6483775f12aa23420ffe447ec9e993bd 100644 +index 80d6d34d3329f831e8add4a0617b8e8bf8a86006..d233d671b4d1bdeb14327bb155310d3b792b932d 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java -@@ -11,6 +11,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; +@@ -12,6 +12,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionsGraph; import org.jetbrains.java.decompiler.struct.StructMethod; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; +import org.jetbrains.java.decompiler.util.DotExporter; import org.jetbrains.java.decompiler.util.FastSparseSetFactory; import org.jetbrains.java.decompiler.util.FastSparseSetFactory.FastSparseSet; - import org.jetbrains.java.decompiler.util.InterpreterUtil; -@@ -71,6 +72,8 @@ public class SSAUConstructorSparseEx { + import org.jetbrains.java.decompiler.util.SFormsFastMapDirect; +@@ -68,6 +69,8 @@ public class SSAUConstructorSparseEx { FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.buildDirectGraph(root); @@ -93,7 +93,7 @@ index f5719d1a14fc0fd41393e44fe84e0d3c9370d323..3607a8dc6483775f12aa23420ffe447e List setInit = new ArrayList<>(); for (int i = 0; i < 64; i++) { setInit.add(i); -@@ -81,25 +84,24 @@ public class SSAUConstructorSparseEx { +@@ -78,25 +81,24 @@ public class SSAUConstructorSparseEx { setCatchMaps(root, dgraph, flatthelper); @@ -126,7 +126,7 @@ index f5719d1a14fc0fd41393e44fe84e0d3c9370d323..3607a8dc6483775f12aa23420ffe447e for (DirectNode node : dgraph.nodes) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java -index c211d680fe9d488b302c92e0ad1ba37f233675ec..eca0d0fb9ef15db26e9de38ebda2bf9ee19857df 100644 +index f9ffa3a3279fd8c3639489260a0dc4a01950c1a2..7a88cb7bc4744aac96bdaffc0ab95652d1937d25 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java @@ -14,6 +14,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; @@ -148,7 +148,7 @@ index c211d680fe9d488b302c92e0ad1ba37f233675ec..eca0d0fb9ef15db26e9de38ebda2bf9e typeProcessor.calculateVarTypes(root, graph); diff --git a/src/org/jetbrains/java/decompiler/util/DotExporter.java b/src/org/jetbrains/java/decompiler/util/DotExporter.java new file mode 100644 -index 0000000000000000000000000000000000000000..561342ed571c2dd99fb28a99d168d9932a4f4e27 +index 0000000000000000000000000000000000000000..c1f55119989bacdc74d279564e78b05833355696 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/DotExporter.java @@ -0,0 +1,238 @@ @@ -189,12 +189,12 @@ index 0000000000000000000000000000000000000000..561342ed571c2dd99fb28a99d168d993 + + for(Statement st : stat.getStats()) { + -+ String sourceid = st.id + (st.getSuccessorEdges(StatEdge.TYPE_EXCEPTION).isEmpty()?"":"000000"); ++ String sourceid = st.id + (st.getSuccessorEdges(StatEdge.EdgeType.EXCEPTION).isEmpty()?"":"000000"); + + buffer.append(sourceid+" [shape=box,label=\""+sourceid+"\"];\r\n"); + -+ for(StatEdge edge : st.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL)) { -+ String destid = edge.getDestination().id + (edge.getDestination().getSuccessorEdges(StatEdge.TYPE_EXCEPTION).isEmpty()?"":"000000"); ++ for(StatEdge edge : st.getSuccessorEdges(StatEdge.EdgeType.DIRECT_ALL)) { ++ String destid = edge.getDestination().id + (edge.getDestination().getSuccessorEdges(StatEdge.EdgeType.EXCEPTION).isEmpty()?"":"000000"); + + buffer.append(sourceid+"->"+destid+";\r\n"); + @@ -203,8 +203,8 @@ index 0000000000000000000000000000000000000000..561342ed571c2dd99fb28a99d168d993 + } + } + -+ for(StatEdge edge : st.getSuccessorEdges(StatEdge.TYPE_EXCEPTION)) { -+ String destid = edge.getDestination().id + (edge.getDestination().getSuccessorEdges(StatEdge.TYPE_EXCEPTION).isEmpty()?"":"000000"); ++ for(StatEdge edge : st.getSuccessorEdges(StatEdge.EdgeType.EXCEPTION)) { ++ String destid = edge.getDestination().id + (edge.getDestination().getSuccessorEdges(StatEdge.EdgeType.EXCEPTION).isEmpty()?"":"000000"); + + buffer.append(sourceid+" -> "+destid+" [style=dotted];\r\n"); + @@ -233,7 +233,7 @@ index 0000000000000000000000000000000000000000..561342ed571c2dd99fb28a99d168d993 + buffer.append(block.id+" [shape=box,label=\""+block.id+"\"];\r\n"); + + -+ List suc = block.getSuccs(); ++ List suc = block.getSuccessors(); + if(!showMultipleEdges) { + HashSet set = new HashSet(); + set.addAll(suc); @@ -244,7 +244,7 @@ index 0000000000000000000000000000000000000000..561342ed571c2dd99fb28a99d168d993 + } + + -+ suc = block.getSuccExceptions(); ++ suc = block.getSuccessorExceptions(); + if(!showMultipleEdges) { + HashSet set = new HashSet(); + set.addAll(suc); @@ -272,7 +272,7 @@ index 0000000000000000000000000000000000000000..561342ed571c2dd99fb28a99d168d993 + + buffer.append((block.var*1000+block.version)+" [shape=box,label=\""+block.var+"_"+block.version+"\"];\r\n"); + -+ for(VarVersionEdge edge: block.succs) { ++ for(VarVersionEdge edge: block.successors) { + VarVersionNode dest = edge.dest; + buffer.append((block.var*1000+block.version)+"->"+(dest.var*1000+dest.version)+(edge.type==VarVersionEdge.EDGE_PHANTOM?" [style=dotted]":"")+";\r\n"); + } @@ -309,7 +309,7 @@ index 0000000000000000000000000000000000000000..561342ed571c2dd99fb28a99d168d993 + + buffer.append(directBlockIdToDot(block.id)+" [shape=box,label=\""+label+"\"];\r\n"); + -+ for(DirectNode dest: block.succs) { ++ for(DirectNode dest: block.successors) { + buffer.append(directBlockIdToDot(block.id)+"->"+directBlockIdToDot(dest.id)+";\r\n"); + } + } diff --git a/FernFlower-Patches/0010-LVT-Fixes-and-Support-for-Enhanced-For-loop-detectio.patch b/FernFlower-Patches/0009-LVT-Fixes-and-Support-for-Enhanced-For-loop-detectio.patch similarity index 89% rename from FernFlower-Patches/0010-LVT-Fixes-and-Support-for-Enhanced-For-loop-detectio.patch rename to FernFlower-Patches/0009-LVT-Fixes-and-Support-for-Enhanced-For-loop-detectio.patch index 10a56ea..51f4f30 100644 --- a/FernFlower-Patches/0010-LVT-Fixes-and-Support-for-Enhanced-For-loop-detectio.patch +++ b/FernFlower-Patches/0009-LVT-Fixes-and-Support-for-Enhanced-For-loop-detectio.patch @@ -5,7 +5,7 @@ Subject: [PATCH] LVT Fixes and Support for Enhanced For loop detection. diff --git a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java -index d0b73c07d62ceedf205d020166e170249b5bb93a..cdadca37d0b24cf3feb1c0e200a113dae53ed51c 100644 +index ec59ac3c399dd1609663bc9444a098285b5dc48a..33906d3a433e4421bbf41c6aed5ff566a69a904a 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java +++ b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java @@ -8,7 +8,6 @@ import org.jetbrains.java.decompiler.main.collectors.VarNamesCollector; @@ -16,35 +16,35 @@ index d0b73c07d62ceedf205d020166e170249b5bb93a..cdadca37d0b24cf3feb1c0e200a113da import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; -@@ -20,7 +19,6 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; - import org.jetbrains.java.decompiler.util.VBStyleCollection; - - import java.util.HashSet; --import java.util.List; - import java.util.Set; - - public class ClassWrapper { -@@ -144,8 +142,9 @@ public class ClassWrapper { - StructLocalVariableTableAttribute attr = mt.getLocalVariableAttr(); - if (attr != null) { - // only param names here -- varProc.setDebugVarNames(attr.getMapParamNames()); -+ varProc.setDebugVarNames(attr.getMapNames()); - -+ /* - // the rest is here - methodWrapper.getOrBuildGraph().iterateExprents(exprent -> { - List lst = exprent.getAllExprents(true); -@@ -161,6 +160,7 @@ public class ClassWrapper { - }); - return 0; +@@ -39,6 +38,7 @@ public class ClassWrapper { + public void init() { + DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS, classStruct); + DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_WRAPPER, this); ++ DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, DecompilerContext.getClassProcessor().getMapRootClasses().get(classStruct.qualifiedName)); + DecompilerContext.getLogger().startClass(classStruct.qualifiedName); + + int maxSec = Integer.parseInt(DecompilerContext.getProperty(IFernflowerPreferences.MAX_PROCESSING_METHOD).toString()); +@@ -162,8 +162,9 @@ public class ClassWrapper { + StructLocalVariableTableAttribute attr = mt.getLocalVariableAttr(); + if (attr != null) { + // only param names here +- varProc.setDebugVarNames(attr.getMapParamNames()); ++ varProc.setDebugVarNames(attr.getMapNames()); + ++ /* + // the rest is here + methodWrapper.getOrBuildGraph().iterateExprents(exprent -> { + List lst = exprent.getAllExprents(true); +@@ -179,6 +180,7 @@ public class ClassWrapper { }); -+ */ - } - } + return 0; + }); ++ */ } + } + } diff --git a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java -index a5fe09983d491f671fdbb80ebc1c570c81c77c0c..76d057fb3970d07a2fc7c07efc756e77e2d53222 100644 +index c122a3f7f937d01dbd99aefb674ad9f1d6f95d10..81fed9eaea4d73a99e87545d15171033f98db3b1 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java +++ b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java @@ -11,7 +11,13 @@ import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; @@ -61,7 +61,7 @@ index a5fe09983d491f671fdbb80ebc1c570c81c77c0c..76d057fb3970d07a2fc7c07efc756e77 import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructMethod; -@@ -114,11 +120,11 @@ public class MethodProcessorRunnable implements Runnable { +@@ -125,11 +131,11 @@ public class MethodProcessorRunnable implements Runnable { ExceptionDeobfuscator.insertDummyExceptionHandlerBlocks(graph, mt.getBytecodeVersion()); } @@ -75,7 +75,7 @@ index a5fe09983d491f671fdbb80ebc1c570c81c77c0c..76d057fb3970d07a2fc7c07efc756e77 } // remove synchronized exception handler -@@ -142,15 +148,26 @@ public class MethodProcessorRunnable implements Runnable { +@@ -153,15 +159,26 @@ public class MethodProcessorRunnable implements Runnable { stackProc.simplifyStackVars(root, mt, cl); varProc.setVarVersions(root); } @@ -105,7 +105,7 @@ index a5fe09983d491f671fdbb80ebc1c570c81c77c0c..76d057fb3970d07a2fc7c07efc756e77 if (DecompilerContext.getOption(IFernflowerPreferences.IDEA_NOT_NULL_ANNOTATION)) { if (IdeaNotNullHelper.removeHardcodedChecks(root, mt)) { -@@ -166,6 +183,12 @@ public class MethodProcessorRunnable implements Runnable { +@@ -177,6 +194,12 @@ public class MethodProcessorRunnable implements Runnable { continue; } @@ -118,7 +118,7 @@ index a5fe09983d491f671fdbb80ebc1c570c81c77c0c..76d057fb3970d07a2fc7c07efc756e77 // initializer may have at most one return point, so no transformation of method exits permitted if (isInitializer || !ExitHelper.condenseExits(root)) { break; -@@ -186,6 +209,8 @@ public class MethodProcessorRunnable implements Runnable { +@@ -192,6 +215,8 @@ public class MethodProcessorRunnable implements Runnable { SecondaryFunctionsHelper.identifySecondaryFunctions(root, varProc); @@ -127,7 +127,7 @@ index a5fe09983d491f671fdbb80ebc1c570c81c77c0c..76d057fb3970d07a2fc7c07efc756e77 varProc.setVarDefinitions(root); // must be the last invocation, because it makes the statement structure inconsistent -@@ -206,4 +231,29 @@ public class MethodProcessorRunnable implements Runnable { +@@ -215,4 +240,29 @@ public class MethodProcessorRunnable implements Runnable { public boolean isFinished() { return finished; } @@ -137,7 +137,7 @@ index a5fe09983d491f671fdbb80ebc1c570c81c77c0c..76d057fb3970d07a2fc7c07efc756e77 + cleanSynchronizedVar(st); + } + -+ if (stat.type == Statement.TYPE_SYNCRONIZED) { ++ if (stat.type == Statement.StatementType.SYNCHRONIZED) { + SynchronizedStatement sync = (SynchronizedStatement)stat; + if (sync.getHeadexprentList().get(0).type == Exprent.EXPRENT_MONITOR) { + MonitorExprent mon = (MonitorExprent)sync.getHeadexprentList().get(0); @@ -158,10 +158,10 @@ index a5fe09983d491f671fdbb80ebc1c570c81c77c0c..76d057fb3970d07a2fc7c07efc756e77 + } } diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e097988997 100644 +index 575759dabaea87058a5a615c05cb91932cb5873b..79e55ad572826f33aa4022b1f60c37917d78a67b 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -@@ -25,6 +25,7 @@ import org.jetbrains.java.decompiler.struct.StructField; +@@ -22,6 +22,7 @@ import org.jetbrains.java.decompiler.struct.StructField; import org.jetbrains.java.decompiler.struct.StructMethod; import org.jetbrains.java.decompiler.struct.attr.StructEnclosingMethodAttribute; import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; @@ -169,7 +169,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.util.DotExporter; -@@ -236,6 +237,7 @@ public class NestedClassProcessor { +@@ -114,6 +115,7 @@ public class NestedClassProcessor { } Map mapNewNames = new HashMap<>(); @@ -177,7 +177,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 enclosingMethod.getOrBuildGraph().iterateExprents(exprent -> { List lst = exprent.getAllExprents(true); -@@ -260,6 +262,7 @@ public class NestedClassProcessor { +@@ -138,6 +140,7 @@ public class NestedClassProcessor { if (param.type == Exprent.EXPRENT_VAR) { mapNewNames.put(varVersion, enclosingMethod.varproc.getVarName(new VarVersionPair((VarExprent)param))); @@ -185,7 +185,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 } } else { -@@ -283,8 +286,26 @@ public class NestedClassProcessor { +@@ -161,8 +164,26 @@ public class NestedClassProcessor { method.setOuterVarNames.addAll(setNewOuterNames); for (Entry entry : mapNewNames.entrySet()) { @@ -213,7 +213,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 } private static void checkNotFoundClasses(ClassNode root, ClassNode node) { -@@ -522,6 +543,7 @@ public class NestedClassProcessor { +@@ -400,6 +421,7 @@ public class NestedClassProcessor { if (method.root != null) { // neither abstract nor native Map mapNewNames = new HashMap<>(); // local var names Map mapNewTypes = new HashMap<>(); // local var types @@ -221,7 +221,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 Map mapParamsToNewVars = new HashMap<>(); if (method.synthParameters != null) { -@@ -536,15 +558,17 @@ public class NestedClassProcessor { +@@ -414,15 +436,17 @@ public class NestedClassProcessor { String varName = null; VarType varType = null; @@ -232,7 +232,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 varType = enclosingMethod.varproc.getVarType(pair); + varLVT = enclosingMethod.varproc.getVarLVT(pair); - enclosingMethod.varproc.setVarFinal(pair, VarTypeProcessor.VAR_EXPLICIT_FINAL); + enclosingMethod.varproc.setVarFinal(pair, VarProcessor.VAR_EXPLICIT_FINAL); } - if (pair.var == -1 || "this".equals(varName)) { @@ -240,7 +240,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 if (parent.simpleName == null) { // anonymous enclosing class, no access to this varName = VarExprent.VAR_NAMELESS_ENCLOSURE; -@@ -552,11 +576,15 @@ public class NestedClassProcessor { +@@ -430,11 +454,15 @@ public class NestedClassProcessor { else { varName = parent.simpleName + ".this"; } @@ -255,8 +255,8 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 + mapNewLVTs.put(newVar, varLVT); } - varIndex += md.params[index++].stackSize; -@@ -572,17 +600,19 @@ public class NestedClassProcessor { + varIndex += md.params[index++].getStackSize(); +@@ -450,17 +478,19 @@ public class NestedClassProcessor { String varName = null; VarType varType = null; @@ -269,7 +269,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 varType = enclosing_method.varproc.getVarType(entry.getValue()); + varLVT = enclosing_method.varproc.getVarLVT(entry.getValue()); - enclosing_method.varproc.setVarFinal(entry.getValue(), VarTypeProcessor.VAR_EXPLICIT_FINAL); + enclosing_method.varproc.setVarFinal(entry.getValue(), VarProcessor.VAR_EXPLICIT_FINAL); } - if (entry.getValue().var == -1 || "this".equals(varName)) { @@ -277,7 +277,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 if (classNode.parent.simpleName == null) { // anonymous enclosing class, no access to this varName = VarExprent.VAR_NAMELESS_ENCLOSURE; -@@ -590,11 +620,15 @@ public class NestedClassProcessor { +@@ -468,11 +498,15 @@ public class NestedClassProcessor { else { varName = classNode.parent.simpleName + ".this"; } @@ -293,7 +293,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 // hide synthetic field if (classNode == child) { // fields higher up the chain were already handled with their classes -@@ -613,16 +647,20 @@ public class NestedClassProcessor { +@@ -491,16 +525,20 @@ public class NestedClassProcessor { for (Entry entry : mapNewNames.entrySet()) { VarVersionPair pair = entry.getKey(); VarType type = mapNewTypes.get(pair); @@ -316,7 +316,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) { AssignmentExprent assignExpr = (AssignmentExprent)exprent; if (assignExpr.getLeft().type == Exprent.EXPRENT_FIELD) { -@@ -630,7 +668,7 @@ public class NestedClassProcessor { +@@ -508,7 +546,7 @@ public class NestedClassProcessor { String qName = child.classStruct.qualifiedName; if (fExpr.getClassname().equals(qName) && // process this class only mapFieldsToNewVars.containsKey(InterpreterUtil.makeUniqueKey(qName, fExpr.getName(), fExpr.getDescriptor().descriptorString))) { @@ -325,8 +325,8 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 } } } -@@ -642,13 +680,13 @@ public class NestedClassProcessor { - if (invokeExpr.getFunctype() == InvocationExprent.TYP_INIT) { +@@ -520,13 +558,13 @@ public class NestedClassProcessor { + if (invokeExpr.getFuncType() == InvocationExprent.TYPE_INIT) { // invocation of the super constructor in an anonymous class child.superInvocation = invokeExpr; // FIXME: save original names of parameters - return 2; @@ -342,7 +342,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 } private Exprent replaceExprent(Exprent exprent) { -@@ -657,7 +695,12 @@ public class NestedClassProcessor { +@@ -535,7 +573,12 @@ public class NestedClassProcessor { if (mapParamsToNewVars.containsKey(varIndex)) { VarVersionPair newVar = mapParamsToNewVars.get(varIndex); method.varproc.getExternalVars().add(newVar); @@ -356,7 +356,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 } } else if (exprent.type == Exprent.EXPRENT_FIELD) { -@@ -665,10 +708,15 @@ public class NestedClassProcessor { +@@ -543,10 +586,15 @@ public class NestedClassProcessor { String key = InterpreterUtil.makeUniqueKey(fExpr.getClassname(), fExpr.getName(), fExpr.getDescriptor().descriptorString); if (mapFieldsToNewVars.containsKey(key)) { //if(fExpr.getClassname().equals(child.classStruct.qualifiedName) && @@ -374,7 +374,7 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 } } -@@ -1044,4 +1092,41 @@ public class NestedClassProcessor { +@@ -922,4 +970,41 @@ public class NestedClassProcessor { return fieldKey.hashCode() + varPair.hashCode(); } } @@ -414,24 +414,24 @@ index 5c7be12a1097a6464fe674cf62823418d2644e99..fb9c7a961ec3cfc1f50c3fd902c299e0 + } + } + -+ stack.addAll(node.succs); ++ stack.addAll(node.successors); + } + } +} diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java -index 8d0100d6e80a3b8dd743a6c21139348217d742b7..653b7697906788ebd61ce5b113803c8dc943e1a8 100644 +index 86cac9e08f0f0d3ebd43353b64eba9560279de55..038dac26540f41092afd00936954670510e16df6 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java -@@ -9,6 +9,8 @@ import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; - import org.jetbrains.java.decompiler.modules.decompiler.decompose.FastExtendedPostdominanceHelper; +@@ -12,6 +12,8 @@ import org.jetbrains.java.decompiler.modules.decompiler.decompose.FastExtendedPo import org.jetbrains.java.decompiler.modules.decompiler.deobfuscator.IrreducibleCFGDeobfuscator; import org.jetbrains.java.decompiler.modules.decompiler.stats.*; + import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement.StatementType; +import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.util.DotExporter; import org.jetbrains.java.decompiler.util.FastFixedSetFactory; import org.jetbrains.java.decompiler.util.FastFixedSetFactory.FastFixedSet; - import org.jetbrains.java.decompiler.util.InterpreterUtil; -@@ -189,17 +191,12 @@ public final class DomHelper { + import org.jetbrains.java.decompiler.util.VBStyleCollection; +@@ -190,17 +192,12 @@ public final class DomHelper { return ret; } @@ -453,7 +453,7 @@ index 8d0100d6e80a3b8dd743a6c21139348217d742b7..653b7697906788ebd61ce5b113803c8d diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java new file mode 100644 -index 0000000000000000000000000000000000000000..adc78392c4a82692b32a603e7c0aa90db86a800a +index 0000000000000000000000000000000000000000..8f7984ec00e84aeca1902484f8f9b43c1fe81cf6 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java @@ -0,0 +1,199 @@ @@ -499,7 +499,7 @@ index 0000000000000000000000000000000000000000..adc78392c4a82692b32a603e7c0aa90d + } + } + -+ if (stat.type == Statement.TYPE_DO && isLoopRedundant((DoStatement)stat)) { ++ if (stat.type == Statement.StatementType.DO && isLoopRedundant((DoStatement)stat)) { + return true; + } + @@ -508,13 +508,13 @@ index 0000000000000000000000000000000000000000..adc78392c4a82692b32a603e7c0aa90d + + private static boolean isLoopRedundant(DoStatement loop) { + -+ if (loop.getLooptype() != DoStatement.LOOP_DO) { ++ if (loop.getLoopType() != DoStatement.LoopType.DO) { + return false; + } + + // get parent loop if exists + Statement parentloop = loop.getParent(); -+ while (parentloop != null && parentloop.type != Statement.TYPE_DO) { ++ while (parentloop != null && parentloop.type != Statement.StatementType.DO) { + parentloop = parentloop.getParent(); + } + @@ -525,7 +525,7 @@ index 0000000000000000000000000000000000000000..adc78392c4a82692b32a603e7c0aa90d + // collect relevant break edges + List lstBreakEdges = new ArrayList<>(); + for (StatEdge edge : loop.getLabelEdges()) { -+ if (edge.getType() == StatEdge.TYPE_BREAK) { // all break edges are explicit because of LOOP_DO type ++ if (edge.getType() == StatEdge.EdgeType.BREAK) { // all break edges are explicit because of LOOP_DO type + lstBreakEdges.add(edge); + } + } @@ -536,7 +536,7 @@ index 0000000000000000000000000000000000000000..adc78392c4a82692b32a603e7c0aa90d + boolean firstok = loopcontent.getAllSuccessorEdges().isEmpty(); + if (!firstok) { + StatEdge edge = loopcontent.getAllSuccessorEdges().get(0); -+ firstok = (edge.closure == loop && edge.getType() == StatEdge.TYPE_BREAK); ++ firstok = (edge.closure == loop && edge.getType() == StatEdge.EdgeType.BREAK); + if (firstok) { + lstBreakEdges.remove(edge); + } @@ -640,7 +640,7 @@ index 0000000000000000000000000000000000000000..adc78392c4a82692b32a603e7c0aa90d + List lst = new ArrayList<>(loop.getLabelEdges()); + for (StatEdge edge : lst) { + loop.removePredecessor(edge); -+ edge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, edge, parentloop); ++ edge.getSource().changeEdgeNode(StatEdge.EdgeDirection.FORWARD, edge, parentloop); + parentloop.addPredecessor(edge); + + parentloop.addLabeledEdge(edge); @@ -657,58 +657,54 @@ index 0000000000000000000000000000000000000000..adc78392c4a82692b32a603e7c0aa90d + } +} diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExitHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExitHelper.java -index 8e0ac9c07218f5efa5915c67550a66e3cd235ef8..d6b44b8bacc2088a63c13f3ffc6af3fa4d119311 100644 +index c5ccfd1a659461646494c3796528767d0ba089c8..ef96a3f610c7fe1af746aa1d8663ba7adb530d8b 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExitHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExitHelper.java -@@ -171,7 +171,7 @@ public final class ExitHelper { +@@ -175,7 +175,7 @@ public final class ExitHelper { private static Statement isExitEdge(StatEdge edge) { Statement dest = edge.getDestination(); -- if (edge.getType() == StatEdge.TYPE_BREAK && dest.type == Statement.TYPE_BASICBLOCK && edge.explicit && (edge.labeled || isOnlyEdge(edge))) { -+ if (edge.getType() == StatEdge.TYPE_BREAK && dest.type == Statement.TYPE_BASICBLOCK && edge.explicit && (edge.labeled || isOnlyEdge(edge)) && edge.canInline) { +- if (edge.getType() == EdgeType.BREAK && dest.type == StatementType.BASIC_BLOCK && edge.explicit && (edge.labeled || isOnlyEdge(edge))) { ++ if (edge.getType() == EdgeType.BREAK && dest.type == StatementType.BASIC_BLOCK && edge.explicit && (edge.labeled || isOnlyEdge(edge)) && edge.canInline) { List data = dest.getExprents(); if (data != null && data.size() == 1) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -index 6aa061689f525158f31aee3fdcc114ac89f11ae5..f19e321da5e392eff9c87da6018aa1407411332d 100644 +index 80d5dab3d3f0101ba5907e6a8e31d275834a73b2..3148af901dbdf25946b67b1da9b0fba8f697a49e 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -@@ -330,7 +330,9 @@ public class ExprProcessor implements CodeConstants { +@@ -316,7 +316,9 @@ public class ExprProcessor implements CodeConstants { case opc_fload: case opc_dload: case opc_aload: -- pushEx(stack, exprlist, new VarExprent(instr.operand(0), varTypes[instr.opcode - opc_iload], varProcessor, bytecode_offsets)); -+ VarExprent varExprent = new VarExprent(instr.operand(0), varTypes[instr.opcode - opc_iload], varProcessor, bytecode_offsets); -+ varProcessor.findLVT(varExprent, bytecode_offset + instr.length); -+ pushEx(stack, exprlist, varExprent); +- pushEx(stack, exprList, new VarExprent(instr.operand(0), varTypes[instr.opcode - opc_iload], varProcessor, offsets)); ++ VarExprent varExprent = new VarExprent(instr.operand(0), varTypes[instr.opcode - opc_iload], varProcessor, offsets); ++ varProcessor.findLVT(varExprent, offset + instr.length); ++ pushEx(stack, exprList, varExprent); break; case opc_iaload: case opc_laload: -@@ -363,8 +365,9 @@ public class ExprProcessor implements CodeConstants { - if (bytecode_offsets != null) { //TODO: Figure out why this nulls in some cases - bytecode_offsets.set(bytecode_offset, bytecode_offset + instr.length); +@@ -343,6 +345,7 @@ public class ExprProcessor implements CodeConstants { + offsets.set(offset, offset + instr.length); } -- AssignmentExprent assign = new AssignmentExprent( -- new VarExprent(varindex, varTypes[instr.opcode - opc_istore], varProcessor, bytecode_offsets), expr, bytecode_offsets); -+ varExprent = new VarExprent(varindex, varTypes[instr.opcode - opc_istore], varProcessor, bytecode_offsets); -+ varProcessor.findLVT(varExprent, bytecode_offset + instr.length); -+ AssignmentExprent assign = new AssignmentExprent(varExprent, expr, bytecode_offsets); - exprlist.add(assign); + VarExprent left = new VarExprent(varIndex, varTypes[instr.opcode - opc_istore], varProcessor, offsets); ++ varProcessor.findLVT(left, offset + instr.length); + exprList.add(new AssignmentExprent(left, value, offsets)); break; - case opc_iastore: -@@ -427,6 +430,7 @@ public class ExprProcessor implements CodeConstants { + } +@@ -405,6 +408,7 @@ public class ExprProcessor implements CodeConstants { break; - case opc_iinc: - VarExprent vevar = new VarExprent(instr.operand(0), VarType.VARTYPE_INT, varProcessor, bytecode_offsets); -+ varProcessor.findLVT(vevar, bytecode_offset + instr.length); - exprlist.add(new AssignmentExprent(vevar, new FunctionExprent( - instr.operand(1) < 0 ? FunctionExprent.FUNCTION_SUB : FunctionExprent.FUNCTION_ADD, Arrays - .asList(vevar.copy(), new ConstExprent(VarType.VARTYPE_INT, Math.abs(instr.operand(1)), null)), + case opc_iinc: { + VarExprent varExpr = new VarExprent(instr.operand(0), VarType.VARTYPE_INT, varProcessor, offsets); ++ varProcessor.findLVT(varExpr, offset + instr.length); + int type = instr.operand(1) < 0 ? FunctionExprent.FUNCTION_SUB : FunctionExprent.FUNCTION_ADD; + List operands = Arrays.asList(varExpr.copy(), new ConstExprent(VarType.VARTYPE_INT, Math.abs(instr.operand(1)), null)); + exprList.add(new AssignmentExprent(varExpr, new FunctionExprent(type, operands, offsets), offsets)); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/InlineSingleBlockHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/InlineSingleBlockHelper.java -index 0c947611f683d78793463aadb950377399664a82..15293498a8a1833a9023f87fcbff330ccb94f805 100644 +index 271ab6a217c507d2fae72fb8aa2f38ebd054c80a..1f648ba330f9728c807c04f79d22894b03334f66 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/InlineSingleBlockHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/InlineSingleBlockHelper.java -@@ -118,6 +118,9 @@ public final class InlineSingleBlockHelper { +@@ -121,6 +121,9 @@ public final class InlineSingleBlockHelper { StatEdge edge = lst.get(0); if (sameCatchRanges(edge)) { @@ -719,10 +715,10 @@ index 0c947611f683d78793463aadb950377399664a82..15293498a8a1833a9023f87fcbff330c for (int i = index; i < seq.getStats().size(); i++) { if (!noExitLabels(seq.getStats().get(i), seq)) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/LoopExtractHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/LoopExtractHelper.java -index b82562e5f1884df165c6d2793a3daba0a6faab16..04b82fc67fca471f6c868c227df24160e57edb5f 100644 +index c4fd9dd28fa7b587cf696187312f2988588ba02b..1743e96a47775011c65a10cddf5a7226ef656473 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/LoopExtractHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/LoopExtractHelper.java -@@ -8,6 +8,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; +@@ -12,6 +12,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement.Statemen import java.util.ArrayList; import java.util.Arrays; @@ -730,14 +726,14 @@ index b82562e5f1884df165c6d2793a3daba0a6faab16..04b82fc67fca471f6c868c227df24160 import java.util.Set; -@@ -63,16 +64,33 @@ public final class LoopExtractHelper { +@@ -67,16 +68,33 @@ public final class LoopExtractHelper { return false; } + List stats = new ArrayList<>(); for (StatEdge edge : stat.getLabelEdges()) { - if (edge.getType() != StatEdge.TYPE_CONTINUE && edge.getDestination().type != Statement.TYPE_DUMMYEXIT) { -+ if (edge.getType() == StatEdge.TYPE_BREAK && isExternStatement(stat, edge.getSource(), edge.getSource())) { + if (edge.getType() != EdgeType.CONTINUE && edge.getDestination().type != StatementType.DUMMY_EXIT) { ++ if (edge.getType() == EdgeType.BREAK && isExternStatement(stat, edge.getSource(), edge.getSource())) { + stats.add(edge.getSource()); + } + else { @@ -766,15 +762,15 @@ index b82562e5f1884df165c6d2793a3daba0a6faab16..04b82fc67fca471f6c868c227df24160 // search for an if condition at the end of the loop Statement last = stat.getFirst(); -@@ -93,6 +111,19 @@ public final class LoopExtractHelper { +@@ -97,6 +115,19 @@ public final class LoopExtractHelper { if (set.isEmpty()) { // no direct continues in a do{}while loop if (isExternStatement(stat, ifstat, ifstat)) { + Statement first = stat.getFirst(); -+ while (first.type == Statement.TYPE_SEQUENCE) { ++ while (first.type == Statement.StatementType.SEQUENCE) { + first = first.getFirst(); + } -+ if (first.type == Statement.TYPE_DO && ((DoStatement)first).getLooptype() == DoStatement.LOOP_DO) { ++ if (first.type == Statement.StatementType.DO && ((DoStatement)first).getLoopType() == DoStatement.LoopType.DO) { + return false; + } + @@ -786,7 +782,7 @@ index b82562e5f1884df165c6d2793a3daba0a6faab16..04b82fc67fca471f6c868c227df24160 extractIfBlock(stat, lastif); return true; } -@@ -103,7 +134,7 @@ public final class LoopExtractHelper { +@@ -107,7 +138,7 @@ public final class LoopExtractHelper { return false; } @@ -795,7 +791,7 @@ index b82562e5f1884df165c6d2793a3daba0a6faab16..04b82fc67fca471f6c868c227df24160 // search for an if condition at the entrance of the loop Statement first = stat.getFirst(); -@@ -121,6 +152,11 @@ public final class LoopExtractHelper { +@@ -125,6 +156,11 @@ public final class LoopExtractHelper { Statement ifstat = firstif.getIfstat(); if (isExternStatement(stat, ifstat, ifstat)) { @@ -807,12 +803,12 @@ index b82562e5f1884df165c6d2793a3daba0a6faab16..04b82fc67fca471f6c868c227df24160 extractIfBlock(stat, firstif); return true; } -@@ -181,5 +217,10 @@ public final class LoopExtractHelper { +@@ -185,5 +221,10 @@ public final class LoopExtractHelper { loop.addPredecessor(edge); } } + -+ List link = target.getPredecessorEdges(StatEdge.TYPE_BREAK); ++ List link = target.getPredecessorEdges(StatEdge.EdgeType.BREAK); + if (link.size() == 1) { + link.get(0).canInline = false; + } @@ -820,7 +816,7 @@ index b82562e5f1884df165c6d2793a3daba0a6faab16..04b82fc67fca471f6c868c227df24160 } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/LowBreakHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/LowBreakHelper.java new file mode 100644 -index 0000000000000000000000000000000000000000..c62c74da3925db6820facb219ee93163610ea737 +index 0000000000000000000000000000000000000000..04f0a2768d2a943475df28a17389407b3dad7a48 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/LowBreakHelper.java @@ -0,0 +1,194 @@ @@ -849,7 +845,7 @@ index 0000000000000000000000000000000000000000..c62c74da3925db6820facb219ee93163 + boolean found = false; + + for (StatEdge edge : stat.getLabelEdges()) { -+ if (edge.getType() == StatEdge.TYPE_BREAK) { ++ if (edge.getType() == StatEdge.EdgeType.BREAK) { + Statement minclosure = getMinClosure(stat, edge.getSource()); + if (minclosure != stat) { + minclosure.addLabeledEdge(edge); @@ -872,7 +868,7 @@ index 0000000000000000000000000000000000000000..c62c74da3925db6820facb219ee93163 + + public static boolean isBreakEdgeLabeled(Statement source, Statement closure) { + -+ if (closure.type == Statement.TYPE_DO || closure.type == Statement.TYPE_SWITCH) { ++ if (closure.type == Statement.StatementType.DO || closure.type == Statement.StatementType.SWITCH) { + + Statement parent = source.getParent(); + @@ -881,7 +877,7 @@ index 0000000000000000000000000000000000000000..c62c74da3925db6820facb219ee93163 + } + else { + return isBreakEdgeLabeled(parent, closure) || -+ (parent.type == Statement.TYPE_DO || parent.type == Statement.TYPE_SWITCH); ++ (parent.type == Statement.StatementType.DO || parent.type == Statement.StatementType.SWITCH); + } + } + else { @@ -896,14 +892,14 @@ index 0000000000000000000000000000000000000000..c62c74da3925db6820facb219ee93163 + Statement newclosure = null; + + switch (closure.type) { -+ case Statement.TYPE_SEQUENCE: ++ case SEQUENCE: + Statement last = closure.getStats().getLast(); + + if (isOkClosure(closure, source, last)) { + newclosure = last; + } + break; -+ case Statement.TYPE_IF: ++ case IF: + IfStatement ifclosure = (IfStatement)closure; + if (isOkClosure(closure, source, ifclosure.getIfstat())) { + newclosure = ifclosure.getIfstat(); @@ -912,7 +908,7 @@ index 0000000000000000000000000000000000000000..c62c74da3925db6820facb219ee93163 + newclosure = ifclosure.getElsestat(); + } + break; -+ case Statement.TYPE_TRYCATCH: ++ case TRY_CATCH: + for (Statement st : closure.getStats()) { + if (isOkClosure(closure, source, st)) { + newclosure = st; @@ -920,7 +916,7 @@ index 0000000000000000000000000000000000000000..c62c74da3925db6820facb219ee93163 + } + } + break; -+ case Statement.TYPE_SYNCRONIZED: ++ case SYNCHRONIZED: + Statement body = ((SynchronizedStatement)closure).getBody(); + + if (isOkClosure(closure, source, body)) { @@ -949,7 +945,7 @@ index 0000000000000000000000000000000000000000..c62c74da3925db6820facb219ee93163 + ok = lst.isEmpty(); + if (!ok) { + StatEdge edge = lst.get(0); -+ ok = (edge.closure == closure && edge.getType() == StatEdge.TYPE_BREAK); ++ ok = (edge.closure == closure && edge.getType() == StatEdge.EdgeType.BREAK); + } + } + @@ -969,7 +965,7 @@ index 0000000000000000000000000000000000000000..c62c74da3925db6820facb219ee93163 + boolean found = false; + + for (StatEdge edge : stat.getLabelEdges()) { -+ if (edge.explicit && edge.labeled && edge.getType() == StatEdge.TYPE_BREAK) { ++ if (edge.explicit && edge.labeled && edge.getType() == StatEdge.EdgeType.BREAK) { + + Statement newclosure = getMaxBreakLift(stat, edge); + @@ -1020,13 +1016,13 @@ index 0000000000000000000000000000000000000000..c62c74da3925db6820facb219ee93163 +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/MergeHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/MergeHelper.java -index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2ffa554d1 100644 +index ba131586bc96dc3522a1db41814102d8bdf62c8c..bbd92a8d84b43d1ead8d83cc02d2d1988a7bb40c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/MergeHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/MergeHelper.java -@@ -4,11 +4,17 @@ package org.jetbrains.java.decompiler.modules.decompiler; - import org.jetbrains.java.decompiler.code.cfg.BasicBlock; +@@ -5,13 +5,19 @@ import org.jetbrains.java.decompiler.code.cfg.BasicBlock; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.collectors.CounterContainer; + import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType; +import org.jetbrains.java.decompiler.modules.decompiler.exps.ArrayExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.AssignmentExprent; import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; @@ -1035,13 +1031,15 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 +import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; import org.jetbrains.java.decompiler.modules.decompiler.stats.*; + import org.jetbrains.java.decompiler.modules.decompiler.stats.DoStatement.LoopType; + import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement.StatementType; import java.util.ArrayList; +import java.util.BitSet; import java.util.List; import java.util.Set; -@@ -42,17 +48,20 @@ public final class MergeHelper { +@@ -47,17 +53,20 @@ public final class MergeHelper { // identify a while loop if (matchWhile(stat)) { @@ -1058,15 +1056,15 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 } break; - case DoStatement.LOOP_WHILE: + case WHILE: - matchFor(stat); + if (!matchForEach(stat)) { + matchFor(stat); + } } - return (stat.getLooptype() != oldloop); -@@ -142,13 +151,14 @@ public final class MergeHelper { + return (stat.getLoopType() != oldLoop); +@@ -147,13 +156,14 @@ public final class MergeHelper { if (firstif.iftype == IfStatement.IFTYPE_IF) { if (firstif.getIfstat() == null) { StatEdge ifedge = firstif.getIfEdge(); @@ -1074,7 +1072,7 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + + if (isDirectPath(stat, ifedge.getDestination()) || addContinueOrBreak(stat, ifedge)) { // exit condition identified - stat.setLooptype(DoStatement.LOOP_WHILE); + stat.setLoopType(LoopType.WHILE); // negate condition (while header) IfExprent ifexpr = (IfExprent)firstif.getHeadexprent().copy(); @@ -1083,7 +1081,7 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 if (stat.getConditionExprent() != null) { ifexpr.getCondition().addBytecodeOffsets(stat.getConditionExprent().bytecode); -@@ -186,7 +196,7 @@ public final class MergeHelper { +@@ -191,7 +201,7 @@ public final class MergeHelper { return true; } } @@ -1092,7 +1090,7 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 StatEdge elseedge = firstif.getAllSuccessorEdges().get(0); if (isDirectPath(stat, elseedge.getDestination())) { // exit condition identified -@@ -240,7 +250,7 @@ public final class MergeHelper { +@@ -245,7 +255,7 @@ public final class MergeHelper { return true; } @@ -1101,16 +1099,16 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 } } } -@@ -325,6 +335,8 @@ public final class MergeHelper { +@@ -330,6 +340,8 @@ public final class MergeHelper { } else { - preData = current.getNeighbours(StatEdge.TYPE_REGULAR, Statement.DIRECTION_BACKWARD).get(0); + preData = current.getNeighbours(EdgeType.REGULAR, EdgeDirection.BACKWARD).get(0); + // we're not a basic block, so we can't dive inside for exprents -+ if (preData.type != Statement.TYPE_BASICBLOCK) break; ++ if (preData.type != Statement.StatementType.BASIC_BLOCK) break; preData = getLastDirectData(preData); if (preData != null && !preData.getExprents().isEmpty()) { initDoExprent = preData.getExprents().get(preData.getExprents().size() - 1); -@@ -363,12 +375,16 @@ public final class MergeHelper { +@@ -368,12 +380,16 @@ public final class MergeHelper { stat.setIncExprent(exp); } @@ -1131,11 +1129,11 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 } } -@@ -401,14 +417,346 @@ public final class MergeHelper { +@@ -406,14 +422,346 @@ public final class MergeHelper { return stat; } -- if (stat.type == Statement.TYPE_SEQUENCE) { +- if (stat.type == StatementType.SEQUENCE) { - for (int i = stat.getStats().size() - 1; i >= 0; i--) { - Statement tmp = getLastDirectData(stat.getStats().get(i)); - if (tmp == null || !tmp.getExprents().isEmpty()) { @@ -1163,12 +1161,12 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + break; + } + -+ if (parent.type == Statement.TYPE_SEQUENCE) { ++ if (parent.type == Statement.StatementType.SEQUENCE) { + if (current == parent.getFirst()) { + current = parent; + } + else { -+ preData = current.getNeighbours(StatEdge.TYPE_REGULAR, Statement.DIRECTION_BACKWARD).get(0); ++ preData = current.getNeighbours(StatEdge.EdgeType.REGULAR, StatEdge.EdgeDirection.BACKWARD).get(0); + preData = getLastDirectData(preData); + if (preData != null && !preData.getExprents().isEmpty()) { + int size = preData.getExprents().size(); @@ -1182,8 +1180,8 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + } + } + break; - } - } ++ } ++ } + else { + break; + } @@ -1198,13 +1196,13 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + lastExprent = lastData.getExprents().get(lastData.getExprents().size() - 1); + } + -+ if (stat.getLooptype() == DoStatement.LOOP_WHILE && initExprents[0] != null && firstDoExprent != null) { ++ if (stat.getLoopType() == DoStatement.LoopType.WHILE && initExprents[0] != null && firstDoExprent != null) { + if (isIteratorCall(initExprents[0].getRight())) { + + //Streams mimic Iterable but arnt.. so explicitly disallow their enhancements + //TODO: Check inheritance for Iterable instead of just names? + InvocationExprent invc = (InvocationExprent)getUncast((initExprents[0]).getRight()); -+ if (invc.getClassname().contains("java/util/stream")) { ++ if (invc.getClassName().contains("java/util/stream")) { + return false; + } + @@ -1241,7 +1239,7 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + stat.getInitExprent().getBytecodeRange(ass.getLeft().bytecode); + } + -+ stat.setLooptype(DoStatement.LOOP_FOREACH); ++ stat.setLoopType(DoStatement.LoopType.FOREACH); + stat.setInitExprent(ass.getLeft()); + stat.setIncExprent(holder.getInstance()); + preData.getExprents().remove(initExprents[0]); @@ -1309,7 +1307,7 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + firstDoExprent.getLeft().addBytecodeOffsets(firstDoExprent.bytecode); + firstDoExprent.getLeft().addBytecodeOffsets(initExprents[0].bytecode); + -+ stat.setLooptype(DoStatement.LOOP_FOREACH); ++ stat.setLoopType(DoStatement.LoopType.FOREACH); + stat.setInitExprent(firstDoExprent.getLeft()); + stat.setIncExprent(funcRight.getLstOperands().get(0)); + preData.getExprents().remove(initExprents[0]); @@ -1342,7 +1340,7 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + FunctionExprent fun = (FunctionExprent)exp; + if (fun.getFuncType() == FunctionExprent.FUNCTION_BOOL_NOT) { + exp = fun.getLstOperands().get(0); -+ } + } + else if (fun.getFuncType() == FunctionExprent.FUNCTION_EQ || + fun.getFuncType() == FunctionExprent.FUNCTION_NE) { + return fun.getLstOperands().get(0); @@ -1376,8 +1374,8 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + FunctionExprent func = (FunctionExprent)exp; + if (func.getFuncType() == FunctionExprent.FUNCTION_CAST) { + return getUncast(func.getLstOperands().get(0)); -+ } -+ } + } + } + return exp; + } + @@ -1385,7 +1383,7 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + exp = getUncast(exp); + if (exp.type == Exprent.EXPRENT_INVOCATION) { + return (InvocationExprent) exp; - } ++ } return null; } -} @@ -1397,7 +1395,7 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + return false; + } + final org.jetbrains.java.decompiler.struct.gen.MethodDescriptor descriptor = iexp.getDescriptor(); -+ if (!DecompilerContext.getStructContext().instanceOf(descriptor.ret.value, "java/util/Iterator")) { ++ if (!DecompilerContext.getStructContext().instanceOf(descriptor.ret.getValue(), "java/util/Iterator")) { + return false; + } + final String name = iexp.getName(); @@ -1410,7 +1408,7 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + if (iexp == null) { + return false; + } -+ if (!DecompilerContext.getStructContext().instanceOf(iexp.getClassname(), "java/util/Iterator")) { ++ if (!DecompilerContext.getStructContext().instanceOf(iexp.getClassName(), "java/util/Iterator")) { + return false; + } + return "hasNext".equals(iexp.getName()) && "()Z".equals(iexp.getStringDescriptor()); @@ -1421,7 +1419,7 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + if (iexp == null) { + return false; + } -+ if (!DecompilerContext.getStructContext().instanceOf(iexp.getClassname(), "java/util/Iterator")) { ++ if (!DecompilerContext.getStructContext().instanceOf(iexp.getClassName(), "java/util/Iterator")) { + return false; + } + return "next".equals(iexp.getName()) && "()Ljava/lang/Object;".equals(iexp.getStringDescriptor()); @@ -1450,11 +1448,11 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + ret |= makeDoWhileRec(st); + } + -+ if (stat.type == Statement.TYPE_DO) { ++ if (stat.type == Statement.StatementType.DO) { + DoStatement dostat = (DoStatement)stat; -+ if (dostat.getLooptype() == DoStatement.LOOP_DO) { ++ if (dostat.getLoopType() == DoStatement.LoopType.DO) { + matchDoWhile(dostat); -+ ret |= dostat.getLooptype() != DoStatement.LOOP_DO; ++ ret |= dostat.getLoopType() != DoStatement.LoopType.DO; + } + } + @@ -1463,20 +1461,20 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + + private static boolean addContinueOrBreak(DoStatement stat, StatEdge ifedge) { + Statement outer = stat.getParent(); -+ while (outer != null && outer.type != Statement.TYPE_SWITCH && outer.type != Statement.TYPE_DO) { ++ while (outer != null && outer.type != Statement.StatementType.SWITCH && outer.type != Statement.StatementType.DO) { + outer = outer.getParent(); + } + -+ if (outer != null && (outer.type == Statement.TYPE_SWITCH || ((DoStatement)outer).getLooptype() != DoStatement.LOOP_DO)) { ++ if (outer != null && (outer.type == Statement.StatementType.SWITCH || ((DoStatement)outer).getLoopType() != DoStatement.LoopType.DO)) { + Statement parent = stat.getParent(); -+ if (parent.type != Statement.TYPE_SEQUENCE || parent.getStats().getLast().equals(stat)) { ++ if (parent.type != Statement.StatementType.SEQUENCE || parent.getStats().getLast().equals(stat)) { + // need to insert a break or continue after the loop + if (ifedge.getDestination().equals(outer)) { -+ stat.addSuccessor(new StatEdge(StatEdge.TYPE_CONTINUE, stat, ifedge.getDestination(), outer)); ++ stat.addSuccessor(new StatEdge(StatEdge.EdgeType.CONTINUE, stat, ifedge.getDestination(), outer)); + return true; + } + else if (MergeHelper.isDirectPath(outer, ifedge.getDestination())) { -+ stat.addSuccessor(new StatEdge(StatEdge.TYPE_BREAK, stat, ifedge.getDestination(), outer)); ++ stat.addSuccessor(new StatEdge(StatEdge.EdgeType.BREAK, stat, ifedge.getDestination(), outer)); + return true; + } + } @@ -1486,10 +1484,10 @@ index c9ca96373685aa74c10f79b1050cca012484bfb2..ef3ab0ed07a435f4fbf2dc1be1117bc2 + } +} diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java -index d73535f1374e3ec59079fddf06ecea6480925467..94dc0a33d7eaec052c6f3ce10fbbb93eb5395025 100644 +index 9d0ec7c864030386838efd4952da1e999ccd967e..b085a40522e69c4bb6e69e8abf946ad61e2a2a24 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java -@@ -5,19 +5,31 @@ import org.jetbrains.java.decompiler.modules.decompiler.exps.AssignmentExprent; +@@ -5,19 +5,32 @@ import org.jetbrains.java.decompiler.modules.decompiler.exps.AssignmentExprent; import org.jetbrains.java.decompiler.modules.decompiler.exps.ConstExprent; import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; import org.jetbrains.java.decompiler.modules.decompiler.exps.FunctionExprent; @@ -1508,6 +1506,7 @@ index d73535f1374e3ec59079fddf06ecea6480925467..94dc0a33d7eaec052c6f3ce10fbbb93e import java.util.LinkedList; import java.util.List; +import java.util.Map; ++import java.util.Objects; public class PPandMMHelper { @@ -1521,8 +1520,8 @@ index d73535f1374e3ec59079fddf06ecea6480925467..94dc0a33d7eaec052c6f3ce10fbbb93e public boolean findPPandMM(RootStatement root) { -@@ -45,6 +57,8 @@ public class PPandMMHelper { - stack.addAll(node.succs); +@@ -45,6 +58,8 @@ public class PPandMMHelper { + stack.addAll(node.successors); } + updateVersions(dgraph); @@ -1530,7 +1529,7 @@ index d73535f1374e3ec59079fddf06ecea6480925467..94dc0a33d7eaec052c6f3ce10fbbb93e return res; } -@@ -120,13 +134,18 @@ public class PPandMMHelper { +@@ -120,13 +135,18 @@ public class PPandMMHelper { Exprent left = as.getLeft(); VarType condtype = econd.getExprType(); @@ -1550,7 +1549,7 @@ index d73535f1374e3ec59079fddf06ecea6480925467..94dc0a33d7eaec052c6f3ce10fbbb93e return ret; } } -@@ -136,4 +155,48 @@ public class PPandMMHelper { +@@ -136,4 +156,48 @@ public class PPandMMHelper { return null; } @@ -1571,7 +1570,7 @@ index d73535f1374e3ec59079fddf06ecea6480925467..94dc0a33d7eaec052c6f3ce10fbbb93e + VarExprent v1 = (VarExprent)e1; + VarExprent v2 = (VarExprent)e2; + return varProc.getVarOriginalIndex(v1.getIndex()) == varProc.getVarOriginalIndex(v2.getIndex()) -+ && InterpreterUtil.equalObjects(v1.getVarType(), v2.getVarType()); ++ && Objects.equals(v1.getVarType(), v2.getVarType()); + } + + @@ -1600,32 +1599,31 @@ index d73535f1374e3ec59079fddf06ecea6480925467..94dc0a33d7eaec052c6f3ce10fbbb93e + } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/StatEdge.java b/src/org/jetbrains/java/decompiler/modules/decompiler/StatEdge.java -index c481c0a343d8ca7825989cfe289fc7d2dd793aa7..cdbcb7090acf9afb536ca003c9a685e5c209d265 100644 +index c3263800aba7cb93e7b879d0bd46888fb696e861..d7c81a5f8538cdb6c99c752a9dd0fba5cb767121 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/StatEdge.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/StatEdge.java -@@ -35,6 +35,8 @@ public class StatEdge { - +@@ -15,6 +15,7 @@ public class StatEdge { + public Statement closure; + public boolean labeled = true; public boolean explicit = true; - + public boolean canInline = true; -+ - public StatEdge(int type, Statement source, Statement destination, Statement closure) { + + public StatEdge(@NotNull EdgeType type, Statement source, Statement destination, Statement closure) { this(type, source, destination); - this.closure = closure; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -index 87522af363670f27a69bf5dee95a954ae14ed594..9803a215b8c5bc40658c8210c10e61644b519231 100644 +index bfae94c3dd24e9fbf624310591ae33ccb454ecff..afaf2bf239640309370fd34cf9750f4a9537ba74 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -@@ -458,7 +458,7 @@ public class InvocationExprent extends Exprent { +@@ -463,7 +463,7 @@ public class InvocationExprent extends Exprent { UNBOXING_METHODS.put("charValue", "java/lang/Character"); } - private boolean isUnboxingCall() { + public boolean isUnboxingCall() { - return !isStatic && lstParameters.size() == 0 && classname.equals(UNBOXING_METHODS.get(name)); + return !isStatic && parameters.size() == 0 && className.equals(UNBOXING_METHODS.get(name)); } -@@ -659,4 +659,4 @@ public class InvocationExprent extends Exprent { +@@ -664,4 +664,4 @@ public class InvocationExprent extends Exprent { return true; } @@ -1633,17 +1631,16 @@ index 87522af363670f27a69bf5dee95a954ae14ed594..9803a215b8c5bc40658c8210c10e6164 \ No newline at end of file +} diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java -index c6f0eaccf94c55175c19bfc6a4beee9569ab9dc0..60048a473001b72b6eb6b8d903a257c043d76902 100644 +index 4c40e5152ffca092883170401453525093da011a..1765af58c1f7db03da58747e06c19d7e3f483dd5 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java -@@ -9,12 +9,15 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; +@@ -9,11 +9,14 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; +import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; +import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; - import org.jetbrains.java.decompiler.modules.decompiler.vars.VarTypeProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.struct.StructMethod; import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; @@ -1652,10 +1649,15 @@ index c6f0eaccf94c55175c19bfc6a4beee9569ab9dc0..60048a473001b72b6eb6b8d903a257c0 import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTypeTableAttribute; import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.struct.gen.generics.GenericFieldDescriptor; -@@ -29,6 +32,7 @@ import org.jetbrains.java.decompiler.util.TextUtil; +@@ -25,10 +28,11 @@ import org.jetbrains.java.decompiler.util.TextBuffer; + import org.jetbrains.java.decompiler.util.TextUtil; + import java.util.ArrayList; +-import java.util.Collections; import java.util.BitSet; ++import java.util.Collections; import java.util.List; + import java.util.Objects; +import java.util.stream.Collectors; public class VarExprent extends Exprent { @@ -1686,7 +1688,7 @@ index c6f0eaccf94c55175c19bfc6a4beee9569ab9dc0..60048a473001b72b6eb6b8d903a257c0 - } if (definition) { - if (processor != null && processor.getVarFinal(varVersion) == VarTypeProcessor.VAR_EXPLICIT_FINAL) { + if (processor != null && processor.getVarFinal(varVersion) == VarProcessor.VAR_EXPLICIT_FINAL) { @@ -105,7 +107,7 @@ public class VarExprent extends Exprent { buffer.append(" "); } @@ -1718,12 +1720,12 @@ index c6f0eaccf94c55175c19bfc6a4beee9569ab9dc0..60048a473001b72b6eb6b8d903a257c0 + if (lvt.getSignature() != null) { + GenericFieldDescriptor descriptor = GenericMain.parseFieldSignature(lvt.getSignature()); + if (descriptor != null) { -+ buffer.append(GenericMain.getGenericCastTypeName(descriptor.type)); ++ buffer.append(GenericMain.getGenericCastTypeName(descriptor.type, Collections.emptyList())); + return; + } + } + } -+ buffer.append(ExprProcessor.getCastTypeName(getVarType())); ++ buffer.append(ExprProcessor.getCastTypeName(getVarType(), Collections.emptyList())); + return; + } + @@ -1836,7 +1838,7 @@ index c6f0eaccf94c55175c19bfc6a4beee9569ab9dc0..60048a473001b72b6eb6b8d903a257c0 // IMatchable implementation // ***************************************************************************** diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java -index aa2fae88906858a3c8bd05508db963edbaf0de07..fc6fc93f29c8e8c9e4319d3c6777562ba3e7dc9f 100644 +index a20acdff7d3ef1415fe6c90d05b92a90cfaf0073..6f21cd6df597613099861d874bb320effd0a366a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java @@ -113,6 +113,21 @@ public class DirectGraph { @@ -1862,30 +1864,30 @@ index aa2fae88906858a3c8bd05508db963edbaf0de07..fc6fc93f29c8e8c9e4319d3c6777562b // 0 - success, do nothing // 1 - cancel iteration diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java -index ca43d660a8ab602fbc317cc3078c6def53902899..2883c91e705ea07717350f813e0bf41638fc0e09 100644 +index c05f6eb84fb8d09d8842851c0c2725dff527449b..a3ef4b8b5fdb820c520a21fcd727e08e9dfe2510 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java -@@ -201,6 +201,7 @@ public class FlattenStatementsHelper { +@@ -205,6 +205,7 @@ public class FlattenStatementsHelper { sourcenode = node; break; - case DoStatement.LOOP_FOR: -+ case DoStatement.LOOP_FOREACH: - DirectNode nodeinit = new DirectNode(DirectNode.NODE_INIT, stat, stat.id + "_init"); + case FOR: ++ case FOREACH: + DirectNode nodeinit = new DirectNode(DirectNodeType.INIT, stat, stat.id + "_init"); if (dostat.getInitExprent() != null) { nodeinit.exprents = dostat.getInitExprentList(); -@@ -208,7 +209,9 @@ public class FlattenStatementsHelper { +@@ -212,7 +213,9 @@ public class FlattenStatementsHelper { graph.nodes.putWithKey(nodeinit, nodeinit.id); - DirectNode nodecond = new DirectNode(DirectNode.NODE_CONDITION, stat, stat.id + "_cond"); + DirectNode nodecond = new DirectNode(DirectNodeType.CONDITION, stat, stat.id + "_cond"); - nodecond.exprents = dostat.getConditionExprentList(); -+ if (looptype != DoStatement.LOOP_FOREACH) { ++ if (loopType != DoStatement.LoopType.FOREACH) { + nodecond.exprents = dostat.getConditionExprentList(); + } graph.nodes.putWithKey(nodecond, nodecond.id); - DirectNode nodeinc = new DirectNode(DirectNode.NODE_INCREMENT, stat, stat.id + "_inc"); + DirectNode nodeinc = new DirectNode(DirectNodeType.INCREMENT, stat, stat.id + "_inc"); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java -index 2fa2d9011729151d59f06cda9542539fad0804d9..25e20bf5a3474103c4ea9b56c795fe28e108a692 100644 +index 499968a156b91709d769ac5867e9fa9ce6f23232..ef2fb6128921b74b815b39d6be6e9c7290a2be70 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java @@ -2,6 +2,7 @@ @@ -1896,7 +1898,7 @@ index 2fa2d9011729151d59f06cda9542539fad0804d9..25e20bf5a3474103c4ea9b56c795fe28 import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.main.collectors.CounterContainer; -@@ -52,7 +53,7 @@ public final class CatchAllStatement extends Statement { +@@ -53,7 +54,7 @@ public final class CatchAllStatement extends Statement { post = edge.getDestination(); } } @@ -1906,10 +1908,10 @@ index 2fa2d9011729151d59f06cda9542539fad0804d9..25e20bf5a3474103c4ea9b56c795fe28 new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/Throwable"), DecompilerContext.getVarProcessor())); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java -index 5168f05b5f073d661ca39c4446c8edbcbf1ccc00..7e41176d17729f6acdf5420c9ed98eb7ffb6f3ae 100644 +index 7c83c48777e2dc683d1321fb297f89466f62e8ce..c3536d73475e1037a82e5f76a328c859f5507077 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java -@@ -41,7 +41,7 @@ public final class CatchStatement extends Statement { +@@ -43,7 +43,7 @@ public final class CatchStatement extends Statement { if (setHandlers.contains(stat)) { stats.addWithKey(stat, stat.id); exctstrings.add(new ArrayList<>(edge.getExceptions())); @@ -1919,23 +1921,15 @@ index 5168f05b5f073d661ca39c4446c8edbcbf1ccc00..7e41176d17729f6acdf5420c9ed98eb7 new VarType(CodeConstants.TYPE_OBJECT, 0, edge.getExceptions().get(0)), // FIXME: for now simply the first type. Should get the first common superclass when possible. diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java -index 46b2f2c2bab6bc401205c3a3523267927beae652..76009831d84f399b9a9dc1b8afc09eff519e000a 100644 +index 2dc447272c2786a80f9638a91c95716484911fe2..0c64170a05d6675803b69284d8ee532e44212ee2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java -@@ -17,6 +17,7 @@ public final class DoStatement extends Statement { - public static final int LOOP_DOWHILE = 1; - public static final int LOOP_WHILE = 2; - public static final int LOOP_FOR = 3; -+ public static final int LOOP_FOREACH = 4; - - private int looptype; - -@@ -122,6 +123,14 @@ public final class DoStatement extends Statement { +@@ -103,6 +103,14 @@ public final class DoStatement extends Statement { buf.append(ExprProcessor.jmpWrapper(first, indent + 1, false, tracer)); buf.appendIndent(indent).append("}").appendLineSeparator(); tracer.incrementCurrentSourceLine(); + break; -+ case LOOP_FOREACH: ++ case FOREACH: + buf.appendIndent(indent).append("for(").append(initExprent.get(0).toJava(indent, tracer)); + buf.append(" : ").append(incExprent.get(0).toJava(indent, tracer)).append(") {").appendLineSeparator(); + tracer.incrementCurrentSourceLine(); @@ -1943,24 +1937,33 @@ index 46b2f2c2bab6bc401205c3a3523267927beae652..76009831d84f399b9a9dc1b8afc09eff + buf.appendIndent(indent).append("}").appendLineSeparator(); + tracer.incrementCurrentSourceLine(); } - return buf; -@@ -139,6 +148,10 @@ public final class DoStatement extends Statement { + } +@@ -117,6 +125,10 @@ public final class DoStatement extends Statement { } - case LOOP_WHILE: + case WHILE: lst.add(getConditionExprent()); + break; -+ case LOOP_FOREACH: ++ case FOREACH: + lst.add(getInitExprent()); + lst.add(getIncExprent()); } - lst.add(first); + switch (loopType) { +@@ -195,6 +207,7 @@ public final class DoStatement extends Statement { + DO, + DO_WHILE, + WHILE, +- FOR ++ FOR, ++ FOREACH + } + } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java -index 74f44c077c0985fa23145f39d617976f94571f55..b2455f278256688815f05a3b1a835726329202a8 100644 +index 9d5fcfd4c907e69c52965517dfe69e3a2f82c5df..57475f98e56d87c8dbd7edc3cda7cf243f0b6b16 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java -@@ -807,6 +807,14 @@ public class Statement implements IMatchable { +@@ -768,6 +768,14 @@ public abstract class Statement implements IMatchable { this.parent = parent; } @@ -1975,20 +1978,20 @@ index 74f44c077c0985fa23145f39d617976f94571f55..b2455f278256688815f05a3b1a835726 public HashSet getLabelEdges() { // FIXME: why HashSet? return labelEdges; } -@@ -833,7 +841,7 @@ public class Statement implements IMatchable { +@@ -794,7 +802,7 @@ public abstract class Statement implements IMatchable { // helper methods public String toString() { -- return id.toString(); +- return Integer.toString(id); + return String.format("{%d}:%d", type, id); } //TODO: Cleanup/cache? diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java -index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172836e22db 100644 +index 46e405dcb94da78180efa7a8e2374392590027db..344772dc14f336d6ffe235c5159225d0656846f1 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java -@@ -4,16 +4,26 @@ package org.jetbrains.java.decompiler.modules.decompiler.vars; +@@ -4,18 +4,28 @@ package org.jetbrains.java.decompiler.modules.decompiler.vars; import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.collectors.VarNamesCollector; @@ -2003,8 +2006,10 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 import org.jetbrains.java.decompiler.modules.decompiler.stats.CatchAllStatement; import org.jetbrains.java.decompiler.modules.decompiler.stats.CatchStatement; import org.jetbrains.java.decompiler.modules.decompiler.stats.DoStatement; + import org.jetbrains.java.decompiler.modules.decompiler.stats.DoStatement.LoopType; +import org.jetbrains.java.decompiler.modules.decompiler.stats.IfStatement; import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; + import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement.StatementType; import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute.LocalVariable; @@ -2015,7 +2020,7 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 import java.util.*; import java.util.Map.Entry; -@@ -29,6 +39,9 @@ public class VarDefinitionHelper { +@@ -31,6 +41,9 @@ public class VarDefinitionHelper { private final VarProcessor varproc; @@ -2025,7 +2030,7 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 public VarDefinitionHelper(Statement root, StructMethod mt, VarProcessor varproc) { mapVarDefStatements = new HashMap<>(); -@@ -36,6 +49,8 @@ public class VarDefinitionHelper { +@@ -38,6 +51,8 @@ public class VarDefinitionHelper { implDefVars = new HashSet<>(); this.varproc = varproc; @@ -2034,7 +2039,7 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 VarNamesCollector vc = varproc.getVarNamesCollector(); -@@ -49,12 +64,12 @@ public class VarDefinitionHelper { +@@ -51,12 +66,12 @@ public class VarDefinitionHelper { } paramcount += md.params.length; @@ -2049,7 +2054,7 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 if (thisvar) { if (i == 0) { -@@ -77,6 +92,8 @@ public class VarDefinitionHelper { +@@ -79,6 +94,8 @@ public class VarDefinitionHelper { vc.addName("this"); } @@ -2058,7 +2063,7 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 // catch variables are implicitly defined LinkedList stack = new LinkedList<>(); stack.add(root); -@@ -106,7 +123,6 @@ public class VarDefinitionHelper { +@@ -108,7 +125,6 @@ public class VarDefinitionHelper { initStatement(root); } @@ -2066,11 +2071,11 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 public void setVarDefinitions() { VarNamesCollector vc = varproc.getVarNamesCollector(); -@@ -139,9 +155,17 @@ public class VarDefinitionHelper { +@@ -141,9 +157,17 @@ public class VarDefinitionHelper { } } } -+ else if (dstat.getLooptype() == DoStatement.LOOP_FOREACH) { ++ else if (dstat.getLoopType() == DoStatement.LoopType.FOREACH) { + if (dstat.getInitExprent() != null && dstat.getInitExprent().type == Exprent.EXPRENT_VAR) { + VarExprent var = (VarExprent)dstat.getInitExprent(); + if (var.getIndex() == index.intValue()) { @@ -2085,7 +2090,7 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 Statement first = findFirstBlock(stat, index); List lst; -@@ -155,7 +179,6 @@ public class VarDefinitionHelper { +@@ -157,7 +181,6 @@ public class VarDefinitionHelper { lst = first.getExprents(); } @@ -2093,7 +2098,7 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 boolean defset = false; // search for the first assignment to var [index] -@@ -184,9 +207,17 @@ public class VarDefinitionHelper { +@@ -186,9 +209,17 @@ public class VarDefinitionHelper { VarExprent var = new VarExprent(index, varproc.getVarType(new VarVersionPair(index.intValue(), 0)), varproc); var.setDefinition(true); @@ -2111,7 +2116,7 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 } -@@ -194,6 +225,50 @@ public class VarDefinitionHelper { +@@ -196,6 +227,50 @@ public class VarDefinitionHelper { // private methods // ***************************************************************************** @@ -2162,15 +2167,15 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 private Statement findFirstBlock(Statement stat, Integer varindex) { LinkedList stack = new LinkedList<>(); -@@ -254,6 +329,7 @@ public class VarDefinitionHelper { - if (st.type == DoStatement.TYPE_DO) { +@@ -256,6 +331,7 @@ public class VarDefinitionHelper { + if (st.type == StatementType.DO) { DoStatement dost = (DoStatement)st; - if (dost.getLooptype() != DoStatement.LOOP_FOR && -+ dost.getLooptype() != DoStatement.LOOP_FOREACH && - dost.getLooptype() != DoStatement.LOOP_DO) { + if (dost.getLoopType() != LoopType.FOR && ++ dost.getLoopType() != LoopType.FOREACH && + dost.getLoopType() != LoopType.DO) { currVars.add(dost.getConditionExprent()); } -@@ -324,7 +400,7 @@ public class VarDefinitionHelper { +@@ -326,7 +402,7 @@ public class VarDefinitionHelper { return res; } @@ -2179,14 +2184,14 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 if (expr.type == Exprent.EXPRENT_ASSIGNMENT) { Exprent left = ((AssignmentExprent)expr).getLeft(); if (left.type == Exprent.EXPRENT_VAR) { -@@ -337,4 +413,660 @@ public class VarDefinitionHelper { +@@ -339,4 +415,660 @@ public class VarDefinitionHelper { } return false; } + + private void populateTypeBounds(VarProcessor proc, Statement stat) { -+ Map mapExprentMinTypes = varproc.getVarVersions().getTypeProcessor().getMapExprentMinTypes(); -+ Map mapExprentMaxTypes = varproc.getVarVersions().getTypeProcessor().getMapExprentMaxTypes(); ++ Map mapExprentMinTypes = varproc.getVarVersions().getTypeProcessor().getMinExprentTypes(); ++ Map mapExprentMaxTypes = varproc.getVarVersions().getTypeProcessor().getMaxExprentTypes(); + LinkedList stack = new LinkedList<>(); + stack.add(root); + @@ -2207,7 +2212,7 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 + String target = null; + if (exp.type == Exprent.EXPRENT_INVOCATION) { + instance = ((InvocationExprent)exp).getInstance(); -+ target = ((InvocationExprent)exp).getClassname(); ++ target = ((InvocationExprent)exp).getClassName(); + } else if (exp.type == Exprent.EXPRENT_FIELD) { + instance = ((FieldExprent)exp).getInstance(); + target = ((FieldExprent)exp).getClassname(); @@ -2215,7 +2220,7 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 + ExitExprent exit = (ExitExprent)exp; + if (exit.getExitType() == ExitExprent.EXIT_RETURN) { + instance = exit.getValue(); -+ target = exit.getRetType().value; ++ target = exit.getRetType().getValue(); + } + } + @@ -2240,9 +2245,9 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 + */ + + if (!newType.equals(oldMax)) { -+ if (oldMax != null && oldMax.type == CodeConstants.TYPE_OBJECT) { ++ if (oldMax != null && oldMax.getType() == CodeConstants.TYPE_OBJECT) { + // If the old min is an instanceof the new target, EXA: List -> ArrayList -+ if (DecompilerContext.getStructContext().instanceOf(newType.value, oldMax.value)) ++ if (DecompilerContext.getStructContext().instanceOf(newType.getValue(), oldMax.getValue())) + mapExprentMaxTypes.put(key, newType); + } else + mapExprentMaxTypes.put(key, newType); @@ -2271,7 +2276,7 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 + + for (VarType var : md.params) { + parent.put(index, new VarVersionPair(index, 0)); -+ index += var.stackSize; ++ index += var.getStackSize(); + } + + populateTypeBounds(varproc, stat); @@ -2312,10 +2317,10 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 + + Map scoped = null; + switch (stat.type) { // These are the type of statements that leak vars -+ case Statement.TYPE_BASICBLOCK: -+ case Statement.TYPE_GENERAL: -+ case Statement.TYPE_ROOT: -+ case Statement.TYPE_SEQUENCE: ++ case BASIC_BLOCK: ++ case GENERAL: ++ case ROOT: ++ case SEQUENCE: + scoped = leaked; + } + @@ -2349,7 +2354,7 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 + */ + + if (leaked_n.size() > 0) { -+ if (stat.type == Statement.TYPE_IF) { ++ if (stat.type == Statement.StatementType.IF) { + IfStatement ifst = (IfStatement)stat; + if (obj == ifst.getIfstat() || obj == ifst.getElsestat()) { + leaked_n.clear(); // Force no leaking at the end of if blocks @@ -2358,8 +2363,8 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 + else if (obj == ifst.getFirst()) { + leaked.putAll(leaked_n); //First is outside the scope so leak! + } -+ } else if (stat.type == Statement.TYPE_SWITCH || -+ stat.type == Statement.TYPE_SYNCRONIZED) { ++ } else if (stat.type == Statement.StatementType.SWITCH || ++ stat.type == Statement.StatementType.SYNCHRONIZED) { + if (obj == stat.getFirst()) { + leaked.putAll(leaked_n); //First is outside the scope so leak! + } @@ -2367,8 +2372,8 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 + leaked_n.clear(); + } + } -+ else if (stat.type == Statement.TYPE_TRYCATCH || -+ stat.type == Statement.TYPE_CATCHALL) { ++ else if (stat.type == Statement.StatementType.TRY_CATCH || ++ stat.type == Statement.StatementType.CATCH_ALL) { + leaked_n.clear(); // Catches can't leak anything mwhahahahah! + } + this_vars.putAll(leaked_n); @@ -2548,8 +2553,8 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 + } + + private VarType getMergedType(VarVersionPair from, VarVersionPair to) { -+ Map minTypes = varproc.getVarVersions().getTypeProcessor().getMapExprentMinTypes(); -+ Map maxTypes = varproc.getVarVersions().getTypeProcessor().getMapExprentMaxTypes(); ++ Map minTypes = varproc.getVarVersions().getTypeProcessor().getMinExprentTypes(); ++ Map maxTypes = varproc.getVarVersions().getTypeProcessor().getMaxExprentTypes(); + return getMergedType(minTypes.get(from), minTypes.get(to), maxTypes.get(from), maxTypes.get(to)); + } + @@ -2561,25 +2566,25 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 + if (type == null || fromMin == null || toMin == null) { + return null; // no common supertype, skip the remapping + } -+ if (type.type == CodeConstants.TYPE_OBJECT) { ++ if (type.getType() == CodeConstants.TYPE_OBJECT) { + if (toMax != null) { // The target var is used in direct invocations + if (fromMax != null) { + // Max types are the highest class that this variable is used as a direct instance of without any casts. + // This will pull up the to var type if the from requires a higher class type. + // EXA: Collection -> List -+ if (DecompilerContext.getStructContext().instanceOf(fromMax.value, toMax.value)) ++ if (DecompilerContext.getStructContext().instanceOf(fromMax.getValue(), toMax.getValue())) + return fromMax; + } else if (fromMin != null) { + // Pull to up to from: List -> ArrayList -+ if (DecompilerContext.getStructContext().instanceOf(fromMin.value, toMax.value)) ++ if (DecompilerContext.getStructContext().instanceOf(fromMin.getValue(), toMax.getValue())) + return fromMin; + } + } else if (toMin != null) { + if (fromMax != null) { -+ if (DecompilerContext.getStructContext().instanceOf(fromMax.value, toMin.value)) ++ if (DecompilerContext.getStructContext().instanceOf(fromMax.getValue(), toMin.getValue())) + return fromMax; + } else if (fromMin != null) { -+ if (DecompilerContext.getStructContext().instanceOf(toMin.value, fromMin.value)) ++ if (DecompilerContext.getStructContext().instanceOf(toMin.getValue(), fromMin.getValue())) + return toMin; + } + } @@ -2608,7 +2613,7 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 + if (lvt != null && lvt.size() > 0) { + types.put(new VarVersionPair(index, 0), new VarInfo(lvt.get(0), null)); + } -+ index += var.stackSize; ++ index += var.getStackSize(); + } + } + @@ -2761,11 +2766,11 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 + + private VarInfo(LocalVariable lvt, VarType type) { + if (lvt != null && lvt.getSignature() != null) -+ this.cast = GenericMain.getGenericCastTypeName(new GenericType(lvt.getSignature())); ++ this.cast = GenericMain.getGenericCastTypeName(new GenericType(lvt.getSignature()), Collections.emptyList()); + else if (lvt != null) -+ this.cast = ExprProcessor.getCastTypeName(lvt.getVarType(), false); ++ this.cast = ExprProcessor.getCastTypeName(lvt.getVarType(), false, Collections.emptyList()); + else if (type != null) -+ this.cast = ExprProcessor.getCastTypeName(type, false); ++ this.cast = ExprProcessor.getCastTypeName(type, false, Collections.emptyList()); + else + this.cast = "this"; + this.lvt = lvt; @@ -2841,16 +2846,17 @@ index 0402097b50b89cd8092915db381abfb61be7f495..fa326a4a190012b9e121baa61880c172 + } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java -index 8d766e0412cc952c42d53eae5cec74db5c992c0d..bc8fa493167a5fabf772403550511855bd24de1a 100644 +index 33c4c3efcf7d9b26737717a2445bffad0db5c4c0..559c96b54667b5b9a051039fdbb3643f8c8601b5 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java -@@ -2,21 +2,26 @@ - package org.jetbrains.java.decompiler.modules.decompiler.vars; - +@@ -5,16 +5,20 @@ import org.jetbrains.java.decompiler.code.CodeConstants; + import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.collectors.VarNamesCollector; + import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; +import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; + import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute.LocalVariable; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; @@ -2863,7 +2869,8 @@ index 8d766e0412cc952c42d53eae5cec74db5c992c0d..bc8fa493167a5fabf772403550511855 +import java.util.stream.Collectors; public class VarProcessor { - private final VarNamesCollector varNamesCollector = new VarNamesCollector(); + public static final int VAR_NON_FINAL = 1; +@@ -25,6 +29,7 @@ public class VarProcessor { private final StructMethod method; private final MethodDescriptor methodDescriptor; private Map mapVarNames = new HashMap<>(); @@ -2871,7 +2878,7 @@ index 8d766e0412cc952c42d53eae5cec74db5c992c0d..bc8fa493167a5fabf772403550511855 private VarVersionsProcessor varVersions; private final Map thisVars = new HashMap<>(); private final Set externalVars = new HashSet<>(); -@@ -37,12 +42,12 @@ public class VarProcessor { +@@ -52,12 +57,12 @@ public class VarProcessor { new VarDefinitionHelper(root, method, this).setVarDefinitions(); } @@ -2886,7 +2893,7 @@ index 8d766e0412cc952c42d53eae5cec74db5c992c0d..bc8fa493167a5fabf772403550511855 List listVars = new ArrayList<>(mapVarNames.keySet()); listVars.sort(Comparator.comparingInt(o -> o.var)); -@@ -52,18 +57,20 @@ public class VarProcessor { +@@ -67,18 +72,20 @@ public class VarProcessor { for (VarVersionPair pair : listVars) { String name = mapVarNames.get(pair); @@ -2911,7 +2918,7 @@ index 8d766e0412cc952c42d53eae5cec74db5c992c0d..bc8fa493167a5fabf772403550511855 name += String.valueOf(counter); } -@@ -72,7 +79,11 @@ public class VarProcessor { +@@ -87,7 +94,11 @@ public class VarProcessor { } public Integer getVarOriginalIndex(int index) { @@ -2924,7 +2931,7 @@ index 8d766e0412cc952c42d53eae5cec74db5c992c0d..bc8fa493167a5fabf772403550511855 } public void refreshVarNames(VarNamesCollector vc) { -@@ -91,7 +102,9 @@ public class VarProcessor { +@@ -106,7 +117,9 @@ public class VarProcessor { } public void setVarType(VarVersionPair pair, VarType type) { @@ -2935,9 +2942,9 @@ index 8d766e0412cc952c42d53eae5cec74db5c992c0d..bc8fa493167a5fabf772403550511855 } public String getVarName(VarVersionPair pair) { -@@ -121,4 +134,68 @@ public class VarProcessor { - public Set getExternalVars() { - return externalVars; +@@ -152,4 +165,68 @@ public class VarProcessor { + public int getFirstParameterPosition() { + return firstParameterPosition; } + + public List getCandidates(int origindex) { @@ -3005,25 +3012,25 @@ index 8d766e0412cc952c42d53eae5cec74db5c992c0d..bc8fa493167a5fabf772403550511855 + } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java -index c31cfad036b4b2de11449c54ded7864e394d5f91..78b5302cba6fc90f7f32520f637a740d21ed7fab 100644 +index f10f59b946137e13a7f6e12d9b61099ce109768c..0e4a1c936a139ef915bddf0410fd7dec07bdaa6a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java -@@ -96,7 +96,12 @@ public class VarTypeProcessor { - - for (Exprent expr : lst) { - if (expr.type == Exprent.EXPRENT_VAR) { -- ((VarExprent)expr).setVarType(VarType.VARTYPE_UNKNOWN); -+ VarExprent ve = (VarExprent)expr; +@@ -193,7 +193,12 @@ public class VarTypeProcessor { + allExprents.add(currExprent); + for (Exprent exprent : allExprents) { + if (exprent.type == Exprent.EXPRENT_VAR) { +- ((VarExprent)exprent).setVarType(VarType.VARTYPE_UNKNOWN); ++ VarExprent ve = (VarExprent)exprent; + if (ve.getLVT() != null) { + ve.setVarType(ve.getLVT().getVarType()); + } else { + ve.setVarType(VarType.VARTYPE_UNKNOWN); + } } - else if (expr.type == Exprent.EXPRENT_CONST) { - ConstExprent constExpr = (ConstExprent)expr; + else if (exprent.type == Exprent.EXPRENT_CONST) { + ConstExprent constExprent = (ConstExprent)exprent; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java -index eca0d0fb9ef15db26e9de38ebda2bf9ee19857df..47e7e0c04f6114a9d64b1d86c1e2643052ad5023 100644 +index 7a88cb7bc4744aac96bdaffc0ab95652d1937d25..02152730af21f255d9fa12bda1e9422159e93694 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java @@ -22,7 +22,7 @@ import java.util.Map.Entry; @@ -3044,7 +3051,7 @@ index eca0d0fb9ef15db26e9de38ebda2bf9ee19857df..47e7e0c04f6114a9d64b1d86c1e26430 // FIXME: advanced merging -@@ -215,7 +215,8 @@ public class VarVersionsProcessor { +@@ -277,7 +277,8 @@ public class VarVersionsProcessor { CounterContainer counters = DecompilerContext.getCounterContainer(); final Map mapVarPaar = new HashMap<>(); @@ -3054,7 +3061,7 @@ index eca0d0fb9ef15db26e9de38ebda2bf9ee19857df..47e7e0c04f6114a9d64b1d86c1e26430 // map var-version pairs on new var indexes List vvps = new ArrayList<>(mapExprentMinTypes.keySet()); -@@ -236,7 +237,7 @@ public class VarVersionsProcessor { +@@ -298,7 +299,7 @@ public class VarVersionsProcessor { } mapVarPaar.put(pair, newIndex); @@ -3063,7 +3070,7 @@ index eca0d0fb9ef15db26e9de38ebda2bf9ee19857df..47e7e0c04f6114a9d64b1d86c1e26430 } } -@@ -266,11 +267,11 @@ public class VarVersionsProcessor { +@@ -328,11 +329,11 @@ public class VarVersionsProcessor { }); if (previousVersionsProcessor != null) { @@ -3079,8 +3086,8 @@ index eca0d0fb9ef15db26e9de38ebda2bf9ee19857df..47e7e0c04f6114a9d64b1d86c1e26430 value = oldValue != null ? oldValue : value; this.mapOriginalVarIndices.put(entry.getKey(), value); } -@@ -297,7 +298,11 @@ public class VarVersionsProcessor { - typeProcessor.getMapFinalVars().put(pair, finalType); +@@ -359,7 +360,11 @@ public class VarVersionsProcessor { + typeProcessor.getFinalVariables().put(pair, finalType); } - public Map getMapOriginalVarIndices() { @@ -3094,7 +3101,7 @@ index eca0d0fb9ef15db26e9de38ebda2bf9ee19857df..47e7e0c04f6114a9d64b1d86c1e26430 } \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/StructContext.java b/src/org/jetbrains/java/decompiler/struct/StructContext.java -index 61486aa06985324eb48a931d50cec4749719a0a1..7f9127710be02e07bcbb08be650cd41bff732abf 100644 +index 80f1e91d6227fc4363b0039e13439d5838d790eb..94cedbee257faebd95ea933ab80a7d242c1ba023 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructContext.java +++ b/src/org/jetbrains/java/decompiler/struct/StructContext.java @@ -159,4 +159,30 @@ public class StructContext { @@ -3129,12 +3136,12 @@ index 61486aa06985324eb48a931d50cec4749719a0a1..7f9127710be02e07bcbb08be650cd41b + } } diff --git a/src/org/jetbrains/java/decompiler/struct/StructMember.java b/src/org/jetbrains/java/decompiler/struct/StructMember.java -index 920e7f9af2c86e1e20cee2f167026097bd828ae0..c0964877be1156aa93cf90a6c4d919757555d3d8 100644 +index f03613981dd7c48929db77e550c194e072c0e76b..dae54e30376ff57c1549783d4b999fa3ded0d56f 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMember.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMember.java -@@ -12,9 +12,11 @@ import java.io.IOException; - import java.util.HashMap; - import java.util.Map; +@@ -18,9 +18,11 @@ import java.util.*; + import java.util.stream.Collectors; + import java.util.stream.Stream; +import static org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute.*; + @@ -3146,7 +3153,7 @@ index 920e7f9af2c86e1e20cee2f167026097bd828ae0..c0964877be1156aa93cf90a6c4d91975 protected StructMember(int accessFlags, Map attributes) { this.accessFlags = accessFlags; -@@ -73,6 +75,20 @@ public abstract class StructMember { +@@ -111,6 +113,20 @@ public abstract class StructMember { } } @@ -3168,11 +3175,11 @@ index 920e7f9af2c86e1e20cee2f167026097bd828ae0..c0964877be1156aa93cf90a6c4d91975 + } } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java -index 66eb5934e4bf29dced9c3d59bff8d47360e4d061..dfdec3252fd252a260a9c2d8e84736c0afd92e17 100644 +index 465687e365cc32acac0d5aef20e96b5af209f7d6..ebc0b97de43fcd3f7e629031fb5da58f24b798ea 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java @@ -1,7 +1,10 @@ - // Copyright 2000-2020 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 org.jetbrains.java.decompiler.struct.attr; +import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; @@ -3214,14 +3221,13 @@ index 66eb5934e4bf29dced9c3d59bff8d47360e4d061..dfdec3252fd252a260a9c2d8e84736c0 } public String getName(int index, int visibleOffset) { -@@ -58,25 +66,58 @@ public class StructLocalVariableTableAttribute extends StructGeneralAttribute { +@@ -58,24 +66,57 @@ public class StructLocalVariableTableAttribute extends StructGeneralAttribute { return matchingVars(index, visibleOffset).map(v -> v.descriptor).findFirst().orElse(null); } - private Stream matchingVars(int index, int visibleOffset) { + public Stream matchingVars(int index, int visibleOffset) { - return localVariables.stream() - .filter(v -> v.index == index && (visibleOffset >= v.start_pc && visibleOffset < v.start_pc + v.length)); + return localVariables.stream().filter(v -> v.index == index && (visibleOffset >= v.start_pc && visibleOffset < v.start_pc + v.length)); } + public Stream matchingVars(int index) { @@ -3277,7 +3283,7 @@ index 66eb5934e4bf29dced9c3d59bff8d47360e4d061..dfdec3252fd252a260a9c2d8e84736c0 private LocalVariable(int start_pc, int length, String name, String descriptor, int index) { this.start_pc = start_pc; -@@ -84,6 +125,53 @@ public class StructLocalVariableTableAttribute extends StructGeneralAttribute { +@@ -83,6 +124,53 @@ public class StructLocalVariableTableAttribute extends StructGeneralAttribute { this.name = name; this.descriptor = descriptor; this.index = index; @@ -3346,7 +3352,7 @@ index 829c78e8a1361bb88cb700696c22af4f7d36349d..cfdda0f2830307d34dfcc3c0a0714f6e public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { diff --git a/src/org/jetbrains/java/decompiler/util/DebugPrinter.java b/src/org/jetbrains/java/decompiler/util/DebugPrinter.java new file mode 100644 -index 0000000000000000000000000000000000000000..71d69efb6418e111b0a7e59e0eb4389eca207f5d +index 0000000000000000000000000000000000000000..15cf67e559a23c86615e477d45db1d3f8edaeaf0 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/DebugPrinter.java @@ -0,0 +1,94 @@ @@ -3381,7 +3387,7 @@ index 0000000000000000000000000000000000000000..71d69efb6418e111b0a7e59e0eb4389e + } + } + -+ if (root.type == Statement.TYPE_ROOT) { ++ if (root.type == Statement.StatementType.ROOT) { + printStatement(((RootStatement)root).getDummyExit(), " ", varProc); + } + System.out.println("}"); @@ -3499,10 +3505,10 @@ index 0000000000000000000000000000000000000000..71d689df60a4377103777be6a408ed4f + @Test public void testLoopMerging() { doTest("pkg/TestLoopMerging"); } +} diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -index dc34cc358594ff94e5abab1733336c1eb1f4d30e..bd4868ea4c65503b6f3f983d2d860f50fa55444a 100644 +index 721a3606e209f4f803dcb6b513a5768c9c437c48..67c41a7676a7d78c5d4bfa2174608cebd575acaa 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -@@ -17,6 +17,7 @@ public class SingleClassesTest extends SingleClassesTestBase { +@@ -28,6 +28,7 @@ public class SingleClassesTest extends SingleClassesTestBase { }; } diff --git a/FernFlower-Patches/0011-Rework-of-Generics-system-for-better-output.patch b/FernFlower-Patches/0010-Rework-of-Generics-system-for-better-output.patch similarity index 80% rename from FernFlower-Patches/0011-Rework-of-Generics-system-for-better-output.patch rename to FernFlower-Patches/0010-Rework-of-Generics-system-for-better-output.patch index 157319e..5749ebe 100644 --- a/FernFlower-Patches/0011-Rework-of-Generics-system-for-better-output.patch +++ b/FernFlower-Patches/0010-Rework-of-Generics-system-for-better-output.patch @@ -92,13 +92,13 @@ index 0000000000000000000000000000000000000000..ad9f8c22d02565f22720a4fa88195111 + } +} diff --git a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java -index e082267cf9e2f20df662ff3565d69d0966df1126..425c2e4480f2c57993e3d4a38f66cfdcbb920047 100644 +index 4c4916e4cc5ccdd06dd4138dae54c31fb7f3bd34..decfe747ba2ab3643209987294ef7bcbbfa15e1b 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java @@ -34,7 +34,7 @@ public final class ClassReference14Processor { invFor.setDescriptor(MethodDescriptor.parseDescriptor("(Ljava/lang/String;)Ljava/lang/Class;")); invFor.setStatic(true); - invFor.setLstParameters(Collections.singletonList(new VarExprent(0, VarType.VARTYPE_STRING, null))); + invFor.setParameters(Collections.singletonList(new VarExprent(0, VarType.VARTYPE_STRING, null))); - BODY_EXPR = new ExitExprent(ExitExprent.EXIT_RETURN, invFor, VarType.VARTYPE_CLASS, null); + BODY_EXPR = new ExitExprent(ExitExprent.EXIT_RETURN, invFor, VarType.VARTYPE_CLASS, null, null); @@ -106,7 +106,7 @@ index e082267cf9e2f20df662ff3565d69d0966df1126..425c2e4480f2c57993e3d4a38f66cfdc ctor.setName(CodeConstants.INIT_NAME); @@ -52,7 +52,7 @@ public final class ClassReference14Processor { invCause.setInstance(newExpr); - invCause.setLstParameters( + invCause.setParameters( Collections.singletonList(new VarExprent(2, new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/ClassNotFoundException"), null))); - HANDLER_EXPR = new ExitExprent(ExitExprent.EXIT_THROW, invCause, null, null); + HANDLER_EXPR = new ExitExprent(ExitExprent.EXIT_THROW, invCause, null, null, null); @@ -121,61 +121,78 @@ index e082267cf9e2f20df662ff3565d69d0966df1126..425c2e4480f2c57993e3d4a38f66cfdc \ No newline at end of file +} diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -index 16a7cfebe26dfe0f6244a46f9af271758be274da..c4bc77b593859f5f9bceff063414c31bedd1ff82 100644 +index 0dc28bc9d8e3b622f691939b1c8fcce9a09c11fe..b7467530cba1d8e317500a5c213dd6013d00a369 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -@@ -446,7 +446,7 @@ public class ClassWriter { - } - buffer.append(node.simpleName); +@@ -371,9 +371,14 @@ public class ClassWriter { + + List typeAnnotations = TypeAnnotation.listFrom(cl); - GenericClassDescriptor descriptor = getGenericClassDescriptor(cl); + GenericClassDescriptor descriptor = cl.getSignature(); if (descriptor != null && !descriptor.fparameters.isEmpty()) { - appendTypeParameters(buffer, descriptor.fparameters, descriptor.fbounds); +- appendTypeParameters(buffer, descriptor.fparameters, descriptor.fbounds, typeAnnotations); ++ DecompilerContext.setProperty(DecompilerContext.IN_CLASS_TYPE_PARAMS, "1"); ++ try { ++ appendTypeParameters(buffer, descriptor.fparameters, descriptor.fbounds, typeAnnotations); ++ } finally { ++ DecompilerContext.setProperty(DecompilerContext.IN_CLASS_TYPE_PARAMS, "0"); ++ } } -@@ -470,12 +470,7 @@ public class ClassWriter { - VarType supertype = new VarType(cl.superClass.getString(), true); + + if (components != null) { +@@ -396,15 +401,7 @@ public class ClassWriter { + List extendsTypeAnnotations = TargetInfo.SupertypeTarget.extractExtends(typeAnnotations); if (!VarType.VARTYPE_OBJECT.equals(supertype)) { buffer.append("extends "); - if (descriptor != null) { -- buffer.append(GenericMain.getGenericCastTypeName(descriptor.superclass)); +- buffer.append(GenericMain.getGenericCastTypeName( +- descriptor.superclass, +- TypeAnnotationWriteHelper.create(extendsTypeAnnotations)) +- ); - } - else { -- buffer.append(ExprProcessor.getCastTypeName(supertype)); +- buffer.append(ExprProcessor.getCastTypeName(supertype, TypeAnnotationWriteHelper.create(extendsTypeAnnotations))); - } -+ buffer.append(ExprProcessor.getCastTypeName(descriptor == null ? supertype : descriptor.superclass)); ++ buffer.append(ExprProcessor.getCastTypeName(descriptor == null ? supertype : descriptor.superclass, TypeAnnotationWriteHelper.create(extendsTypeAnnotations))); buffer.append(' '); } } -@@ -488,12 +483,7 @@ public class ClassWriter { - if (i > 0) { +@@ -418,18 +415,7 @@ public class ClassWriter { buffer.append(", "); } + List superTypeAnnotations = TargetInfo.SupertypeTarget.extract(typeAnnotations, i); - if (descriptor != null) { -- buffer.append(GenericMain.getGenericCastTypeName(descriptor.superinterfaces.get(i))); +- buffer.append(GenericMain.getGenericCastTypeName( +- descriptor.superinterfaces.get(i), +- TypeAnnotationWriteHelper.create(superTypeAnnotations)) +- ); - } - else { -- buffer.append(ExprProcessor.getCastTypeName(new VarType(cl.getInterface(i), true))); +- buffer.append(ExprProcessor.getCastTypeName( +- new VarType(cl.getInterface(i), true), +- TypeAnnotationWriteHelper.create(superTypeAnnotations)) +- ); - } -+ buffer.append(ExprProcessor.getCastTypeName(descriptor == null ? new VarType(cl.getInterface(i), true) : descriptor.superinterfaces.get(i))); ++ buffer.append(ExprProcessor.getCastTypeName(descriptor == null ? new VarType(cl.getInterface(i), true) : descriptor.superinterfaces.get(i), TypeAnnotationWriteHelper.create(superTypeAnnotations))); } buffer.append(' '); } -@@ -541,12 +531,7 @@ public class ClassWriter { - GenericFieldDescriptor descriptor = fieldTypeData.getValue(); +@@ -491,12 +477,7 @@ public class ClassWriter { + final List typeAnnotations = TypeAnnotation.listFrom(fd); if (!isEnum) { - if (descriptor != null) { -- buffer.append(GenericMain.getGenericCastTypeName(descriptor.type)); +- buffer.append(GenericMain.getGenericCastTypeName(descriptor.type, TypeAnnotationWriteHelper.create(typeAnnotations))); - } - else { -- buffer.append(ExprProcessor.getCastTypeName(fieldType)); +- buffer.append(ExprProcessor.getCastTypeName(fieldType, TypeAnnotationWriteHelper.create(typeAnnotations))); - } -+ buffer.append(ExprProcessor.getCastTypeName(descriptor == null ? fieldType : descriptor.type)); ++ buffer.append(ExprProcessor.getCastTypeName(descriptor == null ? fieldType : descriptor.type, TypeAnnotationWriteHelper.create(typeAnnotations))); buffer.append(' '); } -@@ -574,8 +559,8 @@ public class ClassWriter { +@@ -524,8 +505,8 @@ public class ClassWriter { ((ConstExprent) initializer).adjustConstType(fieldType); } @@ -186,16 +203,7 @@ index 16a7cfebe26dfe0f6244a46f9af271758be274da..c4bc77b593859f5f9bceff063414c31b } } else if (fd.hasModifier(CodeConstants.ACC_FINAL) && fd.hasModifier(CodeConstants.ACC_STATIC)) { -@@ -601,7 +586,7 @@ public class ClassWriter { - GenericFieldDescriptor descriptor = fieldTypeData.getValue(); - - if (descriptor != null) { -- buffer.append(GenericMain.getGenericCastTypeName(varArgComponent ? descriptor.type.decreaseArrayDim() : descriptor.type)); -+ buffer.append(ExprProcessor.getCastTypeName(varArgComponent ? descriptor.type.decreaseArrayDim() : descriptor.type)); - } - else { - buffer.append(ExprProcessor.getCastTypeName(varArgComponent ? fieldType.decreaseArrayDim() : fieldType)); -@@ -743,7 +728,7 @@ public class ClassWriter { +@@ -639,7 +620,7 @@ public class ClassWriter { boolean isDeprecated = mt.hasAttribute(StructGeneralAttribute.ATTRIBUTE_DEPRECATED); boolean clInit = false, init = false, dInit = false; @@ -204,8 +212,8 @@ index 16a7cfebe26dfe0f6244a46f9af271758be274da..c4bc77b593859f5f9bceff063414c31b int flags = mt.getAccessFlags(); if ((flags & CodeConstants.ACC_NATIVE) != 0) { -@@ -798,29 +783,7 @@ public class ClassWriter { - clInit = true; +@@ -667,28 +648,7 @@ public class ClassWriter { + appendComment(buffer, "bridge method", indent); } - GenericMethodDescriptor descriptor = null; @@ -230,77 +238,76 @@ index 16a7cfebe26dfe0f6244a46f9af271758be274da..c4bc77b593859f5f9bceff063414c31b - } - } - } -- + GenericMethodDescriptor descriptor = mt.getSignature(); - boolean throwsExceptions = false; - int paramCount = 0; - -@@ -833,12 +796,7 @@ public class ClassWriter { - } + appendAnnotations(buffer, indent, mt); - if (!init) { + buffer.appendIndent(indent); +@@ -729,12 +689,7 @@ public class ClassWriter { + if (init) { + emptyTypeAnnotations.forEach(typeAnnotation -> typeAnnotation.writeTo(buffer)); + } else { - if (descriptor != null) { -- buffer.append(GenericMain.getGenericCastTypeName(descriptor.returnType)); +- buffer.append(GenericMain.getGenericCastTypeName(descriptor.returnType, TypeAnnotationWriteHelper.create(emptyTypeAnnotations))); - } - else { -- buffer.append(ExprProcessor.getCastTypeName(md.ret)); +- buffer.append(ExprProcessor.getCastTypeName(md.ret, TypeAnnotationWriteHelper.create(emptyTypeAnnotations))); - } -+ buffer.append(ExprProcessor.getCastTypeName(descriptor == null ? md.ret : descriptor.returnType)); ++ buffer.append(ExprProcessor.getCastTypeName(descriptor == null ? md.ret : descriptor.returnType, TypeAnnotationWriteHelper.create(emptyTypeAnnotations))); buffer.append(' '); } -@@ -864,7 +822,13 @@ public class ClassWriter { +@@ -751,7 +706,12 @@ public class ClassWriter { + } - int index = isEnum && init ? 3 : thisVar ? 1 : 0; - int start = isEnum && init ? 2 : 0; + int index = methodWrapper.varproc.getFirstParameterVarIndex(); + boolean hasDescriptor = descriptor != null; + //mask should now have the Outer.this in it... so this *shouldn't* be nessasary. + //if (init && !isEnum && ((node.access & CodeConstants.ACC_STATIC) == 0) && node.type == ClassNode.CLASS_MEMBER) + // index++; -+ - for (int i = start; i < md.params.length; i++) { + for (int i = methodWrapper.varproc.getFirstParameterPosition(); i < md.params.length; i++) { + VarType parameterType = hasDescriptor && !descriptor.parameterTypes.isEmpty() ? descriptor.parameterTypes.get(paramCount) : md.params[i]; if (mask == null || mask.get(i) == null) { if (paramCount > 0) { buffer.append(", "); -@@ -880,24 +844,11 @@ public class ClassWriter { +@@ -768,24 +728,12 @@ public class ClassWriter { } String typeName; - boolean isVarArg = i == lastVisibleParameterIndex && mt.hasModifier(CodeConstants.ACC_VARARGS); -- -- if (descriptor != null) { -- GenericType parameterType = descriptor.parameterTypes.get(paramCount); -- isVarArg &= parameterType.arrayDim > 0; + List typeParamAnnotations = TargetInfo.FormalParameterTarget.extract(typeAnnotations, i); +- if (paramType instanceof GenericType) { +- GenericType genParamType = (GenericType) paramType; +- isVarArg &= genParamType.getArrayDim() > 0; - if (isVarArg) { -- parameterType = parameterType.decreaseArrayDim(); +- genParamType = genParamType.decreaseArrayDim(); - } -- typeName = GenericMain.getGenericCastTypeName(parameterType); +- typeName = GenericMain.getGenericCastTypeName(genParamType, TypeAnnotationWriteHelper.create(typeParamAnnotations)); - } - else { -- VarType parameterType = md.params[i]; -- isVarArg &= parameterType.arrayDim > 0; +- VarType varParamType = (VarType) paramType; +- isVarArg &= varParamType.getArrayDim() > 0; - if (isVarArg) { -+ boolean isVarArg = i == lastVisibleParameterIndex && mt.hasModifier(CodeConstants.ACC_VARARGS) && parameterType.arrayDim > 0; -+ if (isVarArg) { - parameterType = parameterType.decreaseArrayDim(); +- varParamType = varParamType.decreaseArrayDim(); - } -- typeName = ExprProcessor.getCastTypeName(parameterType); +- typeName = ExprProcessor.getCastTypeName(varParamType, TypeAnnotationWriteHelper.create(typeParamAnnotations)); ++ boolean isVarArg = i == lastVisibleParameterIndex && mt.hasModifier(CodeConstants.ACC_VARARGS) && parameterType.getArrayDim() > 0; ++ if (isVarArg) { ++ parameterType = parameterType.decreaseArrayDim(); } -+ typeName = ExprProcessor.getCastTypeName(parameterType); ++ typeName = ExprProcessor.getCastTypeName(parameterType, TypeAnnotationWriteHelper.create(typeParamAnnotations)); if (ExprProcessor.UNDEFINED_TYPE_STRING.equals(typeName) && DecompilerContext.getOption(IFernflowerPreferences.UNDEFINED_PARAM_TYPE_OBJECT)) { -@@ -922,7 +873,7 @@ public class ClassWriter { +@@ -804,7 +752,7 @@ public class ClassWriter { paramCount++; } -- index += md.params[i].stackSize; -+ index += parameterType.stackSize; +- index += md.params[i].getStackSize(); ++ index += parameterType.getStackSize(); } buffer.append(')'); -@@ -932,18 +883,13 @@ public class ClassWriter { +@@ -814,19 +762,14 @@ public class ClassWriter { throwsExceptions = true; buffer.append(" throws "); @@ -309,20 +316,30 @@ index 16a7cfebe26dfe0f6244a46f9af271758be274da..c4bc77b593859f5f9bceff063414c31b if (i > 0) { buffer.append(", "); } + TargetInfo.ThrowsTarget.extract(typeAnnotations, i).forEach(typeAnnotation -> typeAnnotation.writeTo(buffer)); - if (descriptor != null && !descriptor.exceptionTypes.isEmpty()) { - GenericType type = descriptor.exceptionTypes.get(i); -- buffer.append(GenericMain.getGenericCastTypeName(type)); +- buffer.append(GenericMain.getGenericCastTypeName(type, Collections.emptyList())); - } - else { - VarType type = new VarType(attr.getExcClassname(i, cl.getPool()), true); -- buffer.append(ExprProcessor.getCastTypeName(type)); +- buffer.append(ExprProcessor.getCastTypeName(type, Collections.emptyList())); - } + VarType type = useDescriptor ? descriptor.exceptionTypes.get(i) : new VarType(attr.getExcClassname(i, cl.getPool()), true); -+ buffer.append(ExprProcessor.getCastTypeName(type)); ++ buffer.append(ExprProcessor.getCastTypeName(type, Collections.emptyList())); } } } -@@ -1050,14 +996,7 @@ public class ClassWriter { +@@ -1054,7 +997,7 @@ public class ClassWriter { + + final List typeAnnotations = TypeAnnotation.listFrom(cd); + if (descriptor != null) { +- buffer.append(GenericMain.getGenericCastTypeName( ++ buffer.append(ExprProcessor.getCastTypeName( + varArgComponent ? descriptor.type.decreaseArrayDim() : descriptor.type, + TypeAnnotationWriteHelper.create(typeAnnotations) + )); +@@ -1108,14 +1051,7 @@ public class ClassWriter { private static Map.Entry getFieldTypeData(StructField fd) { VarType fieldType = new VarType(fd.getDescriptor(), false); @@ -338,7 +355,7 @@ index 16a7cfebe26dfe0f6244a46f9af271758be274da..c4bc77b593859f5f9bceff063414c31b return new AbstractMap.SimpleImmutableEntry<>(fieldType, descriptor); } -@@ -1234,17 +1173,7 @@ public class ClassWriter { +@@ -1255,22 +1191,11 @@ public class ClassWriter { } } @@ -352,29 +369,39 @@ index 16a7cfebe26dfe0f6244a46f9af271758be274da..c4bc77b593859f5f9bceff063414c31b - return null; - } - -- public static void appendTypeParameters(TextBuffer buffer, List parameters, List> bounds) { -+ public static void appendTypeParameters(TextBuffer buffer, List parameters, List> bounds) { + public static void appendTypeParameters( +- TextBuffer buffer, +- List parameters, +- List> bounds, +- final List typeAnnotations +- ) { ++ TextBuffer buffer, ++ List parameters, ++ List> bounds, ++ final List typeAnnotations) { buffer.append('<'); - for (int i = 0; i < parameters.size(); i++) { -@@ -1254,13 +1183,13 @@ public class ClassWriter { - + if (i > 0) { +@@ -1278,15 +1203,15 @@ public class ClassWriter { + } + TargetInfo.TypeParameterTarget.extract(typeAnnotations, i).forEach(typeAnnotation -> typeAnnotation.writeTo(buffer)); buffer.append(parameters.get(i)); - - List parameterBounds = bounds.get(i); + List parameterBounds = bounds.get(i); - if (parameterBounds.size() > 1 || !"java/lang/Object".equals(parameterBounds.get(0).value)) { + if (parameterBounds.size() > 1 || !"java/lang/Object".equals(parameterBounds.get(0).getValue())) { buffer.append(" extends "); -- buffer.append(GenericMain.getGenericCastTypeName(parameterBounds.get(0))); -+ buffer.append(ExprProcessor.getCastTypeName(parameterBounds.get(0))); + TargetInfo.TypeParameterBoundTarget.extract(typeAnnotations, i, 0).forEach(typeAnnotation -> typeAnnotation.writeTo(buffer)); +- buffer.append(GenericMain.getGenericCastTypeName(parameterBounds.get(0), Collections.emptyList())); ++ buffer.append(ExprProcessor.getCastTypeName(parameterBounds.get(0), Collections.emptyList())); for (int j = 1; j < parameterBounds.size(); j++) { buffer.append(" & "); -- buffer.append(GenericMain.getGenericCastTypeName(parameterBounds.get(j))); -+ buffer.append(ExprProcessor.getCastTypeName(parameterBounds.get(j))); + TargetInfo.TypeParameterBoundTarget.extract(typeAnnotations, i, j).forEach(typeAnnotation -> typeAnnotation.writeTo(buffer)); +- buffer.append(GenericMain.getGenericCastTypeName(parameterBounds.get(j), Collections.emptyList())); ++ buffer.append(ExprProcessor.getCastTypeName(parameterBounds.get(j), Collections.emptyList())); } } } -@@ -1277,4 +1206,4 @@ public class ClassWriter { +@@ -1303,4 +1228,4 @@ public class ClassWriter { } } } @@ -382,18 +409,19 @@ index 16a7cfebe26dfe0f6244a46f9af271758be274da..c4bc77b593859f5f9bceff063414c31b \ No newline at end of file +} diff --git a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java -index e2936358fa03746e00e23d30f47351c28124e09f..bf0fe47e7d48b21acd758449b67612e250f19554 100644 +index e2936358fa03746e00e23d30f47351c28124e09f..654d0ddf34821ce4ea800cd5421f6268e2ca3236 100644 --- a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java +++ b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java -@@ -18,6 +18,7 @@ public class DecompilerContext { +@@ -18,6 +18,8 @@ public class DecompilerContext { public static final String CURRENT_CLASS_WRAPPER = "CURRENT_CLASS_WRAPPER"; public static final String CURRENT_CLASS_NODE = "CURRENT_CLASS_NODE"; public static final String CURRENT_METHOD_WRAPPER = "CURRENT_METHOD_WRAPPER"; + public static final String CURRENT_VAR_PROCESSOR = "CURRENT_VAR_PROCESSOR"; ++ public static final String IN_CLASS_TYPE_PARAMS = "IN_CLASS_TYPE_PARAMS"; private final Map properties; private final IFernflowerLogger logger; -@@ -126,4 +127,4 @@ public class DecompilerContext { +@@ -126,4 +128,4 @@ public class DecompilerContext { public static BytecodeSourceMapper getBytecodeSourceMapper() { return getCurrentContext().bytecodeSourceMapper; } @@ -451,7 +479,7 @@ index 5448e7900953da79b2bc01f99fd7e8f3080148e7..bdd34f0382b06687ef7fb3237bbc96ac defaults.put(MAX_PROCESSING_METHOD, "0"); defaults.put(RENAME_ENTITIES, "0"); diff --git a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java -index cdadca37d0b24cf3feb1c0e200a113dae53ed51c..438b04c518f193ac3b229701ddfdaf7cde5cad6e 100644 +index 33906d3a433e4421bbf41c6aed5ff566a69a904a..e32253528718631cd622d6af4ede4a85ff4af061 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java +++ b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java @@ -2,6 +2,7 @@ @@ -462,16 +490,16 @@ index cdadca37d0b24cf3feb1c0e200a113dae53ed51c..438b04c518f193ac3b229701ddfdaf7c import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.collectors.CounterContainer; import org.jetbrains.java.decompiler.main.collectors.VarNamesCollector; -@@ -43,7 +44,7 @@ public class ClassWrapper { +@@ -47,7 +48,7 @@ public class ClassWrapper { for (StructMethod mt : classStruct.getMethods()) { DecompilerContext.getLogger().startMethod(mt.getName() + " " + mt.getDescriptor()); - MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); + MethodDescriptor md = MethodDescriptor.parseDescriptor(mt, null); - VarProcessor varProc = new VarProcessor(mt, md); + VarProcessor varProc = new VarProcessor(classStruct, mt, md); DecompilerContext.startMethod(varProc); -@@ -204,4 +205,4 @@ public class ClassWrapper { +@@ -218,4 +219,4 @@ public class ClassWrapper { public String toString() { return classStruct.qualifiedName; } @@ -479,42 +507,54 @@ index cdadca37d0b24cf3feb1c0e200a113dae53ed51c..438b04c518f193ac3b229701ddfdaf7c \ No newline at end of file +} diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -index f19e321da5e392eff9c87da6018aa1407411332d..03a59cb999d3d05d647128c96007e9743938a0ea 100644 +index 3148af901dbdf25946b67b1da9b0fba8f697a49e..c592f0d58d1048de416eb2cefd6fcf76f2fb97fd 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -@@ -25,6 +25,8 @@ import org.jetbrains.java.decompiler.struct.consts.PrimitiveConstant; +@@ -29,6 +29,7 @@ import org.jetbrains.java.decompiler.struct.consts.PrimitiveConstant; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; + import org.jetbrains.java.decompiler.struct.gen.Type; import org.jetbrains.java.decompiler.struct.gen.VarType; - import org.jetbrains.java.decompiler.util.TextUtil; -+import org.jetbrains.java.decompiler.struct.gen.generics.GenericMain; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericType; + import org.jetbrains.java.decompiler.util.TextBuffer; import java.util.*; - -@@ -496,7 +498,7 @@ public class ExprProcessor implements CodeConstants { - exprlist.add(new ExitExprent(instr.opcode == opc_athrow ? ExitExprent.EXIT_THROW : ExitExprent.EXIT_RETURN, +@@ -474,7 +475,7 @@ public class ExprProcessor implements CodeConstants { + exprList.add(new ExitExprent(instr.opcode == opc_athrow ? ExitExprent.EXIT_THROW : ExitExprent.EXIT_RETURN, instr.opcode == opc_return ? null : stack.pop(), instr.opcode == opc_athrow ? null : methodDescriptor.ret, -- bytecode_offsets)); -+ bytecode_offsets, methodDescriptor)); +- offsets)); ++ offsets, methodDescriptor)); break; case opc_monitorenter: case opc_monitorexit: -@@ -685,7 +687,13 @@ public class ExprProcessor implements CodeConstants { - else if (tp == CodeConstants.TYPE_VOID) { - return "void"; +@@ -690,7 +691,15 @@ public class ExprProcessor implements CodeConstants { + sb.append("void"); + return sb.toString(); } + else if (tp == CodeConstants.TYPE_GENVAR && type.isGeneric()) { -+ return type.value; ++ sb.append(type.getValue()); ++ return sb.toString(); + } else if (tp == CodeConstants.TYPE_OBJECT) { + if (type.isGeneric()) { -+ return ((GenericType)type).getCastName(); ++ ((GenericType)type).appendCastName(sb, typeAnnWriteHelpers); ++ return sb.toString(); + } - String ret = buildJavaClassName(type.value); + String ret; if (getShort) { - ret = DecompilerContext.getImportCollector().getShortName(ret); -@@ -804,6 +812,8 @@ public class ExprProcessor implements CodeConstants { + ret = DecompilerContext.getImportCollector().getNestedName(type.getValue()); +@@ -741,7 +750,9 @@ public class ExprProcessor implements CodeConstants { + boolean shouldWrite = true; + if (!enclosingClasses.isEmpty() && i != nestedTypes.size() - 1) { + String enclosingType = enclosingClasses.remove(0).simpleName; +- shouldWrite = !nestedType.equals(enclosingType); ++ shouldWrite = !nestedType.equals(enclosingType) ++ // Also write out the enclosing class if we are the outermost, and we're in the type params ++ || enclosingClasses.isEmpty() && DecompilerContext.getOption(DecompilerContext.IN_CLASS_TYPE_PARAMS); + } + if (i == 0) { // first annotation can be written already + if (!sb.toString().isEmpty()) shouldWrite = true; // write if annotation exists +@@ -957,6 +968,8 @@ public class ExprProcessor implements CodeConstants { tracer.incrementCurrentSourceLine(); } @@ -523,7 +563,7 @@ index f19e321da5e392eff9c87da6018aa1407411332d..03a59cb999d3d05d647128c96007e974 TextBuffer content = expr.toJava(indent, tracer); if (content.length() > 0) { -@@ -876,7 +886,7 @@ public class ExprProcessor implements CodeConstants { +@@ -1029,7 +1042,7 @@ public class ExprProcessor implements CodeConstants { } } @@ -533,10 +573,10 @@ index f19e321da5e392eff9c87da6018aa1407411332d..03a59cb999d3d05d647128c96007e974 boolean cast = castAlways || diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java -index 26f82b92d1b4a972032c05203e8bb642aaba493e..986a8a72ec138ea637d3446ed2e823f6100c31cc 100644 +index 1af6fc576e1528f6c06b0e493bd912b9b37edff6..e1bed2f0f5f501d05f93dfa6bfcd2f2b3e76b822 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java -@@ -719,7 +719,7 @@ public class SimplifyExprentsHelper { +@@ -721,7 +721,7 @@ public class SimplifyExprentsHelper { Arrays.asList( statement.getHeadexprent().getCondition(), ifExit.getValue(), @@ -545,7 +585,7 @@ index 26f82b92d1b4a972032c05203e8bb642aaba493e..986a8a72ec138ea637d3446ed2e823f6 statement.setExprents(data); StatEdge retEdge = ifStatement.getAllSuccessorEdges().get(0); -@@ -765,4 +765,4 @@ public class SimplifyExprentsHelper { +@@ -767,4 +767,4 @@ public class SimplifyExprentsHelper { return ret; } @@ -553,10 +593,10 @@ index 26f82b92d1b4a972032c05203e8bb642aaba493e..986a8a72ec138ea637d3446ed2e823f6 \ No newline at end of file +} diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java -index e2768f5f53f670e2189454970d66524b4446021a..0f5411be3e790faa5a9f28d1eab3152851944e48 100644 +index 6cc60fd5314369cef21bd56c12e2af8e4c56292d..546ee9178d4469e49485c643d31d01f3d1cb4209 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java -@@ -53,6 +53,11 @@ public class AssignmentExprent extends Exprent { +@@ -49,6 +49,11 @@ public class AssignmentExprent extends Exprent { return left.getExprType(); } @@ -568,7 +608,7 @@ index e2768f5f53f670e2189454970d66524b4446021a..0f5411be3e790faa5a9f28d1eab31528 @Override public CheckTypesResult checkExprTypeBounds() { CheckTypesResult result = new CheckTypesResult(); -@@ -93,8 +98,8 @@ public class AssignmentExprent extends Exprent { +@@ -89,8 +94,8 @@ public class AssignmentExprent extends Exprent { @Override public TextBuffer toJava(int indent, BytecodeMappingTracer tracer) { @@ -579,25 +619,25 @@ index e2768f5f53f670e2189454970d66524b4446021a..0f5411be3e790faa5a9f28d1eab31528 boolean fieldInClassInit = false, hiddenField = false; if (left.type == Exprent.EXPRENT_FIELD) { // first assignment to a final field. Field name without "this" in front of it -@@ -132,14 +137,8 @@ public class AssignmentExprent extends Exprent { +@@ -128,14 +133,8 @@ public class AssignmentExprent extends Exprent { TextBuffer res = right.toJava(indent, tracer); - if (condType == CONDITION_NONE && - !leftType.isSuperset(rightType) && -- (rightType.equals(VarType.VARTYPE_OBJECT) || leftType.type != CodeConstants.TYPE_OBJECT)) { +- (rightType.equals(VarType.VARTYPE_OBJECT) || leftType.getType() != CodeConstants.TYPE_OBJECT)) { - if (right.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST)) { - res.enclose("(", ")"); - } - -- res.prepend("(" + ExprProcessor.getCastTypeName(leftType) + ")"); +- res.prepend("(" + ExprProcessor.getCastTypeName(leftType, Collections.emptyList()) + ")"); + if (condType == CONDITION_NONE) { + this.wrapInCast(leftType, rightType, res, right.getPrecedence()); } buffer.append(condType == CONDITION_NONE ? " = " : OPERATORS[condType]).append(res); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java -index 61b29a83579f85aaba32dd0e432de825a106457d..996eb3c3fe5388f7fde11df8937a09d01843f89d 100644 +index b0c626320205e7e6fac1f8ceafdffbe89a5daf41..db2a53744ffeb8b0bdc7b045a822be2df1695b4e 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java @@ -10,6 +10,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; @@ -635,7 +675,7 @@ index 61b29a83579f85aaba32dd0e432de825a106457d..996eb3c3fe5388f7fde11df8937a09d0 @@ -72,8 +75,12 @@ public class ExitExprent extends Exprent { TextBuffer buffer = new TextBuffer("return"); - if (retType.type != CodeConstants.TYPE_VOID) { + if (retType.getType() != CodeConstants.TYPE_VOID) { + VarType ret = retType; + if (methodDescriptor != null && methodDescriptor.genericInfo != null && methodDescriptor.genericInfo.returnType != null) { + ret = methodDescriptor.genericInfo.returnType; @@ -658,7 +698,7 @@ index 61b29a83579f85aaba32dd0e432de825a106457d..996eb3c3fe5388f7fde11df8937a09d0 public void getBytecodeRange(BitSet values) { measureBytecode(values, value); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java -index 7183241d331031e66f1afca8bce8feffa985e7a2..4aeda0e0c459d4956971b3298b8a4cd6f9424e0c 100644 +index 7183241d331031e66f1afca8bce8feffa985e7a2..afc26187d4b7916f5c8fa284a940f19a8c996702 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java @@ -3,13 +3,21 @@ @@ -723,7 +763,7 @@ index 7183241d331031e66f1afca8bce8feffa985e7a2..4aeda0e0c459d4956971b3298b8a4cd6 + for (int i = 0; i < leftArgs.size(); i++) { + VarType left = leftArgs.get(i); + VarType right = rightArgs.get(i); -+ if (left != null && right.value.equals(fparams.get(i))) { ++ if (left != null && right.getValue().equals(fparams.get(i))) { + genericArgs.add(left); + map.put(right, left); + } else { @@ -745,7 +785,7 @@ index 7183241d331031e66f1afca8bce8feffa985e7a2..4aeda0e0c459d4956971b3298b8a4cd6 + buf.append("<"); + //TODO: Check target output level and use <> operator? + for (int i = 0; i < genericArgs.size(); i++) { -+ buf.append(ExprProcessor.getCastTypeName(genericArgs.get(i))); ++ buf.append(ExprProcessor.getCastTypeName(genericArgs.get(i), Collections.emptyList())); + if(i + 1 < genericArgs.size()) { + buf.append(", "); + } @@ -778,14 +818,14 @@ index 7183241d331031e66f1afca8bce8feffa985e7a2..4aeda0e0c459d4956971b3298b8a4cd6 + } + + protected void wrapInCast(VarType left, VarType right, TextBuffer buf, int precedence) { -+ boolean needsCast = !left.isSuperset(right) && (right.equals(VarType.VARTYPE_OBJECT) || left.type != CodeConstants.TYPE_OBJECT); ++ boolean needsCast = !left.isSuperset(right) && (right.equals(VarType.VARTYPE_OBJECT) || left.getType() != CodeConstants.TYPE_OBJECT); + + if (left != null && left.isGeneric()) { + Map> names = this.getNamedGenerics(); + int arrayDim = 0; + -+ if (left.arrayDim == right.arrayDim) { -+ arrayDim = left.arrayDim; ++ if (left.getArrayDim() == right.getArrayDim()) { ++ arrayDim = left.getArrayDim(); + left = left.resizeArrayDim(0); + right = right.resizeArrayDim(0); + } @@ -801,7 +841,7 @@ index 7183241d331031e66f1afca8bce8feffa985e7a2..4aeda0e0c459d4956971b3298b8a4cd6 + if (type.equals(VarType.VARTYPE_OBJECT) && right.equals(VarType.VARTYPE_OBJECT)) { + continue; + } -+ anyMatch |= right.value == null /*null const doesn't need cast*/ || DecompilerContext.getStructContext().instanceOf(right.value, type.value); ++ anyMatch |= right.getValue() == null /*null const doesn't need cast*/ || DecompilerContext.getStructContext().instanceOf(right.getValue(), type.getValue()); + } + + if (anyMatch) { @@ -822,17 +862,17 @@ index 7183241d331031e66f1afca8bce8feffa985e7a2..4aeda0e0c459d4956971b3298b8a4cd6 + buf.enclose("(", ")"); + } + -+ buf.prepend("(" + ExprProcessor.getCastTypeName(left) + ")"); ++ buf.prepend("(" + ExprProcessor.getCastTypeName(left, Collections.emptyList()) + ")"); + } + // ***************************************************************************** // IMatchable implementation // ***************************************************************************** diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java -index 45b9f87924ca6d651fb2ab0a4671eb95cdb696fd..880a5d29d0b8c8d92ea7bd8918268742c7efcde5 100644 +index 3c1c333b45528adaaf63d149436a4cefa30ad905..be789c6f999339fc4d755850dfd888f600f73a45 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java -@@ -10,6 +10,8 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; +@@ -8,6 +8,8 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; @@ -841,17 +881,17 @@ index 45b9f87924ca6d651fb2ab0a4671eb95cdb696fd..880a5d29d0b8c8d92ea7bd8918268742 import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute; import org.jetbrains.java.decompiler.struct.consts.LinkConstant; import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor; -@@ -23,7 +25,9 @@ import org.jetbrains.java.decompiler.util.TextUtil; +@@ -20,7 +22,9 @@ import org.jetbrains.java.decompiler.util.TextUtil; import java.util.ArrayList; import java.util.BitSet; +import java.util.Collections; import java.util.List; +import java.util.Map; + import java.util.Objects; public class FieldExprent extends Exprent { - private final String name; -@@ -58,6 +62,26 @@ public class FieldExprent extends Exprent { +@@ -56,6 +60,26 @@ public class FieldExprent extends Exprent { return descriptor.type; } @@ -878,7 +918,7 @@ index 45b9f87924ca6d651fb2ab0a4671eb95cdb696fd..880a5d29d0b8c8d92ea7bd8918268742 @Override public int getExprentUse() { return 0; // multiple references to a field considered dangerous in a multithreaded environment, thus no Exprent.MULTIPLE_USES set here -@@ -223,4 +247,4 @@ public class FieldExprent extends Exprent { +@@ -221,4 +245,4 @@ public class FieldExprent extends Exprent { return true; } @@ -886,10 +926,10 @@ index 45b9f87924ca6d651fb2ab0a4671eb95cdb696fd..880a5d29d0b8c8d92ea7bd8918268742 \ No newline at end of file +} diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java -index 53b7403a24707b5719aeec34bfba8391c664b502..161f55c45a3f2c199fcc24b9fdd1bd269bafbfb8 100644 +index f2efd6b594b700b20814c620328753a66aea22a4..c45050559cace73741f7529254e1483c81b747c7 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java -@@ -4,6 +4,8 @@ +@@ -2,6 +2,8 @@ package org.jetbrains.java.decompiler.modules.decompiler.exps; import org.jetbrains.java.decompiler.code.CodeConstants; @@ -898,7 +938,7 @@ index 53b7403a24707b5719aeec34bfba8391c664b502..161f55c45a3f2c199fcc24b9fdd1bd26 import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult; -@@ -185,6 +187,7 @@ public class FunctionExprent extends Exprent { +@@ -182,6 +184,7 @@ public class FunctionExprent extends Exprent { private int funcType; private VarType implicitType; private final List lstOperands; @@ -906,7 +946,7 @@ index 53b7403a24707b5719aeec34bfba8391c664b502..161f55c45a3f2c199fcc24b9fdd1bd26 public FunctionExprent(int funcType, ListStack stack, BitSet bytecodeOffsets) { this(funcType, new ArrayList<>(), bytecodeOffsets); -@@ -292,6 +295,46 @@ public class FunctionExprent extends Exprent { +@@ -289,6 +292,46 @@ public class FunctionExprent extends Exprent { return exprType; } @@ -921,8 +961,8 @@ index 53b7403a24707b5719aeec34bfba8391c664b502..161f55c45a3f2c199fcc24b9fdd1bd26 + Map> names = this.getNamedGenerics(); + int arrayDim = 0; + -+ if (upperBound.arrayDim == right.arrayDim) { -+ arrayDim = upperBound.arrayDim; ++ if (upperBound.getArrayDim() == right.getArrayDim()) { ++ arrayDim = upperBound.getArrayDim(); + upperBound = upperBound.resizeArrayDim(0); + right = right.resizeArrayDim(0); + } @@ -935,7 +975,7 @@ index 53b7403a24707b5719aeec34bfba8391c664b502..161f55c45a3f2c199fcc24b9fdd1bd26 + if (types != null) { + boolean anyMatch = false; //TODO: allMatch instead of anyMatch? + for (VarType type : types) { -+ anyMatch |= DecompilerContext.getStructContext().instanceOf(type.value, cast.value); ++ anyMatch |= DecompilerContext.getStructContext().instanceOf(type.getValue(), cast.getValue()); + } + if (anyMatch) { + this.needsCast = false; @@ -943,7 +983,7 @@ index 53b7403a24707b5719aeec34bfba8391c664b502..161f55c45a3f2c199fcc24b9fdd1bd26 + } + } + else { //TODO: Capture generics to make cast better? -+ this.needsCast = right.type == CodeConstants.TYPE_NULL || !DecompilerContext.getStructContext().instanceOf(right.value, cast.value); ++ this.needsCast = right.getType() == CodeConstants.TYPE_NULL || !DecompilerContext.getStructContext().instanceOf(right.getValue(), cast.getValue()); + } + } + return getExprType(); @@ -953,7 +993,7 @@ index 53b7403a24707b5719aeec34bfba8391c664b502..161f55c45a3f2c199fcc24b9fdd1bd26 @Override public int getExprentUse() { if (funcType >= FUNCTION_IMM && funcType <= FUNCTION_PPI) { -@@ -466,6 +509,9 @@ public class FunctionExprent extends Exprent { +@@ -463,6 +506,9 @@ public class FunctionExprent extends Exprent { case FUNCTION_NEG: return wrapOperandString(lstOperands.get(0), true, indent, tracer).prepend("-"); case FUNCTION_CAST: @@ -964,10 +1004,10 @@ index 53b7403a24707b5719aeec34bfba8391c664b502..161f55c45a3f2c199fcc24b9fdd1bd26 case FUNCTION_ARRAY_LENGTH: Exprent arr = lstOperands.get(0); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -index 9803a215b8c5bc40658c8210c10e61644b519231..d72870ee498d9da075a08dc6e2afef906ba44ad2 100644 +index afaf2bf239640309370fd34cf9750f4a9537ba74..54c7d1fb9150754ba9daa09f4f24aa41c86387a8 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -@@ -18,6 +18,8 @@ import org.jetbrains.java.decompiler.struct.consts.LinkConstant; +@@ -19,6 +19,8 @@ import org.jetbrains.java.decompiler.struct.consts.LinkConstant; import org.jetbrains.java.decompiler.struct.consts.PooledConstant; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; @@ -977,14 +1017,14 @@ index 9803a215b8c5bc40658c8210c10e61644b519231..d72870ee498d9da075a08dc6e2afef90 import org.jetbrains.java.decompiler.struct.match.MatchNode; import org.jetbrains.java.decompiler.struct.match.MatchNode.RuleValue; @@ -56,6 +58,7 @@ public class InvocationExprent extends Exprent { - private int invocationTyp = INVOKE_VIRTUAL; - private List lstParameters = new ArrayList<>(); + private int invocationType = INVOKE_VIRTUAL; + private List parameters = new ArrayList<>(); private List bootstrapArguments; + private List genericArgs = new ArrayList<>(); public InvocationExprent() { super(EXPRENT_INVOCATION); -@@ -163,6 +166,55 @@ public class InvocationExprent extends Exprent { +@@ -165,6 +168,55 @@ public class InvocationExprent extends Exprent { return descriptor.ret; } @@ -1006,7 +1046,7 @@ index 9803a215b8c5bc40658c8210c10e61644b519231..d72870ee498d9da075a08dc6e2afef90 + VarType instType = instance.getInferredExprType(upperBound); + + if (instType.isGeneric()) { -+ StructClass cls = DecompilerContext.getStructContext().getClass(instType.value); ++ StructClass cls = DecompilerContext.getStructContext().getClass(instType.getValue()); + + if (cls != null && cls.getSignature() != null) { + Map map = new HashMap<>(); @@ -1040,7 +1080,7 @@ index 9803a215b8c5bc40658c8210c10e61644b519231..d72870ee498d9da075a08dc6e2afef90 @Override public CheckTypesResult checkExprTypeBounds() { CheckTypesResult result = new CheckTypesResult(); -@@ -295,6 +347,7 @@ public class InvocationExprent extends Exprent { +@@ -297,6 +349,7 @@ public class InvocationExprent extends Exprent { if (buf.length() > 0) { buf.append("."); @@ -1048,7 +1088,7 @@ index 9803a215b8c5bc40658c8210c10e61644b519231..d72870ee498d9da075a08dc6e2afef90 } buf.append(name); -@@ -331,8 +384,30 @@ public class InvocationExprent extends Exprent { +@@ -333,8 +386,30 @@ public class InvocationExprent extends Exprent { isEnum = newNode.classStruct.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM); } } @@ -1060,7 +1100,7 @@ index 9803a215b8c5bc40658c8210c10e61644b519231..d72870ee498d9da075a08dc6e2afef90 + } - BitSet setAmbiguousParameters = getAmbiguousParameters(); -+ StructClass cl = DecompilerContext.getStructContext().getClass(classname); ++ StructClass cl = DecompilerContext.getStructContext().getClass(className); + Map genArgs = new HashMap(); + + // building generic info from the instance @@ -1079,8 +1119,8 @@ index 9803a215b8c5bc40658c8210c10e61644b519231..d72870ee498d9da075a08dc6e2afef90 + } // omit 'new Type[] {}' for the last parameter of a vararg method call - if (lstParameters.size() == descriptor.params.length && isVarArgCall()) { -@@ -348,6 +423,34 @@ public class InvocationExprent extends Exprent { + if (parameters.size() == descriptor.params.length && isVarArgCall()) { +@@ -350,6 +425,34 @@ public class InvocationExprent extends Exprent { if (mask == null || mask.get(i) == null) { TextBuffer buff = new TextBuffer(); boolean ambiguous = setAmbiguousParameters.get(i); @@ -1114,15 +1154,15 @@ index 9803a215b8c5bc40658c8210c10e61644b519231..d72870ee498d9da075a08dc6e2afef90 + */ // 'byte' and 'short' literals need an explicit narrowing type cast when used as a parameter - ExprProcessor.getCastedExprent(lstParameters.get(i), descriptor.params[i], buff, indent, true, ambiguous, true, true, tracer); -@@ -462,12 +565,11 @@ public class InvocationExprent extends Exprent { - return !isStatic && lstParameters.size() == 0 && classname.equals(UNBOXING_METHODS.get(name)); + ExprProcessor.getCastedExprent(parameters.get(i), descriptor.params[i], buff, indent, true, ambiguous, true, true, tracer); +@@ -467,12 +570,11 @@ public class InvocationExprent extends Exprent { + return !isStatic && parameters.size() == 0 && className.equals(UNBOXING_METHODS.get(name)); } - private BitSet getAmbiguousParameters() { + private List getMatchedDescriptors() { + List matches = new ArrayList<>(); - StructClass cl = DecompilerContext.getStructContext().getClass(classname); + StructClass cl = DecompilerContext.getStructContext().getClass(className); - if (cl == null) return EMPTY_BIT_SET; + if (cl == null) return matches; @@ -1131,7 +1171,7 @@ index 9803a215b8c5bc40658c8210c10e61644b519231..d72870ee498d9da075a08dc6e2afef90 nextMethod: for (StructMethod mt : cl.getMethods()) { if (name.equals(mt.getName())) { -@@ -478,11 +580,19 @@ public class InvocationExprent extends Exprent { +@@ -483,11 +585,19 @@ public class InvocationExprent extends Exprent { continue nextMethod; } } @@ -1146,14 +1186,14 @@ index 9803a215b8c5bc40658c8210c10e61644b519231..d72870ee498d9da075a08dc6e2afef90 + } + + private BitSet getAmbiguousParameters(List matches) { -+ StructClass cl = DecompilerContext.getStructContext().getClass(classname); ++ StructClass cl = DecompilerContext.getStructContext().getClass(className); + if (cl == null || matches.size() == 1) { + return EMPTY_BIT_SET; + } // check if a call is unambiguous StructMethod mt = cl.getMethod(InterpreterUtil.makeUniqueKey(name, stringDescriptor)); -@@ -504,7 +614,14 @@ public class InvocationExprent extends Exprent { +@@ -509,7 +619,14 @@ public class InvocationExprent extends Exprent { BitSet ambiguous = new BitSet(descriptor.params.length); for (int i = 0; i < descriptor.params.length; i++) { VarType paramType = descriptor.params[i]; @@ -1170,7 +1210,7 @@ index 9803a215b8c5bc40658c8210c10e61644b519231..d72870ee498d9da075a08dc6e2afef90 ambiguous.set(i); break; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java -index 7914279296b8aaa495f85bed6439676c15963411..f99fdc492e9ca76a1f14695e832ea193b920c1e1 100644 +index 6df45768b067fd2e01ffd61bb157158cb369ad7e..2501863f7396c721a42eaab481b2c89d88209d23 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -14,7 +14,6 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; @@ -1178,10 +1218,10 @@ index 7914279296b8aaa495f85bed6439676c15963411..f99fdc492e9ca76a1f14695e832ea193 import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.struct.gen.generics.GenericClassDescriptor; -import org.jetbrains.java.decompiler.struct.gen.generics.GenericMain; - import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.jetbrains.java.decompiler.util.ListStack; import org.jetbrains.java.decompiler.util.TextBuffer; -@@ -34,6 +33,7 @@ public class NewExprent extends Exprent { + +@@ -30,6 +29,7 @@ public class NewExprent extends Exprent { private boolean anonymous; private boolean lambda; private boolean enumConst; @@ -1189,15 +1229,15 @@ index 7914279296b8aaa495f85bed6439676c15963411..f99fdc492e9ca76a1f14695e832ea193 public NewExprent(VarType newType, ListStack stack, int arrayDim, BitSet bytecodeOffsets) { this(newType, getDimensions(arrayDim, stack), bytecodeOffsets); -@@ -72,6 +72,24 @@ public class NewExprent extends Exprent { - return anonymous ? DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value).anonymousClassType : newType; +@@ -68,6 +68,24 @@ public class NewExprent extends Exprent { + return anonymous ? DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.getValue()).anonymousClassType : newType; } + @Override + public VarType getInferredExprType(VarType upperBound) { + genericArgs.clear(); -+ if (newType.type == CodeConstants.TYPE_OBJECT && newType.arrayDim == 0) { -+ StructClass node = DecompilerContext.getStructContext().getClass(newType.value); ++ if (newType.getType() == CodeConstants.TYPE_OBJECT && newType.getArrayDim() == 0) { ++ StructClass node = DecompilerContext.getStructContext().getClass(newType.getValue()); + + if (node != null && node.getSignature() != null) { + GenericClassDescriptor sig = node.getSignature(); @@ -1207,14 +1247,14 @@ index 7914279296b8aaa495f85bed6439676c15963411..f99fdc492e9ca76a1f14695e832ea193 + } + } + } -+ ++ + return getExprType(); + } + @Override public CheckTypesResult checkExprTypeBounds() { CheckTypesResult result = new CheckTypesResult(); -@@ -173,17 +191,17 @@ public class NewExprent extends Exprent { +@@ -169,17 +187,17 @@ public class NewExprent extends Exprent { } } @@ -1222,20 +1262,20 @@ index 7914279296b8aaa495f85bed6439676c15963411..f99fdc492e9ca76a1f14695e832ea193 + GenericClassDescriptor descriptor = child.getWrapper().getClassStruct().getSignature(); if (descriptor != null) { if (descriptor.superinterfaces.isEmpty()) { -- buf.append(GenericMain.getGenericCastTypeName(descriptor.superclass)); -+ buf.append(ExprProcessor.getCastTypeName(descriptor.superclass)); +- buf.append(GenericMain.getGenericCastTypeName(descriptor.superclass, Collections.emptyList())); ++ buf.append(ExprProcessor.getCastTypeName(descriptor.superclass, Collections.emptyList())); } else { if (descriptor.superinterfaces.size() > 1 && !lambda) { DecompilerContext.getLogger().writeMessage("Inconsistent anonymous class signature: " + child.classStruct.qualifiedName, IFernflowerLogger.Severity.WARN); } -- buf.append(GenericMain.getGenericCastTypeName(descriptor.superinterfaces.get(0))); -+ buf.append(ExprProcessor.getCastTypeName(descriptor.superinterfaces.get(0))); +- buf.append(GenericMain.getGenericCastTypeName(descriptor.superinterfaces.get(0), Collections.emptyList())); ++ buf.append(ExprProcessor.getCastTypeName(descriptor.superinterfaces.get(0), Collections.emptyList())); } } else { -@@ -192,6 +210,7 @@ public class NewExprent extends Exprent { +@@ -188,6 +206,7 @@ public class NewExprent extends Exprent { } } @@ -1243,7 +1283,7 @@ index 7914279296b8aaa495f85bed6439676c15963411..f99fdc492e9ca76a1f14695e832ea193 buf.append('('); if (!lambda && constructor != null) { -@@ -283,6 +302,7 @@ public class NewExprent extends Exprent { +@@ -279,6 +298,7 @@ public class NewExprent extends Exprent { int start = enumConst ? 2 : 0; if (!enumConst || start < parameters.size()) { @@ -1252,10 +1292,10 @@ index 7914279296b8aaa495f85bed6439676c15963411..f99fdc492e9ca76a1f14695e832ea193 boolean firstParam = true; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java -index 60048a473001b72b6eb6b8d903a257c043d76902..899ca15489fb70ff5f81aa3c947ca4c228ba1d31 100644 +index 1765af58c1f7db03da58747e06c19d7e3f483dd5..c571b8463712cff5eeeab9d28df9d23feee42bc6 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java -@@ -22,6 +22,7 @@ import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTypeTableAtt +@@ -21,6 +21,7 @@ import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTypeTableAtt import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.struct.gen.generics.GenericFieldDescriptor; import org.jetbrains.java.decompiler.struct.gen.generics.GenericMain; @@ -1290,8 +1330,8 @@ index 60048a473001b72b6eb6b8d903a257c043d76902..899ca15489fb70ff5f81aa3c947ca4c2 if (lvt.getSignature() != null) { GenericFieldDescriptor descriptor = GenericMain.parseFieldSignature(lvt.getSignature()); if (descriptor != null) { -- buffer.append(GenericMain.getGenericCastTypeName(descriptor.type)); -+ buffer.append(ExprProcessor.getCastTypeName(descriptor.type)); +- buffer.append(GenericMain.getGenericCastTypeName(descriptor.type, Collections.emptyList())); ++ buffer.append(ExprProcessor.getCastTypeName(descriptor.type, Collections.emptyList())); return; } } @@ -1299,41 +1339,41 @@ index 60048a473001b72b6eb6b8d903a257c043d76902..899ca15489fb70ff5f81aa3c947ca4c2 if (signature != null) { GenericFieldDescriptor descriptor = GenericMain.parseFieldSignature(signature); if (descriptor != null) { -- buffer.append(GenericMain.getGenericCastTypeName(descriptor.type)); -+ buffer.append(ExprProcessor.getCastTypeName(descriptor.type)); +- buffer.append(GenericMain.getGenericCastTypeName(descriptor.type, Collections.emptyList())); ++ buffer.append(ExprProcessor.getCastTypeName(descriptor.type, Collections.emptyList())); return; } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java -index 76009831d84f399b9a9dc1b8afc09eff519e000a..46635ec712d20adf9dd3396d2c62846aa8ef6bee 100644 +index 0c64170a05d6675803b69284d8ee532e44212ee2..7a54601fd2fd88d0c652384587e16c2d3f704f7e 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java -@@ -126,6 +126,7 @@ public final class DoStatement extends Statement { +@@ -106,6 +106,7 @@ public final class DoStatement extends Statement { break; - case LOOP_FOREACH: + case FOREACH: buf.appendIndent(indent).append("for(").append(initExprent.get(0).toJava(indent, tracer)); + incExprent.get(0).getInferredExprType(null); //TODO: Find a better then null? For now just calls it to clear casts if needed buf.append(" : ").append(incExprent.get(0).toJava(indent, tracer)).append(") {").appendLineSeparator(); tracer.incrementCurrentSourceLine(); buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true, tracer)); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java -index fa326a4a190012b9e121baa61880c172836e22db..89f1c9709d9002701c3ec8b4563d345337995dac 100644 +index 344772dc14f336d6ffe235c5159225d0656846f1..721c6a83a921b0f382290f3e17bbea5b214b7881 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java -@@ -991,7 +991,7 @@ public class VarDefinitionHelper { +@@ -993,7 +993,7 @@ public class VarDefinitionHelper { private VarInfo(LocalVariable lvt, VarType type) { if (lvt != null && lvt.getSignature() != null) -- this.cast = GenericMain.getGenericCastTypeName(new GenericType(lvt.getSignature())); -+ this.cast = ExprProcessor.getCastTypeName(GenericType.parse(lvt.getSignature()), true); +- this.cast = GenericMain.getGenericCastTypeName(new GenericType(lvt.getSignature()), Collections.emptyList()); ++ this.cast = ExprProcessor.getCastTypeName(GenericType.parse(lvt.getSignature()), true, Collections.emptyList()); else if (lvt != null) - this.cast = ExprProcessor.getCastTypeName(lvt.getVarType(), false); + this.cast = ExprProcessor.getCastTypeName(lvt.getVarType(), false, Collections.emptyList()); else if (type != null) diff --git a/src/org/jetbrains/java/decompiler/struct/StructClass.java b/src/org/jetbrains/java/decompiler/struct/StructClass.java -index 134813e5a764ec4c0cbd2f9efb0a0a2a4e69e1d1..6813dc6c8909900d3f21eb91532bdfa19fb1d83d 100644 +index 0b4275f57e3092623c4e462b032b418cf2bdd84b..ce8b12c815fc939406701ad57627a1bd11771722 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructClass.java +++ b/src/org/jetbrains/java/decompiler/struct/StructClass.java -@@ -2,18 +2,30 @@ +@@ -2,20 +2,32 @@ package org.jetbrains.java.decompiler.struct; import org.jetbrains.java.decompiler.code.CodeConstants; @@ -1341,9 +1381,11 @@ index 134813e5a764ec4c0cbd2f9efb0a0a2a4e69e1d1..6813dc6c8909900d3f21eb91532bdfa1 +import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructGenericSignatureAttribute; + import org.jetbrains.java.decompiler.struct.attr.StructPermittedSubclassesAttribute; import org.jetbrains.java.decompiler.struct.attr.StructRecordAttribute; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; import org.jetbrains.java.decompiler.struct.consts.PrimitiveConstant; + import org.jetbrains.java.decompiler.struct.gen.Type; +import org.jetbrains.java.decompiler.struct.gen.VarType; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericClassDescriptor; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericMain; @@ -1364,7 +1406,7 @@ index 134813e5a764ec4c0cbd2f9efb0a0a2a4e69e1d1..6813dc6c8909900d3f21eb91532bdfa1 /* class_file { -@@ -74,8 +86,16 @@ public class StructClass extends StructMember { +@@ -76,8 +88,16 @@ public class StructClass extends StructMember { Map attributes = readAttributes(in, pool); @@ -1382,7 +1424,7 @@ index 134813e5a764ec4c0cbd2f9efb0a0a2a4e69e1d1..6813dc6c8909900d3f21eb91532bdfa1 if (loader == null) cl.pool = pool; return cl; } -@@ -90,6 +110,7 @@ public class StructClass extends StructMember { +@@ -92,6 +112,7 @@ public class StructClass extends StructMember { private final String[] interfaceNames; private final VBStyleCollection fields; private final VBStyleCollection methods; @@ -1390,7 +1432,7 @@ index 134813e5a764ec4c0cbd2f9efb0a0a2a4e69e1d1..6813dc6c8909900d3f21eb91532bdfa1 private ConstantPool pool; -@@ -104,7 +125,8 @@ public class StructClass extends StructMember { +@@ -106,7 +127,8 @@ public class StructClass extends StructMember { int[] interfaces, String[] interfaceNames, VBStyleCollection fields, @@ -1400,7 +1442,7 @@ index 134813e5a764ec4c0cbd2f9efb0a0a2a4e69e1d1..6813dc6c8909900d3f21eb91532bdfa1 super(accessFlags, attributes); this.qualifiedName = qualifiedName; this.superClass = superClass; -@@ -116,6 +138,7 @@ public class StructClass extends StructMember { +@@ -118,6 +140,7 @@ public class StructClass extends StructMember { this.interfaceNames = interfaceNames; this.fields = fields; this.methods = methods; @@ -1408,9 +1450,9 @@ index 134813e5a764ec4c0cbd2f9efb0a0a2a4e69e1d1..6813dc6c8909900d3f21eb91532bdfa1 } public boolean hasField(String name, String descriptor) { -@@ -197,4 +220,106 @@ public class StructClass extends StructMember { - public String toString() { - return qualifiedName; +@@ -242,4 +265,106 @@ public class StructClass extends StructMember { + protected Type getType() { + return null; } + + public GenericClassDescriptor getSignature() { @@ -1455,9 +1497,9 @@ index 134813e5a764ec4c0cbd2f9efb0a0a2a4e69e1d1..6813dc6c8909900d3f21eb91532bdfa1 + Set visited = new HashSet<>(); //Is there a better way? Is the signature forced to contain all interfaces? + if (this.signature != null) { + for (VarType intf : this.signature.superinterfaces) { -+ visited.add((String)intf.value); ++ visited.add((String)intf.getValue()); + -+ StructClass cls = DecompilerContext.getStructContext().getClass((String)intf.value); ++ StructClass cls = DecompilerContext.getStructContext().getClass((String)intf.getValue()); + if (cls != null) { + Map sig = cls.getGenericMap(intf); + @@ -1516,7 +1558,7 @@ index 134813e5a764ec4c0cbd2f9efb0a0a2a4e69e1d1..6813dc6c8909900d3f21eb91532bdfa1 + } } diff --git a/src/org/jetbrains/java/decompiler/struct/StructContext.java b/src/org/jetbrains/java/decompiler/struct/StructContext.java -index 7f9127710be02e07bcbb08be650cd41bff732abf..36d1d6c4ae8e3b9f1a64dae514d9efa65722033a 100644 +index 94cedbee257faebd95ea933ab80a7d242c1ba023..301737310f3d346cc2229395551d504a34cb6dbc 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructContext.java +++ b/src/org/jetbrains/java/decompiler/struct/StructContext.java @@ -156,6 +156,19 @@ public class StructContext { @@ -1540,11 +1582,11 @@ index 7f9127710be02e07bcbb08be650cd41bff732abf..36d1d6c4ae8e3b9f1a64dae514d9efa6 return classes; } diff --git a/src/org/jetbrains/java/decompiler/struct/StructField.java b/src/org/jetbrains/java/decompiler/struct/StructField.java -index cfa64d2087246cc980bb25f0d80779e11da04232..232f47dd8d559f1cedb39b49bfd04bdec2d6c1b5 100644 +index 0d6df7e05b9b385e743c85261b77215314167989..7b319f148e6925ed77f4002e9064339270dd4d7f 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructField.java +++ b/src/org/jetbrains/java/decompiler/struct/StructField.java -@@ -1,8 +1,14 @@ - // 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. +@@ -1,10 +1,16 @@ + // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.java.decompiler.struct; +import org.jetbrains.java.decompiler.main.DecompilerContext; @@ -1552,13 +1594,15 @@ index cfa64d2087246cc980bb25f0d80779e11da04232..232f47dd8d559f1cedb39b49bfd04bde import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructGenericSignatureAttribute; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; + import org.jetbrains.java.decompiler.struct.gen.Type; + import org.jetbrains.java.decompiler.struct.gen.VarType; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericFieldDescriptor; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericMain; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericMethodDescriptor; import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.IOException; -@@ -26,17 +32,30 @@ public class StructField extends StructMember { +@@ -28,17 +34,30 @@ public class StructField extends StructMember { String[] values = pool.getClassElement(ConstantPool.FIELD, clQualifiedName, nameIndex, descriptorIndex); Map attributes = readAttributes(in, pool); @@ -1590,9 +1634,9 @@ index cfa64d2087246cc980bb25f0d80779e11da04232..232f47dd8d559f1cedb39b49bfd04bde } public final String getName() { -@@ -51,4 +70,8 @@ public class StructField extends StructMember { - public String toString() { - return name; +@@ -58,4 +77,8 @@ public class StructField extends StructMember { + protected Type getType() { + return new VarType(descriptor); } + + public GenericFieldDescriptor getSignature() { @@ -1600,10 +1644,10 @@ index cfa64d2087246cc980bb25f0d80779e11da04232..232f47dd8d559f1cedb39b49bfd04bde + } } diff --git a/src/org/jetbrains/java/decompiler/struct/StructMethod.java b/src/org/jetbrains/java/decompiler/struct/StructMethod.java -index 3b14d7fc755a2d9c33a022aaa2ab728c4a12a4e8..61984e6af43043db7fd29c1b79e16e67789ca707 100644 +index 4e5c7b4da350020f4f69da956eda4384b86df2aa..e3d5edf6e78c37206e5a37abaf24efbb6eb6dfa3 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMethod.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMethod.java -@@ -2,10 +2,15 @@ +@@ -2,12 +2,17 @@ package org.jetbrains.java.decompiler.struct; import org.jetbrains.java.decompiler.code.*; @@ -1614,12 +1658,14 @@ index 3b14d7fc755a2d9c33a022aaa2ab728c4a12a4e8..61984e6af43043db7fd29c1b79e16e67 +import org.jetbrains.java.decompiler.struct.attr.StructGenericSignatureAttribute; import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; + import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; + import org.jetbrains.java.decompiler.struct.gen.Type; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericMain; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericMethodDescriptor; import org.jetbrains.java.decompiler.util.DataInputFullStream; import org.jetbrains.java.decompiler.util.VBStyleCollection; -@@ -39,7 +44,15 @@ public class StructMethod extends StructMember { +@@ -41,7 +46,15 @@ public class StructMethod extends StructMember { attributes.putAll(code.codeAttributes); } @@ -1636,7 +1682,7 @@ index 3b14d7fc755a2d9c33a022aaa2ab728c4a12a4e8..61984e6af43043db7fd29c1b79e16e67 } private static final int[] opr_iconst = {-1, 0, 1, 2, 3, 4, 5}; -@@ -56,6 +69,7 @@ public class StructMethod extends StructMember { +@@ -58,6 +71,7 @@ public class StructMethod extends StructMember { private InstructionSequence seq = null; private boolean expanded = false; private final String classQualifiedName; @@ -1644,7 +1690,7 @@ index 3b14d7fc755a2d9c33a022aaa2ab728c4a12a4e8..61984e6af43043db7fd29c1b79e16e67 private StructMethod(int accessFlags, Map attributes, -@@ -63,7 +77,8 @@ public class StructMethod extends StructMember { +@@ -65,7 +79,8 @@ public class StructMethod extends StructMember { String descriptor, int bytecodeVersion, StructCodeAttribute code, @@ -1654,7 +1700,7 @@ index 3b14d7fc755a2d9c33a022aaa2ab728c4a12a4e8..61984e6af43043db7fd29c1b79e16e67 super(accessFlags, attributes); this.name = name; this.descriptor = descriptor; -@@ -77,6 +92,7 @@ public class StructMethod extends StructMember { +@@ -79,6 +94,7 @@ public class StructMethod extends StructMember { this.localVariables = this.codeLength = this.codeFullLength = -1; } this.classQualifiedName = classQualifiedName; @@ -1662,7 +1708,7 @@ index 3b14d7fc755a2d9c33a022aaa2ab728c4a12a4e8..61984e6af43043db7fd29c1b79e16e67 } public void expandData(StructClass classStruct) throws IOException { -@@ -378,4 +394,8 @@ public class StructMethod extends StructMember { +@@ -385,4 +401,8 @@ public class StructMethod extends StructMember { public String getClassQualifiedName() { return classQualifiedName; } @@ -1713,7 +1759,7 @@ index e50983daf2a1bf6c93ec92c99221587d7c4f7c6a..11fa1a3e621221a09c0e611a7f912932 } } diff --git a/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java b/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java -index 2ad7c680a30eecee8b4359c3d4ac1fc5fa094682..79bd5b3f70510c85a2908fcadeb57119224082bb 100644 +index 14aaf8e28413ccb2dda4d2d181fc79976f2b0710..8044f348e8aad96f451a47ef24f54972e171b9c7 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java @@ -2,14 +2,24 @@ @@ -1791,21 +1837,18 @@ index 2ad7c680a30eecee8b4359c3d4ac1fc5fa094682..79bd5b3f70510c85a2908fcadeb57119 \ No newline at end of file +} diff --git a/src/org/jetbrains/java/decompiler/struct/gen/VarType.java b/src/org/jetbrains/java/decompiler/struct/gen/VarType.java -index 4362f38e086b4ccd996145132135da895ea2d951..af6b8995f8396efdcaa82fae195dd8c3d107b5a7 100644 +index e5100010a55590d289820d91301ddb732398e3f2..d8388e50f6c88e91a0007854400e756153cdb4a6 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/VarType.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/VarType.java -@@ -1,7 +1,10 @@ - // Copyright 2000-2017 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. - package org.jetbrains.java.decompiler.struct.gen; +@@ -3,6 +3,7 @@ package org.jetbrains.java.decompiler.struct.gen; -+import java.util.Map; -+ import org.jetbrains.java.decompiler.code.CodeConstants; -+import org.jetbrains.java.decompiler.struct.gen.generics.GenericType; - import org.jetbrains.java.decompiler.util.InterpreterUtil; - public class VarType { // TODO: optimize switch -@@ -49,7 +52,7 @@ public class VarType { // TODO: optimize switch ++import java.util.Map; + import java.util.Objects; + + public class VarType implements Type { // TODO: optimize switch +@@ -50,7 +51,7 @@ public class VarType implements Type { // TODO: optimize switch this(type, arrayDim, value, getFamily(type, arrayDim), getStackSize(type, arrayDim), false); } @@ -1814,7 +1857,7 @@ index 4362f38e086b4ccd996145132135da895ea2d951..af6b8995f8396efdcaa82fae195dd8c3 this.type = type; this.arrayDim = arrayDim; this.value = value; -@@ -141,7 +144,7 @@ public class VarType { // TODO: optimize switch +@@ -165,7 +166,7 @@ public class VarType implements Type { // TODO: optimize switch } } @@ -1823,7 +1866,7 @@ index 4362f38e086b4ccd996145132135da895ea2d951..af6b8995f8396efdcaa82fae195dd8c3 if (arrayDim > 0) { return 1; } -@@ -158,7 +161,7 @@ public class VarType { // TODO: optimize switch +@@ -182,7 +183,7 @@ public class VarType implements Type { // TODO: optimize switch } } @@ -1832,7 +1875,7 @@ index 4362f38e086b4ccd996145132135da895ea2d951..af6b8995f8396efdcaa82fae195dd8c3 if (arrayDim > 0) { return CodeConstants.TYPE_FAMILY_OBJECT; } -@@ -259,6 +262,15 @@ public class VarType { // TODO: optimize switch +@@ -283,6 +284,15 @@ public class VarType implements Type { // TODO: optimize switch return res; } @@ -1848,7 +1891,7 @@ index 4362f38e086b4ccd996145132135da895ea2d951..af6b8995f8396efdcaa82fae195dd8c3 @Override public boolean equals(Object o) { if (o == this) { -@@ -405,4 +417,15 @@ public class VarType { // TODO: optimize switch +@@ -429,4 +439,15 @@ public class VarType implements Type { // TODO: optimize switch throw new IllegalArgumentException("Invalid type: " + c); } } @@ -1910,18 +1953,21 @@ index a65181762765bfdc9d2ee5695f3ffa68b7768b74..2b0fdf1dad01ec62f3e21f372297c124 } \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java -index 8af6b5068bc844d49a3761e9d9d472e7febccd00..5a128724fab153cc4864fbcef7e60ab25f7c8480 100644 +index 4bf0c0ada3e92dda77bb698fcf78d232f4c2bb2d..4c35ce1fc3fface6ce485d8947a5b453ee88fb66 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java -@@ -5,6 +5,7 @@ import org.jetbrains.java.decompiler.code.CodeConstants; - import org.jetbrains.java.decompiler.main.DecompilerContext; - import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; - import org.jetbrains.java.decompiler.util.TextUtil; +@@ -7,9 +7,9 @@ import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; + import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; + import org.jetbrains.java.decompiler.modules.decompiler.typeann.TypeAnnotationWriteHelper; + import org.jetbrains.java.decompiler.struct.StructTypePathEntry; +import org.jetbrains.java.decompiler.struct.gen.VarType; import java.util.ArrayList; +-import java.util.Arrays; import java.util.List; -@@ -22,7 +23,7 @@ public final class GenericMain { + import java.util.stream.Collectors; + +@@ -26,7 +26,7 @@ public final class GenericMain { "boolean", }; @@ -1930,7 +1976,7 @@ index 8af6b5068bc844d49a3761e9d9d472e7febccd00..5a128724fab153cc4864fbcef7e60ab2 String original = signature; try { GenericClassDescriptor descriptor = new GenericClassDescriptor(); -@@ -30,15 +31,23 @@ public final class GenericMain { +@@ -34,15 +34,23 @@ public final class GenericMain { signature = parseFormalParameters(signature, descriptor.fparameters, descriptor.fbounds); String superCl = GenericType.getNextType(signature); @@ -1956,7 +2002,7 @@ index 8af6b5068bc844d49a3761e9d9d472e7febccd00..5a128724fab153cc4864fbcef7e60ab2 return descriptor; } catch (RuntimeException e) { -@@ -49,7 +58,7 @@ public final class GenericMain { +@@ -53,7 +61,7 @@ public final class GenericMain { public static GenericFieldDescriptor parseFieldSignature(String signature) { try { @@ -1965,7 +2011,7 @@ index 8af6b5068bc844d49a3761e9d9d472e7febccd00..5a128724fab153cc4864fbcef7e60ab2 } catch (RuntimeException e) { DecompilerContext.getLogger().writeMessage("Invalid signature: " + signature, IFernflowerLogger.Severity.WARN); -@@ -61,29 +70,29 @@ public final class GenericMain { +@@ -65,29 +73,29 @@ public final class GenericMain { String original = signature; try { List typeParameters = new ArrayList<>(); @@ -2001,7 +2047,7 @@ index 8af6b5068bc844d49a3761e9d9d472e7febccd00..5a128724fab153cc4864fbcef7e60ab2 } } -@@ -95,7 +104,7 @@ public final class GenericMain { +@@ -99,7 +107,7 @@ public final class GenericMain { } } @@ -2010,7 +2056,7 @@ index 8af6b5068bc844d49a3761e9d9d472e7febccd00..5a128724fab153cc4864fbcef7e60ab2 if (signature.charAt(0) != '<') { return signature; } -@@ -128,7 +137,7 @@ public final class GenericMain { +@@ -132,7 +140,7 @@ public final class GenericMain { String param = value.substring(0, to); value = value.substring(to + 1); @@ -2019,7 +2065,7 @@ index 8af6b5068bc844d49a3761e9d9d472e7febccd00..5a128724fab153cc4864fbcef7e60ab2 while (true) { if (value.charAt(0) == ':') { -@@ -137,7 +146,7 @@ public final class GenericMain { +@@ -141,7 +149,7 @@ public final class GenericMain { } String bound = GenericType.getNextType(value); @@ -2028,77 +2074,125 @@ index 8af6b5068bc844d49a3761e9d9d472e7febccd00..5a128724fab153cc4864fbcef7e60ab2 value = value.substring(bound.length()); -@@ -174,69 +183,9 @@ public final class GenericMain { - return type.value; +@@ -184,83 +192,14 @@ public final class GenericMain { } else if (tp == CodeConstants.TYPE_OBJECT) { -- StringBuilder buffer = new StringBuilder(); -- appendClassName(type, buffer); -- return buffer.toString(); -+ return type.getCastName(); + StringBuilder sb = new StringBuilder(); +- appendClassName(type, sb, typeAnnWriteHelpers); ++ type.appendCastName(sb, typeAnnWriteHelpers); + return sb.toString(); } throw new RuntimeException("Invalid type: " + type); } -- -- private static void appendClassName(GenericType type, StringBuilder buffer) { -- List enclosingClasses = type.getEnclosingClasses(); -- -- if (enclosingClasses.isEmpty()) { -- String name = type.value.replace('/', '.'); -- buffer.append(DecompilerContext.getImportCollector().getShortName(name)); + +- private static void appendClassName(GenericType type, StringBuilder sb, List typeAnnWriteHelpers) { +- List enclosingTypes = type.getEnclosingClasses(); +- typeAnnWriteHelpers = ExprProcessor.writeTypeAnnotationBeforeType(type, sb, typeAnnWriteHelpers); +- if (enclosingTypes.isEmpty()) { +- List nestedTypes = Arrays.asList( +- DecompilerContext.getImportCollector().getNestedName(type.getValue().replace('/', '.')).split("\\.") +- ); +- ExprProcessor.writeNestedClass(sb, type, nestedTypes, typeAnnWriteHelpers); +- ExprProcessor.popNestedTypeAnnotation(typeAnnWriteHelpers); - } - else { -- for (GenericType tp : enclosingClasses) { -- if (buffer.length() == 0) { -- buffer.append(DecompilerContext.getImportCollector().getShortName(tp.value.replace('/', '.'))); -- } -- else { -- buffer.append(tp.value); -- } -- -- appendTypeArguments(tp, buffer); -- buffer.append('.'); +- for (GenericType tp : enclosingTypes) { +- List nestedTypes = Arrays.asList( +- DecompilerContext.getImportCollector().getNestedName(tp.getValue().replace('/', '.')).split("\\.") +- ); +- typeAnnWriteHelpers = ExprProcessor.writeNestedClass(sb, type, nestedTypes, typeAnnWriteHelpers); +- typeAnnWriteHelpers = appendTypeArguments(tp, sb, typeAnnWriteHelpers); +- ExprProcessor.popNestedTypeAnnotation(typeAnnWriteHelpers); +- sb.append('.'); - } -- -- buffer.append(type.value); +- typeAnnWriteHelpers = ExprProcessor.writeNestedTypeAnnotations(sb, typeAnnWriteHelpers); +- ExprProcessor.popNestedTypeAnnotation(typeAnnWriteHelpers); +- sb.append(type.getValue()); - } -- -- appendTypeArguments(type, buffer); +- appendTypeArguments(type, sb, typeAnnWriteHelpers); - } - -- private static void appendTypeArguments(GenericType type, StringBuilder buffer) { +- private static List appendTypeArguments( +- GenericType type, +- StringBuilder sb, +- List typeAnnWriteHelpers +- ) { - if (!type.getArguments().isEmpty()) { -- buffer.append('<'); +- sb.append('<'); - - for (int i = 0; i < type.getArguments().size(); i++) { - if (i > 0) { -- buffer.append(", "); +- sb.append(", "); - } - +- GenericType genPar = type.getArguments().get(i); - int wildcard = type.getWildcards().get(i); +- +- // only take type paths that are in the generic +- List locTypeAnnWriteHelpers = getGenericTypeAnnotations(i, typeAnnWriteHelpers); +- typeAnnWriteHelpers.removeAll(locTypeAnnWriteHelpers); +- locTypeAnnWriteHelpers = writeTypeAnnotationBeforeWildCard(sb, genPar, wildcard, locTypeAnnWriteHelpers); - switch (wildcard) { - case GenericType.WILDCARD_UNBOUND: -- buffer.append('?'); +- sb.append('?'); - break; - case GenericType.WILDCARD_EXTENDS: -- buffer.append("? extends "); +- sb.append("? extends "); - break; - case GenericType.WILDCARD_SUPER: -- buffer.append("? super "); +- sb.append("? super "); - break; - } -- -- GenericType genPar = type.getArguments().get(i); +- locTypeAnnWriteHelpers = writeTypeAnnotationAfterWildCard(sb, genPar, locTypeAnnWriteHelpers); - if (genPar != null) { -- buffer.append(getGenericCastTypeName(genPar)); +- sb.append(getGenericCastTypeName(genPar, locTypeAnnWriteHelpers)); - } - } - -- buffer.append(">"); +- sb.append(">"); - } +- return typeAnnWriteHelpers; - } - } +- +- private static List getGenericTypeAnnotations( ++ public static List getGenericTypeAnnotations( + int argIndex, + List typeAnnWriteHelpers + ) { +@@ -273,9 +212,9 @@ public final class GenericMain { + }).collect(Collectors.toList()); + } + +- private static List writeTypeAnnotationBeforeWildCard( ++ public static List writeTypeAnnotationBeforeWildCard( + StringBuilder sb, +- GenericType type, ++ VarType type, + int wildcard, + List typeAnnWriteHelpers + ) { +@@ -285,7 +224,7 @@ public final class GenericMain { + typeAnnWriteHelper.writeTo(sb); + return false; + } +- if (type.getArrayDim() == typeAnnWriteHelper.getPaths().size() && type.getArrayDim() == typeAnnWriteHelper.arrayPathCount()) { ++ if (type != null && type.getArrayDim() == typeAnnWriteHelper.getPaths().size() && type.getArrayDim() == typeAnnWriteHelper.arrayPathCount()) { + typeAnnWriteHelper.writeTo(sb); + return false; + } +@@ -293,9 +232,9 @@ public final class GenericMain { + }).collect(Collectors.toList()); + } + +- private static List writeTypeAnnotationAfterWildCard( ++ public static List writeTypeAnnotationAfterWildCard( + StringBuilder sb, +- GenericType type, ++ VarType type, + List typeAnnWriteHelpers + ) { + typeAnnWriteHelpers.forEach(typeAnnWriteHelper -> { // remove all wild card path entries diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMethodDescriptor.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMethodDescriptor.java index eb8049193e952f7476a99188838b6c8907f49f8d..a93d250e2400a9680d7561d73cc1a69f7c0f8d79 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMethodDescriptor.java @@ -2133,41 +2227,46 @@ index eb8049193e952f7476a99188838b6c8907f49f8d..a93d250e2400a9680d7561d73cc1a69f this.typeParameterBounds = substitute(typeParameterBounds); this.parameterTypes = substitute(parameterTypes); diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java -index 60bffdb70108c9e035109d77dca48262fa216b32..13cca7906fb5810a0bf70b4b6ce184087e1c99e0 100644 +index ff1fe46b43531409fdce2151485cfc48366d3b62..9e9e64933f89c72460c12dea174429c80cbbfcbb 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java -@@ -2,43 +2,43 @@ +@@ -2,44 +2,49 @@ package org.jetbrains.java.decompiler.struct.gen.generics; import org.jetbrains.java.decompiler.code.CodeConstants; +import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; ++import org.jetbrains.java.decompiler.modules.decompiler.typeann.TypeAnnotationWriteHelper; + import org.jetbrains.java.decompiler.struct.gen.Type; import org.jetbrains.java.decompiler.struct.gen.VarType; import java.util.ArrayList; ++import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Map; ++import java.util.regex.Pattern; --public class GenericType { -+public class GenericType extends VarType { +-public class GenericType implements Type { ++public class GenericType extends VarType implements Type { public static final int WILDCARD_EXTENDS = 1; public static final int WILDCARD_SUPER = 2; public static final int WILDCARD_UNBOUND = 3; public static final int WILDCARD_NO = 4; -- public final int type; -- public final int arrayDim; -- public final String value; -+ private final VarType parent; -+ private final List arguments; -+ private final int wildcard; +- private final int type; +- private final int arrayDim; +- private final String value; ++ private static final Pattern DOT_SPLIT = Pattern.compile("\\."); - private final List enclosingClasses = new ArrayList<>(); - private final List arguments = new ArrayList<>(); - private final List wildcards = new ArrayList<>(); -- ++ private final VarType parent; ++ private final List arguments; ++ private final int wildcard; + - public GenericType(int type, int arrayDim, String value) { - this.type = type; - this.arrayDim = arrayDim; @@ -2180,7 +2279,7 @@ index 60bffdb70108c9e035109d77dca48262fa216b32..13cca7906fb5810a0bf70b4b6ce18408 } - private GenericType(GenericType other, int arrayDim) { -- this(other.type, arrayDim, other.value); +- this(other.getType(), arrayDim, other.getValue()); - enclosingClasses.addAll(other.enclosingClasses); - arguments.addAll(other.arguments); - wildcards.addAll(other.wildcards); @@ -2198,7 +2297,7 @@ index 60bffdb70108c9e035109d77dca48262fa216b32..13cca7906fb5810a0bf70b4b6ce18408 int index = 0; loop: -@@ -56,32 +56,54 @@ public class GenericType { +@@ -57,32 +62,54 @@ public class GenericType implements Type { case 'L': type = CodeConstants.TYPE_OBJECT; signature = signature.substring(index + 1, signature.length() - 1); @@ -2273,13 +2372,28 @@ index 60bffdb70108c9e035109d77dca48262fa216b32..13cca7906fb5810a0bf70b4b6ce18408 break loop; default: -@@ -92,9 +114,20 @@ public class GenericType { +@@ -93,24 +120,20 @@ public class GenericType implements Type { index++; } - this.type = type; - this.arrayDim = arrayDim; - this.value = value; +- } +- +- @Override +- public int getType() { +- return type; +- } +- +- @Override +- public int getArrayDim() { +- return arrayDim; +- } +- +- @Override +- public String getValue() { +- return value; + if (type == CodeConstants.TYPE_GENVAR) { + return new GenericType(type, arrayDim, value, null, null, wildcard); + } @@ -2297,7 +2411,7 @@ index 60bffdb70108c9e035109d77dca48262fa216b32..13cca7906fb5810a0bf70b4b6ce18408 } private static String getNextClassSignature(String value) { -@@ -122,11 +155,13 @@ public class GenericType { +@@ -138,11 +161,13 @@ public class GenericType implements Type { return value.substring(0, index); } @@ -2313,7 +2427,7 @@ index 60bffdb70108c9e035109d77dca48262fa216b32..13cca7906fb5810a0bf70b4b6ce18408 while (value.length() > 0) { String typeStr = getNextType(value); int len = typeStr.length(); -@@ -144,16 +179,16 @@ public class GenericType { +@@ -160,16 +185,16 @@ public class GenericType implements Type { break; } @@ -2333,55 +2447,54 @@ index 60bffdb70108c9e035109d77dca48262fa216b32..13cca7906fb5810a0bf70b4b6ce18408 } public static String getNextType(String value) { -@@ -204,18 +239,124 @@ public class GenericType { +@@ -220,18 +245,130 @@ public class GenericType implements Type { public GenericType decreaseArrayDim() { - assert arrayDim > 0 : this; -- return new GenericType(this, arrayDim - 1); -+ return new GenericType(type, arrayDim - 1, value, parent, arguments, wildcard); - } - -- public List getArguments() { + assert getArrayDim() > 0 : this; +- return new GenericType(this, getArrayDim() - 1); ++ return new GenericType(getType(), getArrayDim() - 1, getValue(), parent, arguments, wildcard); ++ } ++ + public VarType resizeArrayDim(int newArrayDim) { -+ return new GenericType(type, newArrayDim, value, parent, arguments, wildcard); ++ return new GenericType(getType(), newArrayDim, getValue(), parent, arguments, wildcard); + } + + public VarType getParent() { + return parent; -+ } -+ + } + +- public List getArguments() { + public List getArguments() { return arguments; } + +- public List getEnclosingClasses() { +- return enclosingClasses; + @Override + public boolean isGeneric() { + return true; + } - -- public List getEnclosingClasses() { -- return enclosingClasses; ++ + public int getWildcard() { + return wildcard; - } - -- public List getWildcards() { -- return wildcards; -+ public String getCastName() { -+ String clsName = null; -+ if (parent == null) { -+ clsName = DecompilerContext.getImportCollector().getShortName(value.replace('/', '.')); -+ } -+ else if (parent.isGeneric()) { -+ clsName = ((GenericType)parent).getCastName() + "." + value.substring(parent.value.length() + 1); ++ } ++ ++ public List appendCastName(final StringBuilder clsName, List typeAnnWriteHelpers) { ++ if (parent != null && parent.isGeneric()) { ++ typeAnnWriteHelpers = ((GenericType) parent).appendCastName(clsName, typeAnnWriteHelpers); ++ typeAnnWriteHelpers = ExprProcessor.writeNestedTypeAnnotations(clsName, typeAnnWriteHelpers); ++ clsName.append(".").append(getValue().substring(parent.getValue().length() + 1)); + } + else { -+ clsName = DecompilerContext.getImportCollector().getShortName(parent.value.replace('/', '.')) + "." + value.substring(value.lastIndexOf('.') + 1); ++ List nestedTypes = Arrays.asList(DOT_SPLIT.split(DecompilerContext.getImportCollector().getNestedName(getValue().replace('/', '.')))); ++ ExprProcessor.writeNestedClass(clsName, this, nestedTypes, typeAnnWriteHelpers); ++ ExprProcessor.popNestedTypeAnnotation(typeAnnWriteHelpers); + } -+ return clsName + getTypeArguments(); ++ typeAnnWriteHelpers = appendTypeArguments(clsName, typeAnnWriteHelpers); ++ return typeAnnWriteHelpers; + } + -+ private String getTypeArguments() { -+ StringBuilder buffer = new StringBuilder(); ++ private List appendTypeArguments(final StringBuilder buffer, List typeAnnWriteHelpers) { + if (!arguments.isEmpty()) { + buffer.append('<'); + @@ -2391,6 +2504,10 @@ index 60bffdb70108c9e035109d77dca48262fa216b32..13cca7906fb5810a0bf70b4b6ce18408 + } + + VarType par = arguments.get(i); ++ // only take type paths that are in the generic ++ List locTypeAnnWriteHelpers = GenericMain.getGenericTypeAnnotations(i, typeAnnWriteHelpers); ++ typeAnnWriteHelpers.removeAll(locTypeAnnWriteHelpers); ++ locTypeAnnWriteHelpers = GenericMain.writeTypeAnnotationBeforeWildCard(buffer, par, wildcard, locTypeAnnWriteHelpers); + if (par == null) { // Wildcard unbound + buffer.append('?'); + } @@ -2404,16 +2521,17 @@ index 60bffdb70108c9e035109d77dca48262fa216b32..13cca7906fb5810a0bf70b4b6ce18408 + buffer.append("? super "); + break; + } -+ buffer.append(GenericMain.getGenericCastTypeName(gen)); ++ locTypeAnnWriteHelpers = GenericMain.writeTypeAnnotationAfterWildCard(buffer, par, locTypeAnnWriteHelpers); ++ buffer.append(GenericMain.getGenericCastTypeName(gen, locTypeAnnWriteHelpers)); + } + else { -+ buffer.append(ExprProcessor.getCastTypeName(par)); ++ buffer.append(ExprProcessor.getCastTypeName(par, locTypeAnnWriteHelpers)); + } + } + + buffer.append(">"); + } -+ return buffer.toString(); ++ return typeAnnWriteHelpers; + } + + @Override @@ -2428,10 +2546,12 @@ index 60bffdb70108c9e035109d77dca48262fa216b32..13cca7906fb5810a0bf70b4b6ce18408 + break; + } + buf.append(super.toString()); -+ buf.append(getTypeArguments()); ++ appendTypeArguments(buf, Collections.emptyList()); + return buf.toString(); -+ } -+ + } + +- public List getWildcards() { +- return wildcards; + + @Override + public VarType remap(Map map) { @@ -2459,7 +2579,7 @@ index 60bffdb70108c9e035109d77dca48262fa216b32..13cca7906fb5810a0bf70b4b6ce18408 + } + } + if (changed) { -+ return new GenericType(main.type, main.arrayDim, main.value, parent, newArgs, getWildcard()); ++ return new GenericType(main.getType(), main.getArrayDim(), main.getValue(), parent, newArgs, getWildcard()); + } + return this; } @@ -2536,10 +2656,10 @@ index 0000000000000000000000000000000000000000..a76571c1359c904bdb1e374bbc1e4969 + } +} diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -index bd4868ea4c65503b6f3f983d2d860f50fa55444a..b17be32cc74e95701a299fc031e1daa93e49eb5f 100644 +index 67c41a7676a7d78c5d4bfa2174608cebd575acaa..2c7cdac55a8ba8a9bcc8b4da84e4ed5469e98d6e 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -@@ -14,9 +14,11 @@ public class SingleClassesTest extends SingleClassesTestBase { +@@ -25,9 +25,11 @@ public class SingleClassesTest extends SingleClassesTestBase { IFernflowerPreferences.DUMP_ORIGINAL_LINES, "1", IFernflowerPreferences.IGNORE_INVALID_BYTECODE, "1", IFernflowerPreferences.VERIFY_ANONYMOUS_CLASSES, "1", @@ -2620,20 +2740,23 @@ index dec7ba0f20eecdc5a3c7d0774a0fdd4f3b68e6f6..acf1120655937c0e227ab11a1f472c44 } diff --git a/testData/results/TestClassSwitch.dec b/testData/results/TestClassSwitch.dec -index a42bfc86fd3fa9948233d709ba8358f1b8ec7908..8d59b04318021a2188c429be5b4055fe10efa0b8 100644 +index 6a2b156f9ad0e29aad668542ee090d63130d2182..f92c9169b960ab9f1f5ff7440ac4caef9aa62744 100644 --- a/testData/results/TestClassSwitch.dec +++ b/testData/results/TestClassSwitch.dec -@@ -4,11 +4,11 @@ public class TestClassSwitch { +@@ -2,13 +2,13 @@ package pkg; + + public class TestClassSwitch { public void testCaseOrder(int var1) { - switch(var1) {// 22 - case 5: -- System.out.println(5);// 27 -+ System.out.println((int)5);// 27 - default: - return;// 29 - case 13: -- System.out.println(13);// 24 -+ System.out.println((int)13);// 24 +- switch (var1) {// 22 ++ switch(var1) {// 22 + case 5: +- System.out.println(5);// 27 ++ System.out.println((int)5);// 27 + default: + return;// 29 + case 13: +- System.out.println(13);// 24 ++ System.out.println((int)13);// 24 } }// 25 } diff --git a/FernFlower-Patches/0012-Improvements-to-var-and-var.patch b/FernFlower-Patches/0011-Improvements-to-var-and-var.patch similarity index 90% rename from FernFlower-Patches/0012-Improvements-to-var-and-var.patch rename to FernFlower-Patches/0011-Improvements-to-var-and-var.patch index b13cd7f..47e434f 100644 --- a/FernFlower-Patches/0012-Improvements-to-var-and-var.patch +++ b/FernFlower-Patches/0011-Improvements-to-var-and-var.patch @@ -5,20 +5,20 @@ Subject: [PATCH] Improvements to var++ and var-- diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -index fb9c7a961ec3cfc1f50c3fd902c299e097988997..58bf5152299a7ca6f4d22a2e1f8b95b6393e6242 100644 +index 79e55ad572826f33aa4022b1f60c37917d78a67b..e4f693aa6f988445693b5f36efb1d9f810bff3ba 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -@@ -1048,7 +1048,7 @@ public class NestedClassProcessor { - res = classname.equals(((InvocationExprent)expr).getClassname()); +@@ -926,7 +926,7 @@ public class NestedClassProcessor { + res = classname.equals(((InvocationExprent)expr).getClassName()); break; case Exprent.EXPRENT_NEW: - VarType newType = expr.getExprType(); + VarType newType = ((NewExprent)expr).getNewType(); - res = newType.type == CodeConstants.TYPE_OBJECT && classname.equals(newType.value); + res = newType.getType() == CodeConstants.TYPE_OBJECT && classname.equals(newType.getValue()); break; case Exprent.EXPRENT_VAR: diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java -index 94dc0a33d7eaec052c6f3ce10fbbb93eb5395025..806bec52c8e2c3ea5d8416f3edd6f0e6aa79aeff 100644 +index b085a40522e69c4bb6e69e8abf946ad61e2a2a24..6864b5d55d7029299f9de1ade7e28fb8bf6ace6d 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java @@ -13,7 +13,6 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; @@ -29,7 +29,7 @@ index 94dc0a33d7eaec052c6f3ce10fbbb93eb5395025..806bec52c8e2c3ea5d8416f3edd6f0e6 import java.util.HashMap; import java.util.HashSet; -@@ -25,7 +24,7 @@ public class PPandMMHelper { +@@ -26,7 +25,7 @@ public class PPandMMHelper { private boolean exprentReplaced; private VarProcessor varProc; @@ -38,7 +38,7 @@ index 94dc0a33d7eaec052c6f3ce10fbbb93eb5395025..806bec52c8e2c3ea5d8416f3edd6f0e6 public PPandMMHelper(VarProcessor varProc) { this.varProc = varProc; -@@ -34,10 +33,10 @@ public class PPandMMHelper { +@@ -35,10 +34,10 @@ public class PPandMMHelper { public boolean findPPandMM(RootStatement root) { FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); @@ -51,8 +51,8 @@ index 94dc0a33d7eaec052c6f3ce10fbbb93eb5395025..806bec52c8e2c3ea5d8416f3edd6f0e6 HashSet setVisited = new HashSet<>(); -@@ -57,8 +56,6 @@ public class PPandMMHelper { - stack.addAll(node.succs); +@@ -58,8 +57,6 @@ public class PPandMMHelper { + stack.addAll(node.successors); } - updateVersions(dgraph); @@ -60,7 +60,7 @@ index 94dc0a33d7eaec052c6f3ce10fbbb93eb5395025..806bec52c8e2c3ea5d8416f3edd6f0e6 return res; } -@@ -133,7 +130,7 @@ public class PPandMMHelper { +@@ -134,7 +131,7 @@ public class PPandMMHelper { if (econst.type == Exprent.EXPRENT_CONST && ((ConstExprent)econst).hasValueOne()) { Exprent left = as.getLeft(); @@ -69,7 +69,7 @@ index 94dc0a33d7eaec052c6f3ce10fbbb93eb5395025..806bec52c8e2c3ea5d8416f3edd6f0e6 if (exprsEqual(left, econd) && (midlayer == null || midlayer.equals(condtype))) { FunctionExprent ret = new FunctionExprent( func.getFuncType() == FunctionExprent.FUNCTION_ADD ? FunctionExprent.FUNCTION_PPI : FunctionExprent.FUNCTION_MMI, -@@ -143,7 +140,7 @@ public class PPandMMHelper { +@@ -144,7 +141,7 @@ public class PPandMMHelper { exprentReplaced = true; if (!left.equals(econd)) { @@ -78,15 +78,15 @@ index 94dc0a33d7eaec052c6f3ce10fbbb93eb5395025..806bec52c8e2c3ea5d8416f3edd6f0e6 } return ret; -@@ -171,13 +168,13 @@ public class PPandMMHelper { +@@ -172,13 +169,13 @@ public class PPandMMHelper { VarExprent v1 = (VarExprent)e1; VarExprent v2 = (VarExprent)e2; - return varProc.getVarOriginalIndex(v1.getIndex()) == varProc.getVarOriginalIndex(v2.getIndex()) -- && InterpreterUtil.equalObjects(v1.getVarType(), v2.getVarType()); +- && Objects.equals(v1.getVarType(), v2.getVarType()); + return varProc.getVarOriginalIndex(v1.getIndex()) == varProc.getVarOriginalIndex(v2.getIndex()); + // TODO: Verify the types are in the same 'family' {byte->short->int} -+ // && InterpreterUtil.equalObjects(v1.getVarType(), v2.getVarType()); ++ // && Objects.equals(v1.getVarType(), v2.getVarType()); } @@ -96,7 +96,7 @@ index 94dc0a33d7eaec052c6f3ce10fbbb93eb5395025..806bec52c8e2c3ea5d8416f3edd6f0e6 graph.iterateExprents(new DirectGraph.ExprentIterator() { @Override public int processExprent(Exprent exprent) { -@@ -187,10 +184,9 @@ public class PPandMMHelper { +@@ -188,10 +185,9 @@ public class PPandMMHelper { for (Exprent expr : lst) { if (expr.type == Exprent.EXPRENT_VAR) { VarExprent var = (VarExprent)expr; @@ -111,10 +111,10 @@ index 94dc0a33d7eaec052c6f3ce10fbbb93eb5395025..806bec52c8e2c3ea5d8416f3edd6f0e6 } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -index e97be6c82f048e553b0e24b9311169ea5626e263..71f2ad8417d51eaa564a1813fbd34e1de8b50f94 100644 +index 6542c5adf793250866d9b1d46403084c8db8bc97..cbaf9725b714d7fcccb5b1a149b2acc2be76a888 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -@@ -407,7 +407,12 @@ public class ConstExprent extends Exprent { +@@ -458,7 +458,12 @@ public class ConstExprent extends Exprent { public void getBytecodeRange(BitSet values) { measureBytecode(values); } diff --git a/FernFlower-Patches/0013-JAD-Style-variable-naming.patch b/FernFlower-Patches/0012-JAD-Style-variable-naming.patch similarity index 94% rename from FernFlower-Patches/0013-JAD-Style-variable-naming.patch rename to FernFlower-Patches/0012-JAD-Style-variable-naming.patch index 749a869..cf2854a 100644 --- a/FernFlower-Patches/0013-JAD-Style-variable-naming.patch +++ b/FernFlower-Patches/0012-JAD-Style-variable-naming.patch @@ -5,13 +5,13 @@ Subject: [PATCH] JAD Style variable naming diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -index c4bc77b593859f5f9bceff063414c31bedd1ff82..fe61544581f331327c08f026c6e2edbfdbf6b768 100644 +index b7467530cba1d8e317500a5c213dd6013d00a369..eac80ace801517faca82a3a35ac31b58fdd667ab 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -@@ -868,6 +868,11 @@ public class ClassWriter { - else { - parameterName = methodWrapper.varproc.getVarName(new VarVersionPair(index, 0)); - } +@@ -747,6 +747,11 @@ public class ClassWriter { + buffer.append(' '); + + String parameterName = methodWrapper.varproc.getVarName(pair); + + if ((flags & (CodeConstants.ACC_ABSTRACT | CodeConstants.ACC_NATIVE)) != 0) { + parameterName = methodWrapper.methodStruct.getVariableNamer().renameAbstractParameter(parameterName, index); @@ -21,7 +21,7 @@ index c4bc77b593859f5f9bceff063414c31bedd1ff82..fe61544581f331327c08f026c6e2edbf paramCount++; diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java -index f1dc102772e3cb5aa227057276c95b4402447fab..aff6532ccecce0a06518797f3a3c8a6e5e29aeaa 100644 +index 7db5b328969a6dac49054e57b5c00c672ca4ea85..66414bc3eac6e187e5f45f70bc67b783ad4f1a4a 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -4,6 +4,7 @@ package org.jetbrains.java.decompiler.main; @@ -39,7 +39,7 @@ index f1dc102772e3cb5aa227057276c95b4402447fab..aff6532ccecce0a06518797f3a3c8a6e +import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.main.rels.NestedClassProcessor; import org.jetbrains.java.decompiler.main.rels.NestedMemberAccess; - import org.jetbrains.java.decompiler.modules.decompiler.SwitchHelper; + import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent; @@ -146,6 +148,7 @@ public class ClassesProcessor implements CodeConstants { node.access = cl.getAccessFlags(); mapRootClasses.put(cl.qualifiedName, node); @@ -47,8 +47,8 @@ index f1dc102772e3cb5aa227057276c95b4402447fab..aff6532ccecce0a06518797f3a3c8a6e + linkEnclosingMethods(cl); } - if (bDecompileInner) { -@@ -237,6 +240,25 @@ public class ClassesProcessor implements CodeConstants { + // set non-sealed if class extends or implements a sealed class and is not final or sealed itself +@@ -256,6 +259,25 @@ public class ClassesProcessor implements CodeConstants { } } @@ -82,7 +82,7 @@ index f1dc102772e3cb5aa227057276c95b4402447fab..aff6532ccecce0a06518797f3a3c8a6e for (ClassNode nd : node.nested) { destroyWrappers(nd); -@@ -502,7 +525,7 @@ public class ClassesProcessor implements CodeConstants { +@@ -503,7 +526,7 @@ public class ClassesProcessor implements CodeConstants { anonymousClassType = new VarType(lambda_class_name, true); @@ -91,7 +91,7 @@ index f1dc102772e3cb5aa227057276c95b4402447fab..aff6532ccecce0a06518797f3a3c8a6e if (!is_method_reference) { // content method in the same class, check synthetic flag StructMethod mt = classStruct.getMethod(content_method_name, content_method_descriptor); is_method_reference = !mt.isSynthetic(); // if not synthetic -> method reference -@@ -557,4 +580,4 @@ public class ClassesProcessor implements CodeConstants { +@@ -566,4 +589,4 @@ public class ClassesProcessor implements CodeConstants { public boolean is_content_method_static; } } @@ -99,7 +99,7 @@ index f1dc102772e3cb5aa227057276c95b4402447fab..aff6532ccecce0a06518797f3a3c8a6e \ No newline at end of file +} diff --git a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java -index bf0fe47e7d48b21acd758449b67612e250f19554..95baa7dfec5a9c8dcde30a288499aa127aeffa4b 100644 +index 654d0ddf34821ce4ea800cd5421f6268e2ca3236..bb7b5b4e4a590219939a8f7e883b9c259c1adf73 100644 --- a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java +++ b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java @@ -7,6 +7,7 @@ import org.jetbrains.java.decompiler.main.collectors.ImportCollector; @@ -110,10 +110,10 @@ index bf0fe47e7d48b21acd758449b67612e250f19554..95baa7dfec5a9c8dcde30a288499aa12 import org.jetbrains.java.decompiler.modules.renamer.PoolInterceptor; import org.jetbrains.java.decompiler.struct.StructContext; -@@ -19,12 +20,14 @@ public class DecompilerContext { - public static final String CURRENT_CLASS_NODE = "CURRENT_CLASS_NODE"; +@@ -20,12 +21,14 @@ public class DecompilerContext { public static final String CURRENT_METHOD_WRAPPER = "CURRENT_METHOD_WRAPPER"; public static final String CURRENT_VAR_PROCESSOR = "CURRENT_VAR_PROCESSOR"; + public static final String IN_CLASS_TYPE_PARAMS = "IN_CLASS_TYPE_PARAMS"; + public static final String RENAMER_FACTORY = "RENAMER_FACTORY"; private final Map properties; @@ -125,7 +125,7 @@ index bf0fe47e7d48b21acd758449b67612e250f19554..95baa7dfec5a9c8dcde30a288499aa12 private ImportCollector importCollector; private VarProcessor varProcessor; private CounterContainer counterContainer; -@@ -34,7 +37,8 @@ public class DecompilerContext { +@@ -35,7 +38,8 @@ public class DecompilerContext { IFernflowerLogger logger, StructContext structContext, ClassesProcessor classProcessor, @@ -135,7 +135,7 @@ index bf0fe47e7d48b21acd758449b67612e250f19554..95baa7dfec5a9c8dcde30a288499aa12 Objects.requireNonNull(properties); Objects.requireNonNull(logger); Objects.requireNonNull(structContext); -@@ -45,6 +49,7 @@ public class DecompilerContext { +@@ -46,6 +50,7 @@ public class DecompilerContext { this.structContext = structContext; this.classProcessor = classProcessor; this.poolInterceptor = interceptor; @@ -143,7 +143,7 @@ index bf0fe47e7d48b21acd758449b67612e250f19554..95baa7dfec5a9c8dcde30a288499aa12 this.counterContainer = new CounterContainer(); } -@@ -112,6 +117,10 @@ public class DecompilerContext { +@@ -113,6 +118,10 @@ public class DecompilerContext { return getCurrentContext().poolInterceptor; } @@ -327,7 +327,7 @@ index 0000000000000000000000000000000000000000..fc1d7d67864ab12e894fcdf0ed8e1297 + public IVariableNameProvider createFactory(StructMethod structMethod); +} diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java -index 89f1c9709d9002701c3ec8b4563d345337995dac..20651b7d66ad24404c15378da80bbd47e4178e0f 100644 +index 721c6a83a921b0f382290f3e17bbea5b214b7881..f79794242f3eb9b5000af5fa6b41994ee1b25cd9 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java @@ -2,6 +2,7 @@ @@ -348,8 +348,8 @@ index 89f1c9709d9002701c3ec8b4563d345337995dac..20651b7d66ad24404c15378da80bbd47 import org.jetbrains.java.decompiler.modules.decompiler.stats.CatchAllStatement; import org.jetbrains.java.decompiler.modules.decompiler.stats.CatchStatement; import org.jetbrains.java.decompiler.modules.decompiler.stats.DoStatement; -@@ -19,11 +22,15 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.IfStatement; - import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; +@@ -21,11 +24,15 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; + import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement.StatementType; import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.attr.StructEnclosingMethodAttribute; @@ -364,7 +364,7 @@ index 89f1c9709d9002701c3ec8b4563d345337995dac..20651b7d66ad24404c15378da80bbd47 import java.util.*; import java.util.Map.Entry; -@@ -848,6 +855,53 @@ public class VarDefinitionHelper { +@@ -850,6 +857,53 @@ public class VarDefinitionHelper { for (Entry e : types.entrySet()) { typeNames.put(e.getKey(), e.getValue().getCast()); } @@ -377,7 +377,7 @@ index 89f1c9709d9002701c3ec8b4563d345337995dac..20651b7d66ad24404c15378da80bbd47 + if (exprent.type == Exprent.EXPRENT_VAR) { + VarExprent var = (VarExprent)exprent; + if (var.isClassDef()) { -+ ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(var.getVarType().value); ++ ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(var.getVarType().getValue()); + if (child != null) + methods.addAll(child.classStruct.getMethods()); + } @@ -385,7 +385,7 @@ index 89f1c9709d9002701c3ec8b4563d345337995dac..20651b7d66ad24404c15378da80bbd47 + else if (exprent.type == Exprent.EXPRENT_NEW) { + NewExprent _new = (NewExprent)exprent; + if (_new.isAnonymous()) { //TODO: Check for Lambda here? -+ ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(_new.getNewType().value); ++ ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(_new.getNewType().getValue()); + if (child != null) { + if (_new.isLambda()) { + if (child.lambdaInformation.is_method_reference) { @@ -418,7 +418,7 @@ index 89f1c9709d9002701c3ec8b4563d345337995dac..20651b7d66ad24404c15378da80bbd47 Map lvts = new HashMap<>(); for (Entry e : types.entrySet()) { -@@ -857,7 +911,16 @@ public class VarDefinitionHelper { +@@ -859,7 +913,16 @@ public class VarDefinitionHelper { continue; } LocalVariable lvt = e.getValue().getLVT(); @@ -435,17 +435,17 @@ index 89f1c9709d9002701c3ec8b4563d345337995dac..20651b7d66ad24404c15378da80bbd47 varproc.setVarLVT(idx, lvt); lvts.put(idx, lvt); } -@@ -991,7 +1054,7 @@ public class VarDefinitionHelper { +@@ -993,7 +1056,7 @@ public class VarDefinitionHelper { private VarInfo(LocalVariable lvt, VarType type) { if (lvt != null && lvt.getSignature() != null) -- this.cast = ExprProcessor.getCastTypeName(GenericType.parse(lvt.getSignature()), true); -+ this.cast = ExprProcessor.getCastTypeName(GenericType.parse(lvt.getSignature()), false); +- this.cast = ExprProcessor.getCastTypeName(GenericType.parse(lvt.getSignature()), true, Collections.emptyList()); ++ this.cast = ExprProcessor.getCastTypeName(GenericType.parse(lvt.getSignature()), false, Collections.emptyList()); else if (lvt != null) - this.cast = ExprProcessor.getCastTypeName(lvt.getVarType(), false); + this.cast = ExprProcessor.getCastTypeName(lvt.getVarType(), false, Collections.emptyList()); else if (type != null) diff --git a/src/org/jetbrains/java/decompiler/struct/StructMethod.java b/src/org/jetbrains/java/decompiler/struct/StructMethod.java -index 61984e6af43043db7fd29c1b79e16e67789ca707..b9ea275781604d74bb0f4f452ff554d79d8f68fd 100644 +index e3d5edf6e78c37206e5a37abaf24efbb6eb6dfa3..7237f2527530d8dea8d82f934c273c980ada0682 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMethod.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMethod.java @@ -4,6 +4,7 @@ package org.jetbrains.java.decompiler.struct; @@ -456,7 +456,7 @@ index 61984e6af43043db7fd29c1b79e16e67789ca707..b9ea275781604d74bb0f4f452ff554d7 import org.jetbrains.java.decompiler.struct.attr.StructCodeAttribute; import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; import org.jetbrains.java.decompiler.struct.attr.StructGenericSignatureAttribute; -@@ -18,6 +19,7 @@ import java.io.IOException; +@@ -20,6 +21,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -464,7 +464,7 @@ index 61984e6af43043db7fd29c1b79e16e67789ca707..b9ea275781604d74bb0f4f452ff554d7 import static org.jetbrains.java.decompiler.code.CodeConstants.*; -@@ -70,6 +72,8 @@ public class StructMethod extends StructMember { +@@ -72,6 +74,8 @@ public class StructMethod extends StructMember { private boolean expanded = false; private final String classQualifiedName; private final GenericMethodDescriptor signature; @@ -473,7 +473,7 @@ index 61984e6af43043db7fd29c1b79e16e67789ca707..b9ea275781604d74bb0f4f452ff554d7 private StructMethod(int accessFlags, Map attributes, -@@ -382,6 +386,17 @@ public class StructMethod extends StructMember { +@@ -384,6 +388,17 @@ public class StructMethod extends StructMember { return seq; } @@ -493,7 +493,7 @@ index 61984e6af43043db7fd29c1b79e16e67789ca707..b9ea275781604d74bb0f4f452ff554d7 } diff --git a/src/org/jetbrains/java/decompiler/util/JADNameProvider.java b/src/org/jetbrains/java/decompiler/util/JADNameProvider.java new file mode 100644 -index 0000000000000000000000000000000000000000..5607fa993848027c570ad414c8098bf0be28868c +index 0000000000000000000000000000000000000000..e7073956c555e710b18f0495a4166e911cb50de7 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/JADNameProvider.java @@ -0,0 +1,215 @@ @@ -614,7 +614,7 @@ index 0000000000000000000000000000000000000000..5607fa993848027c570ad414c8098bf0 + + MethodDescriptor md = MethodDescriptor.parseDescriptor(this.method.getDescriptor()); + for (VarType param : md.params) { -+ params += param.stackSize; ++ params += param.getStackSize(); + } + + List keys = new ArrayList(entries.keySet()); diff --git a/FernFlower-Patches/0014-Fix-primitive-un-boxing-issues.patch b/FernFlower-Patches/0013-Fix-primitive-un-boxing-issues.patch similarity index 86% rename from FernFlower-Patches/0014-Fix-primitive-un-boxing-issues.patch rename to FernFlower-Patches/0013-Fix-primitive-un-boxing-issues.patch index 823b18a..dcb0562 100644 --- a/FernFlower-Patches/0014-Fix-primitive-un-boxing-issues.patch +++ b/FernFlower-Patches/0013-Fix-primitive-un-boxing-issues.patch @@ -5,35 +5,35 @@ Subject: [PATCH] Fix primitive un/boxing issues. diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -index 03a59cb999d3d05d647128c96007e9743938a0ea..474ffda1b9d610968bd12160f2153713b37f2db9 100644 +index c592f0d58d1048de416eb2cefd6fcf76f2fb97fd..b7d58645dd21d12c16d4efba9604c46614683c35 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -@@ -876,12 +876,14 @@ public class ExprProcessor implements CodeConstants { +@@ -1032,12 +1032,14 @@ public class ExprProcessor implements CodeConstants { if (unbox) { // "unbox" invocation parameters, e.g. 'byteSet.add((byte)123)' or 'new ShortContainer((short)813)' - if (exprent.type == Exprent.EXPRENT_INVOCATION && ((InvocationExprent)exprent).isBoxingCall()) { - InvocationExprent invocationExprent = (InvocationExprent)exprent; -- exprent = invocationExprent.getLstParameters().get(0); -- int paramType = invocationExprent.getDescriptor().params[0].type; -- if (exprent.type == Exprent.EXPRENT_CONST && ((ConstExprent)exprent).getConstType().type != paramType) { +- exprent = invocationExprent.getParameters().get(0); +- int paramType = invocationExprent.getDescriptor().params[0].getType(); +- if (exprent.type == Exprent.EXPRENT_CONST && ((ConstExprent)exprent).getConstType().getType() != paramType) { - leftType = new VarType(paramType); + if (exprent.type == Exprent.EXPRENT_INVOCATION) { + InvocationExprent invocationExprent = (InvocationExprent) exprent; + if (invocationExprent.isBoxingCall() && !invocationExprent.shouldForceBoxing()) { -+ exprent = invocationExprent.getLstParameters().get(0); -+ int paramType = invocationExprent.getDescriptor().params[0].type; -+ if (exprent.type == Exprent.EXPRENT_CONST && ((ConstExprent) exprent).getConstType().type != paramType) { ++ exprent = invocationExprent.getParameters().get(0); ++ int paramType = invocationExprent.getDescriptor().params[0].getType(); ++ if (exprent.type == Exprent.EXPRENT_CONST && ((ConstExprent) exprent).getConstType().getType() != paramType) { + leftType = new VarType(paramType); + } } } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java -index 161f55c45a3f2c199fcc24b9fdd1bd269bafbfb8..068e44b80f9972be77bfd9fe095a5549edf40a2f 100644 +index c45050559cace73741f7529254e1483c81b747c7..a44200c04618f80d9d845cd15087678635913a3a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java -@@ -566,6 +566,19 @@ public class FunctionExprent extends Exprent { +@@ -564,6 +564,19 @@ public class FunctionExprent extends Exprent { } if (funcType <= FUNCTION_I2S) { @@ -51,14 +51,14 @@ index 161f55c45a3f2c199fcc24b9fdd1bd269bafbfb8..068e44b80f9972be77bfd9fe095a5549 + } + } return wrapOperandString(lstOperands.get(0), true, indent, tracer).prepend("(" + ExprProcessor.getTypeName( - TYPES[funcType - FUNCTION_I2L]) + ")"); + TYPES[funcType - FUNCTION_I2L], Collections.emptyList()) + ")"); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -index d72870ee498d9da075a08dc6e2afef906ba44ad2..a557614a3a59a270f2a6917b5eb0cf9046db98e8 100644 +index 54c7d1fb9150754ba9daa09f4f24aa41c86387a8..b5fd9e7e8c6941b69440d9f916cb6bdd6e211195 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -59,6 +59,8 @@ public class InvocationExprent extends Exprent { - private List lstParameters = new ArrayList<>(); + private List parameters = new ArrayList<>(); private List bootstrapArguments; private List genericArgs = new ArrayList<>(); + private boolean forceBoxing = false; @@ -66,7 +66,7 @@ index d72870ee498d9da075a08dc6e2afef906ba44ad2..a557614a3a59a270f2a6917b5eb0cf90 public InvocationExprent() { super(EXPRENT_INVOCATION); -@@ -261,10 +263,10 @@ public class InvocationExprent extends Exprent { +@@ -263,10 +265,10 @@ public class InvocationExprent extends Exprent { } if (isStatic) { @@ -74,19 +74,19 @@ index d72870ee498d9da075a08dc6e2afef906ba44ad2..a557614a3a59a270f2a6917b5eb0cf90 + if (isBoxingCall() && canIgnoreBoxing && !forceBoxing) { // process general "boxing" calls, e.g. 'Object[] data = { true }' or 'Byte b = 123' // here 'byte' and 'short' values do not need an explicit narrowing type cast -- ExprProcessor.getCastedExprent(lstParameters.get(0), descriptor.params[0], buf, indent, false, false, false, false, tracer); -+ ExprProcessor.getCastedExprent(lstParameters.get(0), descriptor.params[0], buf, indent, false, false, true, false, tracer); +- ExprProcessor.getCastedExprent(parameters.get(0), descriptor.params[0], buf, indent, false, false, false, false, tracer); ++ ExprProcessor.getCastedExprent(parameters.get(0), descriptor.params[0], buf, indent, false, false, true, false, tracer); return buf; } -@@ -310,16 +312,36 @@ public class InvocationExprent extends Exprent { +@@ -312,16 +314,36 @@ public class InvocationExprent extends Exprent { TextUtil.writeQualifiedSuper(buf, super_qualifier); } else if (instance != null) { - TextBuffer res = instance.toJava(indent, tracer); - - if (isUnboxingCall()) { -+ VarType leftType = new VarType(CodeConstants.TYPE_OBJECT, 0, classname); ++ VarType leftType = new VarType(CodeConstants.TYPE_OBJECT, 0, className); + if (isUnboxingCall() && !forceUnboxing) { // we don't print the unboxing call - no need to bother with the instance wrapping / casting - buf.append(res); @@ -98,9 +98,9 @@ index d72870ee498d9da075a08dc6e2afef906ba44ad2..a557614a3a59a270f2a6917b5eb0cf90 + + if (func.getLstOperands().get(0).type == Exprent.EXPRENT_VAR) { + VarType inferred = func.getLstOperands().get(0).getInferredExprType(leftType); -+ skipCast = inferred.type != CodeConstants.TYPE_OBJECT || -+ DecompilerContext.getStructContext().instanceOf(inferred.value, this.classname); -+ } else if (this.classname.equals(_const.getConstType().value)) { ++ skipCast = inferred.getType() != CodeConstants.TYPE_OBJECT || ++ DecompilerContext.getStructContext().instanceOf(inferred.getValue(), this.className); ++ } else if (this.className.equals(_const.getConstType().getValue())) { + skipCast = true; + } + @@ -117,19 +117,19 @@ index d72870ee498d9da075a08dc6e2afef906ba44ad2..a557614a3a59a270f2a6917b5eb0cf90 + TextBuffer res = instance.toJava(indent, tracer); + VarType rightType = instance.getExprType(); -- VarType leftType = new VarType(CodeConstants.TYPE_OBJECT, 0, classname); +- VarType leftType = new VarType(CodeConstants.TYPE_OBJECT, 0, className); if (rightType.equals(VarType.VARTYPE_OBJECT) && !leftType.equals(rightType)) { - buf.append("((").append(ExprProcessor.getCastTypeName(leftType)).append(")"); -@@ -417,8 +439,87 @@ public class InvocationExprent extends Exprent { + buf.append("((").append(ExprProcessor.getCastTypeName(leftType, Collections.emptyList())).append(")"); +@@ -419,9 +441,88 @@ public class InvocationExprent extends Exprent { } } - boolean firstParameter = true; int start = isEnum ? 2 : 0; -+ List parameters = new ArrayList<>(lstParameters); ++ List parameters = new ArrayList<>(this.parameters); + VarType[] types = Arrays.copyOf(descriptor.params, descriptor.params.length); -+ for (int i = start; i < parameters.size(); i++) { + for (int i = start; i < parameters.size(); i++) { + Exprent par = parameters.get(i); + if (par.type == Exprent.EXPRENT_INVOCATION) { + InvocationExprent inv = (InvocationExprent)par; @@ -137,19 +137,19 @@ index d72870ee498d9da075a08dc6e2afef906ba44ad2..a557614a3a59a270f2a6917b5eb0cf90 + //However, we must make sure we don't accidentally make the call ambiguous. + //An example being List, remove(Integer.valueOf(1)) and remove(1) are different functions + if (inv.isBoxingCall()) { -+ Exprent value = inv.lstParameters.get(0); ++ Exprent value = inv.parameters.get(0); + types[i] = value.getExprType(); //Infer? + //Unboxing in this case is lossy, so we need to explicitly set the type -+ if (types[i].typeFamily == CodeConstants.TYPE_FAMILY_INTEGER) { ++ if (types[i].getTypeFamily() == CodeConstants.TYPE_FAMILY_INTEGER) { + types[i] = -+ "java/lang/Short".equals(inv.classname) ? VarType.VARTYPE_SHORT : -+ "java/lang/Byte".equals(inv.classname) ? VarType.VARTYPE_BYTE : -+ "java/lang/Integer".equals(inv.classname) ? VarType.VARTYPE_INT : ++ "java/lang/Short".equals(inv.className) ? VarType.VARTYPE_SHORT : ++ "java/lang/Byte".equals(inv.className) ? VarType.VARTYPE_BYTE : ++ "java/lang/Integer".equals(inv.className) ? VarType.VARTYPE_INT : + VarType.VARTYPE_CHAR; + } + + int count = 0; -+ StructClass stClass = DecompilerContext.getStructContext().getClass(classname); ++ StructClass stClass = DecompilerContext.getStructContext().getClass(className); + if (stClass != null) { + nextMethod: + for (StructMethod mt : stClass.getMethods()) { @@ -157,8 +157,8 @@ index d72870ee498d9da075a08dc6e2afef906ba44ad2..a557614a3a59a270f2a6917b5eb0cf90 + MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); + if (md.params.length == descriptor.params.length) { + for (int x = 0; x < md.params.length; x++) { -+ if (md.params[x].typeFamily != descriptor.params[x].typeFamily && -+ md.params[x].typeFamily != types[x].typeFamily) { ++ if (md.params[x].getTypeFamily() != descriptor.params[x].getTypeFamily() && ++ md.params[x].getTypeFamily() != types[x].getTypeFamily()) { + continue nextMethod; + } + } @@ -185,14 +185,14 @@ index d72870ee498d9da075a08dc6e2afef906ba44ad2..a557614a3a59a270f2a6917b5eb0cf90 + // Right now it just do a quick check, but a proper check would be to do compiler like inference of argument + // types, and check unboxing as needed. Currently it causes some false forces + else if (inv.isUnboxingCall() && !inv.shouldForceUnboxing()) { -+ StructClass stClass = DecompilerContext.getStructContext().getClass(classname); ++ StructClass stClass = DecompilerContext.getStructContext().getClass(className); + if (stClass != null) { + for (StructMethod mt : stClass.getMethods()) { + if (name.equals(mt.getName()) && !stringDescriptor.equals(mt.getDescriptor())) { + MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); + if (md.params.length == descriptor.params.length) { -+ if (md.params[i].type == CodeConstants.TYPE_OBJECT) { -+ if (DecompilerContext.getStructContext().instanceOf(inv.getInstance().getExprType().value, md.params[i].value)) { ++ if (md.params[i].getType() == CodeConstants.TYPE_OBJECT) { ++ if (DecompilerContext.getStructContext().instanceOf(inv.getInstance().getExprType().getValue(), md.params[i].getValue())) { + inv.forceUnboxing(true); + break; + } @@ -207,29 +207,30 @@ index d72870ee498d9da075a08dc6e2afef906ba44ad2..a557614a3a59a270f2a6917b5eb0cf90 + + + boolean firstParameter = true; - for (int i = start; i < lstParameters.size(); i++) { ++ for (int i = start; i < this.parameters.size(); i++) { if (mask == null || mask.get(i) == null) { TextBuffer buff = new TextBuffer(); -@@ -453,7 +554,7 @@ public class InvocationExprent extends Exprent { + boolean ambiguous = setAmbiguousParameters.get(i); +@@ -455,7 +556,7 @@ public class InvocationExprent extends Exprent { */ // 'byte' and 'short' literals need an explicit narrowing type cast when used as a parameter -- ExprProcessor.getCastedExprent(lstParameters.get(i), descriptor.params[i], buff, indent, true, ambiguous, true, true, tracer); -+ ExprProcessor.getCastedExprent(lstParameters.get(i), types[i], buff, indent, true, ambiguous, true, true, tracer); +- ExprProcessor.getCastedExprent(parameters.get(i), descriptor.params[i], buff, indent, true, ambiguous, true, true, tracer); ++ ExprProcessor.getCastedExprent(this.parameters.get(i), types[i], buff, indent, true, ambiguous, true, true, tracer); // the last "new Object[0]" in the vararg call is not printed if (buff.length() > 0) { -@@ -506,7 +607,7 @@ public class InvocationExprent extends Exprent { +@@ -508,7 +609,7 @@ public class InvocationExprent extends Exprent { } if (paramType == CodeConstants.TYPE_BYTECHAR || paramType == CodeConstants.TYPE_SHORTCHAR) { -- if (classname.equals("java/lang/Character")) { -+ if (classname.equals("java/lang/Character") || classname.equals("java/lang/Short")) { +- if (className.equals("java/lang/Character")) { ++ if (className.equals("java/lang/Character") || className.equals("java/lang/Short")) { return true; } } -@@ -565,6 +666,18 @@ public class InvocationExprent extends Exprent { - return !isStatic && lstParameters.size() == 0 && classname.equals(UNBOXING_METHODS.get(name)); +@@ -570,6 +671,18 @@ public class InvocationExprent extends Exprent { + return !isStatic && parameters.size() == 0 && className.equals(UNBOXING_METHODS.get(name)); } + public boolean shouldForceBoxing() { @@ -246,19 +247,19 @@ index d72870ee498d9da075a08dc6e2afef906ba44ad2..a557614a3a59a270f2a6917b5eb0cf90 + private List getMatchedDescriptors() { List matches = new ArrayList<>(); - StructClass cl = DecompilerContext.getStructContext().getClass(classname); -@@ -594,6 +707,8 @@ public class InvocationExprent extends Exprent { + StructClass cl = DecompilerContext.getStructContext().getClass(className); +@@ -599,6 +712,8 @@ public class InvocationExprent extends Exprent { return EMPTY_BIT_SET; } -+ BitSet missed = new BitSet(lstParameters.size()); ++ BitSet missed = new BitSet(parameters.size()); + // check if a call is unambiguous StructMethod mt = cl.getMethod(InterpreterUtil.makeUniqueKey(name, stringDescriptor)); if (mt != null) { -@@ -603,18 +718,50 @@ public class InvocationExprent extends Exprent { +@@ -608,18 +723,50 @@ public class InvocationExprent extends Exprent { for (int i = 0; i < md.params.length; i++) { - if (!md.params[i].equals(lstParameters.get(i).getExprType())) { + if (!md.params[i].equals(parameters.get(i).getExprType())) { exact = false; - break; + missed.set(i); @@ -272,8 +273,8 @@ index d72870ee498d9da075a08dc6e2afef906ba44ad2..a557614a3a59a270f2a6917b5eb0cf90 + for (StructMethod mtt : matches) { + boolean failed = false; + MethodDescriptor md = MethodDescriptor.parseDescriptor(mtt.getDescriptor()); -+ for (int i = 0; i < lstParameters.size(); i++) { -+ VarType ptype = lstParameters.get(i).getExprType(); ++ for (int i = 0; i < parameters.size(); i++) { ++ VarType ptype = parameters.get(i).getExprType(); + if (!missed.get(i)) { + if (!md.params[i].equals(ptype)) { + failed = true; @@ -281,9 +282,9 @@ index d72870ee498d9da075a08dc6e2afef906ba44ad2..a557614a3a59a270f2a6917b5eb0cf90 + } + } + else { -+ if (md.params[i].type == CodeConstants.TYPE_OBJECT) { -+ if (ptype.type != CodeConstants.TYPE_NULL) { -+ if (!DecompilerContext.getStructContext().instanceOf(ptype.value, md.params[i].value)) { ++ if (md.params[i].getType() == CodeConstants.TYPE_OBJECT) { ++ if (ptype.getType() != CodeConstants.TYPE_NULL) { ++ if (!DecompilerContext.getStructContext().instanceOf(ptype.getValue(), md.params[i].getValue())) { + failed = true; + break; + } @@ -310,7 +311,7 @@ index d72870ee498d9da075a08dc6e2afef906ba44ad2..a557614a3a59a270f2a6917b5eb0cf90 GenericMethodDescriptor gen = mtt.getSignature(); //TODO: Find synthetic flags for params, as Enum generic signatures do no contain the String,int params if (gen != null && gen.parameterTypes.size() > i && gen.parameterTypes.get(i).isGeneric()) { diff --git a/testData/results/TestPrimitives.dec b/testData/results/TestPrimitives.dec -index a7d1557e6814e071df65c610fbdae860c8ff93bc..07e818e12a3a4371d3cb76ab613b119837332525 100644 +index dcbf031b69cc65b108a2cba8f894d02027372032..0f74573b4b8df58023a80b059dcf6930fd08fabf 100644 --- a/testData/results/TestPrimitives.dec +++ b/testData/results/TestPrimitives.dec @@ -3,6 +3,26 @@ package pkg; diff --git a/FernFlower-Patches/0015-Add-Minecraft-test-framework.patch b/FernFlower-Patches/0014-Add-Minecraft-test-framework.patch similarity index 100% rename from FernFlower-Patches/0015-Add-Minecraft-test-framework.patch rename to FernFlower-Patches/0014-Add-Minecraft-test-framework.patch diff --git a/FernFlower-Patches/0016-Add-better-debug-logging.patch b/FernFlower-Patches/0015-Add-better-debug-logging.patch similarity index 82% rename from FernFlower-Patches/0016-Add-better-debug-logging.patch rename to FernFlower-Patches/0015-Add-better-debug-logging.patch index ee5da8f..d6da986 100644 --- a/FernFlower-Patches/0016-Add-better-debug-logging.patch +++ b/FernFlower-Patches/0015-Add-better-debug-logging.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add better debug logging diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -index fe61544581f331327c08f026c6e2edbfdbf6b768..1188d69d3328702779a4b21336d4eb1414d96493 100644 +index eac80ace801517faca82a3a35ac31b58fdd667ab..17dc8a4a5d4e3164337f6d05ab1e00576191a0ca 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -@@ -939,7 +939,7 @@ public class ClassWriter { +@@ -820,7 +820,7 @@ public class ClassWriter { tracer.addTracer(codeTracer); } catch (Throwable t) { @@ -18,10 +18,10 @@ index fe61544581f331327c08f026c6e2edbfdbf6b768..1188d69d3328702779a4b21336d4eb14 methodWrapper.decompiledWithErrors = true; } diff --git a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java -index 438b04c518f193ac3b229701ddfdaf7cde5cad6e..9ce662b88d6a7406784b8aa1b4e1dc6700cebaa6 100644 +index e32253528718631cd622d6af4ede4a85ff4af061..1910404be55e21448b74caf4d7682ade09a2a1b1 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java +++ b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java -@@ -122,7 +122,7 @@ public class ClassWrapper { +@@ -111,7 +111,7 @@ public class ClassWrapper { } } catch (Throwable t) { @@ -31,7 +31,7 @@ index 438b04c518f193ac3b229701ddfdaf7cde5cad6e..9ce662b88d6a7406784b8aa1b4e1dc67 isError = true; } diff --git a/src/org/jetbrains/java/decompiler/struct/StructContext.java b/src/org/jetbrains/java/decompiler/struct/StructContext.java -index 36d1d6c4ae8e3b9f1a64dae514d9efa65722033a..7c91206d1b64b9873fa24d6d3ad38e736413c0a3 100644 +index 301737310f3d346cc2229395551d504a34cb6dbc..b039480288011a5b9bdca635f7c66e85c92eb311 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructContext.java +++ b/src/org/jetbrains/java/decompiler/struct/StructContext.java @@ -3,6 +3,7 @@ package org.jetbrains.java.decompiler.struct; @@ -59,20 +59,10 @@ index 36d1d6c4ae8e3b9f1a64dae514d9efa65722033a..7c91206d1b64b9873fa24d6d3ad38e73 classes.put(cl.qualifiedName, cl); unit.addClass(cl, name); diff --git a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java -index 1dedf68f53090579fc197d85800b4f7b62d9a1e6..02736cc932eee86708997bbfa919d2041ddfee21 100644 +index 2133783e40306b0c7a78db9f04ff079e341ece6a..489a71c0635dcf579bed3e8b4ce56d882b2f0108 100644 --- a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java +++ b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java -@@ -87,6 +87,9 @@ public class ConstantPool implements NewClassNameBuilder { - pool.add(new LinkConstant(tag, in.readUnsignedByte(), in.readUnsignedShort())); - nextPass[2].set(i); - break; -+ -+ default: -+ throw new RuntimeException("Invalid Constant Pool entry #" + i + " Type: " + tag); - } - } - -@@ -106,7 +109,8 @@ public class ConstantPool implements NewClassNameBuilder { +@@ -113,7 +113,8 @@ public class ConstantPool implements NewClassNameBuilder { int size = in.readUnsignedShort(); for (int i = 1; i < size; i++) { @@ -82,7 +72,7 @@ index 1dedf68f53090579fc197d85800b4f7b62d9a1e6..02736cc932eee86708997bbfa919d204 case CodeConstants.CONSTANT_Utf8: in.readUTF(); break; -@@ -130,11 +134,17 @@ public class ConstantPool implements NewClassNameBuilder { +@@ -138,11 +139,17 @@ public class ConstantPool implements NewClassNameBuilder { case CodeConstants.CONSTANT_Class: case CodeConstants.CONSTANT_String: case CodeConstants.CONSTANT_MethodType: diff --git a/FernFlower-Patches/0017-Add-new-command-line-argument-sef-SkipExtraFiles-To-.patch b/FernFlower-Patches/0016-Add-new-command-line-argument-sef-SkipExtraFiles-To-.patch similarity index 100% rename from FernFlower-Patches/0017-Add-new-command-line-argument-sef-SkipExtraFiles-To-.patch rename to FernFlower-Patches/0016-Add-new-command-line-argument-sef-SkipExtraFiles-To-.patch diff --git a/FernFlower-Patches/0018-Bugfix-Fix-invalid-logic-in-ExprUtils.-https-github..patch b/FernFlower-Patches/0017-Bugfix-Fix-invalid-logic-in-ExprUtils.-https-github..patch similarity index 100% rename from FernFlower-Patches/0018-Bugfix-Fix-invalid-logic-in-ExprUtils.-https-github..patch rename to FernFlower-Patches/0017-Bugfix-Fix-invalid-logic-in-ExprUtils.-https-github..patch diff --git a/FernFlower-Patches/0019-Enhance-Generic-Invocations-Temporarily.patch b/FernFlower-Patches/0018-Enhance-Generic-Invocations-Temporarily.patch similarity index 81% rename from FernFlower-Patches/0019-Enhance-Generic-Invocations-Temporarily.patch rename to FernFlower-Patches/0018-Enhance-Generic-Invocations-Temporarily.patch index 9503888..39fea9d 100644 --- a/FernFlower-Patches/0019-Enhance-Generic-Invocations-Temporarily.patch +++ b/FernFlower-Patches/0018-Enhance-Generic-Invocations-Temporarily.patch @@ -6,28 +6,28 @@ Subject: [PATCH] Enhance Generic Invocations Temporarily. This is a temp separate patch until I get some time to merge it to patch 10/13. diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java -index 4aeda0e0c459d4956971b3298b8a4cd6f9424e0c..58c3471ff26529c091a44670828d272755e75f7d 100644 +index afc26187d4b7916f5c8fa284a940f19a8c996702..d87e027fe9f3a7310d024b3ecda066d546f0a370 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java @@ -266,11 +266,11 @@ public abstract class Exprent implements IMatchable { protected void wrapInCast(VarType left, VarType right, TextBuffer buf, int precedence) { - boolean needsCast = !left.isSuperset(right) && (right.equals(VarType.VARTYPE_OBJECT) || left.type != CodeConstants.TYPE_OBJECT); + boolean needsCast = !left.isSuperset(right) && (right.equals(VarType.VARTYPE_OBJECT) || left.getType() != CodeConstants.TYPE_OBJECT); - if (left != null && left.isGeneric()) { + if (left.isGeneric() || right.isGeneric()) { Map> names = this.getNamedGenerics(); int arrayDim = 0; -- if (left.arrayDim == right.arrayDim) { -+ if (left.arrayDim == right.arrayDim && left.arrayDim > 0) { - arrayDim = left.arrayDim; +- if (left.getArrayDim() == right.getArrayDim()) { ++ if (left.getArrayDim() == right.getArrayDim() && left.getArrayDim() > 0) { + arrayDim = left.getArrayDim(); left = left.resizeArrayDim(0); right = right.resizeArrayDim(0); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java -index 068e44b80f9972be77bfd9fe095a5549edf40a2f..8f69e433dce5541e5f42693c67fbb9f8610821d2 100644 +index a44200c04618f80d9d845cd15087678635913a3a..a735a13e50d76c15800b14d0dd589d2db6947b6e 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java -@@ -7,6 +7,8 @@ import org.jetbrains.java.decompiler.code.CodeConstants; +@@ -5,6 +5,8 @@ import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.util.TextBuffer; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; @@ -36,7 +36,7 @@ index 068e44b80f9972be77bfd9fe095a5549edf40a2f..8f69e433dce5541e5f42693c67fbb9f8 import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult; import org.jetbrains.java.decompiler.struct.gen.VarType; -@@ -302,11 +304,11 @@ public class FunctionExprent extends Exprent { +@@ -299,11 +301,11 @@ public class FunctionExprent extends Exprent { VarType right = lstOperands.get(0).getInferredExprType(upperBound); VarType cast = lstOperands.get(1).getExprType(); @@ -45,17 +45,17 @@ index 068e44b80f9972be77bfd9fe095a5549edf40a2f..8f69e433dce5541e5f42693c67fbb9f8 Map> names = this.getNamedGenerics(); int arrayDim = 0; -- if (upperBound.arrayDim == right.arrayDim) { -+ if (upperBound.arrayDim == right.arrayDim && upperBound.arrayDim > 0) { - arrayDim = upperBound.arrayDim; +- if (upperBound.getArrayDim() == right.getArrayDim()) { ++ if (upperBound.getArrayDim() == right.getArrayDim() && upperBound.getArrayDim() > 0) { + arrayDim = upperBound.getArrayDim(); upperBound = upperBound.resizeArrayDim(0); right = right.resizeArrayDim(0); -@@ -326,6 +328,15 @@ public class FunctionExprent extends Exprent { +@@ -323,6 +325,15 @@ public class FunctionExprent extends Exprent { this.needsCast = false; } } + else { -+ this.needsCast = right.type == CodeConstants.TYPE_NULL || !DecompilerContext.getStructContext().instanceOf(right.value, upperBound.value); ++ this.needsCast = right.getType() == CodeConstants.TYPE_NULL || !DecompilerContext.getStructContext().instanceOf(right.getValue(), upperBound.getValue()); + } + if (!this.needsCast) { + if (arrayDim > 0) { @@ -65,9 +65,9 @@ index 068e44b80f9972be77bfd9fe095a5549edf40a2f..8f69e433dce5541e5f42693c67fbb9f8 + } } else { //TODO: Capture generics to make cast better? - this.needsCast = right.type == CodeConstants.TYPE_NULL || !DecompilerContext.getStructContext().instanceOf(right.value, cast.value); -@@ -583,7 +594,7 @@ public class FunctionExprent extends Exprent { - TYPES[funcType - FUNCTION_I2L]) + ")"); + this.needsCast = right.getType() == CodeConstants.TYPE_NULL || !DecompilerContext.getStructContext().instanceOf(right.getValue(), cast.getValue()); +@@ -581,7 +592,7 @@ public class FunctionExprent extends Exprent { + TYPES[funcType - FUNCTION_I2L], Collections.emptyList()) + ")"); } - // return ""; @@ -75,7 +75,7 @@ index 068e44b80f9972be77bfd9fe095a5549edf40a2f..8f69e433dce5541e5f42693c67fbb9f8 throw new RuntimeException("invalid function"); } -@@ -664,7 +675,7 @@ public class FunctionExprent extends Exprent { +@@ -662,7 +673,7 @@ public class FunctionExprent extends Exprent { measureBytecode(values, lstOperands); measureBytecode(values); } @@ -84,7 +84,7 @@ index 068e44b80f9972be77bfd9fe095a5549edf40a2f..8f69e433dce5541e5f42693c67fbb9f8 // ***************************************************************************** // IMatchable implementation // ***************************************************************************** -@@ -678,4 +689,4 @@ public class FunctionExprent extends Exprent { +@@ -676,4 +687,4 @@ public class FunctionExprent extends Exprent { Integer type = (Integer)matchNode.getRuleValue(MatchProperties.EXPRENT_FUNCTYPE); return type == null || this.funcType == type; } @@ -92,10 +92,10 @@ index 068e44b80f9972be77bfd9fe095a5549edf40a2f..8f69e433dce5541e5f42693c67fbb9f8 \ No newline at end of file +} diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -index a557614a3a59a270f2a6917b5eb0cf9046db98e8..9d4eae94966f13ef56e710f53f67f84ef5a50cd3 100644 +index b5fd9e7e8c6941b69440d9f916cb6bdd6e211195..da71a1497ceb262e80617c525886da7db85e02b3 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -@@ -406,6 +406,7 @@ public class InvocationExprent extends Exprent { +@@ -408,6 +408,7 @@ public class InvocationExprent extends Exprent { isEnum = newNode.classStruct.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM); } } @@ -103,7 +103,7 @@ index a557614a3a59a270f2a6917b5eb0cf9046db98e8..9d4eae94966f13ef56e710f53f67f84e List matches = getMatchedDescriptors(); BitSet setAmbiguousParameters = getAmbiguousParameters(matches); StructMethod desc = null; -@@ -466,7 +467,7 @@ public class InvocationExprent extends Exprent { +@@ -468,7 +469,7 @@ public class InvocationExprent extends Exprent { if (stClass != null) { nextMethod: for (StructMethod mt : stClass.getMethods()) { @@ -112,21 +112,21 @@ index a557614a3a59a270f2a6917b5eb0cf9046db98e8..9d4eae94966f13ef56e710f53f67f84e MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); if (md.params.length == descriptor.params.length) { for (int x = 0; x < md.params.length; x++) { -@@ -501,7 +502,7 @@ public class InvocationExprent extends Exprent { - StructClass stClass = DecompilerContext.getStructContext().getClass(classname); +@@ -503,7 +504,7 @@ public class InvocationExprent extends Exprent { + StructClass stClass = DecompilerContext.getStructContext().getClass(className); if (stClass != null) { for (StructMethod mt : stClass.getMethods()) { - if (name.equals(mt.getName()) && !stringDescriptor.equals(mt.getDescriptor())) { + if (name.equals(mt.getName()) && (currCls == null || canAccess(currCls.classStruct, mt)) && !stringDescriptor.equals(mt.getDescriptor())) { MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); if (md.params.length == descriptor.params.length) { - if (md.params[i].type == CodeConstants.TYPE_OBJECT) { -@@ -518,6 +519,22 @@ public class InvocationExprent extends Exprent { + if (md.params[i].getType() == CodeConstants.TYPE_OBJECT) { +@@ -520,6 +521,22 @@ public class InvocationExprent extends Exprent { } } + if (instance != null && !genArgs.isEmpty()) { -+ StructClass stClass = DecompilerContext.getStructContext().getClass(classname); ++ StructClass stClass = DecompilerContext.getStructContext().getClass(className); + StructMethod me = stClass.getMethodRecursive(getName(), getStringDescriptor()); + if (me != null && me.getSignature() != null) { + for (int x = 0; x < types.length; x++) { @@ -143,13 +143,13 @@ index a557614a3a59a270f2a6917b5eb0cf9046db98e8..9d4eae94966f13ef56e710f53f67f84e + boolean firstParameter = true; - for (int i = start; i < lstParameters.size(); i++) { -@@ -680,27 +697,98 @@ public class InvocationExprent extends Exprent { + for (int i = start; i < this.parameters.size(); i++) { +@@ -685,27 +702,98 @@ public class InvocationExprent extends Exprent { private List getMatchedDescriptors() { List matches = new ArrayList<>(); + ClassNode currCls = ((ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE)); - StructClass cl = DecompilerContext.getStructContext().getClass(classname); + StructClass cl = DecompilerContext.getStructContext().getClass(className); if (cl == null) return matches; - nextMethod: @@ -158,7 +158,7 @@ index a557614a3a59a270f2a6917b5eb0cf9046db98e8..9d4eae94966f13ef56e710f53f67f84e - MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); - if (md.params.length == descriptor.params.length) { - for (int i = 0; i < md.params.length; i++) { -- if (md.params[i].typeFamily != descriptor.params[i].typeFamily) { +- if (md.params[i].getTypeFamily() != descriptor.params[i].getTypeFamily()) { - continue nextMethod; - } + Set visited = new HashSet<>(); @@ -209,7 +209,7 @@ index a557614a3a59a270f2a6917b5eb0cf9046db98e8..9d4eae94966f13ef56e710f53f67f84e + private boolean matches(VarType[] left, VarType[] right) { + if (left.length == right.length) { + for (int i = 0; i < left.length; i++) { -+ if (left[i].typeFamily != right[i].typeFamily) { ++ if (left[i].getTypeFamily() != right[i].getTypeFamily()) { + return false; + } + } @@ -251,13 +251,13 @@ index a557614a3a59a270f2a6917b5eb0cf9046db98e8..9d4eae94966f13ef56e710f53f67f84e + } + private BitSet getAmbiguousParameters(List matches) { - StructClass cl = DecompilerContext.getStructContext().getClass(classname); + StructClass cl = DecompilerContext.getStructContext().getClass(className); if (cl == null || matches.size() == 1) { diff --git a/src/org/jetbrains/java/decompiler/struct/StructClass.java b/src/org/jetbrains/java/decompiler/struct/StructClass.java -index 6813dc6c8909900d3f21eb91532bdfa19fb1d83d..8753a258b8a93d487a3bc268a5bb3bd53e86cb1d 100644 +index ce8b12c815fc939406701ad57627a1bd11771722..894c8e5f0c28ef64acfe392f433ea56f37437054 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructClass.java +++ b/src/org/jetbrains/java/decompiler/struct/StructClass.java -@@ -157,6 +157,35 @@ public class StructClass extends StructMember { +@@ -159,6 +159,35 @@ public class StructClass extends StructMember { return methods.getWithKey(InterpreterUtil.makeUniqueKey(name, descriptor)); } diff --git a/FernFlower-Patches/0020-Add-cfg-argument-Used-to-specify-a-text-file-with-ad.patch b/FernFlower-Patches/0019-Add-cfg-argument-Used-to-specify-a-text-file-with-ad.patch similarity index 97% rename from FernFlower-Patches/0020-Add-cfg-argument-Used-to-specify-a-text-file-with-ad.patch rename to FernFlower-Patches/0019-Add-cfg-argument-Used-to-specify-a-text-file-with-ad.patch index 849a3ac..80a6a54 100644 --- a/FernFlower-Patches/0020-Add-cfg-argument-Used-to-specify-a-text-file-with-ad.patch +++ b/FernFlower-Patches/0019-Add-cfg-argument-Used-to-specify-a-text-file-with-ad.patch @@ -71,7 +71,7 @@ index 75d4d0937f1e39fe630b1318a4ad531de7fbd644..06e362987a3917976627fc1f0b6aad30 \ No newline at end of file +} diff --git a/src/org/jetbrains/java/decompiler/struct/StructContext.java b/src/org/jetbrains/java/decompiler/struct/StructContext.java -index 7c91206d1b64b9873fa24d6d3ad38e736413c0a3..b586ffec22dae82846c1ce335e91c495ae7f11bc 100644 +index b039480288011a5b9bdca635f7c66e85c92eb311..1c0cd6934e9f2225ff1fa40185f0a97ac9ae4daf 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructContext.java +++ b/src/org/jetbrains/java/decompiler/struct/StructContext.java @@ -93,6 +93,7 @@ public class StructContext { diff --git a/FernFlower-Patches/0021-Add-support-for-destination-to-be-a-zip-file-if-ther.patch b/FernFlower-Patches/0020-Add-support-for-destination-to-be-a-zip-file-if-ther.patch similarity index 100% rename from FernFlower-Patches/0021-Add-support-for-destination-to-be-a-zip-file-if-ther.patch rename to FernFlower-Patches/0020-Add-support-for-destination-to-be-a-zip-file-if-ther.patch diff --git a/FernFlower-Patches/0022-Add-a-metadata-file-named-fernflower_abstract_parame.patch b/FernFlower-Patches/0021-Add-a-metadata-file-named-fernflower_abstract_parame.patch similarity index 93% rename from FernFlower-Patches/0022-Add-a-metadata-file-named-fernflower_abstract_parame.patch rename to FernFlower-Patches/0021-Add-a-metadata-file-named-fernflower_abstract_parame.patch index b2090b3..c354d02 100644 --- a/FernFlower-Patches/0022-Add-a-metadata-file-named-fernflower_abstract_parame.patch +++ b/FernFlower-Patches/0021-Add-a-metadata-file-named-fernflower_abstract_parame.patch @@ -7,11 +7,11 @@ Subject: [PATCH] Add a metadata file named Format: ClassName MethodName Descriptor Param1[ Param2...] diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -index 1188d69d3328702779a4b21336d4eb1414d96493..672785f8491db0d42a167ada51b4acc4e2d0fdf6 100644 +index 17dc8a4a5d4e3164337f6d05ab1e00576191a0ca..564236822dab0c638f9a48cb86a6eecc7892080c 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -@@ -870,7 +870,9 @@ public class ClassWriter { - } +@@ -749,7 +749,9 @@ public class ClassWriter { + String parameterName = methodWrapper.varproc.getVarName(pair); if ((flags & (CodeConstants.ACC_ABSTRACT | CodeConstants.ACC_NATIVE)) != 0) { - parameterName = methodWrapper.methodStruct.getVariableNamer().renameAbstractParameter(parameterName, index); @@ -68,7 +68,7 @@ index 57c74fd4bdd195287f616c9b5138bad87b2a96da..c33a9aa83f61a22940b1864d6bbfcdd7 return; otherEntries.add(new String[]{fullPath, entry}); diff --git a/src/org/jetbrains/java/decompiler/struct/StructContext.java b/src/org/jetbrains/java/decompiler/struct/StructContext.java -index b586ffec22dae82846c1ce335e91c495ae7f11bc..83be1cad514f1a48f93db75a1e85dacae14cd105 100644 +index 1c0cd6934e9f2225ff1fa40185f0a97ac9ae4daf..bbbec18e87c940d7daa6983a9ca2b5220e7e2470 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructContext.java +++ b/src/org/jetbrains/java/decompiler/struct/StructContext.java @@ -4,14 +4,18 @@ package org.jetbrains.java.decompiler.struct; @@ -111,7 +111,7 @@ index b586ffec22dae82846c1ce335e91c495ae7f11bc..83be1cad514f1a48f93db75a1e85daca + GenericMethodDescriptor desc = GenericMain.parseMethodSignature(pts[2]); + List params = new ArrayList<>(); + for (int x = 0; x < pts.length - 3; x++) { -+ for (int y = 0; y < desc.parameterTypes.get(x).stackSize; y++) ++ for (int y = 0; y < desc.parameterTypes.get(x).getStackSize(); y++) + params.add(pts[x+3]); + } + this.abstractNames.put(pts[0] + ' '+ pts[1] + ' ' + pts[2], params); diff --git a/FernFlower-Patches/0023-Synthetic-getClass-Objects.requireNonNull-cleanup.patch b/FernFlower-Patches/0022-Synthetic-getClass-Objects.requireNonNull-cleanup.patch similarity index 81% rename from FernFlower-Patches/0023-Synthetic-getClass-Objects.requireNonNull-cleanup.patch rename to FernFlower-Patches/0022-Synthetic-getClass-Objects.requireNonNull-cleanup.patch index 7cd843d..de12c37 100644 --- a/FernFlower-Patches/0023-Synthetic-getClass-Objects.requireNonNull-cleanup.patch +++ b/FernFlower-Patches/0022-Synthetic-getClass-Objects.requireNonNull-cleanup.patch @@ -5,22 +5,22 @@ Subject: [PATCH] Synthetic getClass/Objects.requireNonNull cleanup diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -index 474ffda1b9d610968bd12160f2153713b37f2db9..eef5cdaf7fa5c425abddea9ab0717f6844c97460 100644 +index b7d58645dd21d12c16d4efba9604c46614683c35..e28a44d07de0d1455fdffb5d383e09afe337675e 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -@@ -617,6 +617,23 @@ public class ExprProcessor implements CodeConstants { +@@ -592,6 +592,23 @@ public class ExprProcessor implements CodeConstants { break; case opc_pop: stack.pop(); + // check for synthetic getClass (J8) / Objects.requireNonNull() (J9+) calls added by the compiler + // see https://stackoverflow.com/a/20130641 + if (i > 0) { -+ Exprent last = exprlist.get(exprlist.size() - 1); ++ Exprent last = exprList.get(exprList.size() - 1); + if (last.type == Exprent.EXPRENT_ASSIGNMENT && ((AssignmentExprent)last).getRight().type == Exprent.EXPRENT_INVOCATION) { + InvocationExprent invocation = (InvocationExprent) ((AssignmentExprent) last).getRight(); + if (i + 1 < seq.length()) { + if ((!invocation.isStatic() && invocation.getName().equals("getClass") && invocation.getStringDescriptor().equals("()Ljava/lang/Class;")) // J8 -+ || (invocation.isStatic() && invocation.getClassname().equals("java/util/Objects") && invocation.getName().equals("requireNonNull") && invocation.getStringDescriptor().equals("(Ljava/lang/Object;)Ljava/lang/Object;"))) { // J9+ ++ || (invocation.isStatic() && invocation.getClassName().equals("java/util/Objects") && invocation.getName().equals("requireNonNull") && invocation.getStringDescriptor().equals("(Ljava/lang/Object;)Ljava/lang/Object;"))) { // J9+ + int nextOpc = seq.getInstr(i + 1).opcode; + if (nextOpc >= opc_aconst_null && nextOpc <= opc_ldc2_w) { + invocation.setSyntheticNullCheck(); @@ -31,12 +31,12 @@ index 474ffda1b9d610968bd12160f2153713b37f2db9..eef5cdaf7fa5c425abddea9ab0717f68 + } break; case opc_pop2: - if (stack.getByOffset(-1).getExprType().stackSize == 1) { + if (stack.getByOffset(-1).getExprType().getStackSize() == 1) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java -index 986a8a72ec138ea637d3446ed2e823f6100c31cc..c93911d7e3b3df1e7b455e764f6a96a3843a5df5 100644 +index e1bed2f0f5f501d05f93dfa6bfcd2f2b3e76b822..6d42db459055d505604728dcac4af7bb74a9e21c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java -@@ -71,6 +71,10 @@ public class SimplifyExprentsHelper { +@@ -73,6 +73,10 @@ public class SimplifyExprentsHelper { if (changed) { break; } @@ -47,15 +47,15 @@ index 986a8a72ec138ea637d3446ed2e823f6100c31cc..c93911d7e3b3df1e7b455e764f6a96a3 } res |= changed; -@@ -505,21 +509,53 @@ public class SimplifyExprentsHelper { +@@ -507,21 +511,53 @@ public class SimplifyExprentsHelper { return false; } + private static boolean hasQualifiedNewGetClass(Statement parent, Statement child) { -+ if (child.type == Statement.TYPE_BASICBLOCK && child.getExprents() != null && !child.getExprents().isEmpty()) { ++ if (child.type == Statement.StatementType.BASIC_BLOCK && child.getExprents() != null && !child.getExprents().isEmpty()) { + Exprent firstExpr = child.getExprents().get(child.getExprents().size() - 1); + -+ if (parent.type == Statement.TYPE_IF) { ++ if (parent.type == Statement.StatementType.IF) { + if (isQualifiedNewGetClass(firstExpr, ((IfStatement)parent).getHeadexprent().getCondition())) { + child.getExprents().remove(firstExpr); + return true; @@ -74,7 +74,7 @@ index 986a8a72ec138ea637d3446ed2e823f6100c31cc..c93911d7e3b3df1e7b455e764f6a96a3 - invocation.getStringDescriptor().equals("()Ljava/lang/Class;")) { + if ((!invocation.isStatic() && + invocation.getName().equals("getClass") && invocation.getStringDescriptor().equals("()Ljava/lang/Class;")) // J8 -+ || (invocation.isStatic() && invocation.getClassname().equals("java/util/Objects") && invocation.getName().equals("requireNonNull") ++ || (invocation.isStatic() && invocation.getClassName().equals("java/util/Objects") && invocation.getName().equals("requireNonNull") + && invocation.getStringDescriptor().equals("(Ljava/lang/Object;)Ljava/lang/Object;"))) { // J9+ - List lstExprents = second.getAllExprents(); @@ -89,7 +89,7 @@ index 986a8a72ec138ea637d3446ed2e823f6100c31cc..c93911d7e3b3df1e7b455e764f6a96a3 + final Exprent target; + if (invocation.isStatic()) { // Objects.requireNonNull(target) (J9+) + // detect target type -+ target = invocation.getLstParameters().get(0); ++ target = invocation.getParameters().get(0); + } else { // target.getClass() (J8) + target = invocation.getInstance(); + } @@ -99,14 +99,14 @@ index 986a8a72ec138ea637d3446ed2e823f6100c31cc..c93911d7e3b3df1e7b455e764f6a96a3 + lstExprents.addAll(expr.getAllExprents()); if (expr.type == Exprent.EXPRENT_NEW) { NewExprent newExpr = (NewExprent)expr; - if (newExpr.getConstructor() != null && !newExpr.getConstructor().getLstParameters().isEmpty() && -- newExpr.getConstructor().getLstParameters().get(0).equals(invocation.getInstance())) { -+ (newExpr.getConstructor().getLstParameters().get(0).equals(target) || -+ isUnambiguouslySameParam(invocation.isStatic(), target, newExpr.getConstructor().getLstParameters()))) { + if (newExpr.getConstructor() != null && !newExpr.getConstructor().getParameters().isEmpty() && +- newExpr.getConstructor().getParameters().get(0).equals(invocation.getInstance())) { ++ (newExpr.getConstructor().getParameters().get(0).equals(target) || ++ isUnambiguouslySameParam(invocation.isStatic(), target, newExpr.getConstructor().getParameters()))) { - String classname = newExpr.getNewType().value; + String classname = newExpr.getNewType().getValue(); ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(classname); -@@ -535,6 +571,27 @@ public class SimplifyExprentsHelper { +@@ -537,6 +573,27 @@ public class SimplifyExprentsHelper { return false; } @@ -135,7 +135,7 @@ index 986a8a72ec138ea637d3446ed2e823f6100c31cc..c93911d7e3b3df1e7b455e764f6a96a3 private static boolean isConstructorInvocationRemote(List list, int index) { Exprent current = list.get(index); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -index 9d4eae94966f13ef56e710f53f67f84ef5a50cd3..16158a3d134c7af2ecdf58a539ff1d33ba80c6b9 100644 +index da71a1497ceb262e80617c525886da7db85e02b3..d7c1be5364fdb879c94c6fb748b98399c58afae5 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -61,6 +61,7 @@ public class InvocationExprent extends Exprent { @@ -146,7 +146,7 @@ index 9d4eae94966f13ef56e710f53f67f84ef5a50cd3..16158a3d134c7af2ecdf58a539ff1d33 public InvocationExprent() { super(EXPRENT_INVOCATION); -@@ -161,6 +162,7 @@ public class InvocationExprent extends Exprent { +@@ -163,6 +164,7 @@ public class InvocationExprent extends Exprent { addBytecodeOffsets(expr.bytecode); bootstrapArguments = expr.getBootstrapArguments(); @@ -154,7 +154,7 @@ index 9d4eae94966f13ef56e710f53f67f84ef5a50cd3..16158a3d134c7af2ecdf58a539ff1d33 } @Override -@@ -970,6 +972,14 @@ public class InvocationExprent extends Exprent { +@@ -975,6 +977,14 @@ public class InvocationExprent extends Exprent { return bootstrapArguments; } @@ -168,4 +168,4 @@ index 9d4eae94966f13ef56e710f53f67f84ef5a50cd3..16158a3d134c7af2ecdf58a539ff1d33 + @Override public void getBytecodeRange(BitSet values) { - measureBytecode(values, lstParameters); + measureBytecode(values, parameters); diff --git a/FernFlower-Patches/0023-Fix-shortname-imports-that-are-shadowed-by-super-cla.patch b/FernFlower-Patches/0023-Fix-shortname-imports-that-are-shadowed-by-super-cla.patch new file mode 100644 index 0000000..3f00fd3 --- /dev/null +++ b/FernFlower-Patches/0023-Fix-shortname-imports-that-are-shadowed-by-super-cla.patch @@ -0,0 +1,218 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Justin +Date: Fri, 27 Jul 2018 14:02:27 -0700 +Subject: [PATCH] Fix shortname imports that are shadowed by super class inner + classes + +Adds an option (on by default) to force inner class references to be +qualified to their outer class, -qin + +diff --git a/README.md b/README.md +index 3f5a417a01d918a21b7dcb057b2eb259ec2df475..d553a0f3b5a12d8563c7b5a3ecd4ad280aadc5f0 100644 +--- a/README.md ++++ b/README.md +@@ -65,6 +65,7 @@ The rest of options can be left as they are: they are aimed at professional reve + - inn (1): check for IntelliJ IDEA-specific @NotNull annotation and remove inserted code if found + - lac (0): decompile lambda expressions to anonymous classes + - nls (0): define new line character to be used for output. 0 - '\r\n' (Windows), 1 - '\n' (Unix), default is OS-dependent ++- qin (1): Whether to always qualify inner class references. If this is false, inner class names can be shortened depending on location + - ind: indentation string (default is 3 spaces) + - log (INFO): a logging level, possible values are TRACE, INFO, WARN, ERROR + +diff --git a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java +index 6b7d72b6f599aaf04f122ff38ca872f469c9727e..cdd93212560a15372002c4d927a9debc325edbc3 100644 +--- a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java ++++ b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java +@@ -20,7 +20,7 @@ public class ImportCollector { + private final Set setNotImportedNames = new HashSet<>(); + // set of field names in this class and all its predecessors. + private final Set setFieldNames = new HashSet<>(); +- private final Set setInnerClassNames = new HashSet<>(); ++ private final Map> mapInnerClassNames = new HashMap<>(); + private final String currentPackageSlash; + private final String currentPackagePoint; + +@@ -38,45 +38,18 @@ public class ImportCollector { + } + + Map classes = DecompilerContext.getStructContext().getClasses(); +- LinkedList queue = new LinkedList<>(); +- Set processedClasses = new HashSet<>(); + StructClass currentClass = root.classStruct; + while (currentClass != null) { +- processedClasses.add(currentClass); +- if (currentClass.superClass != null) { +- queue.add(currentClass.superClass.getString()); +- } +- +- Collections.addAll(queue, currentClass.getInterfaceNames()); +- + // all field names for the current class .. + for (StructField f : currentClass.getFields()) { + setFieldNames.add(f.getName()); + } + +- // .. all inner classes for the current class .. +- StructInnerClassesAttribute attribute = currentClass.getAttribute(StructGeneralAttribute.ATTRIBUTE_INNER_CLASSES); +- if (attribute != null) { +- for (StructInnerClassesAttribute.Entry entry : attribute.getEntries()) { +- if (entry.enclosingName != null && entry.enclosingName.equals(currentClass.qualifiedName)) { +- setInnerClassNames.add(entry.simpleName); +- } +- } +- } +- + // .. and traverse through parent. +- do { +- currentClass = queue.isEmpty() ? null : classes.get(queue.removeFirst()); +- +- if (currentClass != null && processedClasses.contains(currentClass)) { +- // Class already processed, skipping. +- +- // This may be sign of circularity in the class hierarchy but in most cases this mean that same interface +- // are listed as implemented several times in the class hierarchy. +- currentClass = null; +- } +- } while (currentClass == null && !queue.isEmpty()); ++ currentClass = currentClass.superClass != null ? classes.get(currentClass.superClass.getString()) : null; + } ++ ++ collectConflictingShortNames(root, new HashMap<>()); + } + + /** +@@ -152,11 +125,36 @@ public class ImportCollector { + // 3) inner class with the same short name in the current class, a super class, or an implemented interface + boolean existsDefaultClass = + (context.getClass(currentPackageSlash + outerShortName) != null && !packageName.equals(currentPackagePoint)) || // current package +- (context.getClass(outerShortName) != null && !currentPackagePoint.isEmpty()) || // default package +- setInnerClassNames.contains(outerShortName); // inner class ++ (context.getClass(outerShortName) != null && !currentPackagePoint.isEmpty()); ++ ++ ClassNode currCls = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE); ++ String mapKey = currCls == null ? "" : currCls.classStruct.qualifiedName; ++ Map innerClassNames = mapInnerClassNames.getOrDefault(mapKey, new HashMap<>()); ++ if (!existsDefaultClass && innerClassNames.containsKey(outerShortName) && !innerClassNames.get(outerShortName).equals(fullName)) { ++ // if the class being accessed is also an inner class ++ // attempt to import the outer class and reference OuterClass.InnerClass ++ if (context.getClass(packageName.replace('.', '/') + "$" + outerShortName) != null) { ++ lastDot = fullName.lastIndexOf(".", lastDot - 1); ++ if (lastDot >= 0) { ++ nestedName = fullName.substring(lastDot + 1); ++ outerShortName = packageName.substring(lastDot + 1); ++ packageName = packageName.substring(0, lastDot); ++ ++ if (innerClassNames.containsKey(outerShortName) && !innerClassNames.get(outerShortName).equals(packageName + '.' + outerShortName)) { ++ existsDefaultClass = true; ++ nestedName = null; ++ } ++ } ++ } ++ else { ++ existsDefaultClass = true; ++ } ++ } + +- if (existsDefaultClass || (mapSimpleNames.containsKey(outerShortName) && !packageName.equals(mapSimpleNames.get(outerShortName)))) { +- return packageName + "." + nestedName; ++ if (existsDefaultClass || ++ (mapSimpleNames.containsKey(outerShortName) && !packageName.equals(mapSimpleNames.get(outerShortName)))) { ++ // don't return full name because if the class is a inner class, full name refers to the parent full name, not the child full name ++ return nestedName == null ? fullName : (packageName + "." + nestedName); + } + else if (!mapSimpleNames.containsKey(outerShortName)) { + mapSimpleNames.put(outerShortName, packageName); +@@ -192,4 +190,43 @@ public class ImportCollector { + .map(ent -> ent.getValue() + "." + ent.getKey()) + .collect(Collectors.toList()); + } +-} ++ ++ private void collectConflictingShortNames(ClassNode root, Map rootNames) { ++ Map names = new HashMap<>(rootNames); ++ getSuperClassInnerClasses(root, names); ++ mapInnerClassNames.put(root.classStruct.qualifiedName, names); ++ ++ for (ClassNode nested : root.nested) { ++ collectConflictingShortNames(nested, names); ++ } ++ } ++ ++ private void getSuperClassInnerClasses(ClassNode node, Map names) { ++ Map classes = DecompilerContext.getStructContext().getClasses(); ++ LinkedList queue = new LinkedList<>(); ++ StructClass currentClass = node.classStruct; ++ while (currentClass != null) { ++ if (currentClass.superClass != null) { ++ queue.add(currentClass.superClass.getString()); ++ } ++ ++ Collections.addAll(queue, currentClass.getInterfaceNames()); ++ ++ // .. all inner classes for the current class .. ++ StructInnerClassesAttribute attribute = currentClass.getAttribute(StructGeneralAttribute.ATTRIBUTE_INNER_CLASSES); ++ if (attribute != null) { ++ for (StructInnerClassesAttribute.Entry entry : attribute.getEntries()) { ++ if (entry.enclosingName != null && entry.enclosingName.equals(currentClass.qualifiedName)) { ++ names.put(entry.simpleName, entry.innerName.replace('/', '.').replace('$', '.')); ++ } ++ } ++ } ++ ++ // .. and traverse through parent. ++ currentClass = !queue.isEmpty() ? classes.get(queue.removeFirst()) : null; ++ while (currentClass == null && !queue.isEmpty()) { ++ currentClass = classes.get(queue.removeFirst()); ++ } ++ } ++ } ++} +\ No newline at end of file +diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +index d91d9faebf718192a679c436792a54c24bed8c63..2493bfcc2eed3e105f819ccc6925ea7a10bfac8c 100644 +--- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java ++++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +@@ -36,6 +36,7 @@ public interface IFernflowerPreferences { + String VERIFY_ANONYMOUS_CLASSES = "vac"; + + String INCLUDE_ENTIRE_CLASSPATH = "iec"; ++ String QUALIFY_INNER_CLASSES = "qin"; + + String LOG_LEVEL = "log"; + String MAX_PROCESSING_METHOD = "mpm"; +@@ -88,6 +89,7 @@ public interface IFernflowerPreferences { + defaults.put(VERIFY_ANONYMOUS_CLASSES, "0"); + + defaults.put(INCLUDE_ENTIRE_CLASSPATH, "0"); ++ defaults.put(QUALIFY_INNER_CLASSES, "1"); + + defaults.put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name()); + defaults.put(MAX_PROCESSING_METHOD, "0"); +diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +index e28a44d07de0d1455fdffb5d383e09afe337675e..27e7432b4c6774a377c9e5f570e04248bb4d2d0c 100644 +--- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java ++++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +@@ -8,6 +8,7 @@ import org.jetbrains.java.decompiler.code.cfg.BasicBlock; + import org.jetbrains.java.decompiler.main.ClassesProcessor; + import org.jetbrains.java.decompiler.main.DecompilerContext; + import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; ++import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; + import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType; + import org.jetbrains.java.decompiler.modules.decompiler.exps.*; + import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectGraph; +@@ -762,12 +763,14 @@ public class ExprProcessor implements CodeConstants { + ) { + List enclosingClasses = enclosingClassList(); + StringBuilder curPathBldr = new StringBuilder(type.getValue().substring(0, type.getValue().lastIndexOf('/') + 1)); ++ boolean forceShouldWrite = DecompilerContext.getOption(IFernflowerPreferences.QUALIFY_INNER_CLASSES); + for (int i = 0; i < nestedTypes.size(); i++) { + String nestedType = nestedTypes.get(i); + boolean shouldWrite = true; + if (!enclosingClasses.isEmpty() && i != nestedTypes.size() - 1) { + String enclosingType = enclosingClasses.remove(0).simpleName; +- shouldWrite = !nestedType.equals(enclosingType) ++ shouldWrite = forceShouldWrite ++ || !nestedType.equals(enclosingType) + // Also write out the enclosing class if we are the outermost, and we're in the type params + || enclosingClasses.isEmpty() && DecompilerContext.getOption(DecompilerContext.IN_CLASS_TYPE_PARAMS); + } diff --git a/FernFlower-Patches/0024-Fix-shortname-imports-that-are-shadowed-by-super-cla.patch b/FernFlower-Patches/0024-Fix-shortname-imports-that-are-shadowed-by-super-cla.patch deleted file mode 100644 index 43fc1c3..0000000 --- a/FernFlower-Patches/0024-Fix-shortname-imports-that-are-shadowed-by-super-cla.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Justin -Date: Fri, 27 Jul 2018 14:02:27 -0700 -Subject: [PATCH] Fix shortname imports that are shadowed by super class inner - classes - - -diff --git a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java -index 647ac7c3dd15323b0580cc42a6ca046c64c01138..464e41a3cd428e1883230bda55fa64172697d1c2 100644 ---- a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java -+++ b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java -@@ -20,7 +20,7 @@ public class ImportCollector { - private final Set setNotImportedNames = new HashSet<>(); - // set of field names in this class and all its predecessors. - private final Set setFieldNames = new HashSet<>(); -- private final Set setInnerClassNames = new HashSet<>(); -+ private final Map> mapInnerClassNames = new HashMap<>(); - private final String currentPackageSlash; - private final String currentPackagePoint; - -@@ -38,36 +38,18 @@ public class ImportCollector { - } - - Map classes = DecompilerContext.getStructContext().getClasses(); -- LinkedList queue = new LinkedList<>(); - StructClass currentClass = root.classStruct; - while (currentClass != null) { -- if (currentClass.superClass != null) { -- queue.add(currentClass.superClass.getString()); -- } -- -- Collections.addAll(queue, currentClass.getInterfaceNames()); -- - // all field names for the current class .. - for (StructField f : currentClass.getFields()) { - setFieldNames.add(f.getName()); - } - -- // .. all inner classes for the current class .. -- StructInnerClassesAttribute attribute = currentClass.getAttribute(StructGeneralAttribute.ATTRIBUTE_INNER_CLASSES); -- if (attribute != null) { -- for (StructInnerClassesAttribute.Entry entry : attribute.getEntries()) { -- if (entry.enclosingName != null && entry.enclosingName.equals(currentClass.qualifiedName)) { -- setInnerClassNames.add(entry.simpleName); -- } -- } -- } -- - // .. and traverse through parent. -- currentClass = !queue.isEmpty() ? classes.get(queue.removeFirst()) : null; -- while (currentClass == null && !queue.isEmpty()) { -- currentClass = classes.get(queue.removeFirst()); -- } -+ currentClass = currentClass.superClass != null ? classes.get(currentClass.superClass.getString()) : null; - } -+ -+ collectConflictingShortNames(root, new HashMap<>()); - } - - /** -@@ -132,8 +114,31 @@ public class ImportCollector { - // 3) inner class with the same short name in the current class, a super class, or an implemented interface - boolean existsDefaultClass = - (context.getClass(currentPackageSlash + shortName) != null && !packageName.equals(currentPackagePoint)) || // current package -- (context.getClass(shortName) != null && !currentPackagePoint.isEmpty()) || // default package -- setInnerClassNames.contains(shortName); // inner class -+ (context.getClass(shortName) != null && !currentPackagePoint.isEmpty()); -+ -+ ClassNode currCls = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE); -+ String mapKey = currCls == null ? "" : currCls.classStruct.qualifiedName; -+ Map innerClassNames = mapInnerClassNames.getOrDefault(mapKey, new HashMap<>()); -+ if (!existsDefaultClass && innerClassNames.containsKey(shortName) && !innerClassNames.get(shortName).equals(fullName)) { -+ // if the class being accessed is also an inner class -+ // attempt to import the outer class and reference OuterClass.InnerClass -+ if (context.getClass(packageName.replace('.', '/') + "$" + shortName) != null) { -+ lastDot = fullName.lastIndexOf(".", lastDot - 1); -+ if (lastDot >= 0) { -+ result = fullName.substring(lastDot + 1); -+ shortName = packageName.substring(lastDot + 1); -+ packageName = packageName.substring(0, lastDot); -+ -+ if (innerClassNames.containsKey(shortName) && !innerClassNames.get(shortName).equals(packageName + '.' + shortName)) { -+ existsDefaultClass = true; -+ result = null; -+ } -+ } -+ } -+ else { -+ existsDefaultClass = true; -+ } -+ } - - if (existsDefaultClass || - (mapSimpleNames.containsKey(shortName) && !packageName.equals(mapSimpleNames.get(shortName)))) { -@@ -174,4 +179,43 @@ public class ImportCollector { - .map(ent -> ent.getValue() + "." + ent.getKey()) - .collect(Collectors.toList()); - } --} -+ -+ private void collectConflictingShortNames(ClassNode root, Map rootNames) { -+ Map names = new HashMap<>(rootNames); -+ getSuperClassInnerClasses(root, names); -+ mapInnerClassNames.put(root.classStruct.qualifiedName, names); -+ -+ for (ClassNode nested : root.nested) { -+ collectConflictingShortNames(nested, names); -+ } -+ } -+ -+ private void getSuperClassInnerClasses(ClassNode node, Map names) { -+ Map classes = DecompilerContext.getStructContext().getClasses(); -+ LinkedList queue = new LinkedList<>(); -+ StructClass currentClass = node.classStruct; -+ while (currentClass != null) { -+ if (currentClass.superClass != null) { -+ queue.add(currentClass.superClass.getString()); -+ } -+ -+ Collections.addAll(queue, currentClass.getInterfaceNames()); -+ -+ // .. all inner classes for the current class .. -+ StructInnerClassesAttribute attribute = currentClass.getAttribute(StructGeneralAttribute.ATTRIBUTE_INNER_CLASSES); -+ if (attribute != null) { -+ for (StructInnerClassesAttribute.Entry entry : attribute.getEntries()) { -+ if (entry.enclosingName != null && entry.enclosingName.equals(currentClass.qualifiedName)) { -+ names.put(entry.simpleName, entry.innerName.replace('/', '.').replace('$', '.')); -+ } -+ } -+ } -+ -+ // .. and traverse through parent. -+ currentClass = !queue.isEmpty() ? classes.get(queue.removeFirst()) : null; -+ while (currentClass == null && !queue.isEmpty()) { -+ currentClass = classes.get(queue.removeFirst()); -+ } -+ } -+ } -+} -\ No newline at end of file diff --git a/FernFlower-Patches/0025-Give-nicer-output-for-float-and-double-literals.patch b/FernFlower-Patches/0024-Give-nicer-output-for-float-and-double-literals.patch similarity index 58% rename from FernFlower-Patches/0025-Give-nicer-output-for-float-and-double-literals.patch rename to FernFlower-Patches/0024-Give-nicer-output-for-float-and-double-literals.patch index 120ab1f..3f989c5 100644 --- a/FernFlower-Patches/0025-Give-nicer-output-for-float-and-double-literals.patch +++ b/FernFlower-Patches/0024-Give-nicer-output-for-float-and-double-literals.patch @@ -5,13 +5,14 @@ Subject: [PATCH] Give nicer output for float and double literals diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -index 71f2ad8417d51eaa564a1813fbd34e1de8b50f94..4bd94d9f47c9d15ef571412a28b97a0fbbfd45ef 100644 +index cbaf9725b714d7fcccb5b1a149b2acc2be76a888..a3434f09438a5b83f0061992b227f9c634c4476f 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -@@ -31,6 +31,67 @@ public class ConstExprent extends Exprent { - CHAR_ESCAPES.put(0x27, "\\'"); /* \u0027: single quote ' */ - CHAR_ESCAPES.put(0x5C, "\\\\"); /* \u005c: backslash \ */ +@@ -48,6 +48,69 @@ public class ConstExprent extends Exprent { } + + private StructMember parent; ++ + private static final Map PI_DOUBLES = new HashMap<>(); + private static final Map PI_FLOATS = new HashMap<>(); + static { @@ -73,29 +74,33 @@ index 71f2ad8417d51eaa564a1813fbd34e1de8b50f94..4bd94d9f47c9d15ef571412a28b97a0f + PI_FLOATS.put(PI_F / 180F, new String[] { "(", " / 180F)" }); + PI_FLOATS.put(180F / PI_F, new String[] { "(180F / ", ")" }); + } - ++ private VarType constType; private final Object value; -@@ -158,34 +219,7 @@ public class ConstExprent extends Exprent { + private final boolean boolPermitted; +@@ -190,37 +253,7 @@ public class ConstExprent extends Exprent { return new TextBuffer(value.toString()).append('L'); case CodeConstants.TYPE_FLOAT: - float floatVal = (Float)value; - if (!literal) { -- if (Float.isNaN(floatVal)) { -- return new FieldExprent("NaN", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); +- if (Float.isNaN(floatVal) && !inConstantVariable(FLOAT_SIG, NAN)) { +- return new FieldExprent(NAN, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); - } -- else if (floatVal == Float.POSITIVE_INFINITY) { -- return new FieldExprent("POSITIVE_INFINITY", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); +- else if (floatVal == Float.POSITIVE_INFINITY && !inConstantVariable(FLOAT_SIG, POS_INF)) { +- return new FieldExprent(POS_INF, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); - } -- else if (floatVal == Float.NEGATIVE_INFINITY) { -- return new FieldExprent("NEGATIVE_INFINITY", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); +- else if (floatVal == Float.NEGATIVE_INFINITY && !inConstantVariable(FLOAT_SIG, NEG_INF)) { +- return new FieldExprent(NEG_INF, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); - } -- else if (floatVal == Float.MAX_VALUE) { -- return new FieldExprent("MAX_VALUE", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); +- else if (floatVal == Float.MAX_VALUE && !inConstantVariable(FLOAT_SIG, MAX_VAL)) { +- return new FieldExprent(MAX_VAL, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); - } -- else if (floatVal == Float.MIN_VALUE) { -- return new FieldExprent("MIN_VALUE", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); +- else if (floatVal == Float.MIN_VALUE && !inConstantVariable(FLOAT_SIG, MIN_VAL)) { +- return new FieldExprent(MIN_VAL, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); +- } +- else if (floatVal == Float.MIN_NORMAL && !inConstantVariable(FLOAT_SIG, MIN_NORM)) { +- return new FieldExprent(MIN_NORM, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); - } - } - else if (Float.isNaN(floatVal)) { @@ -112,27 +117,20 @@ index 71f2ad8417d51eaa564a1813fbd34e1de8b50f94..4bd94d9f47c9d15ef571412a28b97a0f case CodeConstants.TYPE_DOUBLE: double doubleVal = (Double)value; -@@ -202,9 +236,41 @@ public class ConstExprent extends Exprent { - else if (doubleVal == Double.MAX_VALUE) { - return new FieldExprent("MAX_VALUE", "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); - } -+ else if (doubleVal == Double.MIN_NORMAL) { -+ return new FieldExprent("MIN_NORMAL", "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); -+ } - else if (doubleVal == Double.MIN_VALUE) { - return new FieldExprent("MIN_VALUE", "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); +@@ -246,8 +279,31 @@ public class ConstExprent extends Exprent { + else if (doubleVal == Math.E && !inConstantVariable(MATH_SIG, E)) { + return new FieldExprent(E, MATH_SIG, true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); } -+ else if (doubleVal == -Double.MAX_VALUE) { -+ return new FieldExprent("MAX_VALUE", "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("-"); +- else if (doubleVal == Math.PI && !inConstantVariable(MATH_SIG, PI)) { +- return new FieldExprent(PI, MATH_SIG, true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); ++ else if (doubleVal == -Double.MAX_VALUE && !inConstantVariable(DOUBLE_SIG, MAX_VAL)) { ++ return new FieldExprent(MAX_VAL, DOUBLE_SIG, true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("-"); + } + else if (doubleVal == -Double.MIN_NORMAL) { -+ return new FieldExprent("MIN_NORMAL", "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("-"); ++ return new FieldExprent(MIN_NORM, DOUBLE_SIG, true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("-"); + } + else if (doubleVal == -Double.MIN_VALUE) { -+ return new FieldExprent("MIN_VALUE", "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("-"); -+ } -+ else if (doubleVal == Math.E) { -+ return new FieldExprent("E", "java/lang/Math", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); ++ return new FieldExprent(MIN_VAL, DOUBLE_SIG, true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("-"); + } + else if (PI_DOUBLES.containsKey(doubleVal)) { + String[] parts = PI_DOUBLES.get(doubleVal); @@ -150,11 +148,10 @@ index 71f2ad8417d51eaa564a1813fbd34e1de8b50f94..4bd94d9f47c9d15ef571412a28b97a0f + // Include a cast to prevent using the wrong method call in ambiguous cases. + return createFloat(literal, nearestFloatVal, tracer).prepend("(double)"); + } -+ } + } } else if (Double.isNaN(doubleVal)) { - return new TextBuffer("0.0D / 0.0D"); -@@ -233,7 +299,71 @@ public class ConstExprent extends Exprent { +@@ -277,7 +333,71 @@ public class ConstExprent extends Exprent { throw new RuntimeException("invalid constant type: " + constType); } @@ -163,38 +160,38 @@ index 71f2ad8417d51eaa564a1813fbd34e1de8b50f94..4bd94d9f47c9d15ef571412a28b97a0f + private TextBuffer createFloat(boolean literal, float floatVal, BytecodeMappingTracer tracer) { + if (!literal) { + // Float constants, some of which can't be represented directly -+ if (Float.isNaN(floatVal)) { -+ return new FieldExprent("NaN", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); ++ if (Float.isNaN(floatVal) && !inConstantVariable(FLOAT_SIG, NAN)) { ++ return new FieldExprent(NAN, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); + } -+ else if (floatVal == Float.POSITIVE_INFINITY) { -+ return new FieldExprent("POSITIVE_INFINITY", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); ++ else if (floatVal == Float.POSITIVE_INFINITY && !inConstantVariable(FLOAT_SIG, POS_INF)) { ++ return new FieldExprent(POS_INF, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); + } -+ else if (floatVal == Float.NEGATIVE_INFINITY) { -+ return new FieldExprent("NEGATIVE_INFINITY", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); ++ else if (floatVal == Float.NEGATIVE_INFINITY && !inConstantVariable(FLOAT_SIG, NEG_INF)) { ++ return new FieldExprent(NEG_INF, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); + } -+ else if (floatVal == Float.MAX_VALUE) { -+ return new FieldExprent("MAX_VALUE", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); ++ else if (floatVal == Float.MAX_VALUE && !inConstantVariable(FLOAT_SIG, MAX_VAL)) { ++ return new FieldExprent(MAX_VAL, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); + } -+ else if (floatVal == Float.MIN_NORMAL) { -+ return new FieldExprent("MIN_NORMAL", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); ++ else if (floatVal == Float.MIN_NORMAL && !inConstantVariable(FLOAT_SIG, MIN_NORM)) { ++ return new FieldExprent(MIN_NORM, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); + } -+ else if (floatVal == Float.MIN_VALUE) { -+ return new FieldExprent("MIN_VALUE", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); ++ else if (floatVal == Float.MIN_VALUE && !inConstantVariable(FLOAT_SIG, MIN_VAL)) { ++ return new FieldExprent(MIN_VAL, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); + } -+ else if (floatVal == -Float.MAX_VALUE) { -+ return new FieldExprent("MAX_VALUE", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("-"); ++ else if (floatVal == -Float.MAX_VALUE && !inConstantVariable(FLOAT_SIG, MAX_VAL)) { ++ return new FieldExprent(MAX_VAL, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("-"); + } -+ else if (floatVal == -Float.MIN_NORMAL) { -+ return new FieldExprent("MIN_NORMAL", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("-"); ++ else if (floatVal == -Float.MIN_NORMAL && !inConstantVariable(FLOAT_SIG, MIN_NORM)) { ++ return new FieldExprent(MIN_NORM, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("-"); + } -+ else if (floatVal == -Float.MIN_VALUE) { -+ return new FieldExprent("MIN_VALUE", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("-"); ++ else if (floatVal == -Float.MIN_VALUE && !inConstantVariable(FLOAT_SIG, MIN_VAL)) { ++ return new FieldExprent(MIN_VAL, FLOAT_SIG, true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("-"); + } + // Math constants -+ else if (floatVal == (float)Math.E) { -+ return new FieldExprent("E", "java/lang/Math", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("(float)"); ++ else if (floatVal == (float)Math.E && !inConstantVariable(MATH_SIG, E)) { ++ return new FieldExprent(E, MATH_SIG, true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer).prepend("(float)"); + } -+ else if (PI_FLOATS.containsKey(floatVal)) { ++ else if (PI_FLOATS.containsKey(floatVal) && !inConstantVariable(MATH_SIG, PI)) { + String[] parts = PI_FLOATS.get(floatVal); + return getPiFloat(tracer).enclose(parts[0], parts[1]); + } @@ -216,7 +213,7 @@ index 71f2ad8417d51eaa564a1813fbd34e1de8b50f94..4bd94d9f47c9d15ef571412a28b97a0f + } + + private TextBuffer getPiDouble(BytecodeMappingTracer tracer) { -+ return new FieldExprent("PI", "java/lang/Math", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); ++ return new FieldExprent(PI, MATH_SIG, true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); + } + + private TextBuffer getPiFloat(BytecodeMappingTracer tracer) { diff --git a/FernFlower-Patches/0026-Add-try-with-resource-support.patch b/FernFlower-Patches/0025-Add-try-with-resource-support.patch similarity index 88% rename from FernFlower-Patches/0026-Add-try-with-resource-support.patch rename to FernFlower-Patches/0025-Add-try-with-resource-support.patch index 79160f1..cc2a6b6 100644 --- a/FernFlower-Patches/0026-Add-try-with-resource-support.patch +++ b/FernFlower-Patches/0025-Add-try-with-resource-support.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add try with resource support diff --git a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java -index 76d057fb3970d07a2fc7c07efc756e77e2d53222..bb246173b89d733e01ef4a03b59759c8663a20ff 100644 +index 81fed9eaea4d73a99e87545d15171033f98db3b1..d2c448319e75f6acfb462e6b2d9505f13407a1de 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java +++ b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java -@@ -179,6 +179,10 @@ public class MethodProcessorRunnable implements Runnable { +@@ -190,6 +190,10 @@ public class MethodProcessorRunnable implements Runnable { LabelHelper.identifyLabels(root); @@ -21,7 +21,7 @@ index 76d057fb3970d07a2fc7c07efc756e77e2d53222..bb246173b89d733e01ef4a03b59759c8 } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/TryHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/TryHelper.java new file mode 100644 -index 0000000000000000000000000000000000000000..7e18ff4d3c83fe4d844be3547c567b5fa4583a3a +index 0000000000000000000000000000000000000000..6e392e9dc5e31e920e526d9d4c61757ff469d9ae --- /dev/null +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/TryHelper.java @@ -0,0 +1,263 @@ @@ -55,7 +55,7 @@ index 0000000000000000000000000000000000000000..7e18ff4d3c83fe4d844be3547c567b5f + } + + private static boolean makeTryWithResourceRec(Statement stat) { -+ if (stat.type == Statement.TYPE_CATCHALL && ((CatchAllStatement)stat).isFinally()) { ++ if (stat.type == Statement.StatementType.CATCH_ALL && ((CatchAllStatement)stat).isFinally()) { + if (makeTryWithResource((CatchAllStatement)stat)) { + return true; + } @@ -71,7 +71,7 @@ index 0000000000000000000000000000000000000000..7e18ff4d3c83fe4d844be3547c567b5f + } + + private static boolean collapseTryRec(Statement stat) { -+ if (stat.type == Statement.TYPE_TRYCATCH && collapseTry((CatchStatement)stat)) { ++ if (stat.type == Statement.StatementType.TRY_CATCH && collapseTry((CatchStatement)stat)) { + return true; + } + @@ -93,7 +93,7 @@ index 0000000000000000000000000000000000000000..7e18ff4d3c83fe4d844be3547c567b5f + } + + Statement toCheck = finallyStat.getHandler().getFirst(); -+ if (toCheck.type != Statement.TYPE_IF || ((IfStatement)toCheck).getIfstat().type != Statement.TYPE_IF) { ++ if (toCheck.type != Statement.StatementType.IF || ((IfStatement)toCheck).getIfstat().type != Statement.StatementType.IF) { + return false; + } + @@ -118,7 +118,7 @@ index 0000000000000000000000000000000000000000..7e18ff4d3c83fe4d844be3547c567b5f + AssignmentExprent ass = null; + BasicBlockStatement initBlock = null; + for (StatEdge edge : finallyStat.getAllPredecessorEdges()) { -+ if (edge.getDestination().equals(finallyStat) && edge.getSource().type == Statement.TYPE_BASICBLOCK) { ++ if (edge.getDestination().equals(finallyStat) && edge.getSource().type == Statement.StatementType.BASIC_BLOCK) { + ass = findResourceDef(var, edge.getSource()); + if (ass != null) { + initBlock = (BasicBlockStatement)edge.getSource(); @@ -131,7 +131,7 @@ index 0000000000000000000000000000000000000000..7e18ff4d3c83fe4d844be3547c567b5f + Statement stat = finallyStat.getParent(); + Statement stat2 = finallyStat.getFirst(); + -+ if (stat2.type == Statement.TYPE_TRYCATCH) { ++ if (stat2.type == Statement.StatementType.TRY_CATCH) { + CatchStatement child = (CatchStatement)stat2; + + AssignmentExprent resourceDef = (AssignmentExprent)ass.copy(); @@ -165,10 +165,10 @@ index 0000000000000000000000000000000000000000..7e18ff4d3c83fe4d844be3547c567b5f + + private static boolean collapseTry(CatchStatement catchStat) { + Statement parent = catchStat; -+ if (parent.getFirst() != null && parent.getFirst().type == Statement.TYPE_SEQUENCE) { ++ if (parent.getFirst() != null && parent.getFirst().type == Statement.StatementType.SEQUENCE) { + parent = parent.getFirst(); + } -+ if (parent != null && parent.getFirst() != null && parent.getFirst().type == Statement.TYPE_TRYCATCH) { ++ if (parent != null && parent.getFirst() != null && parent.getFirst().type == Statement.StatementType.TRY_CATCH) { + CatchStatement toRemove = (CatchStatement)parent.getFirst(); + + if (toRemove.getTryType() == CatchStatement.RESORCES) { @@ -213,7 +213,7 @@ index 0000000000000000000000000000000000000000..7e18ff4d3c83fe4d844be3547c567b5f + InvocationExprent invocExp = (InvocationExprent)exp; + if (invocExp.getName().equals("close") && invocExp.getStringDescriptor().equals("()V")) { + if (invocExp.getInstance() != null && invocExp.getInstance().type == Exprent.EXPRENT_VAR) { -+ return DecompilerContext.getStructContext().instanceOf(invocExp.getClassname(), "java/lang/AutoCloseable"); ++ return DecompilerContext.getStructContext().instanceOf(invocExp.getClassName(), "java/lang/AutoCloseable"); + } + } + } @@ -244,8 +244,8 @@ index 0000000000000000000000000000000000000000..7e18ff4d3c83fe4d844be3547c567b5f + for (; i < catchStat.getStats().size(); ++i) { + temp = catchStat.getStats().get(i); + -+ if (temp.type == Statement.TYPE_BASICBLOCK && temp.getExprents() != null) { -+ if (temp.getExprents().size() >= 2 && catchStat.getVars().get(i - 1).getVarType().value.equals("java/lang/Throwable")) { ++ if (temp.type == Statement.StatementType.BASIC_BLOCK && temp.getExprents() != null) { ++ if (temp.getExprents().size() >= 2 && catchStat.getVars().get(i - 1).getVarType().getValue().equals("java/lang/Throwable")) { + if (temp.getExprents().get(temp.getExprents().size() - 1).type == Exprent.EXPRENT_EXIT) { + ExitExprent exitExprent = (ExitExprent)temp.getExprents().get(temp.getExprents().size() - 1); + if (exitExprent.getExitType() == ExitExprent.EXIT_THROW && exitExprent.getValue().equals(catchStat.getVars().get(i - 1))) { @@ -272,7 +272,7 @@ index 0000000000000000000000000000000000000000..7e18ff4d3c83fe4d844be3547c567b5f + + if (removed && temp.getExprents().get(temp.getExprents().size() - 2).type == Exprent.EXPRENT_ASSIGNMENT) { + AssignmentExprent assignmentExp = (AssignmentExprent)temp.getExprents().get(temp.getExprents().size() - 2); -+ if (assignmentExp.getLeft().getExprType().value.equals("java/lang/Throwable")) { ++ if (assignmentExp.getLeft().getExprType().getValue().equals("java/lang/Throwable")) { + for (Exprent exprent : initBlock.getExprents()) { + if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) { + AssignmentExprent toRemove = (AssignmentExprent)exprent; @@ -289,14 +289,14 @@ index 0000000000000000000000000000000000000000..7e18ff4d3c83fe4d844be3547c567b5f + } +} diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java -index 2883c91e705ea07717350f813e0bf41638fc0e09..b6754ef09179b8e7028a98248f6bff2b100b94af 100644 +index a3ef4b8b5fdb820c520a21fcd727e08e9dfe2510..f4f8b55a68c10671beef7859540398cac541d6e2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java -@@ -126,6 +126,13 @@ public class FlattenStatementsHelper { - case Statement.TYPE_TRYCATCH: - DirectNode firstnd = new DirectNode(DirectNode.NODE_TRY, stat, stat.id + "_try"); +@@ -130,6 +130,13 @@ public class FlattenStatementsHelper { + case TRY_CATCH: + DirectNode firstnd = new DirectNode(DirectNodeType.TRY, stat, stat.id + "_try"); -+ if (stat.type == Statement.TYPE_TRYCATCH) { ++ if (stat.type == Statement.StatementType.TRY_CATCH) { + CatchStatement catchStat = (CatchStatement)stat; + if (catchStat.getTryType() == CatchStatement.RESORCES) { + firstnd.exprents = catchStat.getResources(); @@ -307,23 +307,21 @@ index 2883c91e705ea07717350f813e0bf41638fc0e09..b6754ef09179b8e7028a98248f6bff2b graph.nodes.putWithKey(firstnd, firstnd.id); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java -index 7e41176d17729f6acdf5420c9ed98eb7ffb6f3ae..d7a975db4e5ee5800c426e62f76be2777c02af6f 100644 +index c3536d73475e1037a82e5f76a328c859f5507077..9db86209721e133416de8379accb6ee5a1235d01 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java -@@ -4,6 +4,8 @@ package org.jetbrains.java.decompiler.modules.decompiler.stats; - import org.jetbrains.java.decompiler.code.CodeConstants; - import org.jetbrains.java.decompiler.code.cfg.BasicBlock; - import org.jetbrains.java.decompiler.main.DecompilerContext; +@@ -10,18 +10,26 @@ import org.jetbrains.java.decompiler.modules.decompiler.DecHelper; + import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; + import org.jetbrains.java.decompiler.modules.decompiler.StatEdge; + import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType; +import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; -+import org.jetbrains.java.decompiler.util.TextBuffer; - import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; - import org.jetbrains.java.decompiler.main.collectors.CounterContainer; - import org.jetbrains.java.decompiler.modules.decompiler.DecHelper; -@@ -14,12 +16,19 @@ import org.jetbrains.java.decompiler.struct.gen.VarType; + import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; + import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.util.TextBuffer; import java.util.ArrayList; +import java.util.BitSet; + import java.util.Collections; import java.util.List; import java.util.Set; @@ -339,15 +337,15 @@ index 7e41176d17729f6acdf5420c9ed98eb7ffb6f3ae..d7a975db4e5ee5800c426e62f76be277 // ***************************************************************************** // constructors -@@ -27,6 +36,7 @@ public final class CatchStatement extends Statement { +@@ -29,6 +37,7 @@ public final class CatchStatement extends Statement { private CatchStatement() { - type = TYPE_TRYCATCH; + super(StatementType.TRY_CATCH); + tryType = NORMAL; } private CatchStatement(Statement head, Statement next, Set setHandlers) { -@@ -141,8 +151,25 @@ public final class CatchStatement extends Statement { +@@ -143,8 +152,25 @@ public final class CatchStatement extends Statement { tracer.incrementCurrentSourceLine(); } @@ -375,7 +373,7 @@ index 7e41176d17729f6acdf5420c9ed98eb7ffb6f3ae..d7a975db4e5ee5800c426e62f76be277 buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true, tracer)); buf.appendIndent(indent).append("}"); -@@ -179,6 +206,15 @@ public final class CatchStatement extends Statement { +@@ -181,6 +207,15 @@ public final class CatchStatement extends Statement { return buf; } @@ -391,7 +389,7 @@ index 7e41176d17729f6acdf5420c9ed98eb7ffb6f3ae..d7a975db4e5ee5800c426e62f76be277 @Override public Statement getSimpleCopy() { CatchStatement cs = new CatchStatement(); -@@ -193,11 +229,35 @@ public final class CatchStatement extends Statement { +@@ -195,11 +230,35 @@ public final class CatchStatement extends Statement { return cs; } @@ -427,15 +425,14 @@ index 7e41176d17729f6acdf5420c9ed98eb7ffb6f3ae..d7a975db4e5ee5800c426e62f76be277 + return resources; + } } -\ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java -index 20651b7d66ad24404c15378da80bbd47e4178e0f..0f7ca6c558a05e02ea98bc17dca37a2d2e119640 100644 +index f79794242f3eb9b5000af5fa6b41994ee1b25cd9..472af3df55a4accb2ae3b249289ee69a47ecf2c0 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java -@@ -113,7 +113,11 @@ public class VarDefinitionHelper { +@@ -115,7 +115,11 @@ public class VarDefinitionHelper { lstVars = ((CatchAllStatement)st).getVars(); } - else if (st.type == Statement.TYPE_TRYCATCH) { + else if (st.type == StatementType.TRY_CATCH) { - lstVars = ((CatchStatement)st).getVars(); + lstVars = new ArrayList<>(((CatchStatement)st).getVars()); + // resource vars must also be included @@ -446,15 +443,17 @@ index 20651b7d66ad24404c15378da80bbd47e4178e0f..0f7ca6c558a05e02ea98bc17dca37a2d if (lstVars != null) { diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -index b17be32cc74e95701a299fc031e1daa93e49eb5f..b53a17c2ba86fe16917e0c6b3e0ae346c87c2547 100644 +index 2c7cdac55a8ba8a9bcc8b4da84e4ed5469e98d6e..c88d5f8ea5ffb16de0d9e8dd8f8e2fd9a726d489 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -@@ -120,4 +120,5 @@ public class SingleClassesTest extends SingleClassesTestBase { +@@ -144,6 +144,7 @@ public class SingleClassesTest extends SingleClassesTestBase { @Test public void testRecordVararg() { doTest("records/TestRecordVararg"); } @Test public void testRecordGenericVararg() { doTest("records/TestRecordGenericVararg"); } @Test public void testRecordAnno() { doTest("records/TestRecordAnno"); } + @Test public void testTryWithResources() { doTest("pkg/TestTryWithResources"); } - } + @Test public void testRootWithClassInner() { doTest("sealed/RootWithClassInner"); } + @Test public void testRootWithInterfaceInner() { doTest("sealed/RootWithInterfaceInner"); } + @Test public void testRootWithClassOuter() { doTest("sealed/RootWithClassOuter", diff --git a/testData/classes/pkg/TestTryWithResources.class b/testData/classes/pkg/TestTryWithResources.class new file mode 100644 index 0000000000000000000000000000000000000000..dba49d9ec1c81714d3b6d7debe6db5697fc5a9bc diff --git a/FernFlower-Patches/0027-Prioritize-self-and-enclosing-class-when-encounterin.patch b/FernFlower-Patches/0026-Prioritize-self-and-enclosing-class-when-encounterin.patch similarity index 88% rename from FernFlower-Patches/0027-Prioritize-self-and-enclosing-class-when-encounterin.patch rename to FernFlower-Patches/0026-Prioritize-self-and-enclosing-class-when-encounterin.patch index 78f0baa..10f9d61 100644 --- a/FernFlower-Patches/0027-Prioritize-self-and-enclosing-class-when-encounterin.patch +++ b/FernFlower-Patches/0026-Prioritize-self-and-enclosing-class-when-encounterin.patch @@ -8,10 +8,10 @@ The compiler encodes all REFERENCED inner classes into the class. The first foun Fixes AccessTransformers. diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -index 672785f8491db0d42a167ada51b4acc4e2d0fdf6..4a9014073b785be9fb7cf42018122e24c545b6dc 100644 +index 564236822dab0c638f9a48cb86a6eecc7892080c..ac0d6feaa643477aa465cd8bb8ebd4503faf522a 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -@@ -1180,6 +1180,10 @@ public class ClassWriter { +@@ -1198,6 +1198,10 @@ public class ClassWriter { } } @@ -19,11 +19,11 @@ index 672785f8491db0d42a167ada51b4acc4e2d0fdf6..4a9014073b785be9fb7cf42018122e24 + return MODIFIERS.entrySet().stream().filter(e -> (e.getKey() & flags) != 0).map(Map.Entry::getValue).collect(Collectors.joining(" ")); + } + - public static void appendTypeParameters(TextBuffer buffer, List parameters, List> bounds) { - buffer.append('<'); - + public static void appendTypeParameters( + TextBuffer buffer, + List parameters, diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java -index aff6532ccecce0a06518797f3a3c8a6e5e29aeaa..bb5ca5bae7c3ae47e2e824f3a0d24246bbd210ca 100644 +index 66414bc3eac6e187e5f45f70bc67b783ad4f1a4a..8aefba318b0f09b559d41d945a3d8099a861ac55 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -43,10 +43,20 @@ public class ClassesProcessor implements CodeConstants { @@ -33,7 +33,7 @@ index aff6532ccecce0a06518797f3a3c8a6e5e29aeaa..bb5ca5bae7c3ae47e2e824f3a0d24246 + private String source; private static boolean equal(Inner o1, Inner o2) { - return o1.type == o2.type && o1.accessFlags == o2.accessFlags && InterpreterUtil.equalObjects(o1.simpleName, o2.simpleName); + return o1.type == o2.type && o1.accessFlags == o2.accessFlags && Objects.equals(o1.simpleName, o2.simpleName); } + + @Override diff --git a/FernFlower-Patches/0028-Fix-ambiguous-lambdas.patch b/FernFlower-Patches/0027-Fix-ambiguous-lambdas.patch similarity index 66% rename from FernFlower-Patches/0028-Fix-ambiguous-lambdas.patch rename to FernFlower-Patches/0027-Fix-ambiguous-lambdas.patch index 7220bf1..84d7b16 100644 --- a/FernFlower-Patches/0028-Fix-ambiguous-lambdas.patch +++ b/FernFlower-Patches/0027-Fix-ambiguous-lambdas.patch @@ -5,11 +5,11 @@ Subject: [PATCH] Fix ambiguous lambdas diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -index eef5cdaf7fa5c425abddea9ab0717f6844c97460..7b554126313ad7abc3c1a6773a8f1ee69549ca93 100644 +index 27e7432b4c6774a377c9e5f570e04248bb4d2d0c..ba88826f42a6769428d70668664131736ed42c00 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java -@@ -913,6 +913,9 @@ public class ExprProcessor implements CodeConstants { - (castNull && rightType.type == CodeConstants.TYPE_NULL && !UNDEFINED_TYPE_STRING.equals(getTypeName(leftType))) || +@@ -1072,6 +1072,9 @@ public class ExprProcessor implements CodeConstants { + (castNull && rightType.getType() == CodeConstants.TYPE_NULL && !UNDEFINED_TYPE_STRING.equals(getTypeName(leftType, Collections.emptyList()))) || (castNarrowing && isIntConstant(exprent) && isNarrowedIntType(leftType)); + boolean castLambda = !cast && exprent.type == Exprent.EXPRENT_NEW && !leftType.equals(rightType) && @@ -18,60 +18,60 @@ index eef5cdaf7fa5c425abddea9ab0717f6844c97460..7b554126313ad7abc3c1a6773a8f1ee6 boolean quote = cast && exprent.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST); // cast instead to 'byte' / 'short' when int constant is used as a value for 'Byte' / 'Short' -@@ -927,6 +930,8 @@ public class ExprProcessor implements CodeConstants { +@@ -1086,6 +1089,8 @@ public class ExprProcessor implements CodeConstants { - if (cast) buffer.append('(').append(getCastTypeName(leftType)).append(')'); + if (cast) buffer.append('(').append(ExprProcessor.getCastTypeName(leftType, Collections.emptyList())).append(')'); -+ if (castLambda) buffer.append('(').append(getCastTypeName(rightType)).append(')'); ++ if (castLambda) buffer.append('(').append(getCastTypeName(rightType, Collections.emptyList())).append(')'); + if (quote) buffer.append('('); if (exprent.type == Exprent.EXPRENT_CONST) { -@@ -959,4 +964,12 @@ public class ExprProcessor implements CodeConstants { - return VarType.VARTYPE_INT.isStrictSuperset(type) || - type.equals(VarType.VARTYPE_BYTE_OBJ) || type.equals(VarType.VARTYPE_SHORT_OBJ); +@@ -1117,4 +1122,12 @@ public class ExprProcessor implements CodeConstants { + private static boolean isNarrowedIntType(VarType type) { + return VarType.VARTYPE_INT.isStrictSuperset(type) || type.equals(VarType.VARTYPE_BYTE_OBJ) || type.equals(VarType.VARTYPE_SHORT_OBJ); } + + private static boolean lambdaNeedsCast(VarType left, NewExprent exprent) { + if (exprent.isLambda() && !exprent.isMethodReference()) { -+ StructClass cls = DecompilerContext.getStructContext().getClass(left.value); ++ StructClass cls = DecompilerContext.getStructContext().getClass(left.getValue()); + return cls == null || cls.getMethod(exprent.getLambdaMethodKey()) == null; + } + return false; + } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -index 16158a3d134c7af2ecdf58a539ff1d33ba80c6b9..4dc461a2da1073a74d9df787ff21d9f27a5a59f2 100644 +index d7c1be5364fdb879c94c6fb748b98399c58afae5..dd3cde1a35d189ad7ea847c9f5de2531e4177a1b 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -@@ -806,7 +806,8 @@ public class InvocationExprent extends Exprent { - if (md.params.length == lstParameters.size()) { +@@ -811,7 +811,8 @@ public class InvocationExprent extends Exprent { + if (md.params.length == parameters.size()) { boolean exact = true; for (int i = 0; i < md.params.length; i++) { -- if (!md.params[i].equals(lstParameters.get(i).getExprType())) { -+ Exprent exp = lstParameters.get(i); +- if (!md.params[i].equals(parameters.get(i).getExprType())) { ++ Exprent exp = parameters.get(i); + if (!md.params[i].equals(exp.getExprType()) || (exp.type == EXPRENT_NEW && ((NewExprent)exp).isLambda() && !((NewExprent)exp).isMethodReference())) { exact = false; missed.set(i); } -@@ -820,7 +821,8 @@ public class InvocationExprent extends Exprent { +@@ -825,7 +826,8 @@ public class InvocationExprent extends Exprent { boolean failed = false; MethodDescriptor md = MethodDescriptor.parseDescriptor(mtt.getDescriptor()); - for (int i = 0; i < lstParameters.size(); i++) { -- VarType ptype = lstParameters.get(i).getExprType(); -+ Exprent exp = lstParameters.get(i); + for (int i = 0; i < parameters.size(); i++) { +- VarType ptype = parameters.get(i).getExprType(); ++ Exprent exp = parameters.get(i); + VarType ptype = exp.getExprType(); if (!missed.get(i)) { if (!md.params[i].equals(ptype)) { failed = true; -@@ -828,6 +830,17 @@ public class InvocationExprent extends Exprent { +@@ -833,6 +835,17 @@ public class InvocationExprent extends Exprent { } } else { + if (exp.type == EXPRENT_NEW) { + NewExprent newExp = (NewExprent)exp; -+ if (newExp.isLambda() && !newExp.isMethodReference() && !DecompilerContext.getStructContext().instanceOf(md.params[i].value, exp.getExprType().value)) { -+ StructClass pcls = DecompilerContext.getStructContext().getClass(md.params[i].value); ++ if (newExp.isLambda() && !newExp.isMethodReference() && !DecompilerContext.getStructContext().instanceOf(md.params[i].getValue(), exp.getExprType().getValue())) { ++ StructClass pcls = DecompilerContext.getStructContext().getClass(md.params[i].getValue()); + if (pcls != null && pcls.getMethod(newExp.getLambdaMethodKey()) == null) { + failed = true; + break; @@ -79,15 +79,15 @@ index 16158a3d134c7af2ecdf58a539ff1d33ba80c6b9..4dc461a2da1073a74d9df787ff21d9f2 + continue; + } + } - if (md.params[i].type == CodeConstants.TYPE_OBJECT) { - if (ptype.type != CodeConstants.TYPE_NULL) { - if (!DecompilerContext.getStructContext().instanceOf(ptype.value, md.params[i].value)) { -@@ -855,7 +868,10 @@ public class InvocationExprent extends Exprent { + if (md.params[i].getType() == CodeConstants.TYPE_OBJECT) { + if (ptype.getType() != CodeConstants.TYPE_NULL) { + if (!DecompilerContext.getStructContext().instanceOf(ptype.getValue(), md.params[i].getValue())) { +@@ -860,7 +873,10 @@ public class InvocationExprent extends Exprent { GenericMethodDescriptor gen = mtt.getSignature(); //TODO: Find synthetic flags for params, as Enum generic signatures do no contain the String,int params if (gen != null && gen.parameterTypes.size() > i && gen.parameterTypes.get(i).isGeneric()) { - break; -+ Exprent exp = lstParameters.get(i); ++ Exprent exp = parameters.get(i); + if (exp.type != EXPRENT_NEW || !((NewExprent)exp).isLambda() || ((NewExprent)exp).isMethodReference()) { + break; + } @@ -95,7 +95,7 @@ index 16158a3d134c7af2ecdf58a539ff1d33ba80c6b9..4dc461a2da1073a74d9df787ff21d9f2 MethodDescriptor md = MethodDescriptor.parseDescriptor(mtt.getDescriptor()); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java -index f99fdc492e9ca76a1f14695e832ea193b920c1e1..bf254b8d843526d872092f4b0a000b13baef518a 100644 +index 2501863f7396c721a42eaab481b2c89d88209d23..5ee4fb58a5687a0e26558fbc4fdaa989695bc6fa 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -5,6 +5,8 @@ import org.jetbrains.java.decompiler.code.CodeConstants; @@ -107,7 +107,17 @@ index f99fdc492e9ca76a1f14695e832ea193b920c1e1..bf254b8d843526d872092f4b0a000b13 import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; -@@ -32,6 +34,7 @@ public class NewExprent extends Exprent { +@@ -14,8 +16,8 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; + import org.jetbrains.java.decompiler.struct.StructClass; + import org.jetbrains.java.decompiler.struct.gen.VarType; + import org.jetbrains.java.decompiler.struct.gen.generics.GenericClassDescriptor; ++import org.jetbrains.java.decompiler.util.InterpreterUtil; + import org.jetbrains.java.decompiler.util.ListStack; +-import org.jetbrains.java.decompiler.util.TextBuffer; + + import java.util.*; + +@@ -28,6 +30,7 @@ public class NewExprent extends Exprent { private boolean isVarArgParam; private boolean anonymous; private boolean lambda; @@ -115,7 +125,7 @@ index f99fdc492e9ca76a1f14695e832ea193b920c1e1..bf254b8d843526d872092f4b0a000b13 private boolean enumConst; private List genericArgs = new ArrayList<>(); -@@ -52,6 +55,7 @@ public class NewExprent extends Exprent { +@@ -48,6 +51,7 @@ public class NewExprent extends Exprent { anonymous = true; if (node.type == ClassNode.CLASS_LAMBDA) { lambda = true; @@ -123,21 +133,23 @@ index f99fdc492e9ca76a1f14695e832ea193b920c1e1..bf254b8d843526d872092f4b0a000b13 } } } -@@ -514,4 +518,17 @@ public class NewExprent extends Exprent { +@@ -511,4 +515,17 @@ public class NewExprent extends Exprent { public void setEnumConst(boolean enumConst) { this.enumConst = enumConst; } +-} +\ No newline at end of file + + public boolean isMethodReference() { + return methodReference; + } + + public String getLambdaMethodKey() { -+ ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value); ++ ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.getValue()); + if (node != null && constructor != null) { + String descriptor = ((PrimitiveConstant)constructor.getBootstrapArguments().get(0)).getString(); + return InterpreterUtil.makeUniqueKey(node.lambdaInformation.method_name, descriptor); + } + return ""; + } - } ++} diff --git a/FernFlower-Patches/0029-Improve-inferred-generic-types.patch b/FernFlower-Patches/0028-Improve-inferred-generic-types.patch similarity index 83% rename from FernFlower-Patches/0029-Improve-inferred-generic-types.patch rename to FernFlower-Patches/0028-Improve-inferred-generic-types.patch index 8541818..afe0ee7 100644 --- a/FernFlower-Patches/0029-Improve-inferred-generic-types.patch +++ b/FernFlower-Patches/0028-Improve-inferred-generic-types.patch @@ -5,30 +5,30 @@ Subject: [PATCH] Improve inferred generic types diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -index d91d9faebf718192a679c436792a54c24bed8c63..01b9cef3bb535025f816f18acab5951083e4ec55 100644 +index 2493bfcc2eed3e105f819ccc6925ea7a10bfac8c..0c1e9296f40007557be90d12daf39cb9a78df448 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -@@ -36,6 +36,7 @@ public interface IFernflowerPreferences { - String VERIFY_ANONYMOUS_CLASSES = "vac"; +@@ -37,6 +37,7 @@ public interface IFernflowerPreferences { String INCLUDE_ENTIRE_CLASSPATH = "iec"; + String QUALIFY_INNER_CLASSES = "qin"; + String EXPLICIT_GENERIC_ARGUMENTS = "ega"; String LOG_LEVEL = "log"; String MAX_PROCESSING_METHOD = "mpm"; -@@ -88,6 +89,7 @@ public interface IFernflowerPreferences { - defaults.put(VERIFY_ANONYMOUS_CLASSES, "0"); +@@ -90,6 +91,7 @@ public interface IFernflowerPreferences { defaults.put(INCLUDE_ENTIRE_CLASSPATH, "0"); + defaults.put(QUALIFY_INNER_CLASSES, "1"); + defaults.put(EXPLICIT_GENERIC_ARGUMENTS, "0"); defaults.put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name()); defaults.put(MAX_PROCESSING_METHOD, "0"); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java -index bf5ff14382c3d5e655778298c87fbe6a8b6592c3..9fd3f0547c17ca6c52cb725ebf1f90771c5ad456 100644 +index 47303b872ca4353b1954d8b3c56d99a0693e095a..fd0e1ab199738bc00cd48f522a75b86e3c29b9bf 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java -@@ -42,6 +42,17 @@ public class ArrayExprent extends Exprent { +@@ -40,6 +40,17 @@ public class ArrayExprent extends Exprent { } } @@ -47,18 +47,18 @@ index bf5ff14382c3d5e655778298c87fbe6a8b6592c3..9fd3f0547c17ca6c52cb725ebf1f9077 public int getExprentUse() { return array.getExprentUse() & index.getExprentUse() & Exprent.MULTIPLE_USES; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -index 4bd94d9f47c9d15ef571412a28b97a0fbbfd45ef..6ed64f77930f44a9c6bd17d2eca51de97a6cbbcf 100644 +index a3434f09438a5b83f0061992b227f9c634c4476f..4b22805aa16a8a95a4bebf3b371df3f0c8dae03a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -@@ -3,6 +3,7 @@ package org.jetbrains.java.decompiler.modules.decompiler.exps; - +@@ -4,6 +4,7 @@ package org.jetbrains.java.decompiler.modules.decompiler.exps; import org.jetbrains.java.decompiler.code.CodeConstants; + import org.jetbrains.java.decompiler.main.ClassesProcessor; import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericType; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; -@@ -111,6 +112,12 @@ public class ConstExprent extends Exprent { +@@ -134,6 +135,12 @@ public class ConstExprent extends Exprent { this.value = value; this.boolPermitted = boolPermitted; addBytecodeOffsets(bytecodeOffsets); @@ -66,13 +66,13 @@ index 4bd94d9f47c9d15ef571412a28b97a0fbbfd45ef..6ed64f77930f44a9c6bd17d2eca51de9 + if (constType.equals(VarType.VARTYPE_CLASS) && value != null) { + String stringVal = value.toString(); + List args = Collections.singletonList(new VarType(stringVal, !stringVal.startsWith("["))); -+ this.constType = new GenericType(constType.type, constType.arrayDim, constType.value, null, args, GenericType.WILDCARD_NO); ++ this.constType = new GenericType(constType.getType(), constType.getArrayDim(), constType.getValue(), null, args, GenericType.WILDCARD_NO); + } } private static VarType guessType(int val, boolean boolPermitted) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java -index 58c3471ff26529c091a44670828d272755e75f7d..8074782862f3842a95050212df0ac5d778f20091 100644 +index d87e027fe9f3a7310d024b3ecda066d546f0a370..b5f3eff75b43be0fffc71bb10839a5ed578beafe 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java @@ -54,6 +54,8 @@ public abstract class Exprent implements IMatchable { @@ -100,7 +100,7 @@ index 58c3471ff26529c091a44670828d272755e75f7d..8074782862f3842a95050212df0ac5d7 - for (int i = 0; i < leftArgs.size(); i++) { - VarType left = leftArgs.get(i); - VarType right = rightArgs.get(i); -- if (left != null && right.value.equals(fparams.get(i))) { +- if (left != null && right.getValue().equals(fparams.get(i))) { - genericArgs.add(left); - map.put(right, left); - } else { @@ -109,7 +109,7 @@ index 58c3471ff26529c091a44670828d272755e75f7d..8074782862f3842a95050212df0ac5d7 - break; - } - } -+ if (upperBound != null && upperBound.isGeneric() && ret.isGeneric() && upperBound.arrayDim == ret.arrayDim) { ++ if (upperBound != null && upperBound.isGeneric() && ret.isGeneric() && upperBound.getArrayDim() == ret.getArrayDim()) { + int left = ((GenericType)upperBound).getArguments().size(); + int right = ((GenericType)ret).getArguments().size(); + if (left == right) { @@ -172,7 +172,7 @@ index 58c3471ff26529c091a44670828d272755e75f7d..8074782862f3842a95050212df0ac5d7 } @@ -311,6 +314,8 @@ public abstract class Exprent implements IMatchable { - buf.prepend("(" + ExprProcessor.getCastTypeName(left) + ")"); + buf.prepend("(" + ExprProcessor.getCastTypeName(left, Collections.emptyList()) + ")"); } + public void setInvocationInstance() {} @@ -181,10 +181,10 @@ index 58c3471ff26529c091a44670828d272755e75f7d..8074782862f3842a95050212df0ac5d7 // IMatchable implementation // ***************************************************************************** diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java -index 880a5d29d0b8c8d92ea7bd8918268742c7efcde5..5143f83d9e4e6fdb6d4e6b54acfaed13a8fdb328 100644 +index be789c6f999339fc4d755850dfd888f600f73a45..66ea2304968dae841fdd736c81e7332c75d9ecd5 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java -@@ -16,6 +16,7 @@ import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribu +@@ -14,6 +14,7 @@ import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribu import org.jetbrains.java.decompiler.struct.consts.LinkConstant; import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; @@ -192,15 +192,15 @@ index 880a5d29d0b8c8d92ea7bd8918268742c7efcde5..5143f83d9e4e6fdb6d4e6b54acfaed13 import org.jetbrains.java.decompiler.struct.match.MatchEngine; import org.jetbrains.java.decompiler.struct.match.MatchNode; import org.jetbrains.java.decompiler.struct.match.MatchNode.RuleValue; -@@ -26,6 +27,7 @@ import org.jetbrains.java.decompiler.util.TextUtil; +@@ -23,6 +24,7 @@ import org.jetbrains.java.decompiler.util.TextUtil; import java.util.ArrayList; import java.util.BitSet; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; - -@@ -76,7 +78,28 @@ public class FieldExprent extends Exprent { + import java.util.Objects; +@@ -74,7 +76,28 @@ public class FieldExprent extends Exprent { } if (ft != null && ft.getSignature() != null) { @@ -210,10 +210,10 @@ index 880a5d29d0b8c8d92ea7bd8918268742c7efcde5..5143f83d9e4e6fdb6d4e6b54acfaed13 + if (instance != null && cl.getSignature() != null) { + VarType instType = instance.getInferredExprType(null); + -+ if (instType.isGeneric() && instType.type != CodeConstants.TYPE_GENVAR) { ++ if (instType.isGeneric() && instType.getType() != CodeConstants.TYPE_GENVAR) { + GenericType ginstance = (GenericType)instType; + -+ cl = DecompilerContext.getStructContext().getClass(instType.value); ++ cl = DecompilerContext.getStructContext().getClass(instType.getValue()); + if (cl != null && cl.getSignature() != null) { + Map tempMap = new HashMap<>(); + cl.getSignature().genericType.mapGenVarsTo(ginstance, tempMap); @@ -231,11 +231,11 @@ index 880a5d29d0b8c8d92ea7bd8918268742c7efcde5..5143f83d9e4e6fdb6d4e6b54acfaed13 return getExprType(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java -index 8f69e433dce5541e5f42693c67fbb9f8610821d2..1f27ed6c5ab25460b0e67c728c7fdcaa23e6c268 100644 +index a735a13e50d76c15800b14d0dd589d2db6947b6e..45a83c38eabb72eb26a618e7b7f8a5288825c6c8 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java -@@ -342,6 +342,11 @@ public class FunctionExprent extends Exprent { - this.needsCast = right.type == CodeConstants.TYPE_NULL || !DecompilerContext.getStructContext().instanceOf(right.value, cast.value); +@@ -339,6 +339,11 @@ public class FunctionExprent extends Exprent { + this.needsCast = right.getType() == CodeConstants.TYPE_NULL || !DecompilerContext.getStructContext().instanceOf(right.getValue(), cast.getValue()); } } + else if (funcType == FUNCTION_IIF) { @@ -246,7 +246,7 @@ index 8f69e433dce5541e5f42693c67fbb9f8610821d2..1f27ed6c5ab25460b0e67c728c7fdcaa return getExprType(); } -@@ -670,6 +675,16 @@ public class FunctionExprent extends Exprent { +@@ -668,6 +673,16 @@ public class FunctionExprent extends Exprent { this.implicitType = implicitType; } @@ -264,19 +264,19 @@ index 8f69e433dce5541e5f42693c67fbb9f8610821d2..1f27ed6c5ab25460b0e67c728c7fdcaa public void getBytecodeRange(BitSet values) { measureBytecode(values, lstOperands); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e84911d208c64 100644 +index dd3cde1a35d189ad7ea847c9f5de2531e4177a1b..0533ef866afdfd90e5bec78866cbd47d8a799ec2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -52,6 +52,7 @@ public class InvocationExprent extends Exprent { private boolean canIgnoreBoxing = true; - private int functype = TYP_GENERAL; + private int funcType = TYPE_GENERAL; private Exprent instance; + private StructMethod desc = null; private MethodDescriptor descriptor; private String stringDescriptor; private String invokeDynamicClassSuffix; @@ -59,6 +60,8 @@ public class InvocationExprent extends Exprent { - private List lstParameters = new ArrayList<>(); + private List parameters = new ArrayList<>(); private List bootstrapArguments; private List genericArgs = new ArrayList<>(); + private Map genericsMap = new HashMap<>(); @@ -284,7 +284,7 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 private boolean forceBoxing = false; private boolean forceUnboxing = false; private boolean isSyntheticNullCheck = false; -@@ -173,45 +176,272 @@ public class InvocationExprent extends Exprent { +@@ -175,45 +178,272 @@ public class InvocationExprent extends Exprent { @Override public VarType getInferredExprType(VarType upperBound) { @@ -293,17 +293,17 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 - if(matches.size() == 1) { - desc = matches.get(0); + if (desc == null) { -+ StructClass cl = DecompilerContext.getStructContext().getClass(classname); ++ StructClass cl = DecompilerContext.getStructContext().getClass(className); + desc = cl != null ? cl.getMethodRecursive(name, stringDescriptor) : null; } genericArgs.clear(); + genericsMap.clear(); + -+ StructClass mthCls = DecompilerContext.getStructContext().getClass(classname); ++ StructClass mthCls = DecompilerContext.getStructContext().getClass(className); + + if (desc != null && mthCls != null) { -+ boolean isNew = functype == TYP_INIT; ++ boolean isNew = funcType == TYPE_INIT; + boolean isGenNew = isNew && mthCls.getSignature() != null; + if (desc.getSignature() != null || isGenNew) { + Map> named = getNamedGenerics(); @@ -317,12 +317,12 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + Map upperBoundsMap = new HashMap<>(); + Map hierarchyMap = new HashMap<>(); + -+ if (!classname.equals(desc.getClassQualifiedName())) { ++ if (!className.equals(desc.getClassQualifiedName())) { + Map> hierarchy = mthCls.getAllGenerics(); + if (hierarchy.containsKey(desc.getClassQualifiedName())) { + hierarchyMap = hierarchy.get(desc.getClassQualifiedName()); + hierarchyMap.forEach((from, to) -> { -+ if (to.type == CodeConstants.TYPE_GENVAR) { ++ if (to.getType() == CodeConstants.TYPE_GENVAR) { + if (bounds.containsKey(to) && !bounds.containsKey(from)) { + bounds.put(from, bounds.get(to)); + } @@ -338,11 +338,11 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 - VarType ret = desc.getSignature().returnType; + // if possible, collect mappings from the ub + // these mappings will be used to help 'fill in the blanks' when creating the ub types for the instance/params -+ if (upperBound != null && !upperBound.equals(VarType.VARTYPE_OBJECT) && (upperBound.type != CodeConstants.TYPE_GENVAR || named.containsKey(upperBound))) { ++ if (upperBound != null && !upperBound.equals(VarType.VARTYPE_OBJECT) && (upperBound.getType() != CodeConstants.TYPE_GENVAR || named.containsKey(upperBound))) { + VarType ub = upperBound; // keep original + VarType r = ret; -+ if (ub.type != CodeConstants.TYPE_GENVAR && r.type != CodeConstants.TYPE_GENVAR && !ub.value.equals(r.value)) { -+ if (DecompilerContext.getStructContext().instanceOf(ub.value, r.value)) { ++ if (ub.getType() != CodeConstants.TYPE_GENVAR && r.getType() != CodeConstants.TYPE_GENVAR && !ub.getValue().equals(r.getValue())) { ++ if (DecompilerContext.getStructContext().instanceOf(ub.getValue(), r.getValue())) { + ub = GenericType.getGenericSuperType(ub, r); + } + else { @@ -350,14 +350,14 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + } + } + -+ if (r.type == CodeConstants.TYPE_GENVAR) { -+ upperBoundsMap.put(r.resizeArrayDim(0), upperBound.resizeArrayDim(upperBound.arrayDim - r.arrayDim)); ++ if (r.getType() == CodeConstants.TYPE_GENVAR) { ++ upperBoundsMap.put(r.resizeArrayDim(0), upperBound.resizeArrayDim(upperBound.getArrayDim() - r.getArrayDim())); + } + else { + gatherGenerics(ub, r, tempMap); + tempMap.forEach((from, to) -> { + if (!genericsMap.containsKey(from)) { -+ if (to != null && (to.type != CodeConstants.TYPE_GENVAR || named.containsKey(to))) { ++ if (to != null && (to.getType() != CodeConstants.TYPE_GENVAR || named.containsKey(to))) { + if (isMappingInBounds(from, to, named, bounds)) { + upperBoundsMap.put(from, to); + } @@ -380,7 +380,7 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + } - if (instType.isGeneric()) { -- StructClass cls = DecompilerContext.getStructContext().getClass(instType.value); +- StructClass cls = DecompilerContext.getStructContext().getClass(instType.getValue()); + // types gathered from the instance have the highest priority + if (instance != null && !isNew) { + instance.setInvocationInstance(); @@ -398,22 +398,22 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + instType = instance.getInferredExprType(instUB); + } + -+ if (instType.type == CodeConstants.TYPE_GENVAR && named.containsKey(instType)) { ++ if (instType.getType() == CodeConstants.TYPE_GENVAR && named.containsKey(instType)) { + instType = named.get(instType).get(0); + } + -+ if (instType.isGeneric() && instType.type != CodeConstants.TYPE_GENVAR) { ++ if (instType.isGeneric() && instType.getType() != CodeConstants.TYPE_GENVAR) { GenericType ginstance = (GenericType)instType; - if (cls.getSignature().fparameters.size() == ginstance.getArguments().size()) { - for (int x = 0; x < ginstance.getArguments().size(); x++) { - if (ginstance.getArguments().get(x) != null) { //TODO: Wildcards are null arguments.. look into fixing things? - map.put(GenericType.parse("T" + cls.getSignature().fparameters.get(x) + ";"), ginstance.getArguments().get(x)); -+ cls = DecompilerContext.getStructContext().getClass(instType.value); ++ cls = DecompilerContext.getStructContext().getClass(instType.getValue()); + if (cls != null && cls.getSignature() != null) { + cls.getSignature().genericType.mapGenVarsTo(ginstance, tempMap); + tempMap.forEach((from, to) -> { -+ if (!fparams.contains(from.value)) { ++ if (!fparams.contains(from.getValue())) { + processGenericMapping(from, to, named, bounds); + } + }); @@ -441,20 +441,20 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + + if (!isInvocationInstance) { + upperBoundsMap.forEach((k, v) -> { -+ if (fparams.contains(k.value) && !GenericType.DUMMY_VAR.equals(v) && !genericsMap.containsKey(k)) { ++ if (fparams.contains(k.getValue()) && !GenericType.DUMMY_VAR.equals(v) && !genericsMap.containsKey(k)) { + genericsMap.put(k, v); + } + }); + } + + Set paramGenerics = new HashSet<>(); -+ if (!lstParameters.isEmpty() && desc.getSignature() != null) { ++ if (!parameters.isEmpty() && desc.getSignature() != null) { + List mask = null; + int start = 0; -+ ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(classname); ++ ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(className); + if (newNode != null) { + if (isNew) { -+ mask = ExprUtil.getSyntheticParametersMask(newNode, stringDescriptor, lstParameters.size()); ++ mask = ExprUtil.getSyntheticParametersMask(newNode, stringDescriptor, parameters.size()); + start = newNode.classStruct.hasModifier(CodeConstants.ACC_ENUM) ? 2 : 0; + } else if (!newNode.enclosingClasses.isEmpty()) { + start = !newNode.classStruct.hasModifier(CodeConstants.ACC_STATIC) ? 1 : 0; @@ -462,7 +462,7 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + } + + int j = 0; -+ for (int i = start; i < lstParameters.size(); ++i) { ++ for (int i = start; i < parameters.size(); ++i) { + if (mask == null || mask.get(i) == null) { + VarType paramType = desc.getSignature().parameterTypes.get(j++); + if (paramType.isGeneric()) { @@ -475,18 +475,18 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + VarType paramUB = paramType.remap(hierarchyMap).remap(combined); + + VarType argtype; -+ if (lstParameters.get(i).type == EXPRENT_FUNCTION && ((FunctionExprent)lstParameters.get(i)).getFuncType() == FunctionExprent.FUNCTION_CAST) { -+ argtype = ((FunctionExprent)lstParameters.get(i)).getLstOperands().get(0).getInferredExprType(paramUB); ++ if (parameters.get(i).type == EXPRENT_FUNCTION && ((FunctionExprent)parameters.get(i)).getFuncType() == FunctionExprent.FUNCTION_CAST) { ++ argtype = ((FunctionExprent)parameters.get(i)).getLstOperands().get(0).getInferredExprType(paramUB); + } + else { -+ argtype = lstParameters.get(i).getInferredExprType(paramUB); ++ argtype = parameters.get(i).getInferredExprType(paramUB); + } + -+ StructClass paramCls = DecompilerContext.getStructContext().getClass(paramType.value); -+ cls = argtype.type != CodeConstants.TYPE_GENVAR ? DecompilerContext.getStructContext().getClass(argtype.value) : null; ++ StructClass paramCls = DecompilerContext.getStructContext().getClass(paramType.getValue()); ++ cls = argtype.getType() != CodeConstants.TYPE_GENVAR ? DecompilerContext.getStructContext().getClass(argtype.getValue()) : null; + + if (cls != null && paramCls != null) { -+ if (paramType.isGeneric() && !paramType.value.equals(argtype.value)) { ++ if (paramType.isGeneric() && !paramType.getValue().equals(argtype.getValue())) { + argtype = GenericType.getGenericSuperType(argtype, paramType); + } + @@ -502,9 +502,9 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + tempMap.clear(); + } + } -+ else if (paramType.type == CodeConstants.TYPE_GENVAR && !paramType.equals(argtype) && argtype.arrayDim >= paramType.arrayDim) { -+ if (paramType.arrayDim > 0) { -+ argtype = argtype.resizeArrayDim(argtype.arrayDim - paramType.arrayDim); ++ else if (paramType.getType() == CodeConstants.TYPE_GENVAR && !paramType.equals(argtype) && argtype.getArrayDim() >= paramType.getArrayDim()) { ++ if (paramType.getArrayDim() > 0) { ++ argtype = argtype.resizeArrayDim(argtype.getArrayDim() - paramType.getArrayDim()); + paramType = paramType.resizeArrayDim(0); + } + paramGenerics.add(paramType); @@ -516,7 +516,7 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + } + + upperBoundsMap.forEach((k, v) -> { -+ if (fparams.contains(k.value) && !GenericType.DUMMY_VAR.equals(v)) { ++ if (fparams.contains(k.getValue()) && !GenericType.DUMMY_VAR.equals(v)) { + processGenericMapping(k, v ,named, bounds); + } + }); @@ -529,7 +529,7 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + boolean skipArgs = true; + if (!fparams.isEmpty() && newRet.isGeneric()) { + for (VarType genVar : ((GenericType)newRet).getAllGenericVars()) { -+ if (fparams.contains(genVar.value)) { ++ if (fparams.contains(genVar.getValue())) { + skipArgs = false; + break; + } @@ -554,7 +554,7 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + } + + boolean suppress = (!missing || !isInvocationInstance) && -+ (upperBound == null || !newRet.isGeneric() || DecompilerContext.getStructContext().instanceOf(newRet.value, upperBound.value)); ++ (upperBound == null || !newRet.isGeneric() || DecompilerContext.getStructContext().instanceOf(newRet.getValue(), upperBound.getValue())); + + if (!suppress || DecompilerContext.getOption(IFernflowerPreferences.EXPLICIT_GENERIC_ARGUMENTS)) { + getGenericArgs(fparams, genericsMap, genericArgs); @@ -579,13 +579,13 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 } } -@@ -314,7 +544,19 @@ public class InvocationExprent extends Exprent { +@@ -316,7 +546,19 @@ public class InvocationExprent extends Exprent { TextUtil.writeQualifiedSuper(buf, super_qualifier); } else if (instance != null) { -+ StructClass cl = DecompilerContext.getStructContext().getClass(classname); ++ StructClass cl = DecompilerContext.getStructContext().getClass(className); + - VarType leftType = new VarType(CodeConstants.TYPE_OBJECT, 0, classname); + VarType leftType = new VarType(CodeConstants.TYPE_OBJECT, 0, className); + if (!genericsMap.isEmpty() && cl != null && cl.getSignature() != null) { + VarType _new = cl.getSignature().genericType.remap(genericsMap); + if (_new != cl.getSignature().genericType) { @@ -599,7 +599,7 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 if (isUnboxingCall() && !forceUnboxing) { // we don't print the unboxing call - no need to bother with the instance wrapping / casting if (instance.type == Exprent.EXPRENT_FUNCTION) { -@@ -343,7 +585,8 @@ public class InvocationExprent extends Exprent { +@@ -345,7 +587,8 @@ public class InvocationExprent extends Exprent { TextBuffer res = instance.toJava(indent, tracer); @@ -608,8 +608,8 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + ((FunctionExprent)instance).getFuncType() == FunctionExprent.FUNCTION_CAST && !((FunctionExprent)instance).doesCast(); if (rightType.equals(VarType.VARTYPE_OBJECT) && !leftType.equals(rightType)) { - buf.append("((").append(ExprProcessor.getCastTypeName(leftType)).append(")"); -@@ -353,7 +596,7 @@ public class InvocationExprent extends Exprent { + buf.append("((").append(ExprProcessor.getCastTypeName(leftType, Collections.emptyList())).append(")"); +@@ -355,7 +598,7 @@ public class InvocationExprent extends Exprent { } buf.append(res).append(")"); } @@ -618,7 +618,7 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 buf.append("(").append(res).append(")"); } else { -@@ -399,6 +642,12 @@ public class InvocationExprent extends Exprent { +@@ -401,6 +644,12 @@ public class InvocationExprent extends Exprent { } } @@ -630,8 +630,8 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + TextBuffer buf = new TextBuffer(); List mask = null; boolean isEnum = false; - if (functype == TYP_INIT) { -@@ -411,28 +660,6 @@ public class InvocationExprent extends Exprent { + if (funcType == TYPE_INIT) { +@@ -413,28 +662,6 @@ public class InvocationExprent extends Exprent { ClassNode currCls = ((ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE)); List matches = getMatchedDescriptors(); BitSet setAmbiguousParameters = getAmbiguousParameters(matches); @@ -640,7 +640,7 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 - desc = matches.get(0); - } - -- StructClass cl = DecompilerContext.getStructContext().getClass(classname); +- StructClass cl = DecompilerContext.getStructContext().getClass(className); - Map genArgs = new HashMap(); - - // building generic info from the instance @@ -659,13 +659,13 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 - } // omit 'new Type[] {}' for the last parameter of a vararg method call - if (lstParameters.size() == descriptor.params.length && isVarArgCall()) { -@@ -521,20 +748,32 @@ public class InvocationExprent extends Exprent { + if (parameters.size() == descriptor.params.length && isVarArgCall()) { +@@ -523,20 +750,32 @@ public class InvocationExprent extends Exprent { } } - if (instance != null && !genArgs.isEmpty()) { -- StructClass stClass = DecompilerContext.getStructContext().getClass(classname); +- StructClass stClass = DecompilerContext.getStructContext().getClass(className); - StructMethod me = stClass.getMethodRecursive(getName(), getStringDescriptor()); - if (me != null && me.getSignature() != null) { - for (int x = 0; x < types.length; x++) { @@ -680,12 +680,12 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + if (desc == null) { + this.getInferredExprType(null); + -+ if (genericsMap.isEmpty() && instance != null && functype != TYP_INIT) { ++ if (genericsMap.isEmpty() && instance != null && funcType != TYPE_INIT) { + VarType instType = instance.getInferredExprType(null); -+ if (instType.isGeneric() && instType.type != CodeConstants.TYPE_GENVAR) { ++ if (instType.isGeneric() && instType.getType() != CodeConstants.TYPE_GENVAR) { + GenericType ginstance = (GenericType)instType; + -+ StructClass cls = DecompilerContext.getStructContext().getClass(instType.value); ++ StructClass cls = DecompilerContext.getStructContext().getClass(instType.getValue()); + if (cls != null && cls.getSignature() != null) { + cls.getSignature().genericType.mapGenVarsTo(ginstance, genericsMap); + } @@ -706,18 +706,18 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 } -@@ -572,6 +811,10 @@ public class InvocationExprent extends Exprent { +@@ -574,6 +813,10 @@ public class InvocationExprent extends Exprent { } */ -+ if (i == parameters.size() - 1 && lstParameters.get(i).getExprType() == VarType.VARTYPE_NULL && NewExprent.probablySyntheticParameter(descriptor.params[i].value)) { ++ if (i == parameters.size() - 1 && this.parameters.get(i).getExprType() == VarType.VARTYPE_NULL && NewExprent.probablySyntheticParameter(descriptor.params[i].getValue())) { + break; // skip last parameter of synthetic constructor call + } + // 'byte' and 'short' literals need an explicit narrowing type cast when used as a parameter - ExprProcessor.getCastedExprent(lstParameters.get(i), types[i], buff, indent, true, ambiguous, true, true, tracer); + ExprProcessor.getCastedExprent(this.parameters.get(i), types[i], buff, indent, true, ambiguous, true, true, tracer); -@@ -587,8 +830,6 @@ public class InvocationExprent extends Exprent { +@@ -589,8 +832,6 @@ public class InvocationExprent extends Exprent { } } @@ -726,12 +726,12 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 return buf; } -@@ -884,6 +1125,162 @@ public class InvocationExprent extends Exprent { +@@ -889,6 +1130,162 @@ public class InvocationExprent extends Exprent { return ambiguous; } + private void processGenericMapping(VarType from, VarType to, Map> named, Map> bounds) { -+ if (VarType.VARTYPE_NULL.equals(to) || (to != null && to.type == CodeConstants.TYPE_GENVAR && !named.containsKey(to))) { ++ if (VarType.VARTYPE_NULL.equals(to) || (to != null && to.getType() == CodeConstants.TYPE_GENVAR && !named.containsKey(to))) { + return; + } + @@ -744,10 +744,10 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + return; + } + -+ if (current.type != CodeConstants.TYPE_GENVAR && to.type == CodeConstants.TYPE_GENVAR) { ++ if (current.getType() != CodeConstants.TYPE_GENVAR && to.getType() == CodeConstants.TYPE_GENVAR) { + if (named.containsKey(to)) { + VarType bound = named.get(to).get(0); -+ if (!bound.equals(VarType.VARTYPE_OBJECT) && DecompilerContext.getStructContext().instanceOf(bound.value, current.value)) { ++ if (!bound.equals(VarType.VARTYPE_OBJECT) && DecompilerContext.getStructContext().instanceOf(bound.getValue(), current.getValue())) { + return; + } + } @@ -770,12 +770,12 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + return false; + } + -+ if (to == null || (to.type == CodeConstants.TYPE_GENVAR && !named.containsKey(to))) { ++ if (to == null || (to.getType() == CodeConstants.TYPE_GENVAR && !named.containsKey(to))) { + return true; + } + + java.util.function.BiFunction verifier = (newTo, bound) -> { -+ if (bound.type == CodeConstants.TYPE_GENVAR) { ++ if (bound.getType() == CodeConstants.TYPE_GENVAR) { + java.util.function.Function map = e -> { + VarType mapped = genericsMap.get(e); + if (mapped == null) @@ -792,19 +792,19 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + } + bound = last; + -+ if (bound.type != CodeConstants.TYPE_GENVAR) { -+ return DecompilerContext.getStructContext().instanceOf(newTo.value, bound.value); ++ if (bound.getType() != CodeConstants.TYPE_GENVAR) { ++ return DecompilerContext.getStructContext().instanceOf(newTo.getValue(), bound.getValue()); + } + } + + return isMappingInBounds(bound, newTo, named, bounds); + } + -+ if (newTo.type < CodeConstants.TYPE_OBJECT) { ++ if (newTo.getType() < CodeConstants.TYPE_OBJECT) { + return bound.equals(VarType.VARTYPE_OBJECT) || bound.equals(newTo); + } + -+ if (!DecompilerContext.getStructContext().instanceOf(newTo.value, bound.value)) { ++ if (!DecompilerContext.getStructContext().instanceOf(newTo.getValue(), bound.getValue())) { + return false; + } + @@ -812,7 +812,7 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + GenericType genbound = (GenericType)bound; + VarType _new = newTo; + -+ if (!newTo.value.equals(bound.value)) { ++ if (!newTo.getValue().equals(bound.getValue())) { + _new = GenericType.getGenericSuperType(newTo, bound); + } + @@ -849,7 +849,7 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + return true; + }; + -+ List toVerify = (to.type == CodeConstants.TYPE_GENVAR) ? named.get(to) : Collections.singletonList(to); ++ List toVerify = (to.getType() == CodeConstants.TYPE_GENVAR) ? named.get(to) : Collections.singletonList(to); + + // We need to satisfy all the bounds for the type we are mapping to + // The bounds can be satisfied by any of the bounds for the named type @@ -889,7 +889,7 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 @Override public void replaceExprent(Exprent oldExpr, Exprent newExpr) { if (oldExpr == instance) { -@@ -996,6 +1393,18 @@ public class InvocationExprent extends Exprent { +@@ -1001,6 +1398,18 @@ public class InvocationExprent extends Exprent { return isSyntheticNullCheck; } @@ -907,9 +907,9 @@ index 4dc461a2da1073a74d9df787ff21d9f27a5a59f2..286c050b26e0b5e46f846e670b0e8491 + @Override public void getBytecodeRange(BitSet values) { - measureBytecode(values, lstParameters); + measureBytecode(values, parameters); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java -index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb21290803108b 100644 +index 5ee4fb58a5687a0e26558fbc4fdaa989695bc6fa..8dfeba4a200154d32b89c6980022792c0fae1f23 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -5,7 +5,16 @@ import org.jetbrains.java.decompiler.code.CodeConstants; @@ -929,21 +929,7 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 import org.jetbrains.java.decompiler.util.TextBuffer; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; -@@ -21,9 +30,13 @@ import org.jetbrains.java.decompiler.util.ListStack; - import org.jetbrains.java.decompiler.util.TextBuffer; - - import java.util.ArrayList; -+import java.util.Arrays; - import java.util.BitSet; - import java.util.Collections; -+import java.util.HashMap; -+import java.util.LinkedList; - import java.util.List; -+import java.util.Map; - - public class NewExprent extends Exprent { - private InvocationExprent constructor; -@@ -37,6 +50,7 @@ public class NewExprent extends Exprent { +@@ -33,6 +42,7 @@ public class NewExprent extends Exprent { private boolean methodReference = false; private boolean enumConst; private List genericArgs = new ArrayList<>(); @@ -951,13 +937,13 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 public NewExprent(VarType newType, ListStack stack, int arrayDim, BitSet bytecodeOffsets) { this(newType, getDimensions(arrayDim, stack), bytecodeOffsets); -@@ -79,18 +93,162 @@ public class NewExprent extends Exprent { +@@ -75,14 +85,158 @@ public class NewExprent extends Exprent { @Override public VarType getInferredExprType(VarType upperBound) { genericArgs.clear(); -- if (newType.type == CodeConstants.TYPE_OBJECT && newType.arrayDim == 0) { -+ if (!lambda && newType.type == CodeConstants.TYPE_OBJECT) { - StructClass node = DecompilerContext.getStructContext().getClass(newType.value); +- if (newType.getType() == CodeConstants.TYPE_OBJECT && newType.getArrayDim() == 0) { ++ if (!lambda && newType.getType() == CodeConstants.TYPE_OBJECT) { + StructClass node = DecompilerContext.getStructContext().getClass(newType.getValue()); if (node != null && node.getSignature() != null) { - GenericClassDescriptor sig = node.getSignature(); @@ -970,11 +956,11 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 + } + return node.getSignature().superclass; + } -+ else if (newType.arrayDim == 0 && !node.getSignature().fparameters.isEmpty()) { ++ else if (newType.getArrayDim() == 0 && !node.getSignature().fparameters.isEmpty()) { + GenericClassDescriptor sig = node.getSignature(); + if (constructor != null) { + VarType ret = constructor.getInferredExprType(upperBound); -+ return ret.type != CodeConstants.TYPE_VOID ? ret : getExprType(); ++ return ret.getType() != CodeConstants.TYPE_VOID ? ret : getExprType(); + } + else { + Map genericsMap = new HashMap<>(); @@ -987,9 +973,9 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 + } + } + } -+ else if (newType.arrayDim > 0 && !lstArrayElements.isEmpty() && newType.value.equals(VarType.VARTYPE_OBJECT.value)) { ++ else if (newType.getArrayDim() > 0 && !lstArrayElements.isEmpty() && newType.getValue().equals(VarType.VARTYPE_OBJECT.getValue())) { + VarType first = lstArrayElements.get(0).getInferredExprType(null); -+ if (first.type == CodeConstants.TYPE_GENVAR) { ++ if (first.getType() == CodeConstants.TYPE_GENVAR) { + boolean matches = true; + for (int i = 1; i < lstArrayElements.size(); ++i) { + VarType type = lstArrayElements.get(i).getInferredExprType(null); @@ -999,19 +985,19 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 + } + } + if (matches) { -+ return first.resizeArrayDim(newType.arrayDim); ++ return first.resizeArrayDim(newType.getArrayDim()); + } + } + } + } + + if (lambda) { -+ ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value); ++ ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.getValue()); + + if (node != null) { + + VarType classType = node.anonymousClassType; -+ StructClass cls = DecompilerContext.getStructContext().getClass(classType.value); ++ StructClass cls = DecompilerContext.getStructContext().getClass(classType.getValue()); + MethodDescriptor desc = MethodDescriptor.parseDescriptor(node.lambdaInformation.method_descriptor); + StructClass methodCls = DecompilerContext.getStructContext().getClass(node.lambdaInformation.content_class_name); + @@ -1040,7 +1026,7 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 + for (int i = 0; i < method.getSignature().parameterTypes.size(); ++i) { + VarType mtype = method.getSignature().parameterTypes.get(i); + VarType rtype = refMethod.getSignature().parameterTypes.get(i); -+ if (mtype.type == CodeConstants.TYPE_GENVAR && rtype.type == CodeConstants.TYPE_GENVAR) { ++ if (mtype.getType() == CodeConstants.TYPE_GENVAR && rtype.getType() == CodeConstants.TYPE_GENVAR) { + if (genericsMap.containsKey(rtype)) { + instanceMap.put(mtype, genericsMap.get(rtype)); + } @@ -1052,19 +1038,19 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 + // generated lambda methods have no generic info, so only map to generic var parameters + List types = method.getSignature() != null ? method.getSignature().parameterTypes : Arrays.asList(desc.params); + for (int i = 0; i < types.size(); ++i) { -+ if (refMethod.getSignature().parameterTypes.get(i).type == CodeConstants.TYPE_GENVAR) { ++ if (refMethod.getSignature().parameterTypes.get(i).getType() == CodeConstants.TYPE_GENVAR) { + if (!genericsMap.containsKey(refMethod.getSignature().parameterTypes.get(i))) { + VarType realType = types.get(i); -+ StructClass typeCls = DecompilerContext.getStructContext().getClass(realType.value); ++ StructClass typeCls = DecompilerContext.getStructContext().getClass(realType.getValue()); + if (typeCls != null && typeCls.getSignature() != null && !realType.equals(typeCls.getSignature().genericType)) { -+ realType = typeCls.getSignature().genericType.resizeArrayDim(realType.arrayDim); ++ realType = typeCls.getSignature().genericType.resizeArrayDim(realType.getArrayDim()); + } + genericsMap.put(refMethod.getSignature().parameterTypes.get(i), realType); + } + } + } + -+ if (refMethod.getSignature().returnType.type == CodeConstants.TYPE_GENVAR) { ++ if (refMethod.getSignature().returnType.getType() == CodeConstants.TYPE_GENVAR) { + VarType key = refMethod.getSignature().returnType; + if (method.getName().equals(CodeConstants.INIT_NAME)) { + if (methodCls.getSignature() != null) { @@ -1077,7 +1063,7 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 + else if (method.getSignature() != null || !desc.ret.equals(VarType.VARTYPE_OBJECT)) { + VarType current = genericsMap.get(key); + VarType returnType = method.getSignature() != null ? method.getSignature().returnType.remap(instanceMap) : desc.ret; -+ StructClass retCls = returnType == null ? null : DecompilerContext.getStructContext().getClass(returnType.value); ++ StructClass retCls = returnType == null ? null : DecompilerContext.getStructContext().getClass(returnType.getValue()); + + if (!isMethodReference() && retCls != null && retCls.getSignature() != null && !retCls.getSignature().genericType.equalsExact(returnType)) { + VarType retUB = current != null && current.equals(returnType) ? current : returnType; @@ -1088,7 +1074,7 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 + } + + boolean add = current == null || returnType == null || returnType.isGeneric() || -+ (!returnType.equals(genericsMap.get(key)) && (current.type != CodeConstants.TYPE_GENVAR || !named.containsKey(current))); ++ (!returnType.equals(genericsMap.get(key)) && (current.getType() != CodeConstants.TYPE_GENVAR || !named.containsKey(current))); + if (add) { + genericsMap.put(key, returnType); + } @@ -1115,12 +1101,7 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 } } } -- -+ - return getExprType(); - } - -@@ -214,30 +372,13 @@ public class NewExprent extends Exprent { +@@ -210,30 +364,13 @@ public class NewExprent extends Exprent { } } @@ -1128,11 +1109,11 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 - buf.append('('); - if (!lambda && constructor != null) { -- List parameters = constructor.getLstParameters(); +- List parameters = constructor.getParameters(); - List mask = child.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, constructor.getStringDescriptor()).synthParameters; - if (mask == null) { - InvocationExprent superCall = child.superInvocation; -- mask = ExprUtil.getSyntheticParametersMask(superCall.getClassname(), superCall.getStringDescriptor(), parameters.size()); +- mask = ExprUtil.getSyntheticParametersMask(superCall.getClassName(), superCall.getStringDescriptor(), parameters.size()); - } - - int start = enumConst ? 2 : 0; @@ -1157,7 +1138,7 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 } buf.append(')'); -@@ -250,6 +391,7 @@ public class NewExprent extends Exprent { +@@ -246,6 +383,7 @@ public class NewExprent extends Exprent { if (!DecompilerContext.getOption(IFernflowerPreferences.LAMBDA_TO_ANONYMOUS_CLASS)) { buf.setLength(0); // remove the usual 'new ()', it will be replaced with lambda style '() ->' } @@ -1165,12 +1146,12 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 Exprent methodObject = constructor == null ? null : constructor.getInstance(); TextBuffer clsBuf = new TextBuffer(); new ClassWriter().classLambdaToJava(child, clsBuf, methodObject, indent, tracer); -@@ -301,35 +443,10 @@ public class NewExprent extends Exprent { +@@ -297,36 +435,10 @@ public class NewExprent extends Exprent { } if (constructor != null) { -- List parameters = constructor.getLstParameters(); -- List mask = ExprUtil.getSyntheticParametersMask(constructor.getClassname(), constructor.getStringDescriptor(), parameters.size()); +- List parameters = constructor.getParameters(); +- List mask = ExprUtil.getSyntheticParametersMask(constructor.getClassName(), constructor.getStringDescriptor(), parameters.size()); - int start = enumConst ? 2 : 0; - if (!enumConst || start < parameters.size()) { @@ -1183,7 +1164,8 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 - Exprent expr = parameters.get(i); - VarType leftType = constructor.getDescriptor().params[i]; - -- if (i == parameters.size() - 1 && expr.getExprType() == VarType.VARTYPE_NULL && probablySyntheticParameter(leftType.value)) { +- if (i == parameters.size() - 1 && expr.getExprType() == VarType.VARTYPE_NULL && probablySyntheticParameter( +- leftType.getValue())) { - break; // skip last parameter of synthetic constructor call - } - @@ -1198,13 +1180,13 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 - } - - buf.append(')'); -+ if (!enumConst || start < constructor.getLstParameters().size()) { ++ if (!enumConst || start < constructor.getParameters().size()) { + appendParameters(buf, constructor.getGenericArgs()); + buf.append('(').append(constructor.appendParamList(indent, tracer)).append(')'); } } } -@@ -389,7 +506,8 @@ public class NewExprent extends Exprent { +@@ -386,7 +498,8 @@ public class NewExprent extends Exprent { return buf; } @@ -1214,7 +1196,7 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(className); return node != null && node.type == ClassNode.CLASS_ANONYMOUS; } -@@ -427,6 +545,158 @@ public class NewExprent extends Exprent { +@@ -424,6 +537,158 @@ public class NewExprent extends Exprent { return null; } @@ -1249,7 +1231,7 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 + } + } + } -+ index += md_content.params[i].stackSize; ++ index += md_content.params[i].getStackSize(); + } + + DummyExitStatement dummyExit = mt.root.getDummyExit(); @@ -1281,8 +1263,8 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 + + private void setLambdaGenericTypes() { + if (inferredLambdaType != null) { -+ ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value); -+ StructClass cls = DecompilerContext.getStructContext().getClass(inferredLambdaType.value); ++ ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.getValue()); ++ StructClass cls = DecompilerContext.getStructContext().getClass(inferredLambdaType.getValue()); + + if (node != null && cls != null) { + StructMethod desc = cls.getMethod(getLambdaMethodKey()); @@ -1290,7 +1272,7 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 + MethodWrapper methodWrapper = wrapper != null ? wrapper.getMethodWrapper(node.lambdaInformation.content_method_name, node.lambdaInformation.content_method_descriptor) : null; + + if (desc != null && desc.getSignature() != null && methodWrapper != null && methodWrapper.root != null) { -+ if (!desc.getClassQualifiedName().equals(inferredLambdaType.value)) { ++ if (!desc.getClassQualifiedName().equals(inferredLambdaType.getValue())) { + StructClass candidate = DecompilerContext.getStructContext().getClass(desc.getClassQualifiedName()); + if (candidate.getSignature() != null) { + cls = candidate; @@ -1337,7 +1319,7 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 + } + } + } -+ index += md_content.params[i].stackSize; ++ index += md_content.params[i].getStackSize(); + } + + VarType curType = md_content.ret; @@ -1373,7 +1355,7 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 @Override public void replaceExprent(Exprent oldExpr, Exprent newExpr) { if (oldExpr == constructor) { -@@ -531,4 +801,10 @@ public class NewExprent extends Exprent { +@@ -528,4 +793,10 @@ public class NewExprent extends Exprent { } return ""; } @@ -1385,12 +1367,12 @@ index bf254b8d843526d872092f4b0a000b13baef518a..2bf3ce1584a2926a628318b7dacb2129 + } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java -index 899ca15489fb70ff5f81aa3c947ca4c228ba1d31..f4f21c900d1e0763eeb049a550847d0497e0e7c5 100644 +index c571b8463712cff5eeeab9d28df9d23feee42bc6..eea545270ec8d5bff3e4f0eae01520f8756022d3 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java -@@ -14,6 +14,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult; +@@ -13,6 +13,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; + import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; - import org.jetbrains.java.decompiler.modules.decompiler.vars.VarTypeProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; +import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructMethod; @@ -1418,12 +1400,12 @@ index 899ca15489fb70ff5f81aa3c947ca4c228ba1d31..f4f21c900d1e0763eeb049a550847d04 + } } - if (vt == null || (varType != null && varType.type != CodeConstants.TYPE_UNKNOWN)) { + if (vt == null || (varType != null && varType.getType() != CodeConstants.TYPE_UNKNOWN)) { diff --git a/src/org/jetbrains/java/decompiler/struct/StructClass.java b/src/org/jetbrains/java/decompiler/struct/StructClass.java -index 8753a258b8a93d487a3bc268a5bb3bd53e86cb1d..0a6e5b74b7a8b07368a0c1970faab818cea6a9d8 100644 +index 894c8e5f0c28ef64acfe392f433ea56f37437054..3e0cbd0fbcbc29ff619d4b2441b13047bb803d11 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructClass.java +++ b/src/org/jetbrains/java/decompiler/struct/StructClass.java -@@ -19,6 +19,7 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; +@@ -21,6 +21,7 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.jetbrains.java.decompiler.util.VBStyleCollection; import java.io.IOException; @@ -1431,7 +1413,7 @@ index 8753a258b8a93d487a3bc268a5bb3bd53e86cb1d..0a6e5b74b7a8b07368a0c1970faab818 import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -@@ -351,4 +352,28 @@ public class StructClass extends StructMember { +@@ -396,4 +397,28 @@ public class StructClass extends StructMember { this.genericHiarachy = ret.isEmpty() ? Collections.emptyMap() : ret; return this.genericHiarachy; } @@ -1461,7 +1443,7 @@ index 8753a258b8a93d487a3bc268a5bb3bd53e86cb1d..0a6e5b74b7a8b07368a0c1970faab818 + } } diff --git a/src/org/jetbrains/java/decompiler/struct/StructContext.java b/src/org/jetbrains/java/decompiler/struct/StructContext.java -index 83be1cad514f1a48f93db75a1e85dacae14cd105..5aa59c4d71dc73bbc8875879ac4c90ab030d6920 100644 +index bbbec18e87c940d7daa6983a9ca2b5220e7e2470..0f3dc610ec134a438e81561ee2b15bb97edc3fb3 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructContext.java +++ b/src/org/jetbrains/java/decompiler/struct/StructContext.java @@ -209,6 +209,24 @@ public class StructContext { @@ -1490,10 +1472,10 @@ index 83be1cad514f1a48f93db75a1e85dacae14cd105..5aa59c4d71dc73bbc8875879ac4c90ab for (String line : string.split("\n")) { String[] pts = line.split(" "); diff --git a/src/org/jetbrains/java/decompiler/struct/gen/VarType.java b/src/org/jetbrains/java/decompiler/struct/gen/VarType.java -index af6b8995f8396efdcaa82fae195dd8c3d107b5a7..88bf2ef12b66bf190249ed8d3703c43be11c7c33 100644 +index d8388e50f6c88e91a0007854400e756153cdb4a6..ab44a6ab25070cb0069c2f55584a992736051420 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/VarType.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/VarType.java -@@ -423,8 +423,10 @@ public class VarType { // TODO: optimize switch +@@ -445,8 +445,10 @@ public class VarType implements Type { // TODO: optimize switch } public VarType remap(Map map) { @@ -1507,27 +1489,30 @@ index af6b8995f8396efdcaa82fae195dd8c3d107b5a7..88bf2ef12b66bf190249ed8d3703c43b return this; } diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java -index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd849e4c3c64 100644 +index 9e9e64933f89c72460c12dea174429c80cbbfcbb..497caabc5178d8c56ffe185302f9c3fe16758ab5 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java -@@ -4,12 +4,16 @@ package org.jetbrains.java.decompiler.struct.gen.generics; - import org.jetbrains.java.decompiler.code.CodeConstants; +@@ -5,15 +5,19 @@ import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; + import org.jetbrains.java.decompiler.modules.decompiler.typeann.TypeAnnotationWriteHelper; +import org.jetbrains.java.decompiler.struct.StructClass; + import org.jetbrains.java.decompiler.struct.gen.Type; import org.jetbrains.java.decompiler.struct.gen.VarType; -+import org.jetbrains.java.decompiler.util.InterpreterUtil; import java.util.ArrayList; + import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; + import java.util.regex.Pattern; ++import java.util.Objects; +import java.util.Set; - public class GenericType extends VarType { + public class GenericType extends VarType implements Type { -@@ -22,6 +26,8 @@ public class GenericType extends VarType { +@@ -28,6 +32,8 @@ public class GenericType extends VarType implements Type { private final List arguments; private final int wildcard; @@ -1536,31 +1521,31 @@ index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd84 public GenericType(int type, int arrayDim, String value, VarType parent, List arguments, int wildcard) { super(type, arrayDim, value, getFamily(type, arrayDim), getStackSize(type, arrayDim), false); this.parent = parent; -@@ -237,6 +243,14 @@ public class GenericType extends VarType { +@@ -243,6 +249,14 @@ public class GenericType extends VarType implements Type { return value.substring(0, index + 1); } + public static VarType withWildcard(VarType var, int wildcard) { + if (var.isGeneric()) { + GenericType genVar = (GenericType)var; -+ return new GenericType(genVar.type, genVar.arrayDim, genVar.value, genVar.parent, genVar.arguments, wildcard); ++ return new GenericType(genVar.getType(), genVar.getArrayDim(), genVar.getValue(), genVar.parent, genVar.arguments, wildcard); + } -+ return new GenericType(var.type, var.arrayDim, var.value, null, Collections.emptyList(), wildcard); ++ return new GenericType(var.getType(), var.getArrayDim(), var.getValue(), null, Collections.emptyList(), wildcard); + } + public GenericType decreaseArrayDim() { - assert arrayDim > 0 : this; - return new GenericType(type, arrayDim - 1, value, parent, arguments, wildcard); -@@ -255,7 +269,7 @@ public class GenericType extends VarType { - } + assert getArrayDim() > 0 : this; + return new GenericType(getType(), getArrayDim() - 1, getValue(), parent, arguments, wildcard); +@@ -262,7 +276,7 @@ public class GenericType extends VarType implements Type { + @Override public boolean isGeneric() { - return true; -+ return type == CodeConstants.TYPE_GENVAR || !arguments.isEmpty() || parent != null || wildcard != WILDCARD_NO; ++ return getType() == CodeConstants.TYPE_GENVAR || !arguments.isEmpty() || parent != null || wildcard != WILDCARD_NO; } public int getWildcard() { -@@ -333,6 +347,10 @@ public class GenericType extends VarType { +@@ -345,6 +359,10 @@ public class GenericType extends VarType implements Type { public VarType remap(Map map) { VarType main = super.remap(map); if (main != this) { @@ -1571,7 +1556,7 @@ index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd84 return main; } boolean changed = false; -@@ -359,4 +377,267 @@ public class GenericType extends VarType { +@@ -371,4 +389,267 @@ public class GenericType extends VarType implements Type { } return this; } @@ -1590,7 +1575,7 @@ index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd84 + } + + GenericType gt = (GenericType)o; -+ if (type != gt.type || arrayDim != gt.arrayDim || wildcard != gt.wildcard || !InterpreterUtil.equalObjects(value, gt.value)) { ++ if (getType() != gt.getType() || getArrayDim() != gt.getArrayDim() || wildcard != gt.wildcard || !Objects.equals(getValue(), gt.getValue())) { + return false; + } + @@ -1622,19 +1607,19 @@ index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd84 + } + + public static boolean isAssignable(VarType from, VarType to, Map> named) { -+ if (from.arrayDim != to.arrayDim) { ++ if (from.getArrayDim() != to.getArrayDim()) { + return false; + } + -+ if (from.type == CodeConstants.TYPE_OBJECT && from.type == to.type) { -+ if (!DecompilerContext.getStructContext().instanceOf(from.value, to.value)) { ++ if (from.getType() == CodeConstants.TYPE_OBJECT && from.getType() == to.getType()) { ++ if (!DecompilerContext.getStructContext().instanceOf(from.getValue(), to.getValue())) { + return false; + } + } + else if (!from.equals(to)) { -+ if (from.type == CodeConstants.TYPE_GENVAR && from.type != to.type && named.containsKey(from)) { ++ if (from.getType() == CodeConstants.TYPE_GENVAR && from.getType() != to.getType() && named.containsKey(from)) { + return named.get(from).stream().anyMatch(bound -> { -+ if (to.isGeneric() && !bound.value.equals(to.value)) { ++ if (to.isGeneric() && !bound.getValue().equals(to.getValue())) { + VarType _new = getGenericSuperType(bound, to); + + if (bound != _new && _new.isGeneric()) { @@ -1650,7 +1635,7 @@ index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd84 + } + } + -+ if (to.isGeneric() && !from.value.equals(to.value)) { ++ if (to.isGeneric() && !from.getValue().equals(to.getValue())) { + VarType _new = getGenericSuperType(from, to); + + if (from != _new && _new.isGeneric()) { @@ -1681,14 +1666,14 @@ index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd84 + int tWild = t.isGeneric() ? ((GenericType)t).wildcard : WILDCARD_NO; + + if (f == null) { -+ StructClass cls = DecompilerContext.getStructContext().getClass(genFrom.value); ++ StructClass cls = DecompilerContext.getStructContext().getClass(genFrom.getValue()); + VarType bounds = cls.getSignature().fbounds.get(i).get(0); + if (VarType.VARTYPE_OBJECT.equals(bounds)) { + return false; + } + f = bounds; + } -+ else if (f.type == CodeConstants.TYPE_GENVAR && f.type != t.type && named.containsKey(f)) ++ else if (f.getType() == CodeConstants.TYPE_GENVAR && f.getType() != t.getType() && named.containsKey(f)) + { + f = named.get(f).get(0); + } @@ -1696,19 +1681,19 @@ index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd84 + int fWild = f.isGeneric() ? ((GenericType)f).wildcard : WILDCARD_NO; + + if (tWild == WILDCARD_EXTENDS) { -+ if (fWild == WILDCARD_SUPER || !DecompilerContext.getStructContext().instanceOf(f.value, t.value)) { ++ if (fWild == WILDCARD_SUPER || !DecompilerContext.getStructContext().instanceOf(f.getValue(), t.getValue())) { + return false; + } + } + else if (tWild == WILDCARD_SUPER) { -+ if (fWild == WILDCARD_EXTENDS || !DecompilerContext.getStructContext().instanceOf(t.value, f.value)) { ++ if (fWild == WILDCARD_EXTENDS || !DecompilerContext.getStructContext().instanceOf(t.getValue(), f.getValue())) { + return false; + } + } + else if (tWild == WILDCARD_NO && fWild != tWild && genFrom.wildcard == genTo.wildcard) { + return false; + } -+ else if (!f.value.equals(t.value)) { ++ else if (!f.getValue().equals(t.getValue())) { + return false; + } + @@ -1724,7 +1709,7 @@ index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd84 + public List getAllGenericVars() { + List ret = new ArrayList<>(); + -+ if (this.type == CodeConstants.TYPE_GENVAR) { ++ if (this.getType() == CodeConstants.TYPE_GENVAR) { + ret.add((GenericType)this.resizeArrayDim(0)); + return ret; + } @@ -1744,7 +1729,7 @@ index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd84 + VarType otherArg = other.arguments.get(i); + + if (thisArg != null && !DUMMY_VAR.equals(otherArg)) { -+ if (thisArg.type == CodeConstants.TYPE_GENVAR) { ++ if (thisArg.getType() == CodeConstants.TYPE_GENVAR) { + int tWild = ((GenericType)thisArg).wildcard; + int oWild = otherArg == null || !otherArg.isGeneric() ? WILDCARD_NO : ((GenericType)otherArg).wildcard; + @@ -1753,14 +1738,14 @@ index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd84 + otherArg = withWildcard(otherArg, WILDCARD_NO); + } + -+ if (otherArg == null && thisArg.arrayDim == 0) { ++ if (otherArg == null && thisArg.getArrayDim() == 0) { + if (!map.containsKey(thisArg)) { + map.put(thisArg, otherArg); + } + } -+ else if (otherArg != null && thisArg.arrayDim <= otherArg.arrayDim) { -+ if (thisArg.arrayDim > 0) { -+ otherArg = otherArg.resizeArrayDim(otherArg.arrayDim - thisArg.arrayDim); ++ else if (otherArg != null && thisArg.getArrayDim() <= otherArg.getArrayDim()) { ++ if (thisArg.getArrayDim() > 0) { ++ otherArg = otherArg.resizeArrayDim(otherArg.getArrayDim() - thisArg.getArrayDim()); + thisArg = thisArg.resizeArrayDim(0); + } + if (!map.containsKey(thisArg)) { @@ -1785,7 +1770,7 @@ index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd84 + { + GenericType parent = this.parent != null && this.parent.isGeneric() ? (GenericType)this.parent : null; + if (parent == null) { -+ StructClass cls = DecompilerContext.getStructContext().getClass(other.parent.value); ++ StructClass cls = DecompilerContext.getStructContext().getClass(other.parent.getValue()); + parent = cls.getSignature().genericType; + } + @@ -1795,7 +1780,7 @@ index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd84 + } + + public boolean hasUnknownGenericType(Set namedGenerics) { -+ if (type == CodeConstants.TYPE_GENVAR) { ++ if (getType() == CodeConstants.TYPE_GENVAR) { + return !namedGenerics.contains(this.resizeArrayDim(0)); + } + @@ -1808,8 +1793,8 @@ index 13cca7906fb5810a0bf70b4b6ce184087e1c99e0..34d03ea99dad1f85220ac85b37f9cd84 + } + + public static VarType getGenericSuperType(VarType derivedType, VarType superType) { -+ StructClass dcls = DecompilerContext.getStructContext().getClass(derivedType.value); -+ StructClass scls = DecompilerContext.getStructContext().getClass(superType.value); ++ StructClass dcls = DecompilerContext.getStructContext().getClass(derivedType.getValue()); ++ StructClass scls = DecompilerContext.getStructContext().getClass(superType.getValue()); + + if (dcls != null && scls != null) { + Map> hierarchy = dcls.getAllGenerics(); diff --git a/FernFlower-Patches/0030-Improve-stack-var-processor-output.patch b/FernFlower-Patches/0029-Improve-stack-var-processor-output.patch similarity index 88% rename from FernFlower-Patches/0030-Improve-stack-var-processor-output.patch rename to FernFlower-Patches/0029-Improve-stack-var-processor-output.patch index 066b36b..cf635e6 100644 --- a/FernFlower-Patches/0030-Improve-stack-var-processor-output.patch +++ b/FernFlower-Patches/0029-Improve-stack-var-processor-output.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Improve stack var processor output diff --git a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java -index bb246173b89d733e01ef4a03b59759c8663a20ff..12d737b747fe5fa60a5c449fd91dda9a39fb4387 100644 +index d2c448319e75f6acfb462e6b2d9505f13407a1de..f2964aa1e2759c4828e65d8db3b8421b7072adbf 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java +++ b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java -@@ -172,11 +172,12 @@ public class MethodProcessorRunnable implements Runnable { +@@ -183,11 +183,12 @@ public class MethodProcessorRunnable implements Runnable { if (DecompilerContext.getOption(IFernflowerPreferences.IDEA_NOT_NULL_ANNOTATION)) { if (IdeaNotNullHelper.removeHardcodedChecks(root, mt)) { SequenceHelper.condenseSequences(root); @@ -24,24 +24,24 @@ index bb246173b89d733e01ef4a03b59759c8663a20ff..12d737b747fe5fa60a5c449fd91dda9a if (TryHelper.enhanceTryStats(root)) { diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -index 58bf5152299a7ca6f4d22a2e1f8b95b6393e6242..2a80835a255c98616352259a8c8a7c733c2ca19e 100644 +index e4f693aa6f988445693b5f36efb1d9f810bff3ba..2d00c7f88b838eaec5582b108701581b60d387ae 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -@@ -263,6 +263,9 @@ public class NestedClassProcessor { +@@ -141,6 +141,9 @@ public class NestedClassProcessor { if (param.type == Exprent.EXPRENT_VAR) { mapNewNames.put(varVersion, enclosingMethod.varproc.getVarName(new VarVersionPair((VarExprent)param))); lvts.put(varVersion, ((VarExprent)param).getLVT()); -+ if (enclosingMethod.varproc.getVarFinal((new VarVersionPair((VarExprent)param))) == VarTypeProcessor.VAR_NON_FINAL) { ++ if (enclosingMethod.varproc.getVarFinal((new VarVersionPair((VarExprent)param))) == VarProcessor.VAR_NON_FINAL) { + //DecompilerContext.getLogger().writeMessage("Lambda in " + parent.simpleName + "." + enclosingMethod.methodStruct.getName() + " given non-final var " + ((VarExprent)param).getName() + "!", IFernflowerLogger.Severity.ERROR); + } } } else { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java -index c93911d7e3b3df1e7b455e764f6a96a3843a5df5..0b6938f11bf202bf1c84930daddce204395d38de 100644 +index 6d42db459055d505604728dcac4af7bb74a9e21c..80c7722f9a189acab1af7d8a8b5666b7fc0a66fe 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java -@@ -132,6 +132,11 @@ public class SimplifyExprentsHelper { +@@ -134,6 +134,11 @@ public class SimplifyExprentsHelper { } Exprent next = list.get(index + 1); @@ -53,7 +53,7 @@ index c93911d7e3b3df1e7b455e764f6a96a3843a5df5..0b6938f11bf202bf1c84930daddce204 // constructor invocation if (isConstructorInvocationRemote(list, index)) { -@@ -339,6 +344,27 @@ public class SimplifyExprentsHelper { +@@ -341,6 +346,27 @@ public class SimplifyExprentsHelper { return 0; } @@ -82,7 +82,7 @@ index c93911d7e3b3df1e7b455e764f6a96a3843a5df5..0b6938f11bf202bf1c84930daddce204 if (first.type == Exprent.EXPRENT_ASSIGNMENT) { AssignmentExprent asf = (AssignmentExprent)first; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java -index 1232e643fae990a7a3a9ee5f2e2ece46e607f934..1a085709ed7a120d109542e4bf7101013fdcf37d 100644 +index d8fd9bdf784704836e69cfdd1596ae29b2732232..139ccdb55347a5d66627c1489ee73910fed46f05 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java @@ -2,6 +2,8 @@ @@ -93,15 +93,14 @@ index 1232e643fae990a7a3a9ee5f2e2ece46e607f934..1a085709ed7a120d109542e4bf710101 +import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.modules.decompiler.exps.*; import org.jetbrains.java.decompiler.modules.decompiler.sforms.*; - import org.jetbrains.java.decompiler.modules.decompiler.stats.DoStatement; -@@ -13,12 +15,15 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; + import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectNode.DirectNodeType; +@@ -16,11 +18,14 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionsGraph; import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; +import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.util.FastSparseSetFactory.FastSparseSet; - import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.jetbrains.java.decompiler.util.SFormsFastMapDirect; import java.util.*; @@ -110,7 +109,7 @@ index 1232e643fae990a7a3a9ee5f2e2ece46e607f934..1a085709ed7a120d109542e4bf710101 public class StackVarsProcessor { public void simplifyStackVars(RootStatement root, StructMethod mt, StructClass cl) { -@@ -27,11 +32,12 @@ public class StackVarsProcessor { +@@ -29,11 +34,12 @@ public class StackVarsProcessor { while (true) { boolean found = false; @@ -124,7 +123,7 @@ index 1232e643fae990a7a3a9ee5f2e2ece46e607f934..1a085709ed7a120d109542e4bf710101 while (sehelper.simplifyStackVarsStatement(root, setReorderedIfs, ssa, cl)) { found = true; } -@@ -43,6 +49,10 @@ public class StackVarsProcessor { +@@ -45,6 +51,10 @@ public class StackVarsProcessor { ssau = new SSAUConstructorSparseEx(); ssau.splitVariables(root, mt); @@ -135,7 +134,7 @@ index 1232e643fae990a7a3a9ee5f2e2ece46e607f934..1a085709ed7a120d109542e4bf710101 if (iterateStatements(root, ssau)) { found = true; } -@@ -265,7 +275,7 @@ public class StackVarsProcessor { +@@ -267,7 +277,7 @@ public class StackVarsProcessor { } } @@ -144,7 +143,7 @@ index 1232e643fae990a7a3a9ee5f2e2ece46e607f934..1a085709ed7a120d109542e4bf710101 return new int[]{-1, changed}; } -@@ -443,7 +453,7 @@ public class StackVarsProcessor { +@@ -445,7 +455,7 @@ public class StackVarsProcessor { } } @@ -153,7 +152,7 @@ index 1232e643fae990a7a3a9ee5f2e2ece46e607f934..1a085709ed7a120d109542e4bf710101 return new Object[]{null, changed, false}; } -@@ -663,4 +673,164 @@ public class StackVarsProcessor { +@@ -664,4 +674,164 @@ public class StackVarsProcessor { return map; } @@ -181,7 +180,7 @@ index 1232e643fae990a7a3a9ee5f2e2ece46e607f934..1a085709ed7a120d109542e4bf710101 + else if (exprent.type == Exprent.EXPRENT_NEW) { + NewExprent newExpr = (NewExprent)exprent; + if (newExpr.isAnonymous()) { -+ ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(newExpr.getNewType().value); ++ ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(newExpr.getNewType().getValue()); + + if (node != null) { + if (!newExpr.isLambda()) { @@ -212,7 +211,7 @@ index 1232e643fae990a7a3a9ee5f2e2ece46e607f934..1a085709ed7a120d109542e4bf710101 + int varsCount = mdContent.params.length - mdLambda.params.length; + + for (int i = 0; i < varsCount; ++i) { -+ Exprent param = newExpr.getConstructor().getLstParameters().get(paramOffset + i); ++ Exprent param = newExpr.getConstructor().getParameters().get(paramOffset + i); + if (param.type == Exprent.EXPRENT_VAR) { + VarExprent paramVar = (VarExprent)param; + VarVersionPair vvp = paramVar.getVarVersionPair(); @@ -221,7 +220,7 @@ index 1232e643fae990a7a3a9ee5f2e2ece46e607f934..1a085709ed7a120d109542e4bf710101 + while (true) { + VarVersionNode next = null; + if (vvnode.var >= VarExprent.STACK_BASE) { -+ vvnode = vvnode.preds.iterator().next().source; ++ vvnode = vvnode.predecessors.iterator().next().source; + VarVersionPair nextVVP = ssau.getVarAssignmentMap().get(new VarVersionPair(vvnode.var, vvnode.version)); + next = ssau.getSsuversions().nodes.getWithKey(nextVVP); + @@ -237,7 +236,7 @@ index 1232e643fae990a7a3a9ee5f2e2ece46e607f934..1a085709ed7a120d109542e4bf710101 + List roots = getRoots(vvnode); + List allRoots = ssau.getSsuversions().nodes.stream() + .distinct() -+ .filter(n -> n.var == varIndex && n.preds.isEmpty()) ++ .filter(n -> n.var == varIndex && n.predecessors.isEmpty()) + .filter(n -> { + if (n.lvt != null) { + return mdContent.params[j].equals(new VarType(n.lvt.getDescriptor())); @@ -303,11 +302,11 @@ index 1232e643fae990a7a3a9ee5f2e2ece46e607f934..1a085709ed7a120d109542e4bf710101 + while (!queue.isEmpty()) { + VarVersionNode next = queue.removeFirst(); + -+ if (next.preds.isEmpty()) { ++ if (next.predecessors.isEmpty()) { + ret.add(next); + } + else { -+ next.preds.forEach(vvn -> { ++ next.predecessors.forEach(vvn -> { + if (visited.add(vvn.source)) { + queue.add(vvn.source); + } @@ -318,25 +317,24 @@ index 1232e643fae990a7a3a9ee5f2e2ece46e607f934..1a085709ed7a120d109542e4bf710101 + return ret; + } } -\ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -index 286c050b26e0b5e46f846e670b0e84911d208c64..12a58c9dc1ec95d56f14b4008bec3fc29d908ad3 100644 +index 0533ef866afdfd90e5bec78866cbd47d8a799ec2..571323649ebe3bab51f946ce423aa66a72f86327 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -@@ -166,6 +166,11 @@ public class InvocationExprent extends Exprent { +@@ -168,6 +168,11 @@ public class InvocationExprent extends Exprent { addBytecodeOffsets(expr.bytecode); bootstrapArguments = expr.getBootstrapArguments(); isSyntheticNullCheck = expr.isSyntheticNullCheck(); + -+ if (invocationTyp == INVOKE_DYNAMIC && !isStatic && instance != null && !lstParameters.isEmpty()) { ++ if (invocationType == INVOKE_DYNAMIC && !isStatic && instance != null && !this.parameters.isEmpty()) { + // method reference, instance and first param are expected to be the same var object -+ instance = lstParameters.get(0); ++ instance = this.parameters.get(0); + } } @Override diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java -index f4f21c900d1e0763eeb049a550847d0497e0e7c5..c8bf497f5cac2bb9e3c7b2187a4b70d392ef9e7c 100644 +index eea545270ec8d5bff3e4f0eae01520f8756022d3..209fb0603e4e283ebd64cb4c993dc245291d952c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java @@ -48,6 +48,7 @@ public class VarExprent extends Exprent { @@ -371,10 +369,10 @@ index f4f21c900d1e0763eeb049a550847d0497e0e7c5..c8bf497f5cac2bb9e3c7b2187a4b70d3 VarVersionPair pair = getVarVersionPair(); if (lvt != null) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java -index 8e57cd727302fe608f178c51ba4a7fb4c8971448..db927122415ad07666d51959debcb24d126c9545 100644 +index 3917ae87c6d147e808768ffc717cc24b08b3f433..737c88143708e0b6b19a6b335e1d4353064ecb94 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java -@@ -238,7 +238,7 @@ public class SSAConstructorSparseEx { +@@ -239,7 +239,7 @@ public class SSAConstructorSparseEx { Integer varindex = vardest.getIndex(); FastSparseSet vers = varmap.get(varindex); @@ -383,7 +381,7 @@ index 8e57cd727302fe608f178c51ba4a7fb4c8971448..db927122415ad07666d51959debcb24d if (cardinality == 1) { // == 1 // set version Integer it = vers.iterator().next(); -@@ -263,7 +263,17 @@ public class SSAConstructorSparseEx { +@@ -264,7 +264,17 @@ public class SSAConstructorSparseEx { // create new phi node phi.put(new VarVersionPair(varindex, nextver), vers); } @@ -403,10 +401,10 @@ index 8e57cd727302fe608f178c51ba4a7fb4c8971448..db927122415ad07666d51959debcb24d } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java -index 3607a8dc6483775f12aa23420ffe447ec9e993bd..58169c235c1cf1d4862f3f515553bf0a9da132d5 100644 +index d233d671b4d1bdeb14327bb155310d3b792b932d..2160f80887ab72b9d2cff50e9dcae1724dc839ca 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java -@@ -67,6 +67,9 @@ public class SSAUConstructorSparseEx { +@@ -64,6 +64,9 @@ public class SSAUConstructorSparseEx { // set factory private FastSparseSetFactory factory; @@ -416,7 +414,7 @@ index 3607a8dc6483775f12aa23420ffe447ec9e993bd..58169c235c1cf1d4862f3f515553bf0a public void splitVariables(RootStatement root, StructMethod mt) { FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); -@@ -291,7 +294,7 @@ public class SSAUConstructorSparseEx { +@@ -288,7 +291,7 @@ public class SSAUConstructorSparseEx { varassign.setVersion(nextver); // ssu graph @@ -425,7 +423,7 @@ index 3607a8dc6483775f12aa23420ffe447ec9e993bd..58169c235c1cf1d4862f3f515553bf0a setCurrentVar(varmap, varindex, nextver); } -@@ -301,6 +304,17 @@ public class SSAUConstructorSparseEx { +@@ -298,6 +301,17 @@ public class SSAUConstructorSparseEx { } setCurrentVar(varmap, varindex, varassign.getVersion()); } @@ -443,7 +441,7 @@ index 3607a8dc6483775f12aa23420ffe447ec9e993bd..58169c235c1cf1d4862f3f515553bf0a } else if (expr.type == Exprent.EXPRENT_FUNCTION) { // MM or PP function FunctionExprent func = (FunctionExprent)expr; -@@ -356,7 +370,7 @@ public class SSAUConstructorSparseEx { +@@ -353,7 +367,7 @@ public class SSAUConstructorSparseEx { FastSparseSet vers = varmap.get(varindex); @@ -452,7 +450,7 @@ index 3607a8dc6483775f12aa23420ffe447ec9e993bd..58169c235c1cf1d4862f3f515553bf0a if (cardinality == 1) { // size == 1 if (current_vers != 0) { if (calcLiveVars) { -@@ -404,7 +418,21 @@ public class SSAUConstructorSparseEx { +@@ -401,7 +415,21 @@ public class SSAUConstructorSparseEx { } createOrUpdatePhiNode(new VarVersionPair(varindex, current_vers), vers, stat); @@ -475,7 +473,7 @@ index 3607a8dc6483775f12aa23420ffe447ec9e993bd..58169c235c1cf1d4862f3f515553bf0a } } -@@ -819,4 +847,8 @@ public class SSAUConstructorSparseEx { +@@ -816,4 +844,8 @@ public class SSAUConstructorSparseEx { public HashMap getMapFieldVars() { return mapFieldVars; } @@ -485,7 +483,7 @@ index 3607a8dc6483775f12aa23420ffe447ec9e993bd..58169c235c1cf1d4862f3f515553bf0a + } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java -index 0f7ca6c558a05e02ea98bc17dca37a2d2e119640..b2c2139ab5c9c2d3aa235b3e2eb6cb5bb409a24e 100644 +index 472af3df55a4accb2ae3b249289ee69a47ecf2c0..4e6f3faa3f39ab68f609a110033f12203923e8a3 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java @@ -11,6 +11,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.exps.ConstExprent; @@ -496,7 +494,7 @@ index 0f7ca6c558a05e02ea98bc17dca37a2d2e119640..b2c2139ab5c9c2d3aa235b3e2eb6cb5b import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent; import org.jetbrains.java.decompiler.modules.decompiler.exps.NewExprent; import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; -@@ -229,6 +230,7 @@ public class VarDefinitionHelper { +@@ -231,6 +232,7 @@ public class VarDefinitionHelper { mergeVars(root); propogateLVTs(root); @@ -504,7 +502,7 @@ index 0f7ca6c558a05e02ea98bc17dca37a2d2e119640..b2c2139ab5c9c2d3aa235b3e2eb6cb5b } -@@ -1136,4 +1138,79 @@ public class VarDefinitionHelper { +@@ -1138,4 +1140,79 @@ public class VarDefinitionHelper { } return false; } @@ -522,14 +520,14 @@ index 0f7ca6c558a05e02ea98bc17dca37a2d2e119640..b2c2139ab5c9c2d3aa235b3e2eb6cb5b + } + + if (!stat.getVarDefinitions().isEmpty()) { -+ if (stat.type != Statement.TYPE_DO) { ++ if (stat.type != Statement.StatementType.DO) { + for (Exprent var : stat.getVarDefinitions()) { + unInitialized.add(new VarVersionPair((VarExprent)var)); + } + } + } + -+ if (stat.type == Statement.TYPE_DO) { ++ if (stat.type == Statement.StatementType.DO) { + DoStatement dostat = (DoStatement)stat; + if (dostat.getInitExprentList() != null) { + setNonFinal(dostat.getInitExprent(), unInitialized); @@ -538,7 +536,7 @@ index 0f7ca6c558a05e02ea98bc17dca37a2d2e119640..b2c2139ab5c9c2d3aa235b3e2eb6cb5b + setNonFinal(dostat.getIncExprent(), unInitialized); + } + } -+ else if (stat.type == Statement.TYPE_IF) { ++ else if (stat.type == Statement.StatementType.IF) { + IfStatement ifstat = (IfStatement)stat; + if (ifstat.getIfstat() != null && ifstat.getElsestat() != null) { + setNonFinal(ifstat.getFirst(), unInitialized); @@ -576,7 +574,7 @@ index 0f7ca6c558a05e02ea98bc17dca37a2d2e119640..b2c2139ab5c9c2d3aa235b3e2eb6cb5b + } + + if (var != null && !var.isDefinition() && !unInitialized.remove(var.getVarVersionPair())) { -+ var.getProcessor().setVarFinal(var.getVarVersionPair(), VarTypeProcessor.VAR_NON_FINAL); ++ var.getProcessor().setVarFinal(var.getVarVersionPair(), VarProcessor.VAR_NON_FINAL); + } + + for (Exprent ex : exp.getAllExprents()) { @@ -585,7 +583,7 @@ index 0f7ca6c558a05e02ea98bc17dca37a2d2e119640..b2c2139ab5c9c2d3aa235b3e2eb6cb5b + } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionNode.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionNode.java -index 914995e6bb53b02680ae1c643185fcb85092944c..17fa070577c578161391a9544b478cbd8a52e4ac 100644 +index 73a054d03a44c110dc949298a9c5e9de761187c8..1625c1d10fa0c40a9a7be98626b8c71597ffa48b 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionNode.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionNode.java @@ -2,6 +2,7 @@ @@ -596,10 +594,10 @@ index 914995e6bb53b02680ae1c643185fcb85092944c..17fa070577c578161391a9544b478cbd import org.jetbrains.java.decompiler.util.SFormsFastMapDirect; import java.util.ArrayList; -@@ -25,12 +26,18 @@ public class VarVersionNode implements IGraphNode { +@@ -19,12 +20,18 @@ public class VarVersionNode implements IGraphNode { + public int flags; public SFormsFastMapDirect live = new SFormsFastMapDirect(); - + public LocalVariable lvt = null; public VarVersionNode(int var, int version) { @@ -612,11 +610,11 @@ index 914995e6bb53b02680ae1c643185fcb85092944c..17fa070577c578161391a9544b478cbd + this.lvt = lvt; + } + - @Override - public List getPredecessors() { - List lst = new ArrayList<>(preds.size()); + public void addPredecessor(VarVersionEdge edge) { + predecessors.add(edge); + } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java -index 58eda687c83938c8b98fe59d54ca1a1972df8ed4..fc10e17c2db45ef9beb3ccd628a22bedc2467ceb 100644 +index 572dde919042921ffebc5f83e0d9f5ebe7276788..51a88dc3d8ecaefd6aff46cbc24eecbebe5d11d2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java @@ -4,6 +4,7 @@ package org.jetbrains.java.decompiler.modules.decompiler.vars; diff --git a/FernFlower-Patches/0031-Fix-finally-processor-instruction-comparison.patch b/FernFlower-Patches/0030-Fix-finally-processor-instruction-comparison.patch similarity index 88% rename from FernFlower-Patches/0031-Fix-finally-processor-instruction-comparison.patch rename to FernFlower-Patches/0030-Fix-finally-processor-instruction-comparison.patch index c47e52d..feb95d7 100644 --- a/FernFlower-Patches/0031-Fix-finally-processor-instruction-comparison.patch +++ b/FernFlower-Patches/0030-Fix-finally-processor-instruction-comparison.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix finally processor instruction comparison diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java -index 171d9bdba69a4701bb7396f2bbe6b5f53cb3bb2b..14da709f122333476cc1482c00f94e6a3ed7cbac 100644 +index f0d3f8516357d7bae44b0ad0e5f24903a717268f..30cdd284745688c1d2b0e10b5e884991173a1527 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java -@@ -854,13 +854,17 @@ public class FinallyProcessor { +@@ -852,13 +852,17 @@ public class FinallyProcessor { int secondOp = second.operand(i); if (firstOp != secondOp) { // a-load/store instructions diff --git a/FernFlower-Patches/0032-Simple-lambda-syntax-support-isl-0-to-disable.patch b/FernFlower-Patches/0031-Simple-lambda-syntax-support-isl-0-to-disable.patch similarity index 74% rename from FernFlower-Patches/0032-Simple-lambda-syntax-support-isl-0-to-disable.patch rename to FernFlower-Patches/0031-Simple-lambda-syntax-support-isl-0-to-disable.patch index 93b605a..013847b 100644 --- a/FernFlower-Patches/0032-Simple-lambda-syntax-support-isl-0-to-disable.patch +++ b/FernFlower-Patches/0031-Simple-lambda-syntax-support-isl-0-to-disable.patch @@ -5,18 +5,30 @@ Subject: [PATCH] Simple lambda syntax support, --isl=0 to disable. diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -index 4a9014073b785be9fb7cf42018122e24c545b6dc..43199af10fde2770ee14b36ba5bbae23ebb5e2cc 100644 +index ac0d6feaa643477aa465cd8bb8ebd4503faf522a..bae5fd174027bc9f8c7c3d2eb53c2ef7ccab6ffe 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -@@ -11,6 +11,7 @@ import org.jetbrains.java.decompiler.main.rels.MethodWrapper; +@@ -10,14 +10,19 @@ import org.jetbrains.java.decompiler.main.rels.ClassWrapper; + import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; - import org.jetbrains.java.decompiler.modules.decompiler.exps.*; + import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent; ++import org.jetbrains.java.decompiler.modules.decompiler.exps.AssignmentExprent; + import org.jetbrains.java.decompiler.modules.decompiler.exps.ConstExprent; ++import org.jetbrains.java.decompiler.modules.decompiler.exps.ExitExprent; + import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; ++import org.jetbrains.java.decompiler.modules.decompiler.exps.FunctionExprent; + import org.jetbrains.java.decompiler.modules.decompiler.exps.NewExprent; ++import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; + import org.jetbrains.java.decompiler.modules.decompiler.typeann.TargetInfo; + import org.jetbrains.java.decompiler.modules.decompiler.typeann.TypeAnnotation; + import org.jetbrains.java.decompiler.modules.decompiler.typeann.TypeAnnotationWriteHelper; + import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; +import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; - import org.jetbrains.java.decompiler.modules.decompiler.vars.VarTypeProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.modules.renamer.PoolInterceptor; -@@ -77,7 +78,15 @@ public class ClassWriter { + import org.jetbrains.java.decompiler.struct.*; +@@ -84,7 +89,15 @@ public class ClassWriter { if (node.lambdaInformation.is_method_reference) { if (!node.lambdaInformation.is_content_method_static && method_object != null) { // reference to a virtual method @@ -33,16 +45,15 @@ index 4a9014073b785be9fb7cf42018122e24c545b6dc..43199af10fde2770ee14b36ba5bbae23 } else { // reference to a static method -@@ -94,6 +103,8 @@ public class ClassWriter { - MethodDescriptor md_content = MethodDescriptor.parseDescriptor(node.lambdaInformation.content_method_descriptor); - MethodDescriptor md_lambda = MethodDescriptor.parseDescriptor(node.lambdaInformation.method_descriptor); +@@ -103,6 +116,7 @@ public class ClassWriter { + List parameterTypeAnnotations = TargetInfo.FormalParameterTarget.extract(TypeAnnotation.listFrom(mt)); + boolean explicitlyTyped = !parameterTypeAnnotations.isEmpty(); + boolean simpleLambda = false; -+ + if (!lambdaToAnonymous) { buffer.append('('); - -@@ -117,16 +128,60 @@ public class ClassWriter { +@@ -134,16 +148,60 @@ public class ClassWriter { } buffer.append(") ->"); @@ -50,7 +61,7 @@ index 4a9014073b785be9fb7cf42018122e24c545b6dc..43199af10fde2770ee14b36ba5bbae23 + RootStatement root = wrapper.getMethodWrapper(mt.getName(), mt.getDescriptor()).root; + if (DecompilerContext.getOption(IFernflowerPreferences.INLINE_SIMPLE_LAMBDAS) && !methodWrapper.decompiledWithErrors && root != null) { + Statement firstStat = root.getFirst(); -+ if (firstStat.type == Statement.TYPE_BASICBLOCK && firstStat.getExprents() != null && firstStat.getExprents().size() == 1) { ++ if (firstStat.type == Statement.StatementType.BASIC_BLOCK && firstStat.getExprents() != null && firstStat.getExprents().size() == 1) { + Exprent firstExpr = firstStat.getExprents().get(0); + boolean isVarDefinition = firstExpr.type == Exprent.EXPRENT_ASSIGNMENT && + ((AssignmentExprent)firstExpr).getLeft().type == Exprent.EXPRENT_VAR && @@ -109,30 +120,30 @@ index 4a9014073b785be9fb7cf42018122e24c545b6dc..43199af10fde2770ee14b36ba5bbae23 } finally { diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -index 01b9cef3bb535025f816f18acab5951083e4ec55..41f7389f3931a6a3c87647f7fde98f04c37af5c0 100644 +index 0c1e9296f40007557be90d12daf39cb9a78df448..86fd580e52b9534c2750139512ba84739308eead 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -@@ -37,6 +37,7 @@ public interface IFernflowerPreferences { - +@@ -38,6 +38,7 @@ public interface IFernflowerPreferences { String INCLUDE_ENTIRE_CLASSPATH = "iec"; + String QUALIFY_INNER_CLASSES = "qin"; String EXPLICIT_GENERIC_ARGUMENTS = "ega"; + String INLINE_SIMPLE_LAMBDAS = "isl"; String LOG_LEVEL = "log"; String MAX_PROCESSING_METHOD = "mpm"; -@@ -90,6 +91,7 @@ public interface IFernflowerPreferences { - +@@ -92,6 +93,7 @@ public interface IFernflowerPreferences { defaults.put(INCLUDE_ENTIRE_CLASSPATH, "0"); + defaults.put(QUALIFY_INNER_CLASSES, "1"); defaults.put(EXPLICIT_GENERIC_ARGUMENTS, "0"); + defaults.put(INLINE_SIMPLE_LAMBDAS, "1"); defaults.put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name()); defaults.put(MAX_PROCESSING_METHOD, "0"); diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -index b53a17c2ba86fe16917e0c6b3e0ae346c87c2547..381a1ecc559e59b38c28a6a10df465384cd40d0e 100644 +index c88d5f8ea5ffb16de0d9e8dd8f8e2fd9a726d489..f9dd18ce93da5481aa016ea665898e3b690db6ec 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -@@ -14,7 +14,8 @@ public class SingleClassesTest extends SingleClassesTestBase { +@@ -25,7 +25,8 @@ public class SingleClassesTest extends SingleClassesTestBase { IFernflowerPreferences.DUMP_ORIGINAL_LINES, "1", IFernflowerPreferences.IGNORE_INVALID_BYTECODE, "1", IFernflowerPreferences.VERIFY_ANONYMOUS_CLASSES, "1", diff --git a/FernFlower-Patches/0033-Add-explicit-cast-to-invocations-of-java-nio-Buffer-.patch b/FernFlower-Patches/0032-Add-explicit-cast-to-invocations-of-java-nio-Buffer-.patch similarity index 84% rename from FernFlower-Patches/0033-Add-explicit-cast-to-invocations-of-java-nio-Buffer-.patch rename to FernFlower-Patches/0032-Add-explicit-cast-to-invocations-of-java-nio-Buffer-.patch index 7b22e66..27112d0 100644 --- a/FernFlower-Patches/0033-Add-explicit-cast-to-invocations-of-java-nio-Buffer-.patch +++ b/FernFlower-Patches/0032-Add-explicit-cast-to-invocations-of-java-nio-Buffer-.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Add explicit cast to invocations of java/nio/Buffer Java 9+ added overrides to these functions to return the specific subclass, however, when there is a compiler "bug" that when targeting release * or below, it will still reference these new methods, causing exceptions at runtime on Java 8. diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -index 12a58c9dc1ec95d56f14b4008bec3fc29d908ad3..dfd8078b728c0439a6a0accb6d9f17b7eb2979fb 100644 +index 571323649ebe3bab51f946ce423aa66a72f86327..122e7ad0ebcaa9fe20263b674887b51bd6044fd0 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -46,6 +46,8 @@ public class InvocationExprent extends Exprent { @@ -17,17 +17,17 @@ index 12a58c9dc1ec95d56f14b4008bec3fc29d908ad3..dfd8078b728c0439a6a0accb6d9f17b7 + private static final VarType JAVA_NIO_BUFFER = new VarType(CodeConstants.TYPE_OBJECT, 0, "java/nio/Buffer"); + private String name; - private String classname; + private String className; private boolean isStatic; -@@ -604,6 +606,12 @@ public class InvocationExprent extends Exprent { +@@ -606,6 +608,12 @@ public class InvocationExprent extends Exprent { else if (instance.getPrecedence() > getPrecedence() && !skippedCast) { buf.append("(").append(res).append(")"); } + //Java 9+ adds some overrides to java/nio/Buffer's subclasses that alter the return types. + //This isn't properly handled by the compiler. So explicit casts are needed to retain J8 compatibility. + else if (JAVA_NIO_BUFFER.equals(descriptor.ret) && !JAVA_NIO_BUFFER.equals(rightType) -+ && DecompilerContext.getStructContext().instanceOf(rightType.value, JAVA_NIO_BUFFER.value)) { -+ buf.append("((").append(ExprProcessor.getCastTypeName(JAVA_NIO_BUFFER)).append(")").append(res).append(")"); ++ && DecompilerContext.getStructContext().instanceOf(rightType.getValue(), JAVA_NIO_BUFFER.getValue())) { ++ buf.append("((").append(ExprProcessor.getCastTypeName(JAVA_NIO_BUFFER, Collections.emptyList())).append(")").append(res).append(")"); + } else { buf.append(res); diff --git a/FernFlower-Patches/0034-Revert-change-to-FieldExprent-getExprentUse.patch b/FernFlower-Patches/0033-Revert-change-to-FieldExprent-getExprentUse.patch similarity index 91% rename from FernFlower-Patches/0034-Revert-change-to-FieldExprent-getExprentUse.patch rename to FernFlower-Patches/0033-Revert-change-to-FieldExprent-getExprentUse.patch index e043785..c39036d 100644 --- a/FernFlower-Patches/0034-Revert-change-to-FieldExprent-getExprentUse.patch +++ b/FernFlower-Patches/0033-Revert-change-to-FieldExprent-getExprentUse.patch @@ -7,10 +7,10 @@ Revert part of a change introduced upstream. https://github.com/MinecraftForge/F This upstream change causes local variables to not be inlined in many cases, and makes decomp very messy for the reason of 'thread safety'. diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java -index 5143f83d9e4e6fdb6d4e6b54acfaed13a8fdb328..fe98a67593856bc9358faf468afcd7bde986b520 100644 +index 66ea2304968dae841fdd736c81e7332c75d9ecd5..e6e3e9d6f50239c716d285d64f37679bbf0ff553 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java -@@ -107,7 +107,13 @@ public class FieldExprent extends Exprent { +@@ -105,7 +105,13 @@ public class FieldExprent extends Exprent { @Override public int getExprentUse() { diff --git a/FernFlower-Patches/0035-Add-only-argument-It-will-filter-what-classes-are-de.patch b/FernFlower-Patches/0034-Add-only-argument-It-will-filter-what-classes-are-de.patch similarity index 98% rename from FernFlower-Patches/0035-Add-only-argument-It-will-filter-what-classes-are-de.patch rename to FernFlower-Patches/0034-Add-only-argument-It-will-filter-what-classes-are-de.patch index 9c82d01..a57506d 100644 --- a/FernFlower-Patches/0035-Add-only-argument-It-will-filter-what-classes-are-de.patch +++ b/FernFlower-Patches/0034-Add-only-argument-It-will-filter-what-classes-are-de.patch @@ -8,7 +8,7 @@ Uses a prefix system, so -only=net/minecraft/block/ will decompile all classes i Useful for debugging to limit scope/runtime. diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java -index bb5ca5bae7c3ae47e2e824f3a0d24246bbd210ca..dc1e19187b9058f0193dbb86a7b4c77da8f0c5ec 100644 +index 8aefba318b0f09b559d41d945a3d8099a861ac55..305b06903b36bc4cdb740a8f050543403e6406fe 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -38,6 +38,7 @@ public class ClassesProcessor implements CodeConstants { diff --git a/FernFlower-Patches/0036-Fix-local-variables-incorrectly-merging.patch b/FernFlower-Patches/0035-Fix-local-variables-incorrectly-merging.patch similarity index 86% rename from FernFlower-Patches/0036-Fix-local-variables-incorrectly-merging.patch rename to FernFlower-Patches/0035-Fix-local-variables-incorrectly-merging.patch index 8809f26..cef82b4 100644 --- a/FernFlower-Patches/0036-Fix-local-variables-incorrectly-merging.patch +++ b/FernFlower-Patches/0035-Fix-local-variables-incorrectly-merging.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix local variables incorrectly merging. diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java -index 1a085709ed7a120d109542e4bf7101013fdcf37d..ca38c8fe1de405dd65f6dc802189581412111fdc 100644 +index 139ccdb55347a5d66627c1489ee73910fed46f05..388ead266fe10aa4c251d3b7c6207e20126e66b9 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java -@@ -601,7 +601,7 @@ public class StackVarsProcessor { +@@ -602,7 +602,7 @@ public class StackVarsProcessor { for (Entry> ent : mapVars.entrySet()) { FastSparseSet liveverset = mapLiveVars.get(ent.getKey()); @@ -17,7 +17,7 @@ index 1a085709ed7a120d109542e4bf7101013fdcf37d..ca38c8fe1de405dd65f6dc8021895814 return false; } -@@ -610,13 +610,13 @@ public class StackVarsProcessor { +@@ -611,13 +611,13 @@ public class StackVarsProcessor { domset.add(ssuversions.nodes.getWithKey(verpaar)); } diff --git a/FernFlower-Patches/0037-Do-not-rebuild-variable-names-in-lambdas.patch b/FernFlower-Patches/0036-Do-not-rebuild-variable-names-in-lambdas.patch similarity index 87% rename from FernFlower-Patches/0037-Do-not-rebuild-variable-names-in-lambdas.patch rename to FernFlower-Patches/0036-Do-not-rebuild-variable-names-in-lambdas.patch index 424c064..250208e 100644 --- a/FernFlower-Patches/0037-Do-not-rebuild-variable-names-in-lambdas.patch +++ b/FernFlower-Patches/0036-Do-not-rebuild-variable-names-in-lambdas.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Do not rebuild variable names in lambdas. Breaks outer this references. Code existed before my time, no idea what it's intention is. diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -index 2a80835a255c98616352259a8c8a7c733c2ca19e..f9d15e108cfff05be4f38b10a00814259364a849 100644 +index 2d00c7f88b838eaec5582b108701581b60d387ae..3530d2f46c4ad90974796e41f664613420e2689a 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -@@ -285,7 +285,7 @@ public class NestedClassProcessor { +@@ -163,7 +163,7 @@ public class NestedClassProcessor { Set setNewOuterNames = new HashSet<>(mapNewNames.values()); setNewOuterNames.removeAll(method.setOuterVarNames); diff --git a/FernFlower-Patches/0038-Add-toString-to-MethodDescriptor.patch b/FernFlower-Patches/0037-Add-toString-to-MethodDescriptor.patch similarity index 94% rename from FernFlower-Patches/0038-Add-toString-to-MethodDescriptor.patch rename to FernFlower-Patches/0037-Add-toString-to-MethodDescriptor.patch index da5ae38..5564f4f 100644 --- a/FernFlower-Patches/0038-Add-toString-to-MethodDescriptor.patch +++ b/FernFlower-Patches/0037-Add-toString-to-MethodDescriptor.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add toString to MethodDescriptor diff --git a/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java b/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java -index 79bd5b3f70510c85a2908fcadeb57119224082bb..327a5bce4f414e0ff7a6dcbf2e02f583d85a7157 100644 +index 8044f348e8aad96f451a47ef24f54972e171b9c7..10a2e187ab1d877e7adca38628c197183b4d8352 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java @@ -19,11 +19,13 @@ import java.util.Objects; diff --git a/FernFlower-Patches/0039-Make-decomp-threaded.patch b/FernFlower-Patches/0038-Make-decomp-threaded.patch similarity index 96% rename from FernFlower-Patches/0039-Make-decomp-threaded.patch rename to FernFlower-Patches/0038-Make-decomp-threaded.patch index 11d3ada..2bc6c50 100644 --- a/FernFlower-Patches/0039-Make-decomp-threaded.patch +++ b/FernFlower-Patches/0038-Make-decomp-threaded.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Make decomp threaded `-thr AUTO` to auto select, (default) diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java -index dc1e19187b9058f0193dbb86a7b4c77da8f0c5ec..09d6175392dd0dcfa2ab3eb6371684ad65653d0d 100644 +index 305b06903b36bc4cdb740a8f050543403e6406fe..e734afaf2fb87c2e9d6ede6925f4ca6b3d560773 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -37,7 +37,8 @@ public class ClassesProcessor implements CodeConstants { @@ -20,7 +20,7 @@ index dc1e19187b9058f0193dbb86a7b4c77da8f0c5ec..09d6175392dd0dcfa2ab3eb6371684ad private final Set whitelist = new HashSet<>(); private static class Inner { -@@ -382,7 +383,7 @@ public class ClassesProcessor implements CodeConstants { +@@ -401,7 +402,7 @@ public class ClassesProcessor implements CodeConstants { return true; } @@ -29,7 +29,7 @@ index dc1e19187b9058f0193dbb86a7b4c77da8f0c5ec..09d6175392dd0dcfa2ab3eb6371684ad ClassNode root = mapRootClasses.get(cl.qualifiedName); if (root.type != ClassNode.CLASS_ROOT) { return; -@@ -391,25 +392,12 @@ public class ClassesProcessor implements CodeConstants { +@@ -410,25 +411,12 @@ public class ClassesProcessor implements CodeConstants { boolean packageInfo = cl.isSynthetic() && "package-info".equals(root.simpleName); boolean moduleInfo = cl.hasModifier(CodeConstants.ACC_MODULE) && cl.hasAttribute(StructGeneralAttribute.ATTRIBUTE_MODULE); @@ -58,7 +58,7 @@ index dc1e19187b9058f0193dbb86a7b4c77da8f0c5ec..09d6175392dd0dcfa2ab3eb6371684ad new LambdaProcessor().processClass(root); // add simple class names to implicit import -@@ -421,7 +409,36 @@ public class ClassesProcessor implements CodeConstants { +@@ -440,7 +428,36 @@ public class ClassesProcessor implements CodeConstants { new NestedClassProcessor().processClass(root, root); new NestedMemberAccess().propagateMemberAccess(root); @@ -95,7 +95,7 @@ index dc1e19187b9058f0193dbb86a7b4c77da8f0c5ec..09d6175392dd0dcfa2ab3eb6371684ad TextBuffer classBuffer = new TextBuffer(AVERAGE_CLASS_SIZE); new ClassWriter().classToJava(root, classBuffer, 0, null); -@@ -431,7 +448,7 @@ public class ClassesProcessor implements CodeConstants { +@@ -450,7 +467,7 @@ public class ClassesProcessor implements CodeConstants { buffer.append("package ").append(packageName).append(';').appendLineSeparator().appendLineSeparator(); } @@ -105,7 +105,7 @@ index dc1e19187b9058f0193dbb86a7b4c77da8f0c5ec..09d6175392dd0dcfa2ab3eb6371684ad int offsetLines = buffer.countLines(); diff --git a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java -index 95baa7dfec5a9c8dcde30a288499aa127aeffa4b..8bbe04c2f404b6c43a6a216bf2a99d3b69a2ad93 100644 +index bb7b5b4e4a590219939a8f7e883b9c259c1adf73..458d119056f3fa7eceec7215fa577018d7f8cb8c 100644 --- a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java +++ b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java @@ -11,6 +11,7 @@ import org.jetbrains.java.decompiler.main.extern.IVariableNamingFactory; @@ -116,7 +116,7 @@ index 95baa7dfec5a9c8dcde30a288499aa127aeffa4b..8bbe04c2f404b6c43a6a216bf2a99d3b import java.util.Map; import java.util.Objects; -@@ -28,12 +29,14 @@ public class DecompilerContext { +@@ -29,12 +30,14 @@ public class DecompilerContext { private final ClassesProcessor classProcessor; private final PoolInterceptor poolInterceptor; private final IVariableNamingFactory renamerFactory; @@ -131,7 +131,7 @@ index 95baa7dfec5a9c8dcde30a288499aa127aeffa4b..8bbe04c2f404b6c43a6a216bf2a99d3b IFernflowerLogger logger, StructContext structContext, ClassesProcessor classProcessor, -@@ -45,6 +48,7 @@ public class DecompilerContext { +@@ -46,6 +49,7 @@ public class DecompilerContext { Objects.requireNonNull(classProcessor); this.properties = properties; @@ -139,7 +139,7 @@ index 95baa7dfec5a9c8dcde30a288499aa127aeffa4b..8bbe04c2f404b6c43a6a216bf2a99d3b this.logger = logger; this.structContext = structContext; this.classProcessor = classProcessor; -@@ -53,6 +57,18 @@ public class DecompilerContext { +@@ -54,6 +58,18 @@ public class DecompilerContext { this.counterContainer = new CounterContainer(); } @@ -158,7 +158,7 @@ index 95baa7dfec5a9c8dcde30a288499aa127aeffa4b..8bbe04c2f404b6c43a6a216bf2a99d3b // ***************************************************************************** // context setup and update // ***************************************************************************** -@@ -67,6 +83,14 @@ public class DecompilerContext { +@@ -68,6 +84,14 @@ public class DecompilerContext { currentContext.set(context); } @@ -173,7 +173,7 @@ index 95baa7dfec5a9c8dcde30a288499aa127aeffa4b..8bbe04c2f404b6c43a6a216bf2a99d3b public static void setProperty(String key, Object value) { getCurrentContext().properties.put(key, value); } -@@ -101,6 +125,10 @@ public class DecompilerContext { +@@ -102,6 +126,10 @@ public class DecompilerContext { IFernflowerPreferences.LINE_SEPARATOR_UNX : IFernflowerPreferences.LINE_SEPARATOR_WIN; } @@ -670,19 +670,19 @@ index c9ece039b0d986c1d84b62426a65e6780ddc80e1..3ca43800b47e1d26a1dc036f21cb6e6e public void endReadingClass() { } diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -index 41f7389f3931a6a3c87647f7fde98f04c37af5c0..a2be81c2a329812c30ffe2606cae2b5f7ab43c3c 100644 +index 86fd580e52b9534c2750139512ba84739308eead..7bcb5652188642db925a5915f8b743fd14b0e328 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -@@ -38,6 +38,7 @@ public interface IFernflowerPreferences { - String INCLUDE_ENTIRE_CLASSPATH = "iec"; +@@ -39,6 +39,7 @@ public interface IFernflowerPreferences { + String QUALIFY_INNER_CLASSES = "qin"; String EXPLICIT_GENERIC_ARGUMENTS = "ega"; String INLINE_SIMPLE_LAMBDAS = "isl"; + String THREADS = "thr"; String LOG_LEVEL = "log"; String MAX_PROCESSING_METHOD = "mpm"; -@@ -92,6 +93,7 @@ public interface IFernflowerPreferences { - defaults.put(INCLUDE_ENTIRE_CLASSPATH, "0"); +@@ -94,6 +95,7 @@ public interface IFernflowerPreferences { + defaults.put(QUALIFY_INNER_CLASSES, "1"); defaults.put(EXPLICIT_GENERIC_ARGUMENTS, "0"); defaults.put(INLINE_SIMPLE_LAMBDAS, "1"); + defaults.put(THREADS, "AUTO"); diff --git a/FernFlower-Patches/0040-Expose-line-mapping-information-in-archive-mode.patch b/FernFlower-Patches/0039-Expose-line-mapping-information-in-archive-mode.patch similarity index 98% rename from FernFlower-Patches/0040-Expose-line-mapping-information-in-archive-mode.patch rename to FernFlower-Patches/0039-Expose-line-mapping-information-in-archive-mode.patch index 13c0375..f18d63a 100644 --- a/FernFlower-Patches/0040-Expose-line-mapping-information-in-archive-mode.patch +++ b/FernFlower-Patches/0039-Expose-line-mapping-information-in-archive-mode.patch @@ -140,10 +140,10 @@ index f434fc92661e1337acfd2ebc7576fbd43f15622f..585494c81bda9c2bde5ea284fb8851df } catch (IOException e) { DecompilerContext.getLogger().writeMessage("Cannot write entry " + entryName + " to " + file, e); diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -index a2be81c2a329812c30ffe2606cae2b5f7ab43c3c..23ed017fc66747daf2f7b603df7d123835145570 100644 +index 7bcb5652188642db925a5915f8b743fd14b0e328..698020bbb42ba78718b5a332ca4e9a3f3660e9e9 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -@@ -58,6 +58,8 @@ public interface IFernflowerPreferences { +@@ -59,6 +59,8 @@ public interface IFernflowerPreferences { String SKIP_EXTRA_FILES = "sef"; @@ -152,7 +152,7 @@ index a2be81c2a329812c30ffe2606cae2b5f7ab43c3c..23ed017fc66747daf2f7b603df7d1238 Map DEFAULTS = getDefaults(); static Map getDefaults() { -@@ -105,6 +107,7 @@ public interface IFernflowerPreferences { +@@ -107,6 +109,7 @@ public interface IFernflowerPreferences { defaults.put(DUMP_ORIGINAL_LINES, "0"); defaults.put(USE_JAD_VARNAMING, "0"); defaults.put(SKIP_EXTRA_FILES, "0"); diff --git a/FernFlower-Patches/0040-Fixup-J9-string-concat.patch b/FernFlower-Patches/0040-Fixup-J9-string-concat.patch new file mode 100644 index 0000000..e4f9849 --- /dev/null +++ b/FernFlower-Patches/0040-Fixup-J9-string-concat.patch @@ -0,0 +1,178 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: JDLogic +Date: Mon, 31 May 2021 21:28:33 -0600 +Subject: [PATCH] Fixup J9 string concat + + +diff --git a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java +index f2964aa1e2759c4828e65d8db3b8421b7072adbf..85d9b2b2752a20b381e0f5e6420e5419ac728f6f 100644 +--- a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java ++++ b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java +@@ -161,6 +161,10 @@ public class MethodProcessorRunnable implements Runnable { + } + while (new PPandMMHelper(varProc).findPPandMM(root)); + ++ if (cl.isVersion(CodeConstants.BYTECODE_JAVA_9)) { ++ ConcatenationHelper.simplifyStringConcat(root); ++ } ++ + while (true) { + LabelHelper.cleanUpEdges(root); + +diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java +index f1f3e7c7e903dd0571c2a18f1ed976999cff99da..e44fa1ffd3929428524c31fdac14f1df2e6a6431 100644 +--- a/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java ++++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java +@@ -4,6 +4,7 @@ package org.jetbrains.java.decompiler.modules.decompiler; + import org.jetbrains.java.decompiler.ClassNameConstants; + import org.jetbrains.java.decompiler.code.CodeConstants; + import org.jetbrains.java.decompiler.modules.decompiler.exps.*; ++import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; + import org.jetbrains.java.decompiler.struct.consts.PooledConstant; + import org.jetbrains.java.decompiler.struct.consts.PrimitiveConstant; + import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; +@@ -22,6 +23,38 @@ public final class ConcatenationHelper { + private static final VarType builderType = new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/StringBuilder"); + private static final VarType bufferType = new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/StringBuffer"); + ++ public static void simplifyStringConcat(Statement stat) { ++ for (Statement s : stat.getStats()) { ++ simplifyStringConcat(s); ++ } ++ ++ if (stat.getExprents() != null) { ++ for (int i = 0; i < stat.getExprents().size(); ++i) { ++ Exprent ret = simplifyStringConcat(stat.getExprents().get(i)); ++ if (ret != null) { ++ stat.getExprents().set(i, ret); ++ } ++ } ++ } ++ } ++ ++ private static Exprent simplifyStringConcat(Exprent exprent) { ++ for (Exprent cexp : exprent.getAllExprents()) { ++ Exprent ret = simplifyStringConcat(cexp); ++ if (ret != null) { ++ exprent.replaceExprent(cexp, ret); ++ } ++ } ++ ++ if (exprent.type == Exprent.EXPRENT_INVOCATION) { ++ Exprent ret = ConcatenationHelper.contractStringConcat(exprent); ++ if (!exprent.equals(ret)) { ++ return ret; ++ } ++ } ++ ++ return null; ++ } + + public static Exprent contractStringConcat(Exprent expr) { + +@@ -150,6 +183,7 @@ public final class ConcatenationHelper { + StringBuilder acc = new StringBuilder(); + int parameterId = 0; + int bootstrapArgumentId = 1; ++ int nonString = 0; + for (int i = 0; i < recipe.length(); i++) { + char c = recipe.charAt(i); + +@@ -172,13 +206,12 @@ public final class ConcatenationHelper { + if (c == TAG_ARG) { + Exprent exprent = parameters.get(parameterId++); + +- if ((exprent instanceof VarExprent) && res.isEmpty()) { +- VarExprent varExprent = (VarExprent) exprent; +- +- if (!VarType.VARTYPE_STRING.equals(varExprent.getVarType())) { +- // First item of concatenation is a variable and variable's type is not a String. ++ if (!VarType.VARTYPE_STRING.equals(exprent.getExprType())) { ++ nonString++; ++ if (nonString == 2 && i == 1) { ++ // First two items of concatenation are a variable and variable's type is not a String. + // Prepend it with empty string literal to force resulting expression type to be String. +- res.add(new ConstExprent(VarType.VARTYPE_STRING, "", expr.bytecode)); ++ res.add(0, new ConstExprent(VarType.VARTYPE_STRING, "", expr.bytecode)); + } + } + +diff --git a/src/org/jetbrains/java/decompiler/struct/StructClass.java b/src/org/jetbrains/java/decompiler/struct/StructClass.java +index 3e0cbd0fbcbc29ff619d4b2441b13047bb803d11..f174c06886eb5b928abcaf3cedd3b459df9d463b 100644 +--- a/src/org/jetbrains/java/decompiler/struct/StructClass.java ++++ b/src/org/jetbrains/java/decompiler/struct/StructClass.java +@@ -286,6 +286,10 @@ public class StructClass extends StructMember { + return isVersion16() || (isVersion14() && isPreviewVersion()); + } + ++ public boolean isVersion(int minVersion) { ++ return majorVersion >= minVersion; ++ } ++ + @Override + public String toString() { + return qualifiedName; +diff --git a/testData/classes/java11/TestJava11StringConcatEmptyAffix.class b/testData/classes/java11/TestJava11StringConcatEmptyAffix.class +index 2b481af59af9a1e2faa68fef62e1f8cf79533791..2f75b2305743bf363663d8b29ff7f7aacc54a929 100644 +GIT binary patch +literal 1730 +zcmb7^+foxj5QhIrAiKtJFbJref(BS15~3(-5QPY3EId?&(hIMaFu+3CP3=x7c@rN) +zudK?258y*t_RJBSRc{8I}zc3_M^+tU0bD)*0f~{6~hKlDE$p26h~mziXWCaevp|tIui5Tlz9M|bJuK4x6*&BZVb+S$T7f<((3NPgvuSJKer5B +zsI19~*YK-++mQvI*(E=3sJ4Ydh?G3HYKPa|khfiug-@X$0}O+ko+kp~+x53x9C`b} +zKmrd|OW)_MIjSHz+35W}IRgLlh-CMPrOcW2`C1Z&zS>1kmcx4y> + +literal 2271 +zcma)+-BQy)6vzMDmNu61VO3B-1SwEHq@XBj5rs;nSiqTf@WQK50t8CZX|{~KiI1UI +z&h)|u@Sz;f?xs*kqU7T2*)!+-_P@I)`}7K;d6ond9ur41 +zv6Mtam@r-m^E!rX49g7BWz#bG3PU(OwaXC6+4}}VPtmlD?Z)YzQ7`LzRf;5wc15r5 +z>UC4h-C%?tnGVBL@mN387Zx&Q!{M9KE%CZ(9p-GSqVx6B8b4n>I559viNh&JMn2UI +z3KcBQa4%g@j7(Lx4l}Blk~_}yYJ(PM151ZvhLr@~qEDCs4evCpYFHDqF%3B}riFP=d%0mt(Ly3qUH{JB +zu~Ff1tRqiN!x;Kc^%FyN;b)T{k>_yT;?%RTnruJHi805$)Q~9A*u{L(r?vcUD~1n3 +z^+$%(r54jVvri1Smz9LPUg38AJccd0*P?BoG-?cqf@K-?Tvc}*gLHjsU(;o%1KiN9 +z{i@-lRAJV8(`}I}h2`^_;gkNQEngj6w!K$eL{6_(OC~qywb-T(@a)e|8^iFw^Dv48 +zJzL`IqNj@bg={a)GBh$8JEnhv{U9fV+hn6M7>0P^5-I_AaF=HEC!&w6D9+LtqA@nu +z6ytYt+smV}yicXL<&=zm+^0f@2N<{xnrYHg=>f$9L4y)B8unG>b4LAvAf@P$uOgo_8VUp{MI*k7qTa2I1cH>JQC~$dFDMlVQi>j9%)S0R +zwFqqq+Tc(VnwON8q!E>K(MTFnvXQ6`#^m^q2GN9Sx4aW8W|fH`%c +za~gwE=Zu#*OFvPkm$`UDW*D>b_j`g(8snsR14R_*C(F=$1Ra>C*n+f+(mt2=g|sjK +E0;Ip6ssI20 + +diff --git a/testData/results/TestJava11StringConcatEmptyAffix.dec b/testData/results/TestJava11StringConcatEmptyAffix.dec +index 6f9349f9123c863be861abde8f29aea3fe0496a9..fb1527258dda5a52c16827ff2439162f0764c272 100644 +--- a/testData/results/TestJava11StringConcatEmptyAffix.dec ++++ b/testData/results/TestJava11StringConcatEmptyAffix.dec +@@ -42,7 +42,7 @@ public class TestJava11StringConcatEmptyAffix { + } + + public String testIntString(int intValue, String stringValue) { +- return "" + intValue + stringValue;// 48 ++ return intValue + stringValue;// 48 + } + + public String testStringInt(int intValue, String stringValue) { +diff --git a/testData/src/java11/TestJava11StringConcatEmptyAffix.java b/testData/src/java11/TestJava11StringConcatEmptyAffix.java +index b53609095131d2f029c6d6d7e03f773107f6e1e3..90e3f54180a4f2767daecf9b4a86cba4c4c53284 100644 +--- a/testData/src/java11/TestJava11StringConcatEmptyAffix.java ++++ b/testData/src/java11/TestJava11StringConcatEmptyAffix.java +@@ -45,7 +45,7 @@ public class TestJava11StringConcatEmptyAffix { + } + + public String testIntString(int intValue, String stringValue) { +- return "" + intValue + stringValue; ++ return intValue + stringValue; + } + + public String testStringInt(int intValue, String stringValue) { diff --git a/FernFlower-Patches/0041-Fixup-J9-string-concat.patch b/FernFlower-Patches/0041-Fixup-J9-string-concat.patch deleted file mode 100644 index 4b16f3e..0000000 --- a/FernFlower-Patches/0041-Fixup-J9-string-concat.patch +++ /dev/null @@ -1,386 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: JDLogic -Date: Mon, 31 May 2021 21:28:33 -0600 -Subject: [PATCH] Fixup J9 string concat - - -diff --git a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java -index 12d737b747fe5fa60a5c449fd91dda9a39fb4387..795cc200b44c547862cfb8742b216b1c7032f2e8 100644 ---- a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java -+++ b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java -@@ -150,6 +150,10 @@ public class MethodProcessorRunnable implements Runnable { - } - while (new PPandMMHelper(varProc).findPPandMM(root)); - -+ if (cl.isVersion(CodeConstants.BYTECODE_JAVA_9)) { -+ ConcatenationHelper.simplifyStringConcat(root); -+ } -+ - while (true) { - LabelHelper.cleanUpEdges(root); - -diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java -index a41e8de55f8edf43d7271ec02b6bca1e14138a1b..2e77549e3cbe5511085ef262884cc6f24b1ffeb2 100644 ---- a/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java -+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java -@@ -3,6 +3,7 @@ package org.jetbrains.java.decompiler.modules.decompiler; - - import org.jetbrains.java.decompiler.code.CodeConstants; - import org.jetbrains.java.decompiler.modules.decompiler.exps.*; -+import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; - import org.jetbrains.java.decompiler.struct.consts.PooledConstant; - import org.jetbrains.java.decompiler.struct.consts.PrimitiveConstant; - import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; -@@ -22,6 +23,38 @@ public final class ConcatenationHelper { - private static final VarType builderType = new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/StringBuilder"); - private static final VarType bufferType = new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/StringBuffer"); - -+ public static void simplifyStringConcat(Statement stat) { -+ for (Statement s : stat.getStats()) { -+ simplifyStringConcat(s); -+ } -+ -+ if (stat.getExprents() != null) { -+ for (int i = 0; i < stat.getExprents().size(); ++i) { -+ Exprent ret = simplifyStringConcat(stat.getExprents().get(i)); -+ if (ret != null) { -+ stat.getExprents().set(i, ret); -+ } -+ } -+ } -+ } -+ -+ private static Exprent simplifyStringConcat(Exprent exprent) { -+ for (Exprent cexp : exprent.getAllExprents()) { -+ Exprent ret = simplifyStringConcat(cexp); -+ if (ret != null) { -+ exprent.replaceExprent(cexp, ret); -+ } -+ } -+ -+ if (exprent.type == Exprent.EXPRENT_INVOCATION) { -+ Exprent ret = ConcatenationHelper.contractStringConcat(exprent); -+ if (!exprent.equals(ret)) { -+ return ret; -+ } -+ } -+ -+ return null; -+ } - - public static Exprent contractStringConcat(Exprent expr) { - -@@ -44,6 +77,18 @@ public final class ConcatenationHelper { - } - else if ("makeConcatWithConstants".equals(iex.getName())) { // java 9 style - List parameters = extractParameters(iex.getBootstrapArguments(), iex); -+ -+ boolean addEmptyString = true; -+ for (int index = 0; index < parameters.size() && index < 2; index++) { -+ if (parameters.get(index).getExprType().equals(VarType.VARTYPE_STRING)) { -+ addEmptyString = false; -+ break; -+ } -+ } -+ if (addEmptyString) { -+ parameters.add(0, new ConstExprent(VarType.VARTYPE_STRING, "", expr.bytecode)); -+ } -+ - if (parameters.size() >= 2) { - return createConcatExprent(parameters, expr.bytecode); - } -diff --git a/src/org/jetbrains/java/decompiler/struct/StructClass.java b/src/org/jetbrains/java/decompiler/struct/StructClass.java -index 0a6e5b74b7a8b07368a0c1970faab818cea6a9d8..b7bd346863cd2e56c513b60dcb3c2923f2d7813a 100644 ---- a/src/org/jetbrains/java/decompiler/struct/StructClass.java -+++ b/src/org/jetbrains/java/decompiler/struct/StructClass.java -@@ -246,6 +246,10 @@ public class StructClass extends StructMember { - return majorVersion >= CodeConstants.BYTECODE_JAVA_8; - } - -+ public boolean isVersion(int minVersion) { -+ return majorVersion >= minVersion; -+ } -+ - @Override - public String toString() { - return qualifiedName; -diff --git a/testData/classes/java11/TestJava11StringConcat.class b/testData/classes/java11/TestJava11StringConcat.class -index 8ec1fbd7849ee94217014605f9d8e94f18806fb7..ed4d6dc33d127ed0e6d2d6f43cff6ab9d7cb4d82 100644 -GIT binary patch -delta 459 -zcmZXPO-=$q5QSe2GBf-M3dK9Y -znFR;%C?3N2nh;H}7xk+8ebrU{Wq#O=&+l*wpo7CWEEF8(YYqgS&ek0mC|jsls7}hy -ziD=Lt1xJEfy{p>BhI<(d?;mbY1vBGVkgsP6n=KwTNVoXK7FiE>j8 -zV~ne*Q5Yw9XR-qHACgFEhgF6Dh)`|c3z_1Lx!{j>SuGkU_NW^@v73#i4e3f7Z -z**X6Ecc&OfBj_ME$IDc%0IL*o|9^0W16|q%@@P`y#P`sKk0MrByY%(^;w+YC -GapMQA^Dqhk - -delta 316 -zcmZXOJ8l9&5JamN*d3Oy`5Dae_eZcIL{2SYd=hMVtZ61vr8oAX^*w0Em-V -zJ_Di#5y1pi)jhAL=STh7t=%E|1@Md~7YXDG%%uVZ6$iHts_Xtn*To;$a0K~r5QK|x -zKK*!o3*Up;B4?wfaF<3MDFx4XMlWR)YoMvO;wuL&)9mSg>C1zzSX+72duy_abD23Y -zuHxHN#i~IUdSdVm`CBi*6i-?{0?v6L?f?J) - -diff --git a/testData/classes/java9/TestJava9StringConcat.class b/testData/classes/java9/TestJava9StringConcat.class -index 721a0ed9499e46d3ea2ea1853198faba1186a168..eb77c0bd9a3d94d562fb31e60c90811645274591 100644 -GIT binary patch -delta 477 -zcmZXPyG{aO5QWbyvb)>_mPJKYZeF-7cnKN{3llpMt!!;fAZjB9wlv`x$i9G;g_Rb> -zWD6g_7x68O=id+u*y5a%nQ#A@`O#-)^ZPgW0&s$(I1H>=%$pVjj!Ih=G?Wcg3{X)-st(RRtB2mY(f4fhn$7noG#P30*qq7gO=b52ik0F$fHehq{Nx+h}9j5=AaNL1`Mt -z$vSzSKh2iODqgIME}9yx9NNfgbgbvii`+Y1T$xW9YY%}P-k76|Bs3MZP2CDYbEiV{ -zqXv&DX4>O0kr7nQu1gnsI@&=#SO_vy_cXMh^O2=mvrpl`3FC_AnX7D - -diff --git a/testData/classes/pkg/TestStringConcat.class b/testData/classes/pkg/TestStringConcat.class -index 029207376cef59555729fc47605dda16cd3b41b5..854f9982885d799d24a6ff98763b3ae909dd109e 100644 -GIT binary patch -delta 382 -zcmZ8cJ5Iwu6r8ul_R5$*oH!07fdGcs;3bhr#Ydu{$Pu9D1f=H-(Ow`&pg=|fi5hVM -zEAj0|f6WT>t<8 - -delta 237 -zcmYj~T@JxO6ot>7rrI<`RZG$OZP6z4A|4Uzuq&Boi7gO`#DfLcfDL%F2XUt_Ofuh@ -zb58D^i}f?qgqgA)KFJD -ziqjOCixg8AGt3F3uOt{!N}cCyb9JES#^t~CF+kv9rpGQ}C04Vzf=>J(G? 5 - 24 <-> 9 -+28 <-> 13 -+32 <-> 17 -diff --git a/testData/results/TestJava9StringConcat.dec b/testData/results/TestJava9StringConcat.dec -index 29890ed8d641519f957d34981fc41e678a7caf2f..d42978e195540e9c844b460d66c2b386e2ed3d5b 100644 ---- a/testData/results/TestJava9StringConcat.dec -+++ b/testData/results/TestJava9StringConcat.dec -@@ -8,6 +8,14 @@ public class TestJava9StringConcat { - public String test2(String var1, int var2, Object var3) { - return "(" + var1 + "-" + var2 + "---" + var3 + ")";// 24 - } -+ -+ public String test3(int var1, Object var2) { -+ return "" + var1 + var2;// 28 -+ } -+ -+ public String test4(int var1) { -+ return "" + var1;// 32 -+ } - } - - class 'java9/TestJava9StringConcat' { -@@ -33,8 +41,31 @@ class 'java9/TestJava9StringConcat' { - 7 8 - 8 8 - } -+ -+ method 'test3 (ILjava/lang/Object;)Ljava/lang/String;' { -+ 0 12 -+ 1 12 -+ 2 12 -+ 3 12 -+ 4 12 -+ 5 12 -+ 6 12 -+ 7 12 -+ } -+ -+ method 'test4 (I)Ljava/lang/String;' { -+ 0 16 -+ 1 16 -+ 2 16 -+ 3 16 -+ 4 16 -+ 5 16 -+ 6 16 -+ } - } - - Lines mapping: - 20 <-> 5 - 24 <-> 9 -+28 <-> 13 -+32 <-> 17 -diff --git a/testData/results/TestStringConcat.dec b/testData/results/TestStringConcat.dec -index 951a761c030b7d6e62e309019b361722ebdd40d9..615dc5c2ef5d662cbbc6e01e52d1d6fcae5dfb3a 100644 ---- a/testData/results/TestStringConcat.dec -+++ b/testData/results/TestStringConcat.dec -@@ -8,6 +8,14 @@ public class TestStringConcat { - public String test2(String var1, int var2, Object var3) { - return "(" + var1 + "-" + var2 + "---" + var3 + ")";// 24 - } -+ -+ public String test3(int var1, Object var2) { -+ return var1 + "" + var2;// 28 -+ } -+ -+ public String test4(int var1) { -+ return "" + var1;// 32 -+ } - } - - class 'pkg/TestStringConcat' { -@@ -37,8 +45,31 @@ class 'pkg/TestStringConcat' { - 29 8 - 2a 8 - } -+ -+ method 'test3 (ILjava/lang/Object;)Ljava/lang/String;' { -+ 7 12 -+ b 12 -+ c 12 -+ 10 12 -+ 14 12 -+ 15 12 -+ 16 12 -+ 17 12 -+ } -+ -+ method 'test4 (I)Ljava/lang/String;' { -+ 7 16 -+ 8 16 -+ c 16 -+ 10 16 -+ 11 16 -+ 12 16 -+ 13 16 -+ } - } - - Lines mapping: - 20 <-> 5 - 24 <-> 9 -+28 <-> 13 -+32 <-> 17 -diff --git a/testData/src/java11/TestJava11StringConcat.java b/testData/src/java11/TestJava11StringConcat.java -index 3f9e04047c6b2edcaa9eb84bbae8df1ec9fa1836..d1043feecbe07d9e7a9498425221a6bdb66145c6 100644 ---- a/testData/src/java11/TestJava11StringConcat.java -+++ b/testData/src/java11/TestJava11StringConcat.java -@@ -23,4 +23,12 @@ public class TestJava11StringConcat { - public String test2(String var, int b, Object c) { - return "(" + var + "-" + b + "---" + c + ")"; - } -+ -+ public String test3(int b, Object c) { -+ return b + "" + c; -+ } -+ -+ public String test4(int b) { -+ return "" + b; -+ } - } -\ No newline at end of file -diff --git a/testData/src/java9/TestJava9StringConcat.java b/testData/src/java9/TestJava9StringConcat.java -index 9e1959649e53304be2f23689824b4bcf77c56f0a..727413c0254c729be3c06513a1f5833f31e750b6 100644 ---- a/testData/src/java9/TestJava9StringConcat.java -+++ b/testData/src/java9/TestJava9StringConcat.java -@@ -23,4 +23,12 @@ public class TestJava9StringConcat { - public String test2(String var, int b, Object c) { - return "(" + var + "-" + b + "---" + c + ")"; - } -+ -+ public String test3(int b, Object c) { -+ return b + "" + c; -+ } -+ -+ public String test4(int b) { -+ return "" + b; -+ } - } -\ No newline at end of file -diff --git a/testData/src/pkg/TestStringConcat.java b/testData/src/pkg/TestStringConcat.java -index 1a77677ad523807401c4269ca0296c1fa45d265e..6cc0eb1f9f66ba098884850970392f64becd3c21 100644 ---- a/testData/src/pkg/TestStringConcat.java -+++ b/testData/src/pkg/TestStringConcat.java -@@ -23,4 +23,12 @@ public class TestStringConcat { - public String test2(String var, int b, Object c) { - return "(" + var + "-" + b + "---" + c + ")"; - } -+ -+ public String test3(int b, Object c) { -+ return b + "" + c; -+ } -+ -+ public String test4(int b) { -+ return "" + b; -+ } - } -\ No newline at end of file diff --git a/FernFlower-Patches/0042-Temporary-fix-for-a-loop-inlining-failure.patch b/FernFlower-Patches/0041-Temporary-fix-for-a-loop-inlining-failure.patch similarity index 74% rename from FernFlower-Patches/0042-Temporary-fix-for-a-loop-inlining-failure.patch rename to FernFlower-Patches/0041-Temporary-fix-for-a-loop-inlining-failure.patch index 9a563f5..6af58ac 100644 --- a/FernFlower-Patches/0042-Temporary-fix-for-a-loop-inlining-failure.patch +++ b/FernFlower-Patches/0041-Temporary-fix-for-a-loop-inlining-failure.patch @@ -9,10 +9,10 @@ loop, but allows producing a compilable result for now. Co-Authored-By: Geolykt diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java -index afcf55e1429a880ca5d945cd127ef90de25daee2..725951ff0d0350720ab0f92601e1db7767d73f2b 100644 +index 2528d7e0c1d657daf3c7154c426f3fefa4f43311..4504531347d3753fc2a0afa900597db7df53b66c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java -@@ -109,7 +109,7 @@ public final class IfHelper { +@@ -117,7 +117,7 @@ public final class IfHelper { private static boolean collapseIfIf(IfNode rtnode) { if (rtnode.edgetypes.get(0) == 0) { IfNode ifbranch = rtnode.succs.get(0); @@ -21,7 +21,7 @@ index afcf55e1429a880ca5d945cd127ef90de25daee2..725951ff0d0350720ab0f92601e1db77 // if-if branch if (ifbranch.succs.get(1).value == rtnode.succs.get(1).value) { -@@ -181,7 +181,7 @@ public final class IfHelper { +@@ -189,7 +189,7 @@ public final class IfHelper { private static boolean collapseIfElse(IfNode rtnode) { if (rtnode.edgetypes.get(0) == 0) { IfNode ifbranch = rtnode.succs.get(0); @@ -30,7 +30,7 @@ index afcf55e1429a880ca5d945cd127ef90de25daee2..725951ff0d0350720ab0f92601e1db77 // if-else branch if (ifbranch.succs.get(0).value == rtnode.succs.get(1).value) { -@@ -230,7 +230,7 @@ public final class IfHelper { +@@ -238,7 +238,7 @@ public final class IfHelper { } private static boolean collapseElse(IfNode rtnode) { @@ -39,7 +39,7 @@ index afcf55e1429a880ca5d945cd127ef90de25daee2..725951ff0d0350720ab0f92601e1db77 IfNode elsebranch = rtnode.succs.get(1); if (elsebranch.succs.size() == 2) { -@@ -363,7 +363,11 @@ public final class IfHelper { +@@ -371,7 +371,11 @@ public final class IfHelper { } // else branch @@ -52,7 +52,7 @@ index afcf55e1429a880ca5d945cd127ef90de25daee2..725951ff0d0350720ab0f92601e1db77 Statement elsechild = edge.getDestination(); IfNode elsenode = new IfNode(elsechild); -@@ -494,7 +498,7 @@ public final class IfHelper { +@@ -501,7 +505,7 @@ public final class IfHelper { ifstat.iftype = IfStatement.IFTYPE_IFELSE; } @@ -62,10 +62,10 @@ index afcf55e1429a880ca5d945cd127ef90de25daee2..725951ff0d0350720ab0f92601e1db77 // negate the if condition IfExprent statexpr = ifstat.getHeadexprent(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/LoopExtractHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/LoopExtractHelper.java -index 04b82fc67fca471f6c868c227df24160e57edb5f..4bdc50263e88ec2857661aaae9ef6d21b4add97c 100644 +index 1743e96a47775011c65a10cddf5a7226ef656473..d2a4fa2b327ecc82a26fbe38ba13d6763d23d5f6 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/LoopExtractHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/LoopExtractHelper.java -@@ -102,9 +102,13 @@ public final class LoopExtractHelper { +@@ -106,9 +106,13 @@ public final class LoopExtractHelper { IfStatement lastif = (IfStatement)last; if (lastif.iftype == IfStatement.IFTYPE_IF && lastif.getIfstat() != null) { Statement ifstat = lastif.getIfstat(); @@ -76,21 +76,21 @@ index 04b82fc67fca471f6c868c227df24160e57edb5f..4bdc50263e88ec2857661aaae9ef6d21 + } + StatEdge elseedge = successorEdges.get(0); -- if (elseedge.getType() == StatEdge.TYPE_CONTINUE && elseedge.closure == stat) { -+ if (elseedge == null || elseedge.getType() == StatEdge.TYPE_CONTINUE && elseedge.closure == stat) { +- if (elseedge.getType() == EdgeType.CONTINUE && elseedge.closure == stat) { ++ if (elseedge == null || elseedge.getType() == EdgeType.CONTINUE && elseedge.closure == stat) { - Set set = stat.getNeighboursSet(StatEdge.TYPE_CONTINUE, Statement.DIRECTION_BACKWARD); + Set set = stat.getNeighboursSet(EdgeType.CONTINUE, EdgeDirection.BACKWARD); set.remove(last); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java -index b6754ef09179b8e7028a98248f6bff2b100b94af..3f15c35b5cec992393c52bbfaba023844cd4a94e 100644 +index f4f8b55a68c10671beef7859540398cac541d6e2..7717f0df479c5357f685046d6231f391735772a2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java -@@ -283,7 +283,7 @@ public class FlattenStatementsHelper { +@@ -287,7 +287,7 @@ public class FlattenStatementsHelper { node = graph.nodes.getWithKey(mapDestinationNodes.get(stat.getFirst().id)[0]); mapDestinationNodes.put(stat.id, new String[]{node.id, null}); -- if (stat.type == Statement.TYPE_IF && ((IfStatement)stat).iftype == IfStatement.IFTYPE_IF) { -+ if (stat.type == Statement.TYPE_IF && ((IfStatement)stat).iftype == IfStatement.IFTYPE_IF && !stat.getAllSuccessorEdges().isEmpty()) { - lstSuccEdges.add(stat.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL).get(0)); // exactly one edge +- if (stat.type == StatementType.IF && ((IfStatement)stat).iftype == IfStatement.IFTYPE_IF) { ++ if (stat.type == StatementType.IF && ((IfStatement)stat).iftype == IfStatement.IFTYPE_IF && !stat.getAllSuccessorEdges().isEmpty()) { + lstSuccEdges.add(stat.getSuccessorEdges(EdgeType.DIRECT_ALL).get(0)); // exactly one edge sourcenode = tailexprlst.get(0) == null ? node : graph.nodes.getWithKey(node.id + "_tail"); } diff --git a/FernFlower-Patches/0043-Fix-compound-assignments.patch b/FernFlower-Patches/0042-Fix-compound-assignments.patch similarity index 95% rename from FernFlower-Patches/0043-Fix-compound-assignments.patch rename to FernFlower-Patches/0042-Fix-compound-assignments.patch index 91ea0ec..4370671 100644 --- a/FernFlower-Patches/0043-Fix-compound-assignments.patch +++ b/FernFlower-Patches/0042-Fix-compound-assignments.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix compound assignments diff --git a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java -index 795cc200b44c547862cfb8742b216b1c7032f2e8..1de3ccd0d3966f82bd07d0b45e1692f6c22348db 100644 +index 85d9b2b2752a20b381e0f5e6420e5419ac728f6f..fd6c22a4b18b2875a5f0f1b7d3f18fa2ed0ba305 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java +++ b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java -@@ -222,6 +222,8 @@ public class MethodProcessorRunnable implements Runnable { +@@ -228,6 +228,8 @@ public class MethodProcessorRunnable implements Runnable { varProc.setVarDefinitions(root); @@ -18,10 +18,10 @@ index 795cc200b44c547862cfb8742b216b1c7032f2e8..1de3ccd0d3966f82bd07d0b45e1692f6 // FIXME: new edge type needed LabelHelper.replaceContinueWithBreak(root); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java -index beaa6c260a1e85e939556705f38b0bb16280a29d..e4056c4ae81eff96d2c4e84b86c81148ae732e05 100644 +index 3aa5956fbb79de630c5e9e600c9fd27ae7da0091..bd09bfc980b57c840c8b48ef2723a4ccc62910f7 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java -@@ -431,4 +431,46 @@ public final class SecondaryFunctionsHelper { +@@ -430,4 +430,46 @@ public final class SecondaryFunctionsHelper { return null; } @@ -69,13 +69,13 @@ index beaa6c260a1e85e939556705f38b0bb16280a29d..e4056c4ae81eff96d2c4e84b86c81148 + } } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -index 381a1ecc559e59b38c28a6a10df465384cd40d0e..ee57e305da26b7678fb605f61e16f61f35e112c4 100644 +index f9dd18ce93da5481aa016ea665898e3b690db6ec..3760b901af42d9321df36c7bcf5f1a8827ba8923 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java -@@ -122,4 +122,5 @@ public class SingleClassesTest extends SingleClassesTestBase { - @Test public void testRecordGenericVararg() { doTest("records/TestRecordGenericVararg"); } - @Test public void testRecordAnno() { doTest("records/TestRecordAnno"); } - @Test public void testTryWithResources() { doTest("pkg/TestTryWithResources"); } +@@ -214,4 +214,5 @@ public class SingleClassesTest extends SingleClassesTestBase { + + @Test(expected = ClassFormatException.class) + public void testUnsupportedConstantPoolEntry() { doTest("java11/TestUnsupportedConstantPoolEntry"); } + @Test public void testCompoundAssignment() { doTest("pkg/TestCompoundAssignment"); } } diff --git a/testData/classes/pkg/TestCompoundAssignment.class b/testData/classes/pkg/TestCompoundAssignment.class diff --git a/FernFlower-Patches/0044-Filter-out-generated-Record-getters-and-constructor..patch b/FernFlower-Patches/0043-Filter-out-generated-Record-getters-and-constructor..patch similarity index 82% rename from FernFlower-Patches/0044-Filter-out-generated-Record-getters-and-constructor..patch rename to FernFlower-Patches/0043-Filter-out-generated-Record-getters-and-constructor..patch index ffdbeaa..65a9d5e 100644 --- a/FernFlower-Patches/0044-Filter-out-generated-Record-getters-and-constructor..patch +++ b/FernFlower-Patches/0043-Filter-out-generated-Record-getters-and-constructor..patch @@ -6,10 +6,10 @@ Subject: [PATCH] Filter out generated Record getters and constructor. Make diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -index 43199af10fde2770ee14b36ba5bbae23ebb5e2cc..f9b40d707e880c27e3d3d29ef9cc0ca224db5ed3 100644 +index bae5fd174027bc9f8c7c3d2eb53c2ef7ccab6ffe..15cdda39d2354f1e0eab1e72a7769fb9d2083958 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -@@ -330,6 +330,18 @@ public class ClassWriter { +@@ -350,6 +350,18 @@ public class ClassWriter { return str.startsWith("return this." + name + "(this"); } } @@ -28,7 +28,7 @@ index 43199af10fde2770ee14b36ba5bbae23ebb5e2cc..f9b40d707e880c27e3d3d29ef9cc0ca2 } return false; } -@@ -781,7 +793,7 @@ public class ClassWriter { +@@ -676,7 +688,7 @@ public class ClassWriter { boolean isAnnotation = cl.hasModifier(CodeConstants.ACC_ANNOTATION); boolean isEnum = cl.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM); boolean isDeprecated = mt.hasAttribute(StructGeneralAttribute.ATTRIBUTE_DEPRECATED); @@ -37,7 +37,7 @@ index 43199af10fde2770ee14b36ba5bbae23ebb5e2cc..f9b40d707e880c27e3d3d29ef9cc0ca2 MethodDescriptor md = MethodDescriptor.parseDescriptor(mt, node); -@@ -832,6 +844,41 @@ public class ClassWriter { +@@ -728,6 +740,41 @@ public class ClassWriter { name = node.simpleName; init = true; } @@ -79,7 +79,7 @@ index 43199af10fde2770ee14b36ba5bbae23ebb5e2cc..f9b40d707e880c27e3d3d29ef9cc0ca2 } else if (CodeConstants.CLINIT_NAME.equals(name)) { name = ""; -@@ -856,6 +903,7 @@ public class ClassWriter { +@@ -752,6 +799,7 @@ public class ClassWriter { } buffer.append(toValidJavaIdentifier(name)); @@ -87,20 +87,20 @@ index 43199af10fde2770ee14b36ba5bbae23ebb5e2cc..f9b40d707e880c27e3d3d29ef9cc0ca2 buffer.append('('); List mask = methodWrapper.synthParameters; -@@ -954,6 +1002,7 @@ public class ClassWriter { - buffer.append(ExprProcessor.getCastTypeName(type)); +@@ -837,6 +885,7 @@ public class ClassWriter { + buffer.append(ExprProcessor.getCastTypeName(type, Collections.emptyList())); } } + } } tracer.incrementCurrentSourceLine(buffer.countLines(start_index_method)); -@@ -987,7 +1036,7 @@ public class ClassWriter { +@@ -870,7 +919,7 @@ public class ClassWriter { BytecodeMappingTracer codeTracer = new BytecodeMappingTracer(tracer.getCurrentSourceLine()); TextBuffer code = root.toJava(indent + 1, codeTracer); -- hideMethod = code.length() == 0 && (clInit || dInit || hideConstructor(node, init, throwsExceptions, paramCount, flags)) || -+ hideMethod |= code.length() == 0 && (clInit || dInit || hideConstructor(node, init, throwsExceptions, paramCount, flags)) || - isSyntheticRecordMethod(cl, mt, code); +- hideMethod = code.length() == 0 && ++ hideMethod |= code.length() == 0 && + (clInit || dInit || hideConstructor(node, !typeAnnotations.isEmpty(), init, throwsExceptions, paramCount, flags)) || + isSyntheticRecordMethod(cl, mt, code); - buffer.append(code); diff --git a/FernFlower-Patches/0046-Fix-variables-in-finally-blocks-not-getting-renamed.patch b/FernFlower-Patches/0044-Fix-variables-in-finally-blocks-not-getting-renamed.patch similarity index 81% rename from FernFlower-Patches/0046-Fix-variables-in-finally-blocks-not-getting-renamed.patch rename to FernFlower-Patches/0044-Fix-variables-in-finally-blocks-not-getting-renamed.patch index 0e54f62..250ac76 100644 --- a/FernFlower-Patches/0046-Fix-variables-in-finally-blocks-not-getting-renamed.patch +++ b/FernFlower-Patches/0044-Fix-variables-in-finally-blocks-not-getting-renamed.patch @@ -5,16 +5,16 @@ Subject: [PATCH] Fix variables in finally blocks not getting renamed diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java -index 14da709f122333476cc1482c00f94e6a3ed7cbac..6fb6867aab76221d87d79195dbb7d468265bbac5 100644 +index 30cdd284745688c1d2b0e10b5e884991173a1527..d60e7cc9b67c1e850d4d998f96ea3fdd2c8eb31a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java -@@ -763,23 +763,29 @@ public class FinallyProcessor { +@@ -762,23 +762,29 @@ public class FinallyProcessor { int finallytype, List lstStoreVars) { InstructionSequence seqPattern = pattern.getSeq(); -+ List instrOldOffsetsPattern = pattern.getInstrOldOffsets(); ++ List instrOldOffsetsPattern = pattern.getOriginalOffsets(); InstructionSequence seqSample = sample.getSeq(); -+ List instrOldOffsetsSample = sample.getInstrOldOffsets(); ++ List instrOldOffsetsSample = sample.getOriginalOffsets(); if (type != 0) { seqPattern = seqPattern.clone(); @@ -38,19 +38,19 @@ index 14da709f122333476cc1482c00f94e6a3ed7cbac..6fb6867aab76221d87d79195dbb7d468 seqPattern.removeLast(); } } -@@ -806,6 +812,7 @@ public class FinallyProcessor { +@@ -805,6 +811,7 @@ public class FinallyProcessor { seq.addInstruction(0, seqSample.getInstr(i), -1); - oldOffsets.addFirst(sample.getOldOffset(i)); + oldOffsets.addFirst(sample.getOriginalOffset(i)); seqSample.removeInstruction(i); + instrOldOffsetsSample.remove(i); } - BasicBlock newblock = new BasicBlock(++graph.last_id); -@@ -969,26 +976,31 @@ public class FinallyProcessor { + BasicBlock newBlock = new BasicBlock(++graph.last_id, seq); +@@ -967,26 +974,31 @@ public class FinallyProcessor { private static void removeExceptionInstructionsEx(BasicBlock block, int blocktype, int finallytype) { InstructionSequence seq = block.getSeq(); -+ List instrOldOffsets = block.getInstrOldOffsets(); ++ List instrOldOffsets = block.getOriginalOffsets(); if (finallytype == 3) { // empty finally handler for (int i = seq.length() - 1; i >= 0; i--) { diff --git a/FernFlower-Patches/0045-Remove-default-keyword-from-private-interface-method.patch b/FernFlower-Patches/0045-Remove-default-keyword-from-private-interface-method.patch deleted file mode 100644 index 46fc5b0..0000000 --- a/FernFlower-Patches/0045-Remove-default-keyword-from-private-interface-method.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: coehlrich -Date: Tue, 16 Nov 2021 18:22:31 +1300 -Subject: [PATCH] Remove default keyword from private interface methods - - -diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -index f9b40d707e880c27e3d3d29ef9cc0ca224db5ed3..64e0635a9835a153ce1a300146d6e40db624c63a 100644 ---- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java -+++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java -@@ -829,7 +829,7 @@ public class ClassWriter { - - appendModifiers(buffer, flags, METHOD_ALLOWED, isInterface, METHOD_EXCLUDED); - -- if (isInterface && !mt.hasModifier(CodeConstants.ACC_STATIC) && mt.containsCode()) { -+ if (isInterface && !mt.hasModifier(CodeConstants.ACC_STATIC) && !mt.hasModifier(CodeConstants.ACC_PRIVATE) && mt.containsCode()) { - // 'default' modifier (Java 8) - buffer.append("default "); - } diff --git a/FernFlower-Patches/0047-Search-generics-when-finding-where-to-inject-local-c.patch b/FernFlower-Patches/0045-Search-generics-when-finding-where-to-inject-local-c.patch similarity index 83% rename from FernFlower-Patches/0047-Search-generics-when-finding-where-to-inject-local-c.patch rename to FernFlower-Patches/0045-Search-generics-when-finding-where-to-inject-local-c.patch index d89c9d3..814aa32 100644 --- a/FernFlower-Patches/0047-Search-generics-when-finding-where-to-inject-local-c.patch +++ b/FernFlower-Patches/0045-Search-generics-when-finding-where-to-inject-local-c.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Search generics when finding where to inject local classes. diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -index f9d15e108cfff05be4f38b10a00814259364a849..ece03f96d212c2ba26d7a7c6d9caab6ca93cd626 100644 +index 3530d2f46c4ad90974796e41f664613420e2689a..d83ecd553177e5b1ed50776bc5e48d44eb94ba90 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java -@@ -28,6 +28,7 @@ import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; +@@ -25,6 +25,7 @@ import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute.LocalVariable; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; @@ -16,7 +16,7 @@ index f9d15e108cfff05be4f38b10a00814259364a849..ece03f96d212c2ba26d7a7c6d9caab6c import org.jetbrains.java.decompiler.util.DotExporter; import org.jetbrains.java.decompiler.util.InterpreterUtil; -@@ -80,7 +81,7 @@ public class NestedClassProcessor { +@@ -77,7 +78,7 @@ public class NestedClassProcessor { if (child.type == ClassNode.CLASS_LOCAL && child.enclosingMethod != null) { MethodWrapper enclosingMethodWrapper = node.getWrapper().getMethods().getWithKey(child.enclosingMethod); @@ -25,18 +25,18 @@ index f9d15e108cfff05be4f38b10a00814259364a849..ece03f96d212c2ba26d7a7c6d9caab6c setLocalClassDefinition(enclosingMethodWrapper, child); } } -@@ -1057,9 +1058,15 @@ public class NestedClassProcessor { +@@ -935,9 +936,15 @@ public class NestedClassProcessor { case Exprent.EXPRENT_VAR: VarExprent varExpr = (VarExprent)expr; if (varExpr.isDefinition()) { - VarType varType = varExpr.getVarType(); -- if (classType.equals(varType) || (varType.arrayDim > 0 && classType.value.equals(varType.value))) { +- if (classType.equals(varType) || (varType.getArrayDim() > 0 && classType.getValue().equals(varType.getValue()))) { - res = true; + Stack stack = new Stack<>(); + stack.push(varExpr.getDefinitionType()); + while (!stack.isEmpty()) { + VarType varType = stack.pop(); -+ if (classType.equals(varType) || (varType.arrayDim > 0 && classType.value.equals(varType.value))) { ++ if (classType.equals(varType) || (varType.getArrayDim() > 0 && classType.getValue().equals(varType.getValue()))) { + res = true; + } else if (varType.isGeneric()) { + ((GenericType)varType).getArguments().forEach(stack::push); @@ -45,7 +45,7 @@ index f9d15e108cfff05be4f38b10a00814259364a849..ece03f96d212c2ba26d7a7c6d9caab6c } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java -index c8bf497f5cac2bb9e3c7b2187a4b70d392ef9e7c..a7bf7eb3b499d623d11914bcca98702328e57329 100644 +index 209fb0603e4e283ebd64cb4c993dc245291d952c..0fb1e4749f39a0122735c1d54ea42f94e34d38d2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java @@ -153,7 +153,8 @@ public class VarExprent extends Exprent { @@ -62,13 +62,13 @@ index c8bf497f5cac2bb9e3c7b2187a4b70d392ef9e7c..a7bf7eb3b499d623d11914bcca987023 if (lvt.getSignature() != null) { GenericFieldDescriptor descriptor = GenericMain.parseFieldSignature(lvt.getSignature()); if (descriptor != null) { -- buffer.append(ExprProcessor.getCastTypeName(descriptor.type)); +- buffer.append(ExprProcessor.getCastTypeName(descriptor.type, Collections.emptyList())); - return; + return descriptor.type; } } } -- buffer.append(ExprProcessor.getCastTypeName(getVarType())); +- buffer.append(ExprProcessor.getCastTypeName(getVarType(), Collections.emptyList())); - return; + return getVarType(); } @@ -78,7 +78,7 @@ index c8bf497f5cac2bb9e3c7b2187a4b70d392ef9e7c..a7bf7eb3b499d623d11914bcca987023 if (signature != null) { GenericFieldDescriptor descriptor = GenericMain.parseFieldSignature(signature); if (descriptor != null) { -- buffer.append(ExprProcessor.getCastTypeName(descriptor.type)); +- buffer.append(ExprProcessor.getCastTypeName(descriptor.type, Collections.emptyList())); - return; + return descriptor.type; } @@ -88,7 +88,7 @@ index c8bf497f5cac2bb9e3c7b2187a4b70d392ef9e7c..a7bf7eb3b499d623d11914bcca987023 if (attr != null) { String descriptor = attr.getDescriptor(originalIndex, visibleOffset); if (descriptor != null) { -- buffer.append(ExprProcessor.getCastTypeName(new VarType(descriptor))); +- buffer.append(ExprProcessor.getCastTypeName(new VarType(descriptor), Collections.emptyList())); - return; + return new VarType(descriptor); } @@ -99,9 +99,9 @@ index c8bf497f5cac2bb9e3c7b2187a4b70d392ef9e7c..a7bf7eb3b499d623d11914bcca987023 + return getVarType(); + } -- buffer.append(ExprProcessor.getCastTypeName(getVarType())); +- buffer.append(ExprProcessor.getCastTypeName(getVarType(), Collections.emptyList())); + private void appendDefinitionType(TextBuffer buffer) { -+ buffer.append(ExprProcessor.getCastTypeName(getDefinitionType())); ++ buffer.append(ExprProcessor.getCastTypeName(getDefinitionType(), Collections.emptyList())); } @Override diff --git a/FernFlower-Patches/0048-Reduce-allocations-in-getAllExprents.patch b/FernFlower-Patches/0046-Reduce-allocations-in-getAllExprents.patch similarity index 84% rename from FernFlower-Patches/0048-Reduce-allocations-in-getAllExprents.patch rename to FernFlower-Patches/0046-Reduce-allocations-in-getAllExprents.patch index ddb6f3d..b4f8c23 100644 --- a/FernFlower-Patches/0048-Reduce-allocations-in-getAllExprents.patch +++ b/FernFlower-Patches/0046-Reduce-allocations-in-getAllExprents.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Reduce allocations in getAllExprents diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java -index a6601eee39bde738f840f01806a13b907583af50..df0898d64a1201d56643673a3da752ed13b56c3d 100644 +index 982b660190ba9488c3ff62022aca0dfecbefab48..8dcde8a4d88fa068b6c2b25e00c4de1eae7253a3 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java -@@ -28,6 +28,13 @@ public class AnnotationExprent extends Exprent { +@@ -26,6 +26,13 @@ public class AnnotationExprent extends Exprent { this.parValues = parValues; } @@ -23,10 +23,10 @@ index a6601eee39bde738f840f01806a13b907583af50..df0898d64a1201d56643673a3da752ed public TextBuffer toJava(int indent, BytecodeMappingTracer tracer) { TextBuffer buffer = new TextBuffer(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java -index 9fd3f0547c17ca6c52cb725ebf1f90771c5ad456..ecdbdc6dfc70072edd75ecdc14957112b2826f9d 100644 +index fd0e1ab199738bc00cd48f522a75b86e3c29b9bf..7cfac1bea71a366e2ef6004d0c2c78c094b6721c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java -@@ -67,8 +67,7 @@ public class ArrayExprent extends Exprent { +@@ -65,8 +65,7 @@ public class ArrayExprent extends Exprent { } @Override @@ -54,10 +54,10 @@ index 097c10a32ed819368c48efa51866420c01584395..34d99a13692ca6a7cedc59b7d4d9de4e public TextBuffer toJava(int indent, BytecodeMappingTracer tracer) { TextBuffer buffer = new TextBuffer(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java -index 0f5411be3e790faa5a9f28d1eab3152851944e48..c43a4ea06ca4e5c4761ba34a2b90e1a6b5d8198b 100644 +index 546ee9178d4469e49485c643d31d01f3d1cb4209..922994232e50057249552fcd6d5e5240933aadb0 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java -@@ -79,8 +79,7 @@ public class AssignmentExprent extends Exprent { +@@ -75,8 +75,7 @@ public class AssignmentExprent extends Exprent { } @Override @@ -68,10 +68,10 @@ index 0f5411be3e790faa5a9f28d1eab3152851944e48..c43a4ea06ca4e5c4761ba34a2b90e1a6 lst.add(right); return lst; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -index 6ed64f77930f44a9c6bd17d2eca51de97a6cbbcf..805e0ee518123d6578abcd60d2c297d2f437bec0 100644 +index 4b22805aa16a8a95a4bebf3b371df3f0c8dae03a..0087bbfa80332d79401703c784dd4c9cf40d390c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -@@ -164,8 +164,8 @@ public class ConstExprent extends Exprent { +@@ -187,8 +187,8 @@ public class ConstExprent extends Exprent { } @Override @@ -83,7 +83,7 @@ index 6ed64f77930f44a9c6bd17d2eca51de97a6cbbcf..805e0ee518123d6578abcd60d2c297d2 @Override diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java -index 996eb3c3fe5388f7fde11df8937a09d01843f89d..0de6ad2cfa8f7dde5b9142a10525b58853f0549a 100644 +index db2a53744ffeb8b0bdc7b045a822be2df1695b4e..55d7420c771b6abf6d32056d9b82ec95384bf581 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java @@ -59,8 +59,7 @@ public class ExitExprent extends Exprent { @@ -97,7 +97,7 @@ index 996eb3c3fe5388f7fde11df8937a09d01843f89d..0de6ad2cfa8f7dde5b9142a10525b588 lst.add(value); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java -index 8074782862f3842a95050212df0ac5d778f20091..4a696f53b52d3a577b7a1258c37e40996952b576 100644 +index b5f3eff75b43be0fffc71bb10839a5ed578beafe..26f988a9b34ab29690a1d9da505dbc7ed1d59c0a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java @@ -99,14 +99,25 @@ public abstract class Exprent implements IMatchable { @@ -152,10 +152,10 @@ index 8074782862f3842a95050212df0ac5d778f20091..4a696f53b52d3a577b7a1258c37e4099 throw new RuntimeException("not implemented"); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java -index fe98a67593856bc9358faf468afcd7bde986b520..05c06d88383a5c74496837dd0da61c36ef7631c6 100644 +index e6e3e9d6f50239c716d285d64f37679bbf0ff553..c20697620a61837d787aa637a8722e3a2dd736b8 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java -@@ -117,8 +117,7 @@ public class FieldExprent extends Exprent { +@@ -115,8 +115,7 @@ public class FieldExprent extends Exprent { } @Override @@ -166,10 +166,10 @@ index fe98a67593856bc9358faf468afcd7bde986b520..05c06d88383a5c74496837dd0da61c36 lst.add(instance); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java -index 1f27ed6c5ab25460b0e67c728c7fdcaa23e6c268..16c0279e2aaa1dd5ba1d1db7b844b347502079c8 100644 +index 45a83c38eabb72eb26a618e7b7f8a5288825c6c8..e17051eda8fb757a8def9042ee69fbe27942b18a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java -@@ -453,8 +453,9 @@ public class FunctionExprent extends Exprent { +@@ -450,8 +450,9 @@ public class FunctionExprent extends Exprent { } @Override @@ -182,7 +182,7 @@ index 1f27ed6c5ab25460b0e67c728c7fdcaa23e6c268..16c0279e2aaa1dd5ba1d1db7b844b347 @Override diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java -index f9177d5f5f7991637bb793cdf479b6af63dcf414..f48f20934e3abd19bcdb0f9e52eb58578abd5b13 100644 +index 36e528ae73df7a893d4f50dd2bc8660b803953d8..ca13e1610450ff0228de2e5d3c5ac70df7976b52 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java @@ -96,8 +96,7 @@ public class IfExprent extends Exprent { @@ -196,10 +196,10 @@ index f9177d5f5f7991637bb793cdf479b6af63dcf414..f48f20934e3abd19bcdb0f9e52eb5857 return lst; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -index dfd8078b728c0439a6a0accb6d9f17b7eb2979fb..79782777a705f87d145522ee160103659e0aaea3 100644 +index 122e7ad0ebcaa9fe20263b674887b51bd6044fd0..6a90becad21cbc1994f39b14211fbc493b27064b 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java -@@ -473,8 +473,7 @@ public class InvocationExprent extends Exprent { +@@ -475,8 +475,7 @@ public class InvocationExprent extends Exprent { } @Override @@ -210,7 +210,7 @@ index dfd8078b728c0439a6a0accb6d9f17b7eb2979fb..79782777a705f87d145522ee16010365 lst.add(instance); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/MonitorExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/MonitorExprent.java -index 380f47a9de0e1b9d342d5c8557175d7e5a6b1e8a..5d312499ded2b8ed035b092cfce27bd758c39894 100644 +index 3ad223c61453159d096405bb73184644595b75a9..9102f8bf3d8409a8273072106fede15f3d0a7e4a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/MonitorExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/MonitorExprent.java @@ -33,8 +33,7 @@ public class MonitorExprent extends Exprent { @@ -224,22 +224,22 @@ index 380f47a9de0e1b9d342d5c8557175d7e5a6b1e8a..5d312499ded2b8ed035b092cfce27bd7 return lst; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java -index 2bf3ce1584a2926a628318b7dacb21290803108b..7f82d46f96dc4873aa2ba41b8824d5cf4284aa12 100644 +index 8dfeba4a200154d32b89c6980022792c0fae1f23..72006db699168dfdd44c355cb934f3e72fd5afb5 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java -@@ -278,9 +278,7 @@ public class NewExprent extends Exprent { +@@ -270,9 +270,8 @@ public class NewExprent extends Exprent { } @Override - public List getAllExprents() { - List lst = new ArrayList<>(); -- + + public List getAllExprents(List lst) { - if (newType.arrayDim != 0) { + if (newType.getArrayDim() != 0) { lst.addAll(lstDims); lst.addAll(lstArrayElements); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java -index 81f7546312493c244636b50fa972c0a3817b9aed..303a1c53c26c9764120f2ce50fad0a1ca8933de8 100644 +index 105c4d951f806fffb8d42386933a7629fa61d76c..7699ea8d3139df210e69208c04eb604c26c8db22 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java @@ -67,8 +67,7 @@ public class SwitchExprent extends Exprent { @@ -253,7 +253,7 @@ index 81f7546312493c244636b50fa972c0a3817b9aed..303a1c53c26c9764120f2ce50fad0a1c return lst; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java -index a7bf7eb3b499d623d11914bcca98702328e57329..abe36c09953b0e2656e43be18ecdeec2c5f6393d 100644 +index 0fb1e4749f39a0122735c1d54ea42f94e34d38d2..3a87696731f1f247c48aa24ffb923032e6a6abe2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java @@ -89,8 +89,8 @@ public class VarExprent extends Exprent { diff --git a/fernflower.gradle b/fernflower.gradle index a300c90..a08c942 100644 --- a/fernflower.gradle +++ b/fernflower.gradle @@ -23,6 +23,8 @@ dependencies { // The Java9 code depends on (can see) the "main" source set java9Implementation sourceSets.main.output + implementation 'org.jetbrains:annotations:20.1.+' + testImplementation 'junit:junit:4.+' testImplementation 'org.hamcrest:hamcrest-core:1.3' testImplementation 'org.assertj:assertj-core:3.+'