From 68a0fb4aa3f252ef96c5bc2380718ca9a8f620b2 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 18 Sep 2015 20:54:22 +0200 Subject: [PATCH 001/138] update quality of non-Retina UI elements for Mac OS X laf --- .../ide/ui/laf/icons/buttonComboLeft.png | Bin 223 -> 186 bytes .../ide/ui/laf/icons/buttonComboMiddle.png | Bin 121 -> 92 bytes .../ide/ui/laf/icons/buttonComboRight.png | Bin 227 -> 202 bytes .../intellij/ide/ui/laf/icons/buttonLeft.png | Bin 227 -> 187 bytes .../ide/ui/laf/icons/buttonLeftFocused.png | Bin 464 -> 289 bytes .../ide/ui/laf/icons/buttonLeftSelected.png | Bin 490 -> 319 bytes .../ui/laf/icons/buttonLeftSelectedFocused.png | Bin 661 -> 408 bytes .../intellij/ide/ui/laf/icons/buttonMiddle.png | Bin 138 -> 92 bytes .../ide/ui/laf/icons/buttonMiddleFocused.png | Bin 161 -> 107 bytes .../ide/ui/laf/icons/buttonMiddleSelected.png | Bin 330 -> 195 bytes .../laf/icons/buttonMiddleSelectedFocused.png | Bin 320 -> 208 bytes .../intellij/ide/ui/laf/icons/buttonRight.png | Bin 236 -> 201 bytes .../ide/ui/laf/icons/buttonRightFocused.png | Bin 466 -> 302 bytes .../ide/ui/laf/icons/buttonRightSelected.png | Bin 496 -> 330 bytes .../laf/icons/buttonRightSelectedFocused.png | Bin 676 -> 406 bytes .../com/intellij/ide/ui/laf/icons/checkBox.png | Bin 222 -> 218 bytes .../ide/ui/laf/icons/checkBoxFocused.png | Bin 509 -> 469 bytes .../ide/ui/laf/icons/checkBoxSelected.png | Bin 560 -> 446 bytes .../ui/laf/icons/checkBoxSelectedFocused.png | Bin 731 -> 662 bytes .../intellij/ide/ui/laf/icons/comboLeft.png | Bin 231 -> 195 bytes .../ide/ui/laf/icons/comboLeftDisabled.png | Bin 254 -> 204 bytes .../ide/ui/laf/icons/comboLeftFocused.png | Bin 476 -> 297 bytes .../intellij/ide/ui/laf/icons/comboMiddle.png | Bin 152 -> 99 bytes .../ide/ui/laf/icons/comboMiddleDisabled.png | Bin 226 -> 107 bytes .../ide/ui/laf/icons/comboMiddleFocused.png | Bin 172 -> 116 bytes .../intellij/ide/ui/laf/icons/comboRight.png | Bin 1080 -> 597 bytes .../ide/ui/laf/icons/comboRightDisabled.png | Bin 507 -> 320 bytes .../ide/ui/laf/icons/comboRightFocused.png | Bin 1271 -> 653 bytes .../laf/icons/graphite/buttonLeftFocused.png | Bin 421 -> 288 bytes .../laf/icons/graphite/buttonLeftSelected.png | Bin 437 -> 307 bytes .../graphite/buttonLeftSelectedFocused.png | Bin 553 -> 387 bytes .../laf/icons/graphite/buttonMiddleFocused.png | Bin 156 -> 108 bytes .../icons/graphite/buttonMiddleSelected.png | Bin 280 -> 180 bytes .../graphite/buttonMiddleSelectedFocused.png | Bin 293 -> 189 bytes .../laf/icons/graphite/buttonRightFocused.png | Bin 423 -> 290 bytes .../laf/icons/graphite/buttonRightSelected.png | Bin 460 -> 311 bytes .../graphite/buttonRightSelectedFocused.png | Bin 588 -> 387 bytes .../ui/laf/icons/graphite/checkBoxFocused.png | Bin 532 -> 443 bytes .../ui/laf/icons/graphite/checkBoxGraphite.png | Bin 496 -> 218 bytes .../ui/laf/icons/graphite/checkBoxSelected.png | Bin 733 -> 424 bytes .../icons/graphite/checkBoxSelectedFocused.png | Bin 699 -> 630 bytes .../ui/laf/icons/graphite/comboLeftFocused.png | Bin 476 -> 288 bytes .../laf/icons/graphite/comboMiddleFocused.png | Bin 172 -> 117 bytes .../ide/ui/laf/icons/graphite/comboRight.png | Bin 890 -> 549 bytes .../laf/icons/graphite/comboRightFocused.png | Bin 1271 -> 594 bytes .../laf/icons/graphite/helpButtonFocused.png | Bin 1476 -> 913 bytes .../ui/laf/icons/graphite/macBorderBottom.png | Bin 95 -> 81 bytes .../laf/icons/graphite/macBorderBottomLeft.png | Bin 125 -> 92 bytes .../icons/graphite/macBorderBottomRight.png | Bin 126 -> 93 bytes .../ui/laf/icons/graphite/macBorderLeft.png | Bin 95 -> 78 bytes .../ui/laf/icons/graphite/macBorderRight.png | Bin 96 -> 79 bytes .../ide/ui/laf/icons/graphite/macBorderTop.png | Bin 94 -> 82 bytes .../ui/laf/icons/graphite/macBorderTopLeft.png | Bin 123 -> 89 bytes .../laf/icons/graphite/macBorderTopRight.png | Bin 126 -> 90 bytes .../icons/graphite/progressLeftSelected.png | Bin 125 -> 110 bytes .../icons/graphite/progressMiddleSelected.png | Bin 99 -> 80 bytes .../icons/graphite/progressRightSelected.png | Bin 119 -> 111 bytes .../ide/ui/laf/icons/graphite/radioFocused.png | Bin 796 -> 688 bytes .../ui/laf/icons/graphite/radioSelected.png | Bin 626 -> 525 bytes .../icons/graphite/radioSelectedFocused.png | Bin 841 -> 753 bytes .../intellij/ide/ui/laf/icons/helpButton.png | Bin 758 -> 618 bytes .../ide/ui/laf/icons/macBorderBottom.png | Bin 95 -> 79 bytes .../ide/ui/laf/icons/macBorderBottomLeft.png | Bin 125 -> 89 bytes .../ide/ui/laf/icons/macBorderBottomRight.png | Bin 126 -> 93 bytes .../ide/ui/laf/icons/macBorderLeft.png | Bin 95 -> 79 bytes .../ide/ui/laf/icons/macBorderRight.png | Bin 96 -> 78 bytes .../intellij/ide/ui/laf/icons/macBorderTop.png | Bin 94 -> 81 bytes .../ide/ui/laf/icons/macBorderTopLeft.png | Bin 123 -> 88 bytes .../ide/ui/laf/icons/macBorderTopRight.png | Bin 126 -> 91 bytes .../intellij/ide/ui/laf/icons/progressLeft.png | Bin 116 -> 106 bytes .../ide/ui/laf/icons/progressLeftSelected.png | Bin 122 -> 103 bytes .../ide/ui/laf/icons/progressMiddle.png | Bin 100 -> 76 bytes .../ui/laf/icons/progressMiddleSelected.png | Bin 102 -> 80 bytes .../ide/ui/laf/icons/progressRight.png | Bin 124 -> 102 bytes .../ide/ui/laf/icons/progressRightSelected.png | Bin 124 -> 119 bytes .../com/intellij/ide/ui/laf/icons/radio.png | Bin 454 -> 411 bytes .../ide/ui/laf/icons/radioDisabled.png | Bin 468 -> 415 bytes .../intellij/ide/ui/laf/icons/radioFocused.png | Bin 901 -> 738 bytes .../ide/ui/laf/icons/radioSelected.png | Bin 593 -> 573 bytes .../ide/ui/laf/icons/radioSelectedDisabled.png | Bin 554 -> 464 bytes .../ide/ui/laf/icons/radioSelectedFocused.png | Bin 905 -> 825 bytes 81 files changed, 0 insertions(+), 0 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboLeft.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboLeft.png index 16eb5e083f60a72fcb55ba3cd7dff60e10d7b40c..1444d54054c09bbbada97c49aee85d5b226ed6d5 100644 GIT binary patch delta 171 zcmV;c0960q0lEQ@7k?E91^@s6j=3a$0001iNkl)K?1y6w{Fe;^XJcp|4;xDRDSpF-J$f}$%{tSJ5c`}ap=K_(zpUA%a4)r%J|P6EUAJ1pc`fFxKNh)sdm2`P%eI@o}i Z0{}kS5`K&v&s+ci002ovPDHLkV1m?nO%MP8 delta 208 zcmV;>05AW#0p9_T7k?B81^@s6MdkO~0001{Nkler3svs~d%}<>=^+_KXt_Z;oA3iYLxpSxL z$dM!e&z(E>|H_ps{~2Drdc^<={U=YJ1YNv%aTQS4G6qmUqhkO$l4?~oR+BUU0000< KMNUMnLSTYVgkyXF diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboMiddle.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboMiddle.png index 0e759578621f1ff7304df41ac3267755a4611bca..0c4a27f989d29a2af0c810ff39a19b799eb2df54 100644 GIT binary patch delta 74 zcmb=7nIP^e%E89Kz)-Y?e+!UO_H=O!skoJ#kdSaef%Ct*U{99BRfAQHLc9(Syp+-& cD6ld!>|L4UrRZbl2~^JD>FVdQ&MBb@05WqHUjP6A delta 103 zcmV-t0GR(=d5{-k6bJ?Y006o0+z|i(06)KVmTn@VSs_ZfB$}c z|Ni~KojZ4C0=Z&f!T(V3=g*%H+qP}X0SfWL1wr85yLX3yg32g@K%>3@1$9saK>#SI zH+%#^A%-FN=FOX0pkIX7k?B81^@s6MdkO~00020Nkl6x_0f_;fD_& z>b!gRj)CDn6ny^t`Tva@H{L&b^hg{e_z5QQ`t|Gow{G2PLJ|D-?Hfq-aumVu-@pIA ze*O9a43$8^`2#9A51ZfuY>wZ7P30~W!RODP|G#|s@&vdbFijl)pE`BwKQK(q8LnKp z^8ehqbN`PVIr9I`ojX+@K73$c0Lm`Ac=6(@Cr_RPfkOS&t5@KV$G`whnQB$T6gc+) O0000`zCo`U+={I2=t&6}g>f?_LHtSJ5c z`}ap=K_*ZXEMC00>cxu}CxL5I-AZKu2|j%IQ0LmU zYlngK-=|NX{$P0Y=#lu18#ms6{`~nr6#QWTDsOuI`t^S#@QDGaYWcTs-%tgwU%$TK z`}gk{g7dMd9MXbVy}1ZO<>kwl`=395jw%QYZOc=qPW=bQ06;?U!-o$HckbM&I&$R5 z|8wWg{l9YM%72DeuU>)U>B*BPK^HGxTm{s%3;=Ubk3beB=PdvL002ovPDHLkV1kCM BW?29L diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonLeftFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonLeftFocused.png index 8f7d4c64e4d8a3691ccb313832d8e19f66e266e2..70ba7a202a6f09831e641e800182bb1db80db61c 100644 GIT binary patch delta 275 zcmV+u0qp+J1EB(t7k?WF1^@s6K~2uS0002!NklRPaZ!e#faz5VdzKQaI*2!Dqus9k;gJIGjc1#tTt z*4+A!4n`GFQvo6_R^G%K7x383TXf_4oA;kF6u{GiQ~$#WTTkBq|NGA$6a|PBRrMz} zV(PWcn~&f5|LW~WXo^Bl&E?Cizp@z7!6U33pe6IoaaQlGdOL628}VT#uyVj^I7yc-44Iig4~O8H+Ovt3J!I? zQ&m*`haM`D(na=?q&q$*3$kBRZ$%w7<5h$W-3(hY5-qYTj+e8x{yeoA_pe zv>UZJ!W|FoHGeRdX#529tXlX2X5;^Xe+RxsJ@~g#M-8>$s>fY*K(GGg2jPsp{sA;;&31=in?wKr002ovPDHLkV1oO_&x!y5 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonLeftSelected.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonLeftSelected.png index f23a9720ff6c81a987de2a075b6caebeab19b098..ce8ef940f9f0704d99c748aa8b7f839330e920c2 100644 GIT binary patch delta 292 zcmV+<0o(rS1HS^0B!31;L_t(|+EvltM?-NO#_{K(v{P)-l1xz-qe!Aiqr_yoi4t9m zax4*%lIWtWIsITvsm4@NMx~PehxAXhe}H zmu$A)=c^R=nX>XqLAt{I**i+^C4kAYU&}sFmYxC_KW9DrNPh`K>Xfo@uVJ)AnX76T zE>dQ0H4Gh5rf)P1c$D;&hQ2&yqM{+WOBpL01-(0zku#&9dz&(NViY7cDg7m*pktkq zEE)yzHP(BMjfA0f)vqNAM!F6Ih%SF0v~5v3J@XHd%v-c2_wy0kpv3o#wAE~JEAk5uEfnf$>c2Mt00000Wbc)0_p>hB!96*@%Mo05=m~#<7rqa~X(P@fMGsJZzL?JCkNiB!D65e}sgt_;e`*fVe zZ}aC_Jd`m1(azr(EqvR#xcFVKT>i0li>w2k);D9wo8tth=Ekr|9oLmmWn9 z;hq5Qhb8LX*$#!i=z-FpjRz5d`mlw%u*E5`YG@@viQ0J!_d>^PPW}}`D;@!E&swOS zu~9Rl;^1e46%9GK`Nl@obPA`wPbPB(fE$xGDqbrSD)ug!EPntf9~W@Hv{Cj-aOz$# zSZ)tc`a+;&On>0on2NrSCOg{+Tp5)p9+tQ~tfKe5$+Fsk3qt~hnn01JVtd$R8LfaT zAW`5KaQP*twt3FdT7dI|5_$b8oLWPiQ8SR+D{-#JQB?H2Rj~=kdF~*mOYu3Jnx_sl zY6Q;s9AtZy4iz6ys^vo<(+iw>n!<@ibd73(6VHH?ZAmGdcDJ_O`JM#m4nXP!J%LF` z#%UwE-B8h?<8LfjVs diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonLeftSelectedFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonLeftSelectedFocused.png index ddbd2a5f9aeda84f1d4b5392d33366fc52be3ac7..4ca54c232e3d5985b7493dcaec6508dc78227dca 100644 GIT binary patch delta 395 zcmV;60d)SA1(*Yn7k?WF1^@s6K~2uS0004BNklZ zz|S|e#jk+-49~s-C|CkTo@2KnK;NMxJ$9O%QB>?HNj>{5 zY#z+f+M^`~vZZAcnXf)DF6Tf07*qoL?E0iKm;DA=JiW`T8NWq#-t2RwKn35)HQ(tLgAP&{G*1AX<)3hdtiUa7% zg|3PThBu`oZ~8s&y@pg=e7wc^-noZ+|HFP~vrOhQ?C0Dc7JvK3JH|ir&4X!a%s(T~ z`jhe`6LJ|=5He=*LRVa#b5F_eB_%v~E1{oYnM{_&zw=FZqB44?WpHT`eF*^_Q4y}F zD6)?~ax3Vsf;U0Ml!)tNB94dWaVk>4=_f^zO@8HDTrnAgX}frUQ*iEuhRYKwu1u&R z<5E)0mz2>r&41%qXdY)rsQ6OF#ZePQWHfEU9L7BJXsCem&s8*yD1`Z?4tsSF*jHT=*0yV?xD8ac8>n$lt<>7D^33`iiX!8`>JcdXL#Ix|cvJn4^eP=um|E!FGv}D0bi}Q;XCrXPm k`iXDh($e_C;=KL~Lc?fPph{1d00000NkvXXt^-0~f>stN3;+NC diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonMiddle.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonMiddle.png index 5e6e01824d8439a4f2f23381b61f1ba452836bd0..e93b2eb1d954b8c2ff91a8724746c70d6bf7f2d2 100644 GIT binary patch delta 62 zcmeBTjG3Tfq3r467*cU7IUyk-K%Miyx?oS1#8rb;jq9Wu4or19bHI^{jiFy`5?`;3 R*GUE-@O1TaS?83{1OU1X6_fw~ delta 108 zcmV-y0F(b*iUE)$W>HB*K~#9!W4LkSMivkk0dYP73{sQD@Z`ypUqJkyNc@Z8|NsAg z{u2-WfHZs}LBpp}4Wk-HH6UrYdiCmmQZU2GlP6aL@pd5ILI8u*tOfvZcljtvt*#{i O0000=`DXFpbqi7-H~;@(aJZf+A>`l+ tCM|7^+2xPy?amws_@ybRzsw?@fkFNGljoae#Q|9i44$rjF6*2UngG_-B1ixL delta 145 zcmV;C0B-+lp#hK=e;Nn|0001r5gi)<003x7L_t(|+U?3K3V=`)gyFMu7a)SkV7RWq zTNM=%7a^Dho0EKm@!TpL!S29UhF^wx&s3q@L-;aD`jc-Yt~V$eAa2~CXn>Fe?ftc52BYyyjNkl40*EyiYwEUc;o8-!Q4gCroPg4wIU`!lWk8Fsbn)Olouwld5iE zQiDsFRR0_%)jOq0b&qLMokN;bxlfa7@6x1N+cc@>CQYibP9c*jR%uf8d6?8+jr;-Y WdBUFpkZ7j>0000R^NknaJ5%Z+ph+_&wZZL!MppM;d8#r`O#?db1<5G2cqF| zBo3)DnEf^ebJm&tQSg~M!Ah2bp+PWASP4|`8`S#=D}ie727k2=!(MNTf~t|heq`9E zniaJ7Y#>rG7mbR31`P?o(C*ZQrI4tOVNXT5NVxRswBwEY>@gl|bdT z#ai2PSqD@K9acljevV6_42o9{#cRh(pu(j?;li;JD1Xk#pD|09%YHyBrwqYLAZp1u zVfJb*3d%L-oGCj_{F+%Qj=yfk40@bpZy0!D6tO zEEbDF7K7y^MN+Q7WR#?olsa|lNJ>ePYcu};SKPt37@qB2Us${c*7rf@7;>0BLk`nN z$YFdBISg+hho5W6p??WE^v)rN?kVKZ{tr2{{z4AT-;_h+kUDax?^6!7UCN=lO*vFH vDTnep2AxlG17{>AU3s@FrGHuCZ zv)N2bOAchkVDcO68f2m{xFCp#D8gjI90~@P42B_o7n{!va?ic@@!6Ul-x+@A5AO-5 zoY&4KpJSQG%P+Ip*e+hDT*Qu_KOl6#w(q_mbinqW0)!6O?tfzjp#!$_kU{8xweJJk zqd+w_(i5#=z}7IZ^#{#i%|Sr(HZU@n7uM(pG;VT6`e9bs=5-FC1GaIQL+F65pXU%d zU~8uZgbvv1Ndch)R!a-i(~|YH_@Op$30vuv5ISJXM{0g##j)k#=w~00000NkvXXu0mjf@QO?; delta 208 zcmV;>05AW^0qg;gB!9C>L_t(|+GDtN>sIRR+qa{ESpLO}7Yy&-y<=c_`t<3KhYuhA zy>{)|VIZvo7X1JJ{~sX!|M~Oh|2J;jc>n0pBXN-6r~gp!`t|GoK;xQF1iyXz22#Bo zMezIg@Bgn~zrFxNB~Wnw@Dar4%|$4J&!0d4fBEv|ez+ho#7Y03I(6zlF!U`Mu3WkD z|J=EA|BoCw^8e1AJ5?V(d|+Sz$}YQj@#3l{Po4yU;^)ja0000< KMNUMnLSTaKBy?5) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonRightFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonRightFocused.png index e59ebb6c9944284f0d53da79cfdca01604f84d76..fcbeba38d7b86741c4562787d2efd4678a38b02f 100644 GIT binary patch delta 288 zcmV+*0pI@81Fiy)7k?WF1^@s6K~2uS0002>NklZ{J5u`{HQA8L>!1%_lFJPxZiA8MV1sun$v%YV!GqZqy&MpW9NEFl@ z=}1$2`e$_JJ1nD#kWvxB_21HSSm$G>EzXJ!YMrycbY@<~hJR1B5!#nn%}Yd!qHt{R zH(Hakssqf%`lc^o!k@Mf$PlbZgbPB}+I;w5n}F4CF!58_DnI8rM*$Y>gBb~ovpA^FkB@Ilj*WlUENnYW`?-oU~ z(IY1(!sn)EvjK0cOR7nd*2cGA5@hwr37O62(-&|%WjgpK^+)gxVumS{IB1_AN1 v+)9*1GJh)8Xb;Bqt~GR66Rc1dOe5eL`)bX0b@E-j00000NkvXXu0mjf!u-|s diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonRightSelected.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonRightSelected.png index 9471e23255320cdf45d9fb52dbbf87d5d8abc23e..ef1759ba03dc5beb38de8a625218ca5bf2bd913e 100644 GIT binary patch delta 303 zcmV+~0nq;N1IhxBB!3Y}L_t(|+D*^jM?+y8$MNT)v{P)-lFXtmMv+93Mv2LE6D7JB z!=u0YGW!XQK_W=A^j8m_#YBE-{=F9 z_LMEO#2RC&#B-Fk6~@j33oX9PzbE%BLW!b9^OFB*+C7U<%eo-C@V#qVxf|cMh^-2m z@;|SU>~qvOt|$bK>%Tj5UtWE>5;Ol3p$4i8!!PY36zTW$!}0(C002ovPDHLkV1gf6 Ble+)_ delta 470 zcmV;{0V)2<0`LQnB!9O_L_t(|+6~T6NYh~)$MNqah`wq;wb& z{h_GD8WjD*gG81L)@clh+mj2n=lA^HJ%`Wb z_4&g0BdbNNMY=OJ<;(o5_doqJ|9^R=u&4gFB;tFl-JYyN z=R>%dTjcBapIhZrRx4jtb2_K#7}I3lm11%tqg8iCb8=F%GiivuEhpq?x~`5q(j2oz z`>0Fwjm3j0tq!C#htitO!xmqcz>2j2M(SHgr_X- zPC9B=(xKz7Lx0N<485qtW!s3O+D8oAM-9y(2tBjdmN3eOwqe7n00f^{Y>gV#dfTuu zW@s3IK-S{=TSje&7(7wKlFQ(qRB>4wcGbGDq2;DQ`d}bqu{q=_8`j)#kzTlxw%8PO zRnwr$>gyKILtjcIq%nY6aSa-SAZOsxguPtuM>Y6isZX6FJrK{85+YZri2W+Z!P8%5 z{>N;mEIU_Y<%LDOgC)M@XU|eAioBoB-}&+>KW54^JDh4!3dIHa5BCc(D*G2pp#T5? M07*qoM6N<$g5Ck|SpWb4 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonRightSelectedFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonRightSelectedFocused.png index df2acedf4a21a18742f355a97a339bf61dbe6b02..db9b7e2cd6f2d850c23138997769a321670f0777 100644 GIT binary patch delta 393 zcmV;40e1eR1(pMl7k?WF1^@s6K~2uS00049Nkl;==(BlOCspnSH#&C#aeXiDynkqC~8TF)wHJ- zRauirO^I@m1;fy)&$4YPYF^fp@$VN?vJ_>39V`(QL`4tCRf}3l zGo<&PdzG2FkALTzw3!w^&f@&;|NFknIihV=A8(t}=ewiY$baZ(lKyS?0Gc6e;; z^%!`ReMD}9O}TCxT;Zq#_PEXeh3&OAF_7fc0J~~4Li$&4s{w6$07y1h13POB`1qM! z8wp#gL4OQ#7;zUUtWO{?r^qIrM70Sa?tz4ho40{YH*MVLSJC@kMLiG9*cZhm94><# zt|SWXuj1;{WrW@-@Xf5INA80hxrWzqV$ePnM-Mms+>}E*vAFVgXuF~sByICLJd>;N zrpJCIGxoeVZ{*?xquS{3C#5RPi}N#UasB`Xh!SX3TOKE$00000NkvXXu0mjfa!fM@ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBox.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBox.png index 0983672a77d9022f1c69f16aa973e67631613300..61fa7902edad801d89c10d59291e68628131a679 100644 GIT binary patch delta 190 zcmV;v073uW0onnOB!8hvL_t(|+U=Av3IZ_@MN=>A4fO`LUSS0{mEaw=-Ydwa-Xix% z6#{B9&W9A*OrmTPaNu?Czj722sVz}$1+~^ab7UrFE-+=cmx707Syt!V-Fr_GaEvi4 zHd62!LU^W>sC01PVj~4FHL>?7Hd0X2mzOsU2ge_R<3IQjJU7J{AGI;K*hs;>wf0sM sg##BGDcCVPW?;?*hU|6?|HCbK0qZ#moy*`}pa1{>07*qoM6N<$fK!rPb&k-IE84{TsFXrE=Vow+4!U5v z!g-!)^i-xTR7!nDg_UUwt+jDfSedra7&9!a%wKq+a6KSgw>$Qb4(wrnv89xc5W;R5 wx?s9O?>$?V<@tLxVm4br2VF2X{twT{7v&O1I=TzMv;Y7A07*qoM6N<$f}Y`4+yDRo diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxFocused.png index c1b5d0472600bdd7146f3e6253213888f4f1e32d..a0c093a7f39d0a9a4cd23444bcafe349e5bef3a3 100644 GIT binary patch delta 443 zcmV;s0Yv`&1JwhNB!8SqL_t(|+O3tpO2beT#*@B+Tb=q6($Q{({((T!Lg=8AFVKS3 zNgaeD1wpA!El5#x?^3N4ElmamCpRC#f)Waa=6KKbTsaLTt;WEYK=OS*ZqCU)(X?IA zNV-r$XiX?Blv|)Qc`>5{fQC}A6`}P&ATMMHnL?IOfvzUq&wn#-3KXE$E${2Ic9p7Kd&C^DODwFv|!6|mCi4j!B*7>!2Y zd0wc{^XNW9xp6zBGUOynoHFV)Ypu>?JRXDZ`>^Oh4|*{}B`_q5HK16(=q?50P|Q$W zi;}~dVAtDs@PFF_GptdD0%8qH5rHMiA)xh7KuZA&-@x7>2$g@4853P-(i+-J)_!moR`-(SO$t7^lmpDm+h3~%y5Vwd~EEr zT&I57pB!KHAx!A0HeENq|GCBXvK$UE8a-+YnjvFr-ZU69DVLHgHegc`=HbkMRf^H; lCt0JyCU%y*n2D)hz!&_yISMdM*69EM002ovPDHLkV1f^r%Q*l5 delta 483 zcmV<90UZ9-1N{S#B!9$7L_t(|+U1qYPQpMGhUdxjxx8SE8Z{xh;O5F53q&@8!Emt} zz=hG8)`ejqf(tOv7OV^;2F-E)!6J~xP~y%eXVIDe`$Fe(V2zf+9-iB*+A!J8V`uSL zwPOdR?scfZ@54o|i_)e_#~d=qf&mK$T+A>H_Efi6QnUB`3V$cR(xXtZN0HL+g$%M_ zz`_9+Yg-0O>979n9H&5`FN0fW9rC3tT03qSH-|a+JB-$rAkBtn*A9_1}q$KG3*!?c_nF5MtdQz4;Zj=qlAmeqaj{=DU)(~ z%d-#+SUBKf@@#zzGg@+ z5X{8E9$q~(hAyq2)aka;nOTM`7_e~2tLHR_K%pluI$Q$LtA;qROkKC77W-? zb8y<%PJSp27C3FD+j3p7*lvY6WRL{|77ojFZLoaQV8yPv)=z`w6AiXy2;pD;1=O1c Z`vMW5VZ0vGQCR>0002ovPDHLkV1np9&#rPS7>P4xAieAQU;A-MFwOD@Sd&wbCi z;ramh{!=X$!!fyoDa}-3f{RLeZl@D49pq$$lM1F?L^+g8HGfV(Q7d3jUWTzYMDHfK z8k2-jLiyTeif~77*+`edQ9SCdS z@*lX%ODMe8FuozE8+ZoNd}fl8>VnqvjAyH=yM>g1(OAWF?g6L)azzElHxkCSs+ij? zL;3u|;Z*^H>wkI6TwQ>Q4wSHS@~S!_XW0i4#R>y#3g+oHfQmbi<}(m^!U1z+#Nyr~ zMxteNz6R72&^U-dM8J8jjHBx!hSr`f&ceJmhhoEljET62o|Sv_t~R&&qh{qJM0|w(Qdq7=L5V z1`|LeEfHH1xP3-^7R?BZq*)SI$(DUu0wad_%&>`^z|HJw@!2SWv}YEghK2Er2W6j@ zKrJasdj3xsiveA8HLMmb?3)tNwB=nuJ}rSM-9UDr>2U`v26@I-bMd{1wG#;aEwyXa~5tS>lh|*@KGJh?`kT# z$(21^o;`wIfV#{V7&e3|`cK=%#*U3k(&OBUI2p&HC&5V2>cbpNn3Tb zd6Xi4gWde}^d&FSP|7AJhhWr%-0vsIHbK9qcWOB-3bh;}hD(y(Vn}(*L2Gw8T#N;K Z0y0UC01#aauZREu002ovPDHLkV1i&i_7VU9 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxSelectedFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxSelectedFocused.png index c3b33c79614e87985e229023c94a654cb0ab19bf..45fa2c46835b08aba500d79ddd02c77bc06c15eb 100644 GIT binary patch delta 637 zcmV-@0)qY91(pSnB!68=L_t(|+NG3FYZGA*#^3ZSc$4&yi+WIqwbrzPHa!*ER08<} zAtIu9vmjIib1M-79;9hwH}+5vya8kN#Y_)rEV#S0(q8N;=hfC&l z#chOuF$YMn@rnskRSV7z5yem}LAebH$-A?E_AB+c}dIJw@1E00@1$CEdW zen8tL1E~jj4`}+JvHM*(ultJpfEf>H1GaSwUc5KpRCymV51U~9Ie&m>Z|iXM&W^9I0bnNJ&|;tg z8!vaIBXYL&xea;?0e5TebUmQe*I`NpQh$yte}$*$$T=1teSwqrnr?p`XaJZBOxYU< z4dVE64PI?G;rTlqjupT8oK0yx4&5owIqzY#Y$*;*m{@DW;ai_zw9s3sBg#?U!+G`7 zOU^v#=yv0k-lTttVlk(od?_*CatIfji!&P?J-TYiQU-})Ft!mc?%h(q`k56sb}ykW57pAIiE&V=|2 XDnW{XJB;qV00000NkvXXu0mjfffXmb delta 707 zcmV;!0zCbe1=|IXB!8kwL_t(|+O3t#Pg6k@#wTvkr6$IWf-xF{2q;hmsXPA%^?z_< zFi{gt6l>}w@+h}dVBtc15EtrB#D-#wL6ou(V~7UjC6w2_7fSD=pYx3pwY>xu+~g!p z=KFqg&Y3e)F*P$QM!wIBvB{Je7@e;@jk$c$Qq!!o3#m$cXlvxcA0DY@Og5HPq5WFBxQsg}GVrJh>RIf4PiEpNY=5 z1{&igv|bYpul<8-)KE(gy=0IjK7O6A3B9rqNtnH%m>choS~gdFUmBETQ+CgX~9R z+)%rgNmzB8i<3D~6LV3iyC`YQAkdnTT312op_dG@1W$}j)?{x2QAe7*JQ#z3-Sug7 z4`-0FJOuO%jx-VIC@&dg3623zj?HF&Dtv&ls(&j+ftc1wvB@~CvZTMrMKk)hkSumvRA=a24&5w@(^6? zy0MD;@6#%~3y-I<;Gb)pzbFsqcXFY zw>e;WYkw9+vb-0=hJxJcu`uw%0kX0Up$Qa*GpKFPs@|>#{O?fMmy#w2+b@oz=hFh# zzPhK=D7d_+N?kiFA7IjVY=Rv!%kV1pT_4BiNel6jMeMvXgX4Nup7`G>pf->@HtP-c z=}zE~md4&|;}SfD(qqx0J;Jlps`=@DbV|m21XUoN`XG1xX^s_=FL%j3dB~d zSW)`>_wSFm6fl93+2X~Et6sc#aT1ttzGF*rEI=#`#HK*(gdi)?f=prqVh+mFKLAU= VBAlRN3@!iw002ovPDHLkV1fju delta 203 zcmV;+05t!@0p|gbB!8|+L_t(|+U?V^3c@fD2H<-I!DsS4oO}rJ0elfRN8h0#Q)mcH z8=+0f(xy-f3J%E`#U&yU5u7~ur~5c=xC2ClRNy0Et%bU-p{lBdQfeioTt=Ypdnk%x z6Plwj21CvfD9du)wkJ!V;kob!7kFbu=(aA)DNwgK)5Av^f`FRqH4zdtAQ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/comboLeftDisabled.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/comboLeftDisabled.png index 430e3e5d74436340abaa84978b5ae2a386584251..8f81b3ef18676f25a1e1650a6979196bb5a42ae6 100644 GIT binary patch delta 176 zcmV;h08jt^0n7oAB!81hL_t(|+GAj#1z-bWejpYGVi9yn?wvb#n!bPkKJoA0zt#W$ z|8GE+WZ$}VtJ$AFe=0x{FpR7~=-s<_iO7=Z3dDfMR^d}1jxIT>fL0152*riyn>TNg z@hRY5v0{bw@87>GaVcN~C9}ng7u&vg@gfzNaB9#MfB+K^^CyY-%Z`(8VW^|M;01CV+^rCHM$vng;5+hN`L#q)1A6dIIP&D$DX_j6ton zA4kSfDTTu@;5d#>Ye4mV?+iX!9>9^)G&zG)SRTOf3lL184qN^X2zD{g^J`#9VB<$c zzMbT{$lw#3Kv5L;Wfy`#p66$RT$|Qfm$qKHeU@b+NfH!7IC((VbFgxLri3^`?*nQ#o|979h z{{Q>;FW6D~FiF>GZ+dr~fA;^+pTGZMfC1`Su!6#6_pZJD@PFk$G5{$EhbgFCefvAe zSabz&`y1BW`i~Aq6;M+FA}&_m#2Ody*vwmWnA+><}Br)r={3}s&u7)n1S hl8`SDicoSE02E;VBy4mq1pfd4002ovPDHLkV1lg`jv@d6 delta 463 zcmV;=0Wkil0^9?T7k?TE1^@s6iV+8GzycTiE$8Nzy%crMYHH6dD(CdPF%7~GR7pngt*L0zwXyrL_}+c60B_1FjZ@GSZ{laa zfg@f6r!|gq2`=HN#QHo`))8%Wg3b`bLj4}^9#ENtc%Dy9g#VQt-oC~H!^b8em=)ht zGb-C1G4Y8>2!Eu-(gbxp;xlkQ@dB`$5sM1=M8I799e6ts$cW|6sJ*X@`g>L^*lAfL z4s>bkIS|bYms(VTGdwFB4O^Rw5gp)mdKI;Vst0A4>A%K!iX delta 122 zcmV-=0EPc!m;sO^bYDqCK~#9!WBC97KLa%|1Jw+=b?a6F5T^lgDmHxc=1nlhB@e?4 zPoF;h3dH{@#UN+>{Z9n|GU(H&L8AtZ8Z>Iqurlb{wQK*Wff-JnI<*>zw*&DON-*`R cBWf8009`@PA}7ERuK)l507*qoM6N<$g1D$M?EnA( diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/comboMiddleDisabled.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/comboMiddleDisabled.png index 3ac500fe145102b8df385f5c4aadd0ea89d24947..1813cd16f50d84abf89e7d6ed4cbdb1573ad61b4 100644 GIT binary patch delta 77 zcmaFFm_0$o-N@6$F{I*Fa)LyULyOjr|NsB%t1h#cU5vI5?)PY>|vu h(Xx`I;oo8|Hiojk$J*9Bt>z3s;OXk;vd$@?2><|=9+Ln7 delta 197 zcmV;$06PC`;sKB(f2m1CK~#9!&DFsQ!ypU>;JoTCqmQ=hVDIBaz38bhP*k$a+p?6_ zYQe*YQ1NdPDFsA?5nx!5G3G`Va_6kIm9)o!bM8%$^WIm|p0p1+=Rz>0gx{6hdd@)z zVI|mW!k`#qa}b@W=Ben~Al@49eQ#EWXLK}J43chT?`5ZFKQ!d}rD``@YYqKt?aX|B zDrz}=?MGWmSqb(6tu>ASN~s5Vk!KH>?!Wc{xi!I>0ri;T00000NkvXXu0mjf6f9t> diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/comboMiddleFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/comboMiddleFocused.png index adc3a4d2b319be0eaa991bb7b0b8f33e286b3e65..3c039723239ccf9120c0eaf349cbc050da049f01 100644 GIT binary patch delta 99 zcmZ3(STaF8R+@v2fq|j$;QjeP%G%S#F{I*Fa>9y#^3I|*KX|fk{&-+-YH+w-t1+32$D4)C>lYE=Z|NQ`+EzjQ*EO777Yh<)YFSEu;TLo0000< KMNUMnLSTZPDMHu) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/comboRight.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/comboRight.png index 29c74153b421721d73abdc0bb5c6f2938937a0b1..084618a0725f897457948bfa002ba1a34f0d5b3d 100644 GIT binary patch delta 573 zcmV-D0>b^c2-O6TBYy%MNklhQM%zu6}%zVQH00fFjpyM`NyJ(>}g zTEgaM1izdZCxqg3(-NMaAo!&zNjNl;{%Q%Ep2~p*aA1gxB|M!V{EM?m#^8Gg#(`Ah z^=Fd#x!OAfOL$TqZXQn}OL~!>* z9(HzHR0$8p37WdN5g2uM|FS<KEA7wqt(sAcHyY{LQ zZs})eHpL7g(*}-6Qga!vMy44X`|`6DmzA(eLYj3wjLKevwinqub?f@x>`Z4@wJBkx zd-4J(zofq9HC+t9RCF+wx2C^Y!qriRUshZplwSDJX$e=#RSKp22BR!OSl0aWT}k~^ zsU-}C2{r{{g5mU+;JNwe;@aUd>Fs}tY$ZNeA}k8zw*UJZEw=DCTrH~e(nY@y00000 LNkvXXu0mjfYv&C8 delta 1060 zcmV+<1l#-71h@#0BYy+`NklwTT{U*g!7y1QqjskCX-@*?+|GGFXkTb*F6-IHSE%H-+ zGK>OW7@JNg-G9XFL1Szd1RZ8CgR zQ)s4Fhx6=+%MzG>jI;a>4#f+{IMyEFc=8ZO&t-||Pk$%WR+rU>4No3Io7ucJlD>#h&Ef(8yC2` zMX=Sa0*Z&698G;@SnIbs=F{{1gBz)X*11TsD5 z%#XMP(i{TI8fajnF!ZcOQ=jeNSgv&PukcEwRsmI~;sTe{Nk%}S%nuw8xTjL!akr$) zk;ou@X}!dQq^DE}WJL5Oq)jgeDn5w|TP~Bp$7m zNG_LH(<*W38{G(;S0k~I^u$u2+#eT6oop@{6t}-8QT?@U9DdC?9g}PllXgiw?34&c zE@ieuVkS+TPTJ&MKv@^F2BtYAOLORk@&5f1Q%VIq7tF!7ULE&UO56;Y&*~Va?U8iG z5`S}O_1X@g)E5_+TBS1ridp-0+(`qpcXZUB|LeVmq(v`s=@ejkQupbYNv*aWupf^L zOsUY>j7oK83ebhmekU+(K?;5I+X479lib{RH&)2i!z6(exki_V)!EE`J|z%aJP?VsuCw932|| epFg7$9r!1>=;ujzJl-Mz0000%K!iW8%V)_|NgCh|NedA z&Ye3=f!evrHVB6Q{P|O{ZQC|8pb_j883e-b-n~l#8X-inK|pU-0gVtNXwdE3xBo9# zu;4$4#-#>mgg9PBD_5*oVGS?b$SBZiUc7jbvT)%-TWGP%2rDF&NyLgk rEDgkbK+J?(Y#y_aftitAGB^PM_LmXQzi+WD00000NkvXXu0mjfK6;4U delta 481 zcmV<70UrLq0{a7yB!9w5L_t(|+O3tlY63wNhW80l<^l2yd4@bl3LDdCn@ZBSAS(C* ziCxNslonzd1x2g{jpF@+iudcE`A0U)UR+kP2M#kkGyCm1|CyQ90BC-=<{PNpZUzFlA#e7QZs7-jAvJnD)zrXzNJPh7K@(5cCDIP{!l1n zDnIv=T7J(OsT(qpNO<3n#=-P@M3~yeBXZ55RWwR_zFJ0{PCnthvuKd$gk5ye-t*?bpiJrFXPOnm+w`33p~ X^wfHHzX0q)00000NkvXXu0mjfH|^p` diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/comboRightFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/comboRightFocused.png index 83c3813bb9d3c01fe14a820067dddf9cc306bf3e..d3c448a855c1687bc79ac9a8a8d192e829c9f775 100644 GIT binary patch delta 641 zcmV-{0)GAX35^Ai7k?WF1^@s6eBZCw00071Nklq~P zsA>rB+k_siJq1)KZAqY-QTS{VHfU}4)CbGpU<@Ef&T z&t=D#RbOUzM})Bc7LWwhm!Hn-eDo&r5k>uNvc_g#W-G4>p>F~xk4fZ16TcuntT4}g z7P;9SeL`3pR|{0&jT3w0$lmck)cmY6yY-R~?jJ*vcz?!__l%N4)fn<#bF47?GFuTA z!s-zuNrsqb-s)UAjJ!)xHB6j(qqEtU*-ht#aOZU-N#G$_46Wv#A~%4)zUHh zGP}M<2)7L)Nw!3ZgR{iClFWZGtQwp}-W)-e*|IZ2SP@b8L9n48xqN`Q`%!kLX5BcD z?aAz#Zh9ds??+k=rKiQayzUB8p_KI^tqO==8+RX4p_GJxRs=F>n{c1DT3y8{r5BM_ z29?bJ{e4krvC}4WYsDQv4uRrM_~i0u(nV*#b>;0TT4>>vW6pg&sr4+LSaR3?xWaNLIk`bL5)RC z+oikH-P-oA12$W_O2quK1ip7JuRDDo2Q;KlpMFU-mg_ zt~L+zdK+0&QzL6=Y-DW9@c`}w$B6(olZ`(bMDno!vZ`C;AAdK!(asx~mqc08QO*-Q z9En{-$8I^sk$KLK-RD{m?+GA-?6tqV6R-c%#Ms>8HXc>hh6V0+qQeqpHtzPDeDh1& zF|YVvM3n@Pa(~>9?DH+ya3qM5I)8n=7X09l;43NwK0HL&HZ-s3oQGSzMtd;3SmLdM zRya@k;XEBc`q>s-ymn(6i#aHGbh$wE0Ru6%jV`D0K?6(o8CbYS`z@?Bf#t+Ul>#&K z4SZbALs_O!Z>ui*lGxJy24Awz+T6i=#DX$`xurDTZ-3zJV$15dCHn-$2rN4w@MeKP z%-#TU&-<~-6U51%nzys4J%SU6qDs<%v>E?CNV8n zQieg~g?|JCIDCZ!XBSC6yNH@h%qo-^w_Bk6M@wv1t-@=00)nMD7I>)AJ-Ixddn* zM(=2ls{S-ebQ(fDs*41@Z>fH!@iWk4ich+ho>pZ*u+Bm`4xu?4sj?xgi_am zk8M`CZ;gbj&e|O7F)<)Pp{3oL>o)Y>pns^x8WVlin~2K4MQ~t}$q8r%ZKfdFz&}Je&wCj$--~cdZ8A$!SHYEm)-mBQ}B)c%Xv~K)+2u4?6wsIG{fr!oC3dl7COf zMbLT#jr$O66$xgC310TOS(w)Sex68=@7OO7@gRP^wZ7QaVCK6^e6l4pWf+gz#4=1i!~4# zXP|$qO`J{GIMOD9d;{a!Fva1=R%wqHxwY04KxNneex06xq{;@KT-kuGl2qAG#ytr32K=@G#I0000!1E2zs7k?WF1^@s6K~2uS0002zNkl%Cqi9HD3te>Cfd?V)V-lD*g20ukstcku(Uxe> zn=7INE7sibCI!f0$zEEPg?!&ngCMArs+z9mTlRaHUPb$=j?9~w;4G*KMK(6%j1 zC5*ov0LO9CvMhnE9@tHQ>$-K{mIvtjp63Byf8dt@orP`NH9N`KG!a5sQ4}+P=D{$G zYZOJ$G|dY@6QwB1kwEt_3?a|+Avm)%%d&hT!kVUKx~@Oorn>JWNzz#q#mo15@oBT3 YR_a9}oFG{O01E&B07*qoM6N<$g40lWR{#J2 delta 408 zcmV;J0cZZ80;L0x7k?TE1^@s6iV+yKiq58V1&w+WsHy{3D@Yhc+m_h@otmPEveTz2 zEEWskQIMb??4u-Ry(Wp`mnewm`p0cW6Wx^R@FNQ1Ft>!=QeDQGO900^5kNx*)9CyI ze+C$HPZ7W;UVnPkuIrcZu}}d$@C)eogM$xyRVy`^JaPfC)DY%Ds9ZWPNX#vdelq3ZQ zs%BFh=Nu?+CaqQ}2l8B}W%$m)bf%IYL>x%33b|g$!FVFm!U;Hd5vOF^J_n;`sWmN^ zy6`j*o87JkJ7N#Q!*Dc_WYTo|05`XH=dAD}j%PGi3{o|Vb}z!^)%C@FuRj!oLBkqa fbaKQTGbewGM-m@hqlAFR00000NkvXXu0mjf{2GD^ delta 412 zcmV;N0b~BN0<{B>BYy#WNklsJ*pH7 z1)Hwi>#M(L>bgY>X0w-sL#Oj#sw%@wrikfufpBQI@0p?)m`dd_namLmtyYIgl7@*y z7US^@;m~ZhnJAv4Wu-9|OVQ-eXxuVEh`9euB4Y`{p;l`$zdwYAVWFYK_VPRqtSXG5XSB89rXDG^!vpr zESKLf7<_KYvWE2F!GRZHGMT_)v4H7xy4LUa*~`nT{uK*o0Xs5+8$^Ww0000q1cL*R7k?WF1^@s6K~2uS0003>NklgN9!0eZqW&cQ<%|;SYN)Nar z?u4sJ<-=e0xMS{2R1WTQr@Mn=71= zXOM~sZG)i~yvA_~^Z8RnDrQ>*(JD=s+pkM`P!oc6I$MHB5@+nV0ZgY01O;s1!(@^n zDCpB6y&~Dx+trZ~*Y`$P6bRJZ-{oc|IAQr2j6Gbdb zzPeUFRjmtmJsV6y;n$foO;c8y+FL_zuIdeC{pYE+ZTp-Ma>3)v|J@7m*}YjmKS>9~ Tpy#Z#00000NkvXXu0mjf@jj># delta 541 zcmV+&0^UEj^FPNk$85LT zvHgC}w%aXR{#>2S=Zklf@wDEzho;>dd}YpWhdn?4Vaw&}t$*3=J$4Kewl%YCxG@76!MWjiR;tCTXghDY~U(1M4(vibayMMyfRYXWU>4*?It`P8tg%k`% zUHElRbdu1w2MAKp=L?7;7YQ1e`Hu@jH!+*eP%hPQdHG&Qet(GLu=RTLnvWbGn8|pC zB3;twPeJ%T1n|)pa6CiXqiN=&$0z%?{T=PrH^(#f-A?bZ+p)lV;*E2d_s3bD-QUm8 fDdoofaTfjoez|isDk8=R00000NkvXXu0mjf6L|wj diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonMiddleFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonMiddleFocused.png index 079e29220c4e65f691c1e99274bbe1e1d8ca16c1..b310695df72bc58d31c6ec539a4705d9d5a82730 100644 GIT binary patch delta 91 zcmbQkm@`2gTe~DWM4f>klJ_ delta 140 zcmV;70CWFroB@y*e;Nn|0001r5gi)<003i2L_t(|+U?3a3V<*WgyFsa1yYK2#L8Ep zF+{w81`je97}r+VfV~4>GyIbCkJ*Z=q;_tRb;P&Lev@s_y0a{0&-}2I_~FuT}s6002ov22Mn-LSTZrIXEEz diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonMiddleSelected.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonMiddleSelected.png index 3d4aee44a76c31dc606fcefbab37dcde4f8c4ea0..ee5e439d2dea50f69af6c307fef18bca80f8b779 100644 GIT binary patch delta 152 zcmV;J0B8T00<-~;B!7EJL_t(|+Lh7E5rRMf1kpa4wO-6XL=Xh|h-@LSmYUv33e#0D zf~M<(9K`sOgLVDN!Loeh;5EPHV49*Fgs{lLIL>k~43ix6+YAS7`;>!w^N@q8?&P4n zHF9t*YB|XBN)9erDF<=~WLa)_yhTK+!5dLZ*_S90000&1`4mo&WamWiG#w%jI`QkMs~=%}kER)0NceD#LKPkviS%fPWkyeg6YeC&=OO z4N@n_em|h=zBGiLEo8UrLFxo)+YY2oknQ#pq)w2!Zb9ktd+bqUfedz)m9wUQ(`NYk{KWR115T4f-0g2ZtOQYXk_@rva#(GYgF zkSK}~MK2l_+d}5^C%t07TKfxHD?w1%j9e zf&|25A|Z}?x-GoHHWaV>?T58?r(k>F$3O+8{HS1Ezf_R(hYDWHn+j4YR1jmPf)Exe znCCf{(^G+S9Ti+`O9ge^P$xlkc2r<0O9hAHi3*G{ cdu962+e*Vw6olbQ$fq1TLOY=OIoUZlzJE~6L2T9~ z#T-Okzf#OWRMiv397I{x6mt;!{UgO3#CBV8w|lTI^{~WRFMkzt5Jj=0n1fiYHWYIZ z%Vj|^2a)IZ6mt-1ddn=kvo7_p#C)DpY_V9jgcfd?PBV(lW;ZRNg&UG&L9xjsZ3!*h zFdok+<{(C+3B?>l9A9%dOsq>iEYa_eI2c@6mwH$tieg5+*tGxkV&dibjbaYs)co2x dxb$)U07R;1ArNeQ>F59e002ovPDHLkV1fVuf5!j- diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonRightFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonRightFocused.png index 9cf707c6022f0b9fe994871eb7d702f428f67270..dbd1b76e440708f299ba71a8022739011457791f 100644 GIT binary patch delta 276 zcmV+v0qg#!1EKLFYN7 z^6v-`eoG(<1W34nn9#xruqGkUDv)u9!tAcb&d!&-X7}5jN#+ePO;e#>Q?IBO06mZ7vngP}vfaT&izB9mv15inl0NckO_z8fs2*Z$_g~9=C+k)@=w~x~th5?GA z0LO7oTplneP18W0=XiNF3}eS7%C_x?Wmz{}*U!}Zw@j+4dek)SAiR{n#arQRSlT{0000XL%3Dl}erqmk} z(lrxQEa-N7ADG-q#tCCsmGPDi)k+=ewOgsA-f<9?olYi`4F&+&VzGef+Z3oBK{_|F zT?d9iurC4legsv@HQA2B@B7Cq06orisnS$6a2@Y_4WLPC6-6r8!pW@xrqKbMYzf%z z#Xs;@fPOWto__!#oXhoPp*Ki@mgP9!>MmyQGbk0y@MFV%-#_^U=Ce5{N&{|6Wwc&< zX_%Mc0Yk}*Dhl~)8DzN@%3F`(HAzy&^0}*w5@ZsM8#0L}@QJS8iSPtS0YA);K_g;i z7z~45x{DC4&xEiG=p6p!`NcSn57RW+eD((n`%B;p1`~b5C0oX(rT_o{07*qoM6N<$ Ef++yH761SM diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonRightSelected.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonRightSelected.png index 3397c49e79029f6a5c2fa1c3487aa771d60e99a6..ef0375895631f7752331453ccfac83b2eb970584 100644 GIT binary patch delta 285 zcmV+&0pkA51GfT@BYyz?Nkl+ciz#>j1@EDd7E?8C>=KhS zNz*3HViuC7Db*W@mvFgA;Q0?2n1LS*kAZm<#d#xq34P(1+NtYzRMj3?ULlOK58;Hi z+c$L5w8T0{demNZ%5n$KkAJA#?7*$OsG*{$!MV!-l#2(Pvw!eGS+)UZ*(*?z6yVIc z3yR|$oNhRvFigQ|FBWJWyn>s~OpxbC;Kmajv|I(?)MpK}aD8yY(G=u39=IoE46^Jc zxQ9ozp}8pAF+|6ES@|WybkG^8Q%JpmOuAuXrp=)YCvEU~b$xS6Vre8v{=U8I56&+x j&**=SghSz=3l{zWaF-ul-J|R<00000NkvXXu0mjf9VCar delta 435 zcmV;k0Zjh40?Y%DBYy#tNkl9A8vmmSxe5vSE7FT}DtP0C2UMt()pIUBHmt>lk43MqKR>^`ynT9j zc-)%JX0%)`iK^A}Rjt<8TwY%N@_qlqYPBK~!9UMChiw;eaevW*@Bi77As3)t{{hQ# zaex09mG4{tS;%lazB8y&sdE85?>n+t2cyxgO{G$e3s5e9gJIYrys@cJ@OZIUg)CAj z3&Y`<(b-vryKWicLeoqP1|vrKe345X$0;F^NTc7sW|YghoH18;7N96e^m;=^mgR5( zB$0@UPN&bvG=CY-WNe|6$H_?y?RJk*I&E>o$UzbcMbTsb_blH#o6TRMr>E!aWHMok#bSHC dUekO&r~ixSJ2s=|Np%1K002ovPDHLkV1lmj&T#+$ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonRightSelectedFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonRightSelectedFocused.png index d261fbf0df36cd2cdd34e645434d6be2744a88e1..e5e6f7f1cd521910a1099247485fc32fc48e7f2e 100644 GIT binary patch delta 373 zcmV-*0gC?21cL*R7k?WF1^@s6K~2uS0003>Nklk2PWwOH=9(=r3JwJlNzAx(1Iz@F7k?TE1^@s6iV+K zcUf6riYW{o#%3l!6Pggz(9AQN6lh>&SXspatShE;^?OcBBJJXUW?ssCpMdn5QF{*gZ>cRb{`F+g@0DF^KG$MzIlB7DdZ0+ zME$lQ33S?BjD};hTRrgeaQ$Q-2gI=y;IABqiyZu@{tX>FRugS7r zL$O#vG?Ij_SE8k!r{0i5Q!uZ z3ae0*u=y3A1;JoU5?~Z13co*O3WkHdKv5!+022s=;eYd9SOrueeZHVs$?@Ey>;>b$ z0p}-LIQgVWExqNUsyoZ8@pbE)VjLq(Z+vTT3pOfscx^OtoB>|hw ziPO_}DC9LvCsXRuBEx)sE8g2((r$C%?95F+tAO!nY8r+t_xs`N>ZQ1;evq}BkEWy9 zY8`TS{W+7trajtj$+W!8ejzj)ZGvonzc_lf{nN#v>hj&)?1Yk*i}MGFWpf`Yr&PiK O0000Nj9E1BRs04Sx;!y?q7MHD2=N;bb!T z4#RLaolaAdc%WbM?kO`?R@(xwBZ0HoY`5KR#rb>|Ns?3w9(XCU=Q4oN0nn7&jG`z@ z(^M2iAs$`uz>5r*0NXb;r2&J*Vo?jGLXqLRqNbJvqHDwDaw(p@kWm`dmq65D^db;) zB+zXL=t>~=KYv=SR!;+wQGkQe3L5~rr5ZK>bV^-*5%}L_Q+|h3;4IJc+Aw&LQNF{T zdi3l#jt{5PNz{SD121Kc%1OB#y|z5dK@g1R^Z8-DUT2%lMpOwN@*aKP|546z8$d%D zUlzZ-H@0q#F^6+t821M3v-7YtV5JP+en)9k)x_?x7aAEu{sR605W$?>GTMoK00000 LNkvXXu0mjfw4%l& delta 506 zcmV8-?zDFOyZFhZy_7NJj zwh>{*RvBl28Auan=8j!b3q&!5z+O|x@q8D>U~S_x-Ie4gnS1{4=W@9B;Ec!Pwc&8M zG#CtCwA`nG&|aewJ#so6d8L-DJD)WU|; zYmwB$-$-kC@WQ~7p;_xT&}8|}@sV$hje0DH-jS3KT&a}3Cq)epUKm(1Y+$F;d0jm| zu|+;@cju#c?xBQ1%_<1O1>LXX!3zURMz7a<>!e9$x6b0;hfk86rgD9AEz{{#CX5Y|nq`P%Icwu14=ytpB zei>iLbH8X`T-$6$)q-@58lHPUtX{$Q^LcpH@7n=e)oru&FsR!m|4Df8R_#|c+x`C4 we86s~R#Y!_p1ny<#q>wq9WcHl@4s>s5veUvZ3VT~J#%CxW-c&gx0iy4Wm#6|+}(Rm5^#($ zD>hQ_8bWxcl&ExY;9?^MFEz3EC^k}1)0dYw4F|^`g5y8<5jZ@>7$3DUxY$U+y|wmM t6NLj88!6Z^J7!?c1%~W)4gbR}cmeA<3Z2W~UZ4N~002ovPDHLkV1iX)P+R~2 delta 471 zcmV;|0Vw|30q_HmBYy$6NklSw)J}DY6bh3lUK( z#nL9=BZdeTzM>9@Ad2E!3l%KXoNt^F1PyAHBEoMm_y4{b?%X*t9*^%dGM!GP-|tJU zR+D%!r}1AuttY23@i@KBYy@LMx&8*IvuIk>lX{@!hgWpQujgF>-DTO8V!j= zBI5CQ#Ow8n&*wV|*I1)N*Wr$Y+<~-OEy-rHuc=h3o=&Gt&G(s@bm+o3yd|8^=SI8T z7Sl8(m&?6XtJU3lz20rN+udffIT_aI(1n4;p)R+qRx6`eEJ`2{kbFM>vAgmI1B*jl zdtsqau=Ypq_|&2{M!_%(FsI-Koz`T^4e+_^2vecu28 N002ovPDHLkV1lK8<|Y6D diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxSelected.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxSelected.png index c590775c3a290e2709c56101b152049afcbc2186..86d6dac33d56b1b8c15950c29859384ed645fdd0 100644 GIT binary patch delta 399 zcmV;A0dW4^1*ij%BYy#JNklD%PDHLkV1h+{y&V7m delta 710 zcmV;%0y+Jt1KkCXBYy&wJ?oKz{B{YsjaAh+8`UT??{xPJo&Txg($hj=~3@vz-) zQLXk%P@_VjNYUszxm+Idc!Gw&9XQ}Z11&tn>zN!alOA%lTBF_F&o6>OZOiWuZwCU= zq!Dlj4!F>arEH;2r)?^ie^NeQpj7J1^X28Y916ua8r@(`TfYLl3y0(C9sm~_XyGAI zT4*pBm<|pOX@7OqOM!rv0uka!Byk0JhdZw~$iZNAWE^K`poK@T*R#;s+0eAVpC+r- zL4JQ^8&O<01H$11FDe}7 zNN3f5+(82^Jo^2fu_3Uw7E!4oVrc@eth`f^ouB_S1qd}8UQN_D(h z6NW}(1Ah@BaX6fOdRpf~;RnypFYxsl{ok-_V{_ABClVi|lYX|_onpMC8lKIjvJ zecPu81ATn(d;Al;@zc|n16EL_Qk_^1B1}rxM~gw5SPsxYd$}CsFtu7Os@H!D>Xggn zW#4(FrgqgRBj64kaG`+~9=hRuxMM+fIvokULO+?zp(-*uX9V1V11>b9y0Ry!pY}6o{n2=yW zlkB)N<{x;`kU}3KEbT>ziqz&R*xMA+D}@F`PR|+VY-ZOsn+$xc&YthLXU>@!M=9kP zrBF+#cc>NA`vk3+Sn{L*z#%d04Qe@N$fMR!E~dEYuTOlEP|x&f3? zm4B#g-mk}?DaWL&C#6)Sqa%NCaNz$zL4qDJ_B(p2R<=t7%rfxs&>slV2BpqGwG)If z6pNmrDFZRG1kCX=@vBqYB-QC0uFP+o^MukM-#^j+wP#)eT7J&48c?LAFvy1S9D%N{ zyKsO13q-5UKz}fGrJCj$NL?#4a3M>4`tk%WKYsxlH#a>Ej{zymH3m`*Dj`rsmrF1y zPjzPF@fh~@KH5tLtNShk3pS7dTy!$hGYG!v?9R_S&}@pZ6ft0dfwcZgvpEM6;Njsn z42QR9XhElQ0khc*y1hQscJ?E+)t)C{F_K{j#DZU41%EoDAovP*cO#fgCQz?8bjD#h z7J-FG4H-zLYIO&?-5&7xba4rdh8L~xBG8R=nSm7C@{eI_dlyEdpV03QpjO*|+VIxC zw18okbG#4n<&+I1+Qjb0CX`B*c~@iIH^8a24_ED@hbN`=!!!HqC8AjL+*&6^AH58p zWzQ4a6jnfArKKcjO0npvTW2{#z%*Z9QpyiPh@$6tTc}!+Ft&=G4O22=r2lupzV<$h rT(GRPS$@`P)N?oXs)^0$%*^-;OSb02Ib7Po00000NkvXXu0mjft#Kgt delta 675 zcmV;U0$ly}1iJ;0B!7ZQL_t(|+MSi%ZW2)t$M*${*CxJ!PoTFxf%m=!X${2`Qb>`2 z?LuMsv}(izV-s&J-|PaKmQpk&Hds=rcp;bd2Gfr7pLI#=uC;ZOS#mh@|DBmR=gcaT z$>a{(_3vzh&j$~7I^7dPZ;{?;lA$}BIoBfiLIdr@wEGIbu74dJeN}ieUoKXuRIE^~ z+Ms$(ztG?VUud8OgITxny3y_SUTnTCiDRqTrfQ{5qtoCw~%&iU!&;Gq#zf7)DFNMhY5>;FwJ2Y?ewr5$Nh_TzmkRU;YnTFu+ob zh9QG;sVZqe)j%Lbz1~MUKK>zoDn|+pv;t(7f@6RIijDd>0TJEua)k2v0^#9W z$#@Ofum)NIGRqMNKrEJ&l+x*SsaY`iSR$KFf0ExHq2=H@(7PivFT z1K-<$NE7MxdLIN*2kSgZ?8|*v$64p z+-|R=YJY8(J;J8*v4IGYc)flakH1mB|A`hBe6!k~1=^3zUk-LI_ndb!N{fqr1_xw= ztW+&?JlGdqJ&0ELW~iz*i^wv$dSQpF_pj!F6eZ2eHV3nP?MnM<{73t0%-Ywk*}l+V z$K$aySgdl@1`7?eU|0?I9@|Z}TO4wbYkKKV033Xwf%Z4U^$YYr$25UKb%+1}002ov JPDHLkV1nW`NW}mE diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/comboLeftFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/comboLeftFocused.png index d732f8ac29029b3f310ad1b834ce995f86b67bf7..d9f7824c07ba908eed3d6b1799be310b8aeb0d6c 100644 GIT binary patch delta 274 zcmV+t0qy?W1E2zs7k?WF1^@s6K~2uS0002zNkl%Cqi9HD3te>Cfd?V)V-lD*g20ukstcku(Uxe> zn=7INE7sibCI!f0$zEEPg?!&ngCMArs+z9mTlRaHUPb$=j?9~w;4G*KMK(6%j1 zC5*ov0LO9CvMhnE9@tHQ>$-K{mIvtjp63Byf8dt@orP`NH9N`KG!a5sQ4}+P=D{$G zYZOJ$G|dY@6QwB1kwEt_3?a|+Avm)%%d&hT!kVUKx~@Oorn>JWNzz#q#mo15@oBT3 YR_a9}oFG{O01E&B07*qoM6N<$f(|`-jsO4v delta 463 zcmV;=0Wkic0^9?T7k?TE1^@s6iV+8GzycTiE$8Nzy%crMYHH6dD(CdPF%7~GR7pngt*L0zwXyrL_}+c60B_1FjZ@GSZ{laa zfg@f6r!|gq2`=HN#QHo`))8%Wg3b`bLj4}^9#ENtc%Dy9g#VQt-oC~H!^b8em=)ht zGb-C1G4Y8>2!Eu-(gbxp;xlkQ@dB`$5sM1=M8I799e6ts$cW|6sJ*X@`g>L^*lAfL z4s>bkIS|bYmsx@|EYl) z{!Iqs6nF!jT(g0pxLu$|EC6Km@;Kb3pMcItJeS32$D4)C>lYE=Z|NQ`+EzjQ*EO777Yh<)YFSEu;TLo0000< KMNUMnLSTZP#X{Kt diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/comboRight.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/comboRight.png index ea04e5346271d03a5f4515d1722a02134b829436..d89d36f022db321d647e75558871740d40017bd3 100644 GIT binary patch delta 525 zcmV+o0`mR(2Bid$BYy$xNkl(48u`TffXyW&98C%9wHryEU z+VN8QLMc)hi!PA_GB+8K#A{&U&`;pzb>Z*n;lezp<$`V(Hu>f0Ir;Z@PTHqA5&-Eg zk?vfm8&xcc!x%F*84o3iZc1u4Pp~YF#s^r{1~lF3G9D4((SOlL1f^23QButfB6L>^ ziftdGs2Ep7XxEQ%8wy3;A;Ma%3193c`u%U1PN%#s%H{GZh_K3Dt{>ftub9ndxVibm zYp>V$&B=!f64@h^m?t&1C&n=J#SY{w_m>ZqP%i z3`H^Kl>Xt)i`m#giVBO04iU$3FuMHCdQ6*B&@dcc@_8}4x1XTGd_jdstJUEjU@#aV z&-!dI9P#m|R@;+}zKv7iVNQV`?anFhzu(u_ymmUDeSdR1yD=)1Gub?D!>iX(`Y)$hV+JM3dT=WonGj(zB_k-i(HKG-+hHP1B(qqSgLoQ|oqbo< zd-nXrV3t=;@q8moV0(eXyJSvpZ+b{LW=&cQpW@ zc}!^@9oT4m8EQ24hkEya(yMyC@p5nP^V8GQQ_aQ21rJX{c zmni%Db11AV5Kv%uw_@giOH28Fh6qqI!60bI#fp;bXEvB=AP|M^?GIiKm`?W=%+D{9 z5Q<~JKLSTbCx6iGc42vW1$@3R%?Di#Q`x|Boe1=u)JtA0d98?TCH!OUUzqQ zRHDZtlMiN(cdu85Qt7>u116J;Aj=8?6=j}fBE!MKR|2vAQ1dZMyn1CuU~Vo+P?swJ zo15D_Fp)@6FEBGv^g^Xlqs6t_J~$j6QY@B)+uK{R%YSkVLLr5MqyNUn77xVCus^aq z$4UyJ1MKX4Vr2*Vfh5VtO3p#GTBmU^7^ODN&bncJeUk?&N`irc6g3=M3(M5|e z2-@+Ec0uUbRh!-JgtfH|9*7X9)6aG+Opc=H0jpJ{G4>0E5G>DXb#Qiz#R03U?|5J+ z6eS2|iGL+92Pl_6g3TsTAax=3x>Bjq7&imKMxz~y#Wfxn3`VFF?3rF~W&PXj@32m1 zfteXIJ079_rbv>PHVPBK`9fip2jVfY+c6s-Wok6qsQGx6N@be6xw)Y+mTs}kQa@4C z(=-8*pNqryMJJ>*_PE8reM}PIzY7OiyD)K;#WHQ-lXH}Wa0zsS2 z7F=In)4`vZ(6Lh8G%pBFdLAF2fowLQzoFir zoLwBh;D9=v8OFx6tigKf+e5-RRoF|kNs@y86lg0;<(oqE@Rj)&45x8?RQY u;bybxKR^HR{PMD+IXgT1&%e>f2L1wN1qedL0gS=`0000ct@nnH#njkr4fu&E! zGy46_NHg|W&@}BqMD7z-3AYF<0)H(b{;b~4${3g(S-1d3!c}8c^n*m#OZX37Z*QiJv!>+yquml zSYfbQJnugo(tnwqoP0soYtb6C_xBHw&u(cYR#>k$fG2o(JpPK+nn$VCUy}AImGW6d zEwI9B)dL>8>LP>fqGda?0l2KJ}FPBg=NDA9&+L6_%oKu){K&c!{IRo{d_jFA%C&LV#x%aZnsAlU@#bAv1sC8 zIHK*hT_5>uI+J6C`GNuS@Oyi7|NS^Wr?uC6hx2mDRF)O$dKnhs`+Ia|L0y!2E^e^G zEv*RGA)ZLH@3KlZ=Ca7L4$tDL?;+t`K~{8FmQ*?mqL|rbzK4>mK~!GkR1lM!@Z_m@ zDl1Bi`9ET>t;ZoEm+P^_Sv-;4l_V*4?xWaNLIk`bL5)RC z+oikH-P-oA12$W_O2quK1ip7JuRDDo2Q;KlpMFU-mg_ zt~L+zdK+0&QzL6=Y-DW9@c`}w$B6(olZ`(bMDno!vZ`C;AAdK!(asx~mqc08QO*-Q z9En{-$8I^sk$KLK-RD{m?+GA-?6tqV6R-c%#Ms>8HXc>hh6V0+qQeqpHtzPDeDh1& zF|YVvM3n@Pa(~>9?DH+ya3qM5I)8n=7X09l;43NwK0HL&HZ-s3oQGSzMtd;3SmLdM zRya@k;XEBc`q>s-ymn(6i#aHGbh$wE0Ru6%jV`D0K?6(o8CbYS`z@?Bf#t+Ul>#&K z4SZbALs_O!Z>ui*lGxJy24Awz+T6i=#DX$`xurDTZ-3zJV$15dCHn-$2rN4w@MeKP z%-#TU&-<~-6U51%nzys4J%SU6qDs<%v>E?CNV8n zQieg~g?|JCIDCZ!XBSC6yNH@h%qo-^w_Bk6M@wv1t-@=00)nMD7I>)AJ-Ixddn* zM(=2ls{S-ebQ(fDs*41@Z>fH!@iWk4ich+ho>pZ*u+Bm`4xu?4sj?xgi_am zk8M`CZ;gbj&e|O7F)<)Pp{3oL>o)Y>pns^x8WVlin~2K4MQ~t}$q8r%ZKfdFz&}Je&wCj$--~cdZ8A$!SHYEm)-mBQ}B)c%Xv~K)+2u4?6wsIG{fr!oC3dl7COf zMbLT#jr$O66$xgC310TOS(w)Sex68=@7OO7@gRP^wZ7QaVCK6^e6l4pWf+gz#4=1i!~4# zXP|$qO`J{GIMOD9d;{a!Fva1=R%wqHxwY04KxNneex06xq{;@KT-kuGl2qAG#ytr32K=@G#I00001BCp<3y}wqBYy)}NklwxzdV&#B^e?_zR}Uq?v|F8GZu@*wzjtR zbZ2Mhy)4V?v42=>7d^(9$9LGlo>tmNJe7K4Vv^9^!NI{B1qB7A(P;Du-`p58ZZX)w z9)9po5)}7~WpT7p2z&zr1Fe~vna4LbH|JRz4fgPZKdrEbc(anlDrs}2k&zK^et!PR zt*xyvJ3xaU{J}$e==~i|5^JMu@;5d%o?cyDeXd3H;(vq6js|6Bm1I`@P-dY8MN^Rb zPk@J#2E1(vF_F%RG&D4Xth%5@F#kzq8Fv(Rbyi_>ODb!9sjv(#Iy}pGuO24>Yjm*_742D0+pP22ptYb4boZ5`O>t^ zq*s54A%Aw{fy}PVYKw86NL^iBby6r@0-boIX`rN}qyp#1OdXmeyme;<3yYzZw@6y?;HcHIt3$Hoa`zbI!)c$D52u!cmnq zO(`t=#dvGMqjk=-D#(N$$>ckgS#Hbm-e6U_6=Y9s42447d3kwdyr?c5Bz*9LKX~+N z+8?^e7pNkl9J~Y1g z7Z_jK_~46)ebE$cq*P<0t>sQB29>7T6ieD#z*s>pGa#3N5;Pr#J9Fopz0YBQ!(j%f z1zKIM?*JCc40V#tX79be-#TmG))rFAY%Z>?Wya85(}r|ux_^8w5K|(m>0*k@z=XNC zb0nVKHZ+rs8g2Ar9ComW4*DmV@FV!of5lMiWio1rKPC;)H)aYi7thf2+qVYhu2ufN z;45+`^mDC?I%>4hk8#++9y;hZSzGz|<5K(&N>t-0rlhz#F)cbrr!$&-GiSf|TGJ(- z1uAqeQh7&`Dt|f_=n@yyXrmwFu!B8x(1QcsCL4a7Klp+e4~$2Ykh(5>K{MxSuQgok zUZ7%6lFHg`I@f5@r#~w?U2jkx7u0B@ALFotJ#^5610J{=5xU^ji7Ya;-Z>IBUajt) zU%Jqipo{$VU;fJAIz{E~S*rIXsVn#w4NR>%HQMOMIDhP54;}R2fVatoA7S!>Mm6bt z#ZcII@w;w&@q#-^7uzj5Q!lBgWtP0rRa$;TDSzn4IP72#9rWP%nKuzdbk6#5WJ+d@ zMWpbDWCl+`?5j3j7Z!YSTcc`kg6tLgUq9Hv9y;j30dFuUGXhbGpt6Ln%V$T!O0@Xm zXA5`=uz&Dp>U9<-Y4xAf;J?#2ggtc7g9BbObH|tuKSJXWheB%4P}d{LG*eBk;o^?DJE(P@3esqdT_u4cOWVyz^u--s(AId`!;IfUUbp3^Of&T0 zfLF|1@I!n@@-?E1j^X%m&QH8u=jqgqDE+BFObfa_O!UHOqF=_-JA)n^@NmvJ(H@VR zx^Ob^L_}utNq4X!%^$A>AAW@7TR#%x6cbiiKX@&x zz_Y~jJxd?f1n64deA)<8MFe~3pa%y$aKVQk!Qr_g8r~hc@CVh=sxEuAhz*NdX6R(i zBo#GDUV{}{OXFnCS)&!l4))MN4}T7L;DT?ejZCfcjXcUZEfmxENub_j!?gl_TabHM7q;x)O=X&SU~L+UUnP>|hUFOnc0F^4+-O zMU2M@9zxiz%J~SLA1wNQo-C4AI4`}%&?BhPMnA?kBFKae`cyCCe*yH6GVAcDmT3S0 N002ovPDHLkV1hEy+5rFn diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderBottom.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderBottom.png index 2b8c0afbed796a3146ebd35b3529645f0b5dd555..68a3a8a3a3f6a5ca66564b5b2d8bc057d6014709 100644 GIT binary patch delta 50 zcmazKoS>pB;pyTSQgJJJhGlUY^TrvCWnKUO|MxdxW3UOy>DJ)7$;to(p00i_>zopr E0OSc02LJ#7 delta 64 zcmWHHpP*u`=IP=XQgJJJM%k0sY6|y!dD0k!{&yZ-qB*bb%WXD=d)!BMb39OH_z~Z| U@b{MsatuJ=>FVdQ&MBb@0Dx&5UjP6A diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderBottomLeft.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderBottomLeft.png index 018f141c8c76ebf519a1a24a86ef207bebba824c..761dfd42669ff9f78b09b9bbfea4d7aa4c63f997 100644 GIT binary patch delta 61 zcmb=8nV@2!?CIhdQgJK!$N&HKhtJG3p4_m5u|;wL(=H7r1qM+cCT@jf25u>}BqJ_w QHU=Q@boFyt=akR{0LFY1d;kCd delta 94 zcmV-k0HOa}eUKzsL`g(JRCwBBm~!OXj_F6fewqfsn;GUD|GK~bz}Npk!T&&k{|rZO ze{$&D`|UqWkm1Ao_Y8Zle{!6A;_IdkjssI2007*qoM6N<$f_Jho A&j0`b diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderBottomRight.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderBottomRight.png index 0fd1bcbdb2ca7a5c2db200a4f29813d9d37aa9f1..db5c031e92130e862116dd3540f1410d0d303ef0 100644 GIT binary patch delta 62 zcmb=6ouFc=;_2cTQgJJJhGlUYvxxfN|NrMVGI~0Qt4&~eWWc}}!Qi5h%<#)zEy?(@ R+ZzTT@O1TaS?83{1OUB96+Zv~ delta 95 zcmV-l0HFU}evl+uMM*?KRCwBBn0DmrW+47F9f+qK`L=@r$oUWC{O>>T_5YmXU-vV> zIGuaH{Xcs9lLNz)!{2tyJ@IwZ-s_(n-@kv)006j^F~=S&O}zjB002ovPDHLkV1k7! BFu?!- diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderLeft.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderLeft.png index 463acba3b17a9eb648fa18e2b8e7f5e27c33ba59..b4251f12964b568e6eda8dc7071d7321e163ccc2 100644 GIT binary patch delta 47 zcma#|o1mg4>gnPbQgJK!$N&HK%+6o`OIXMmF)^g8#g?5Y>1JmD0#8>zmvv4FO#rIW B5UBtF delta 64 zcmeZ^pP*u`=IP=XQgJJJM%|a&ZJF--{%p|!k!d%Z8^d8)4Lw$d$IadC TGu4u3FaUw4tDnm{r-UW|Q>z$X diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderRight.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderRight.png index 284d4142a53dd362e3fa5a24cb52ec7f45100f35..c5c17f14d7d31fa49835f20c9547220c4984bfe0 100644 GIT binary patch delta 48 zcmYfBpP-^G=IP=XQgJIeVZ}dr=EML0|4&blFk)gj_dB-CbDz#p1|aZs^>bP0l+XkK D;1Ux3 delta 65 zcmeZIn4n^#?&;zfQgJJJM%k0sY6}1O4_)rByM2Hm<&B%rjc&aS*$FHM-Z>O%GCcC` UZf9|t(#ik?p00i_>zopr0IT;J+W-In diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderTop.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderTop.png index fccd5aa516a629d7892ce0354748cee4191426a3..f1894c59f36d8c4ad7e29c5bb3661010a0c45093 100644 GIT binary patch delta 51 zcmazGnxLX5>FMGaQgJK!$N&HK%o}GUK07m$_ejz$O*RHsshn>0XPdehfWXt$&t;uc GLK6TpCKP=D delta 63 zcmWHFo1kK)>gnPbQgJJJM%|a&Yzp_dkL>1npv-f*uja46j#}hLHHCY=JZubHG2IKD S`nCBOfWXt$&t;ucLK6TUBNqDr diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderTopLeft.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/macBorderTopLeft.png index 9f4ae60ac6f0bb35fa9914955f9f7afd84a3b931..2cacc7eb414490bb3793757020934fa5daef787f 100644 GIT binary patch delta 58 zcmb=9oSh-a7KR(&G~;#r&Rk&t N0#8>zmvv4FO#s427QFxf delta 92 zcmV-i0Hgm|dyphoLPcLL+vOnS!N9P`Of#P4!|bID OK;Y@>=d#Wzp$Pz$))ck? delta 95 zcmV-l0HFU`evl+uMM*?KRCwBBm~!~rj=3kkZrXeOljDc??->}TANl&f|G?M(oqNCi zKYII<1H&|+08DVs@vr+q0-J&O6HxHelq27E004y|F~|?N)o}m-002ovPDHLkV1lJH BFYW*U diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/progressLeftSelected.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/progressLeftSelected.png index fe83f11b32be374f0c74d305b20f60f412d4d14c..b10d30ca34a291b32dd24387324a318fb7641498 100644 GIT binary patch delta 79 zcmV-V0I>gkZjdBOHAzH4RCwBB*s^6i!=_DJ4z;#+{$~Jkc7YhPX3hW4(9<*V|IC^5 lz!;UYWy?0OG8hML002q=Fc_$6^l$(G002ovPDHLkV1m;0BF6v# delta 94 zcmV-k0HObGeUKzsL`g(JRCwBBc>DGZ!=_DJ4o#Ra^%KLEE!%fBG_?PpHEaHVhMt~@ z|L4qE2;zK1RN33NZ@~ui_fPo*0EKEXcs9v}=l}o!07*qoM6N<$f{7q3 Az5oCK diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/progressMiddleSelected.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/progressMiddleSelected.png index 22f6283a6194972d78f0f622c1a8003847e71c2b..6f5af6f217bf1328dd510d7115887fdbf4b82167 100644 GIT binary patch delta 60 zcmYcem>_A+#K6GN*}gd%NQry8IEGZ*O3uiA+oI4m)A+fg0Hat8JHzsi^2QpB^K5`h O7(8A5T-G@yGywn~2odW5 delta 79 zcmWGYo*?PP#=yY9_Ed!jNNIVxIEGZ*N`CQv{wJOe`^Jnm%VM#=?GIZ2OQxNh^PRKf he{)6%Uzbq|Geb>>Ve%37U;&^m22WQ%mvv4FO#o~y9JK%d diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/progressRightSelected.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/progressRightSelected.png index 6858682c3fefa75da62fc446292f8850d7813aeb..bead76a2ed54dca0322cef3d03ef523c3c115a68 100644 GIT binary patch delta 80 zcmXTVpP=Gx=IP=XQgJIeBlqo}{h61iIY)2HNlutyS$wa40>gyO+-GLmRv-L-@1E!X kK+DZ(XWccLB^j1TG6cKn&t)tzopr0Nj`&0RR91 delta 88 zcmV-e0H^_tclc+02s6TUizTpU$;OLlS(O&p)IQM+>-E;0a zbF>A6LECd6gs=qLzb0fS>=RssV}^@u_LmTH5WWz;6V3=1gnwUz-~4;Q_9McZrwHv3 z4q4!w;2|gkFTp3l%XSa@ISH?<3PI!(;gnCV1Ofp+p+?Vr!kp2E4SOuAus<@eV@2qY zMR3Z?a5$_+qfxzDt%`QLEqcA40X)NoJ@UCD-)oK#Jm)4M2d4`syQG)gm&;`_7!1T@ zG7+=cOz6690DsT04TnQfsZ=1S5$B4||S-oBt;7U;) ztP*l@Uw9LVL?8FE?E(i}sr22egpRoheVI&VKAldt7JmW@a-O+(rc^g$1i9~J+ zg@SISwB-^92VAM@_RJdgE7!k|dO~eBo0f&(3yzew(@mcso zH0Dn%7W0$fE#1MOR4Og#<i;_rI>R$j~)#>Gr;d7;q_BT`H6)I yi~05LCH|c3q9=Iro^uGBr6Pk=3Z!wk@4bM=mcf z{mz&<*1&*;0~Zan&}=mB7&UZ!_xAS30Oqm8Tmf872KTuyEj_f!5)VhJOy>VYiXalyS0%9nH-yh+$-8 z&;|!C8fe+JJ9c)~>^8Ejt@rH2NSi*G|6tGt$KRyZz)0V-H$OW^-A4K@eB#)V)tIcM z2R}{F;07AS^^NUz+Z*XJy1DTZUR)t-hBktWMsTrp+K=`$DqCAa8^OJ8l*{Hv9}Hbo zAKNr@Lw_5=MPn^x61tt!Q)lFUG9(QhTT_<8%W`q?YhV*NaM4I53{Lm<1leW4aW~&xWK_vgG{y{C%DQbF6^@8@zMDqw4ilCN#m!UuT*~z~gL6~LpEUZXkCXk%<3|6@cimqM3t`K?uoFN40000aLaY-oDH+P$Khq-ljQG3GGWkC4pyA5BlWd`9i| z6E&JGs#MM`o3)9)k6km_vrs0ZHr<6+wLFzd73%eR)E_)&8?U(=gt>lB)EPPrQdO(f zX>>GkGNBlw>3{3^IMKM!-QB~OP_$fD3^fA^o=jyZms4@Fd%C{4B_T9APRhd#0}i-3&q9fWw1yOP-9_f#R4Plm z@qLQ#9a!^z+q=@%JvvIR`}tsl*qJVbj}I2U%wevtn{6Q)-CmL;<5Z%61c?~}KSZrry+Gk=e9zWdRBBP^P2>b@TaCfl{Yn$vdtA{V> q1PcKR4nmGC`1fAenF{@zzgr(k66!a}e44ue0000PcC$rgkp7+PRGrLQSG5Q;# z7tp^6@_nCbwK|z*gBlHs&d;k$rBeBAHv730kLw16Yuv*eJb&;agRJYi4>SYhk!`o= z`npc#^4Y6cEHQ{i<4n_1OxLqQxW+xq!2>Tc$j%MwcDv+xKIQX;cZ#yl4i3^Rnfy3W zn1csiWRS(GMm4i_mCCo*k;wkU!jr)8B7>}H)*omp=;Gq%f~sn^ru{C6R$<)TRqyp) zXmk!lz9G^NJn{IEd z1rAz#(o+K~i^>O9u4K{!dv#@!<5<-1+Z2Y@(_cZdMN-pVK^Q&HqnjJR8qfDqbsU$2 oTmcHh#`Aq9<_5id%KuN$FHT8=(Zl+8-v9sr07*qoM6N<$f)v9o%>V!Z diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/radioSelectedFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/radioSelectedFocused.png index 5682e883c31316a35fc19b2fe857e554b3ccea54..c6d5ba7871ee886eca49c73ee2b8d327214674a7 100644 GIT binary patch delta 730 zcmV<00ww*)2Jr=uBYy(8Nkl5hMOrFQCC4-`jp$hqg->CB{u&I+^*tc{A^OGt-3U zd5OP));bmv{~J*f7zHxGq#z@G$+I9z0XKl#z+GSlm<8_3?|+Q+PXHGZeZE0NL%_HY z| z8W$3-avqayV`ATSR<-M`X|MJo0Nd>27-E{P>n+L-nU@|!loGkPvU#lflV#UBlSjcu z3}O$Fvmj*5Pk)_6G$C3SxRW>}AsEXXL&m8nqNMC5Pu(d=XCki+<<^7M+fGd@Rqr8V zj!`p8INXnDRIJL~Y*PPjc{Vm)>Vt!i`u+X~-DtcD`hrD-G00)Av8%CuL>W03MLNnX zyrWk2`g%kAzOTcNZT4}@GzfDI>u38BP0ArG(Z0ua1AnPnt#`Wn+sDo<+v}F^$T(;B zqKN30Ql-*Mw7dJZhiGrF)t1kQMecWl=uVV$vqJREb$?68!q;kRJ<@qzJupZo4mrsE zVi0Ac%n;P5T6MOLnE?e~Dpycw2RnPCw|AP_vXp+d^!&JCf&=Vq88sSCa32cSh^Jy+7KT~a>DG)`Mz(@WoA|ok$4Cb4=$wZ zy0mh+A_|3~s8*{&RaJg2^K;>8Hv7$%QqsP7EE$Gjj5(~q2Y8}EcYyxItm=@AJTsGGsO-QluV?gVT?Jf!3Vy;06UbBs#Zn0QW2R<_Jv8LB-7GB zj%OIg=DhhLzyJ%5dxZ?c;P7kW`1s4q=-vS( z9S$eCEyP|XcDel0ycS{jz!w;^X5a!RtX8uKmCEHY6n~W4mh=9JQ{rw%(h9JIatfiz8*w!?&` zSUZgYi2>G(>Ll~kuBvE^^WQ=U6*)%RqNAKnUzfyYTcXX)ZMyy2+S-+CrXMiCf&*Of zxDxt)dVeaKP5n_<2)iAH#G9afQ3rtWKR^G545Qv7)M#AEsI0!gf zQg@dSaz8Wknsog~kC0(p((J6gTgx7yXe^Y^6-29bH8^!B_T1beg~RW9gd&mmyk_q< zgf(^T<4Rf6bxqvdGzK>VNc{dadi83W0)Y_aa(@NN=L-}JuFE+e6HB36&9EOuGn_0o znw2x=cW-i~=X=^A(hspotIosa%d-5YqQj_{hO4Z0>qaq(3cTOD-q xjV$6SFEO?<>^H-|ew?U`DKhq6q5tN)?iWm9se$Sw%WMDu002ovPDHLkV1nrWkoN!p diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/helpButton.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/helpButton.png index c390f92d5016db7adde794992729600d5e7eb77b..af66d4902619d3a73f4cba0fb47a74e6fc2061c5 100644 GIT binary patch delta 593 zcmV-X0`ew;_iFX`RqV1@9q16cn}9Z zhTS*wec9dF*)$PR(@o*d;*5uk9>!zF6Y)JVAHNQf7$duSt}!1tJQu{2tyw7 zg~!t#l}e?I6Vdvlm$S$~d#-~pdWtlMo>p6iuwUuI?-NOk#Z~XQ$*>tBPj6 z{U?T4|9eGK8_r_Pa{xY**Z}U2pF)_={oBT$C(hfbwXVrkaJ50ic?m7<=&K_6xNQ!V zYv5{0{2~)UY&uDoGY=penq=h^MigmYoG4|!6B zzPf*e(a9LDR;#~*2q7MMk{|Kg`LX;i#%Q5XSn?x;IK)d{bI>=fh0)F!N~hD4`Fwt* zUauc(4vC9g$A1xQOH>}jxI7(k f8Arox+wHQyA6vl^GiXqr00000NkvXXu0mjfy!{~1 delta 734 zcmV<40wMkC1oj1xB!9h0L_t(|+U1tJi&H@u#Rp|A1Z}hxwiJmh=qmCf{2Z< z77B`j3WAMTh{cMHViB-V!L?9O2r+>`0-E<@#XL8U-8>OOf{|=|GTCFNs{F9s#yY#*W99@>c8-U|3@TOpINIf~^Y0bF6vcnRC z!QeN*s?4Z556s^NuD%5hikUhKytC;S_2iJJHIrTC;O??Zjt3HOaeLj)%fPWm_M_X{ zr4FrGJRZNP+Z6NnfW?*Vb$eu#hwke)3wfrIIXj(>t$(=p4frv(GoBd7HbYkyX&)l@JTyd|e!3wo9S_Fe*Be$<;$PY!v;>q;)r-5!spF87)iHZ)8hb<~q% zysmh0HX02+FAFZ03-UzFbn7#oI_k+WUc_u<=J4h9Jubp8@Tk zl#H=FWIfv%$9U@g$ZRCyLd#>gPo9i3vePce^Kpe=mRZksJDt(&pZeeU3r9~(h_a$o QH2?qr07*qoM6N<$f+%l$2><{9 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderBottom.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderBottom.png index 2b8c0afbed796a3146ebd35b3529645f0b5dd555..5b57c480d0af12016e2c4e2a5aa92db339c81b69 100644 GIT binary patch delta 48 zcma#|pP-^G=IP=XQgJIeVZ}drXOm@fAN~LTU$~dChCj9}z&=l&0SG)@{an^LB{Ts5 D*&-4~ delta 64 zcmeZ|pP*u`=IP=XQgJJJM%k0sY6|y!dD0k!{&yZ-qB*bb%WXD=d)!BMb39OH_z~Z| U@b{MsatuJ=>FVdQ&MBb@0DtKlT>t<8 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderBottomLeft.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderBottomLeft.png index 018f141c8c76ebf519a1a24a86ef207bebba824c..f01b02740b30fdad60fdd618ce4100e69ecfa5be 100644 GIT binary patch delta 58 zcmb=8oSlUFn_bumm@ARWWd#&|SW_3IM{u4)D# N@O1TaS?83{1OTaw6}kWb delta 94 zcmV-k0HOa`eUKzsL`g(JRCwBBm~!OXj_F6fewqfsn;GUD|GK~bz}Npk!T&&k{|rZO ze{$&D`|UqWkm1Ao_Y8Zle{!6A;_IdkjssI2007*qoM6N<$f_9iN A%m4rY diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderBottomRight.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderBottomRight.png index 0fd1bcbdb2ca7a5c2db200a4f29813d9d37aa9f1..766153e6fed15b0e025fd0b5532da80cbe270797 100644 GIT binary patch delta 62 zcmb=6ouFc=;_2cTQgJIeVZ}dr=A(K4|Nl=>T_5YmXU-vV> zIGuaH{Xcs9lLNz)!{2tyJ@IwZ-s_(n-@kv)006j^F~=S&O}zjB002ovPDHLkV1k7! BFu?!- diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderLeft.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderLeft.png index 463acba3b17a9eb648fa18e2b8e7f5e27c33ba59..c5c17f14d7d31fa49835f20c9547220c4984bfe0 100644 GIT binary patch delta 48 zcma#|pP-^G=IP=XQgJIeVZ}dr=EML0|4&blFk)gj_dB-CbDz#p1|aZs^>bP0l+XkK D-{KPd delta 64 zcmeZ|pP*u`=IP=XQgJJJM%|a&ZJF--{%p|!k!d%Z8^d8)4Lw$d$IadC TGu4u3FaUw4tDnm{r-UW|Q|lOD diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderRight.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderRight.png index 284d4142a53dd362e3fa5a24cb52ec7f45100f35..b4251f12964b568e6eda8dc7071d7321e163ccc2 100644 GIT binary patch delta 47 zcmYfBo1mg4>gnPbQgJK!$N&HK%+6o`OIXMmF)^g8#g?5Y>1JmD0#8>zmvv4FO#rI_ B5UKzG delta 65 zcmeZEn4n^#?&;zfQgJJJM%k0sY6}1O4_)rByM2Hm<&B%rjc&aS*$FHM-Z>O%GCcC` UZf9|t(#ik?p00i_>zopr0IRkd+5i9m diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderTop.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderTop.png index fccd5aa516a629d7892ce0354748cee4191426a3..49e5555eb7fb0602cac1bb6fd20501d665791b69 100644 GIT binary patch delta 50 zcmazGoS>pB;pyTSQgJK!$N&HK%o}GkF8o!`b8$vm7o+y(*fLAICF~49;OXk;vd$@? F2>=~n6UP7m delta 63 zcmWHHo1kK)>gnPbQgJJJM%|a&Yzp_dkL>1npv-f*uja46j#}hLHHCY=JZubHG2IKD S`nCBOfWXt$&t;ucLK6TT diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderTopLeft.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/macBorderTopLeft.png index 9f4ae60ac6f0bb35fa9914955f9f7afd84a3b931..f57239d62e648c6c31e2cd3a6dcb8d82a7de6355 100644 GIT binary patch delta 57 zcmb=9n4n@J@9E+gQgJK!$N&HK%tmeotNv>gTe~DWM4f+VmEv delta 95 zcmV-l0HFU{evl+uMM*?KRCwBBm~!~rj=3kkZrXeOljDc??->}TANl&f|G?M(oqNCi zKYII<1H&|+08DVs@vr+q0-J&O6HxHelq27E004y|F~|?N)o}m-002ovPDHLkV1lKR BFYf>V diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/progressLeft.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/progressLeft.png index de79a6179a0dd3985d57bf3cae4d1c936f57c5d1..a5da5ab037193447c9d15d73712b9ad897104f57 100644 GIT binary patch delta 75 zcmXTPnxNul=;`7ZQgJJ};^!yT%Tu+(`Q$AM9@sNa*vNilNA2%#^=uN%9rlZg0;V+b f?5O!^bc2E6SCO^KyMsFpF#v(5tDnm{r-UW|#)}_? delta 85 zcmV-b0IL6LbdV%aJ4r-ARCwBBc=_@r)0Hb%4xc%5<`V;uvFH5x^Zy?_c<`SAC<12O rzJ2>6DhEXw$bie2FCRX8_UtDBBnUh+AMP~}00000NkvXXu0mjfZU`eA diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/progressLeftSelected.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/progressLeftSelected.png index 5b955519192e744ef09a78ea6e513c13c54a9558..d7dd4df2319ec01f65733fae170aa21ed5903775 100644 GIT binary patch delta 72 zcmbD|?3w%j8%uoM!)9z?x%R}V csEIrb40e+Ygq0V|1Tz4Er>mdKI;Vst0BD>X6#xJL delta 91 zcmV-h0HptCdXOYmK}keGRCwBB`1tlEL(`_Ghb$+&{>0F><>@Zr#xMU(Xa4`sVAS*a xzs2nT|7~Xd{)ozHg(@?f1ylwzz@q=vCjfUpF_A+#K6GN*}gd%NQry8IEGZ*N;b&c$?C{sW?b(qz$g~O&M<4Iysl+c_fDV^ N22WQ%mvv4FO#tR}5QYE% delta 82 zcmWGYn;_}S#=yY9_Ed!jNa=dIIEGZ*O5X6I{x465ePagO?VbPsH*YvQ=l_4noV0)c lSdRQ(+i0T2?kc&7ks(jtFfz?xW*JZ;gQu&X%Q~loCIA~QALIZ4 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/progressRight.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/progressRight.png index 10eddd5f84e4467bc123f1f63edfd51df378416f..01451a62b716c176566f1b7036e4c5d83091fa5f 100644 GIT binary patch delta 71 zcmb*?YcQgJKUqTs=S|Jvc}Wa@r?QWZY@_V)Jw&aB@WEDaca_+lhG3SVAQ b-N48oaLn4a{h+cC0}yz+`njxgN@xNAUnm@q delta 93 zcmV-j0HXh9e2^qqLrFwIRCwAYjJXZKKnTE4_8%!-S{@0}(LhO=TY&pYTb2P4hnam< z^*}_li1ZRKxck4wD*8ZXUf7nIZ$?BzRnK4oHX=MQoL}{F00000NkvXXu0mjfG_xjD diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/progressRightSelected.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/progressRightSelected.png index e928c5ec8c3365deb51c03da24dd2ec8740a5722..b9bd5805387a0a00af863a2fbf3fc65c0679f276 100644 GIT binary patch delta 88 zcmV-e0H^;g&U^DCY zM~m72{~Pzb{txDugE+lFj@c|EWfuLf;06Eyb_+3HI|Kmg00000NkvXXu0mjfD0(eA diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/radio.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/radio.png index 13e0f9cc9410ff18fc600197edb840ad1a39f59a..543bb9aeb34c765615cf19e80b192c6072d9901d 100644 GIT binary patch delta 384 zcmV-`0e}9+1DgYoB!6N_L_t(|+U=FSO2j}Eg;S^xvE9DZ!s-JE7NVWlh}NkDf1W^V ztB|A!7P3u}Vz&ti_JJh3B+LJ*B}V;FbrD=&!}OKbbmzJ>jml{XPTzjaU6@X zEM;BSQV6jYo>5DZMCiKiQ13ZBeLx3>Va$r6kZs$_uNL;uW18lSJo_vV8AhbLJkJGw z{dWsJ=!FMf4rt=K?tIfpK06sa@Nz(xQ53BtbHM{I2Xs?aRm%mz11}5IGz}X>Nvz0w z&APfQ%h*?!rg`a-yceu6c%C=sg2=PrhG8A=t+M?daellz*wnV|mu*4lg{SWbI_Y4W zP9_}3!BjZyHG)3Crlfn{_ZKv3R&+xxC9fEWH8E6g&>%MMY`=0000>zi^by8a5%hV!GM((tyU{BpMTGVVHkI%Qpsfr@tl0$ zr!WlZa5#|XdBg(Zbt)7JugHP{D=p#;g=JYcnM~%r-|y4ubfWJD)_T1jAqxhqv}iV) ziAts7Os7+l9h1p~_=+8zN?KH{R#Td$k?LqP8dR&*QYs=V2m)mh7_ibJUDrcOIAT^# z)NZ$fq@tLW6Mvbe=_M7#temLZ?Y<=y#jNzz8TLKrt(MOH?!4RWD2k%5 z%`wM2zOFN$L`N13SS8V7vA7iXFwtx_AGuySosQ3~$t6Kyj(1o?<}cr`W&U56crS76y0=j6pPX>jxB{u)F-azr{IJsF1a?s?va@B0G6HEOs=I)5b{Hv&n>6+BHqgT-PoOp-(`ibAE@Uf~{kbX^~kr_TbBp+mY~ ztyTh0{}W^@^q?0WcsZb+ZQG+mC)sy0c;MxLZh|0~)`e^Z54;@E-Fm$iTo63)vOsyB zvq6-^Px9WfMtv8@F?)1T6ivu`%?g9#I3q5IJY#McHu0v|)*c^v+3}XJzG<2-bwTK5 z|6zAl(7A*iI+?I63tQo$(F)pu^)V9Hb;q=7rWg?=@{7VUK~0Wp(0Hltd1pPO5z$A4 ikuF*5v|rd3#L_o44dD%%)b_Rj0000$yy7UG5ZiTLePVH0zeThCm#zKg3 z96KpV$UPZiJQ#wV+f-1`Cu~SVLZl9b(hLU)o&VD>$w#u%TC3j(bus#zMw7`z4F&@> z91c~l*HiU+{Z^vld7dwAOcebJIW%ZtV4aLcqmk-#I!Y#d34ek>%S1YkW1Xg{3HpqY zLxUE^$!Ip4seZq&YPH&%w0gN*>O9Z&YPB-$exDqgLTgxSBUa}7{*$zNy4#qZH#DPt&OC59+M<7m1Jv#76#U(7_Q{< zeQvi~>#9Qw1M75Q1-M%*7H3Pm{5EJ|oG$EqJ~t0!v)O#*Zm?R8=I~Wuj2s%YFtFA} z)9KVaj#5D?ilTd&Am{wEEHkSo=rcwR4O$pjCnJtvJTo4f$FP--GDD~b#P})eTr3pzi zh7k3nNEQ5(fEaI5>`k!L(grkC>rL^HLTK@%_LBCH)TE7T8XNym(l%{VlkRS&^DPq@ zLN?vCJ?O#*!_52g%bR&SZw-d~#BdN1qD_W>4P>Hfqq0)( zKsL75o(m(H*t^**sZ=V;534;`Lkwc!;kL0?4P;{3xK9nP2X03eyni>IFXjuy9isPv2VSo9yBdLd z*dcoFOr%6nl5~UMftLe0nu6}WOp6k&D!tFH2+-nh4%DxZNmZNcDO*d$cdc0%VDGt=GR^Ce0Ssrf$gRhok9YseF3lF?p)tS{^ z*mJD@y??&(Tx=$>su_e>c(`or`&~iG&0q{k{%bFU1b(1dVpw~hTqQI%2@jXeaV?js zQWVCJ?DvIpvEXE;I{$Tp6id4V`$if=r^SO0k&>odms4Bna-CY0x002ovPDHLkV1j@_SY-eJ delta 879 zcmV-#1CadU1%(HYBYy)-Nkl*M!D1w zgM?s+1Vjpw5NWB{auHfeiy#(y+upa^-CnlE2;n&26fc$5QcQSolaox&`7X1wGkb;+ z5j&4y=WZm$6&B**3aD&lPh(q>$~=KIbNJGRC9ig6#+@Aj5>0&?SE#S`t18c?Dj;IZjOAR&Ivd5Pdi0mj2vpf01FPd(1;|ey%7qj6q|Hq zU$xEYe5U)2r#3va=;Grxy^hk5#d}JVUuNKd z3k_&Fed()uCSGndwUK>^?fP^Oe-|`F-&KDz=cLHKhTe@165E(hWn;4Mbi1Y zZNLE+8qk_p&kctYa^>yaXD?FoWP-+5qIDaA1Ai_wO50m)$W=SAo#L(X)HE)UCzv_4 z39#UR3k_&NlSlPm5N6adm!TGZCO(B~n*jqXIN(A9TF~4IrT_j@H7=ISZjDJ|Ns=nQ z+2L>Uha!g>Fu;P-#!XCI16t4w#+BM_qL=^vu@raS#Oa<%q5*4|Z{Mg0jFCeP7+`<4 ziD&T1kuOBM8wq z=&=im9`=~YvA%*)5K$1)2Wa7BiuNkk1WzMX{dl>~=T2_|+@D$rd3V`t_sAGDIWEIfGEMh1ML6y$P{e`xFr zCDpaU1|hGRUw@P?ED7y=|Lhq`pQGrDx>i!Yv`LT*x(0X&b|a7PKnJH!YDx7tcTjDJ zq>0kWSULmb!h;{(yn9!=(crDt6fBNB=shnR)V=(=<`fJNsb?_(-t`#lMIIn@5{D7~ z3LFcGq8R6f4Cq}i8)To0_c~S;#Ym#nzjx^o+9t1|eShjk9qS#b$C0OV_P)=|3v0!l zi5#y$5sbAmwY1UJ+B(IOhrFh~3@zUIhHig4TnzhI9KJsodrY2+KB~>bGmW^*0G1?6 z_17E3%?_UCXboewTE_xSU%e)3I;JoC>5#FbVwgCCN>O*wT*q{bqnPiy_^d3M4OPcv mV{_L3cOAoiE2wJzZoL6NOX?8)dm=9Y0000}Nm1knVLB!3u5L_t(|+U-@}OB7KQzW;+r4`J38STA7+R=Bf&fZ$({1ikej zf=?v``Bb@^Y503qG9dzkKxOH1s|O{rhXNBs!qzQ<(3v22r&;FC*ZuB{x@f_)$wK6X z!yL}}zWMIC_uP9008tGSheH3R(DJ$^vhQv2V#yW@E0*ZXet$pPHCya&d+5$L4SP8n zea4t0hFEgQjV!d3v&8FFTf9`{?o1)sIOxgPJs*uj5{a~@jlPbl95KX_LvCcD+?P$U z{LvEakDVuVDIZNE5^>W*eB47zX!IFlju>LeAvdznN`6D!cvk2=nglM6?Fz(AiRRJ3 z=x+-WLo7MuMt>HXUi{W@Wn&no&BflaxbEUq%F%m9EPpxVRwgv&qyE+w=07<5gkG&V zIDUHz=M|mw`BkaIGUb^yTU{@IvK92NQxb)x? zGH-2U-r2Z3`B}$|v>#w9X@LY3rEIRodRaI}*jLO%hSE4X?ZAYAwW00009e!BD#~&g)cBO8yy(*1q5}W4lc$&xAVyrZj=2v6SN2y9}H*CcYmJa=QSp!jQxdT zJJA0Cl}e=q>4LGVwZyMMbjTj*fOOkxwVryt-gCd-7k?0*QNugZA!$DnNI_2P z_4>nbI25zl%$U#T#%i@%3(u&HMk8UG<|Fla%oU)tMCpz&1N%8 zo)im2hB)bJI-Lr9`p+O6p$EP2z{>$89mmOqC+T!LvQnwYTCFDA?Y0b01`oU((D`66 zDC!5ft}Dys@_##_ruV=DF9&oP1cA^GsaC5WK$uSNfd^g|Xt7wZL6pQ7@?Nl3H zs~eBU1@dNCVemXJ7f#nE445t)28cX)ZWz|_rr3(_qOC=oA8!RqS(bJGQxJODKUnPw zI##f+CKI-8<5oC{bOmX!6jsvhcJp-A6tN;oSoj+W-In delta 529 zcmV+s0`C3L1F8g&B!BTqL_t(|+U=D|ikmSIg>{jvvdINm;~6|rU7xTT)6gJo0wKM4NLIb4S1PG~8xb*o1Ln=>-!vKyho;-@ znqIGGTCJAJ<#Hbt5BYq)pyLeO<`2Z+z(s>L$f)1%n?|EybbrGirBX?BBbm)+vREuE zn6pL<4qP-rM&t3=bUGcA&1Qe;D9hzi*6X!wHXA$M&xyggajn+dh|CIw!Z#gdyWLu_ zG1%|-7Vfu;!@X(zjVhJOhkCs(yWP%i;!bhBUgdN;$?hg(My+PGJk2&Y&PY5K0lkmMT6Gcs8*}xU8e3N?RHz@@wh~zQHxkCX3dD*bJ2Pm z=?nTphGa`g$UKwDNF)-GL?U5{B|& zMeA*(ujlK0KDU|rJ_fjG(1tvQciMax*DtHp>ec5>%zyP48ni(TtAbC{=~UcZxn3f3 zcT#s+IB?MfHSA;ZGuh{1u225pcLB^V3__TySC7T;@GzUXF;is}uItPz6)7fq1S+h6(rY4ik5lR`4n T9zv%8015yANkvXXu0mjfRv87e diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/radioSelectedFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/radioSelectedFocused.png index 6b5460862a64f851e621d6fe0d9d94221f72e5cc..78343eeb051e4ea91d8a692f9f4eaf65487e3e1c 100644 GIT binary patch delta 802 zcmV+-1Ks?I2e}52B!2)&L_t(|+Rc{FPZLoP$9u*@y&}SYV1L-4rG#oJ0)`-gW+7>6 z)WoDjy=dY=>Os$1q`#nB{soLC#%N;v3p{Ypgh*nLA6^WRQdYWUOUIeFuiaO=txLGD z$v1gj&h;`s1dFJpKCuJ$bamKK?iCWbpthy3ZW!H zAwEww=gqcg4T^ys)yDx7s3}w!6){nmuali0b=De4hYX^|_^HE=xl+7eF0Og!OPVvO z0jUSaG)HR!P~x|(48qmPqqxbvMw6a9IXZ9;+FmS;WP(M zvYWL8={ccrNq+?K%c|l@Yqiar$&=BbFI!T`hr=YcR}0WEk9D{|r*2w-)L>|fJ{v+9 zN6kTc3Da$+Fz&My5@REM+_Rv;+%2d)uS?lX$OFrbwK@EPO{bNQDl3Y%Cx7|rfkk!GktnnHR|~|)6HjxrhBm+K zvHX1@H$kgyVwiu0BeutdTdw$S;@YCR?px5XO_Z^OSr|2%bIKRz7N>!%|+mj^D}~f#*;cdFQSECk)YhQtdm< go*Ps9yLDpFKhpGUjvcIsZ2$lO07*qoM6N<$f_{~eYXATM delta 882 zcmV-&1C9K-28jodB!5szL_t(|+TB)3OjA)5{Vuw5M~EvYG{lgw&_tZ58{N1i#%M4` zcP@;HJKYE?rh)^e422X-FaeDT7!pksnowy;C>=CG6iO+r3>|*$5K4jH>plNdAeL58 zVPTV-zTSI=zW46??+ZjE>_!N?ZZtg`5ZoL#mnaNPgoM%Qpnu?S1qF*UxX1KOyxi*u zceI%!mIh#<5Uo6)!>4pki`KzexE{Bs$e3QE~H%9DnClBlR0KV1NY&Txb|Zf0PCS zn;1=a{VKgF;;iNMZZ~5l3zYv@qB9!|iggkdH7bE|$`BY}!2uT<+%V%azPY_=Mk7wK zq`FVp_=mjih4stpGtt3FqQjacI##zR2gb;umYNwj;6ejhBhKKJG^026aF>Q#6`h1l zE_j+U;D6xnyqW~v?T%Cb_!1d7?!AfA5lv!!DH#I}xX?h`_t+wxX+~}4s8ws^voa8+ zi`-Esw9=Xg{{8LO3k*xr`X@eeLfD;KF$@14tG(4Nl038A@(|_R_fXCQ59OAH9 zRiCCr`L@nz^e?XRVSZ<@PKvT#R-?atIWdp(%Skq)|K`2!Cz}S~2W@603IG5A07*qo IM6N<$f=7Uy0{{R3 From 4b3b8097d2f947e577e1ff82ee3c283337b53747 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 18 Sep 2015 22:53:23 +0300 Subject: [PATCH 002/138] FileReferenceSet: support different separators & escaping. attempt 2 --- .../impl/providers/FileReferenceSet.java | 67 ++++++++++--------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java index f615cba2f29b..2429771abab3 100644 --- a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java +++ b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java @@ -124,6 +124,15 @@ public class FileReferenceSet { return "/"; } + protected int findSeparatorLength(@NotNull CharSequence sequence, int atOffset) { + return StringUtil.startsWith(sequence, atOffset, getSeparatorString()) ? + getSeparatorString().length() : 0; + } + + protected int findSeparatorOffset(@NotNull CharSequence sequence, int startingFrom) { + return StringUtil.indexOf(sequence, getSeparatorString(), startingFrom); + } + /** * This should be removed. Please use {@link FileReference#getContexts()} instead. */ @@ -216,17 +225,12 @@ public class FileReferenceSet { } protected void reparse() { - String str = myPathStringNonTrimmed; - - final List referencesList = reparse(str, myStartInElement); - + List referencesList = reparse(myPathStringNonTrimmed, myStartInElement); myReferences = referencesList.toArray(new FileReference[referencesList.size()]); } protected List reparse(String str, int startInElement) { - String separatorString = getSeparatorString(); // separator's length can be more then 1 char - int sepLen = separatorString.length(); - int currentSlash = -sepLen; + int wsHead = 0; int wsTail = 0; LiteralTextEscaper escaper; @@ -239,7 +243,7 @@ public class FileReferenceSet { StringBuilder sb = new StringBuilder(); escaper.decode(valueRange, sb); decoded = sb; - currentSlash += startInElement - valueRange.getStartOffset(); + wsHead += Math.max(0, startInElement - valueRange.getStartOffset()); } else { escaper = null; @@ -248,36 +252,37 @@ public class FileReferenceSet { } List referencesList = ContainerUtil.newArrayList(); - // skip head white spaces - for (int i = currentSlash + sepLen; i < decoded.length() && Character.isWhitespace(decoded.charAt(i)); i++) { - currentSlash++; + for (int i = wsHead; i < decoded.length() && Character.isWhitespace(decoded.charAt(i)); i++) { + wsHead++; // skip head white spaces } - // skip tail white spaces for (int i = decoded.length() - 1; i >= 0 && Character.isWhitespace(decoded.charAt(i)); i--) { - wsTail++; + wsTail++; // skip tail white spaces } - if (currentSlash + 2 * sepLen < decoded.length() && - StringUtil.equals(decoded.subSequence(currentSlash + sepLen, currentSlash + 2 * sepLen), separatorString)) { - currentSlash += sepLen; - } int index = 0; + int curSep = findSeparatorOffset(decoded, wsHead); + int sepLen = curSep >= wsHead ? findSeparatorLength(decoded, curSep) : 0; - if (decoded.equals(separatorString)) { - TextRange r = new TextRange(startInElement, offset(sepLen, escaper, valueRange) + 1); - referencesList.add(createFileReference(r, index++, separatorString)); + if (curSep >= 0 && decoded.length() == curSep + sepLen + wsTail) { + TextRange r = TextRange.create(startInElement, offset(curSep + sepLen, escaper, valueRange) + 1); + return Collections.singletonList(createFileReference(r, 0, decoded.subSequence(curSep, curSep + sepLen).toString())); } - - while (true) { - int nextSlash = StringUtil.indexOf(decoded, separatorString, currentSlash + sepLen); - String subReferenceText = decoded.subSequence(currentSlash + sepLen, nextSlash > 0 ? nextSlash : decoded.length()).toString(); - int end = nextSlash > 0 ? nextSlash : Math.max(currentSlash + sepLen, decoded.length() - 1 - wsTail); - TextRange r = new TextRange(offset(currentSlash + sepLen, escaper, valueRange), - offset(end, escaper, valueRange) + (nextSlash > 0 ? 0 : 1)); - referencesList.add(createFileReference(r, index++, subReferenceText)); - if ((currentSlash = nextSlash) < 0) { - break; - } + curSep = curSep == wsHead ? curSep + sepLen : wsHead; // reset offsets & start again for simplicity + sepLen = 0; + while (curSep >= 0) { + int nextSep = findSeparatorOffset(decoded, curSep + sepLen); + int start = curSep + sepLen; + int endTrimmed = nextSep > 0 ? nextSep : Math.max(start, decoded.length() - wsTail); + int endInclusive = nextSep > 0 ? nextSep : Math.max(start, decoded.length() - 1); + // todo move ${placeholder} support (the str usage below) to a reference implementation + // todo reference-set should be bound to exact range & text in a file, consider: ${slash}path${slash}file&.txt + String refText = index == 0 && nextSep < 0 && !StringUtil.contains(decoded, str) ? str : + decoded.subSequence(start, endTrimmed).toString(); + TextRange r = new TextRange(offset(start, escaper, valueRange), + offset(endInclusive, escaper, valueRange) + (nextSep < 0 && refText.length() > 0 ? 1 : 0)); + referencesList.add(createFileReference(r, index++, refText)); + curSep = nextSep; + sepLen = curSep > 0 ? findSeparatorLength(decoded, curSep) : 0; } return referencesList; From e0591ad6408161ad150a4c7b49f9625b82f57902 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Fri, 18 Sep 2015 20:53:31 -0300 Subject: [PATCH 003/138] Make switch keymap action dumb aware --- .../com/intellij/ide/actions/QuickChangeKeymapAction.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/QuickChangeKeymapAction.java b/platform/platform-impl/src/com/intellij/ide/actions/QuickChangeKeymapAction.java index bd1820570a07..4f4c18cac90d 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/QuickChangeKeymapAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/QuickChangeKeymapAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +15,13 @@ */ package com.intellij.ide.actions; -import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.keymap.ex.KeymapManagerEx; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; @@ -39,7 +39,7 @@ public class QuickChangeKeymapAction extends QuickSwitchSchemeAction { } private static void addKeymapAction(final DefaultActionGroup group, final KeymapManagerEx manager, final Keymap current, final Keymap keymap, final boolean addScheme) { - group.add(new AnAction(keymap.getPresentableName(), "", keymap == current ? ourCurrentAction : ourNotCurrentAction) { + group.add(new DumbAwareAction(keymap.getPresentableName(), "", keymap == current ? ourCurrentAction : ourNotCurrentAction) { @Override public void actionPerformed(AnActionEvent e) { if (addScheme) { From 95620fd89aa1b60237923299cc071ee54564a03d Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Fri, 18 Sep 2015 20:54:57 -0300 Subject: [PATCH 004/138] Make switch code style action dumb aware --- .../ide/actions/QuickChangeCodeStyleSchemeAction.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java b/platform/lang-impl/src/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java index da3499735e35..2473f422a52d 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.intellij.ide.actions; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.psi.codeStyle.CodeStyleScheme; import com.intellij.psi.codeStyle.CodeStyleSchemes; @@ -52,8 +53,8 @@ public class QuickChangeCodeStyleSchemeAction extends QuickSwitchSchemeAction { final CodeStyleScheme currentScheme, final CodeStyleScheme scheme, final boolean addScheme) { - group.add(new AnAction(scheme.getName(), "", - scheme == currentScheme && !manager.USE_PER_PROJECT_SETTINGS ? ourCurrentAction : ourNotCurrentAction) { + group.add(new DumbAwareAction(scheme.getName(), "", + scheme == currentScheme && !manager.USE_PER_PROJECT_SETTINGS ? ourCurrentAction : ourNotCurrentAction) { @Override public void actionPerformed(@NotNull AnActionEvent e) { if (addScheme) { From c6930173dfc680f0922a8787b337cc02e18de840 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Fri, 18 Sep 2015 21:03:14 -0300 Subject: [PATCH 005/138] Do not search ZenCodingGenerators for invalid context (EA-73274) --- .../intellij/codeInsight/template/emmet/ZenCodingTemplate.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java index 2540fec6de44..978dec974a63 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java @@ -66,6 +66,9 @@ public class ZenCodingTemplate extends CustomLiveTemplateBase { @Nullable public static ZenCodingGenerator findApplicableDefaultGenerator(@NotNull PsiElement context, boolean wrapping) { + if (!context.isValid()) { + return null; + } for (ZenCodingGenerator generator : ZenCodingGenerator.getInstances()) { if (generator.isMyContext(context, wrapping) && generator.isAppliedByDefault(context)) { return generator; From e686d5a9b67247f8fb1e00999f3a59c99d1ff5f5 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 19 Sep 2015 12:10:34 +0200 Subject: [PATCH 006/138] less tree traversals when calculating element's resolve scope --- .../src/com/intellij/psi/impl/ResolveScopeManager.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/core-impl/src/com/intellij/psi/impl/ResolveScopeManager.java b/platform/core-impl/src/com/intellij/psi/impl/ResolveScopeManager.java index 33b2593a4a52..057b7d6b4514 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/ResolveScopeManager.java +++ b/platform/core-impl/src/com/intellij/psi/impl/ResolveScopeManager.java @@ -19,6 +19,7 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NotNull; @@ -45,6 +46,10 @@ public abstract class ResolveScopeManager { @NotNull public static GlobalSearchScope getElementResolveScope(@NotNull PsiElement element) { + PsiFile file = element.getContainingFile(); + if (file != null) { + return getInstance(file.getProject()).getResolveScope(file); + } return getInstance(element.getProject()).getResolveScope(element); } } From 102df0fb49ec8015eae1ade6b62cb684314a2390 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 19 Sep 2015 12:31:09 +0200 Subject: [PATCH 007/138] don't cache (and retrieve getProject for that) constant values of java literal expressions --- .../intellij/psi/impl/JavaConstantExpressionEvaluator.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/JavaConstantExpressionEvaluator.java b/java/java-psi-impl/src/com/intellij/psi/impl/JavaConstantExpressionEvaluator.java index 1dfb3b57532e..73b72a0943b0 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/JavaConstantExpressionEvaluator.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/JavaConstantExpressionEvaluator.java @@ -117,6 +117,10 @@ public class JavaConstantExpressionEvaluator extends JavaRecursiveElementWalking final PsiConstantEvaluationHelper.AuxEvaluator auxEvaluator) { if (expression == null) return null; + if (expression instanceof PsiLiteralExpression) { + return ((PsiLiteralExpression)expression).getValue(); // don't bother with caching etc + } + JavaConstantExpressionEvaluator evaluator = new JavaConstantExpressionEvaluator(visitedVars, throwExceptionOnOverflow, expression.getProject(), auxEvaluator); if (expression instanceof PsiCompiledElement) { From 2d90351e682c4ef57f03a548f5b44fce54205234 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 19 Sep 2015 12:41:44 +0200 Subject: [PATCH 008/138] avoid double AST hierarchy traversal in TestUtils.isInTestSourceContent --- .../src/com/siyeh/ig/psiutils/TestUtils.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TestUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TestUtils.java index e2de10c72bac..1020bb1f9ef4 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TestUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TestUtils.java @@ -39,14 +39,8 @@ public class TestUtils { return false; } final PsiFile file = element.getContainingFile(); - final VirtualFile virtualFile = file.getVirtualFile(); - if (virtualFile == null) { - return true; - } - final Project project = element.getProject(); - final ProjectRootManager rootManager = ProjectRootManager.getInstance(project); - final ProjectFileIndex fileIndex = rootManager.getFileIndex(); - return fileIndex.isInTestSourceContent(virtualFile); + final VirtualFile virtualFile = file == null ? null : file.getVirtualFile(); + return virtualFile != null && ProjectRootManager.getInstance(file.getProject()).getFileIndex().isInTestSourceContent(virtualFile); } public static boolean isPartOfJUnitTestMethod(@NotNull PsiElement element) { From 9c6be81b45cd0195de183af3ab3ab2a7b7b59657 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 19 Sep 2015 12:58:51 +0200 Subject: [PATCH 009/138] avoid double AST hierarchy traversal in MavenDomUtil --- .../main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java index 179127db648d..ab88c1f963dc 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java @@ -353,10 +353,11 @@ public class MavenDomUtil { } public static boolean isFilteredResourceFile(PsiElement element) { - VirtualFile file = getVirtualFile(element); + PsiFile psiFile = element.getContainingFile(); + VirtualFile file = getVirtualFile(psiFile); if (file == null) return false; - MavenProjectsManager manager = MavenProjectsManager.getInstance(element.getProject()); + MavenProjectsManager manager = MavenProjectsManager.getInstance(psiFile.getProject()); MavenProject mavenProject = manager.findContainingProject(file); if (mavenProject == null) return false; From 07512c090a16cc0ef592c9d82a91b608ff18ce53 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 19 Sep 2015 13:01:21 +0200 Subject: [PATCH 010/138] dfa cleanup and cache project --- .../dataFlow/ControlFlowAnalyzer.java | 81 +++++++++---------- .../dataFlow/DataFlowRunner.java | 15 ++-- 2 files changed, 46 insertions(+), 50 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index 738e467c520a..2559f4e9f3a5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -19,11 +19,11 @@ import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInspection.dataFlow.instructions.*; import com.intellij.codeInspection.dataFlow.value.*; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.registry.Registry; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.templateLanguages.OuterLanguageElement; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.*; import com.intellij.util.IncorrectOperationException; @@ -42,18 +42,20 @@ import static com.intellij.psi.CommonClassNames.*; public class ControlFlowAnalyzer extends JavaElementVisitor { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer"); public static final String ORG_JETBRAINS_ANNOTATIONS_CONTRACT = Contract.class.getName(); + private final PsiElement myCodeFragment; private boolean myIgnoreAssertions; + private final Project myProject; private static class CannotAnalyzeException extends RuntimeException { } private final DfaValueFactory myFactory; private ControlFlow myCurrentFlow; private Stack myCatchStack; - private DfaValue myRuntimeException; - private DfaValue myError; - private DfaValue myString; - private PsiType myNpe; - private PsiType myAssertionError; + private final DfaValue myRuntimeException; + private final DfaValue myError; + private final DfaValue myString; + private final PsiType myNpe; + private final PsiType myAssertionError; private final Stack myElementStack = new Stack(); /** @@ -61,50 +63,45 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { */ private FactoryMap myExceptionHolders; - ControlFlowAnalyzer(final DfaValueFactory valueFactory) { + ControlFlowAnalyzer(final DfaValueFactory valueFactory, @NotNull PsiElement codeFragment, boolean ignoreAssertions) { myFactory = valueFactory; - } - - @Nullable - public ControlFlow buildControlFlow(@NotNull PsiElement codeFragment, boolean ignoreAssertions) { - if (PsiTreeUtil.findChildOfType(codeFragment, OuterLanguageElement.class) != null) { - return null; - } - + myCodeFragment = codeFragment; + myProject = codeFragment.getProject(); myIgnoreAssertions = ignoreAssertions; - final PsiManager manager = codeFragment.getManager(); GlobalSearchScope scope = codeFragment.getResolveScope(); - myRuntimeException = myFactory.createTypeValue(createClassType(manager, scope, JAVA_LANG_RUNTIME_EXCEPTION), Nullness.NOT_NULL); - myError = myFactory.createTypeValue(createClassType(manager, scope, JAVA_LANG_ERROR), Nullness.NOT_NULL); - myNpe = createClassType(manager, scope, JAVA_LANG_NULL_POINTER_EXCEPTION); - myAssertionError = createClassType(manager, scope, JAVA_LANG_ASSERTION_ERROR); - myString = myFactory.createTypeValue(createClassType(manager, scope, JAVA_LANG_STRING), Nullness.NOT_NULL); + myRuntimeException = myFactory.createTypeValue(createClassType(scope, JAVA_LANG_RUNTIME_EXCEPTION), Nullness.NOT_NULL); + myError = myFactory.createTypeValue(createClassType(scope, JAVA_LANG_ERROR), Nullness.NOT_NULL); + myNpe = createClassType(scope, JAVA_LANG_NULL_POINTER_EXCEPTION); + myAssertionError = createClassType(scope, JAVA_LANG_ASSERTION_ERROR); + myString = myFactory.createTypeValue(createClassType(scope, JAVA_LANG_STRING), Nullness.NOT_NULL); myExceptionHolders = new FactoryMap() { @Nullable @Override protected DfaVariableValue create(PsiTryStatement key) { String text = "java.lang.Object $exception" + myExceptionHolders.size() + "$"; - PsiParameter mockVar = JavaPsiFacade.getElementFactory(manager.getProject()).createParameterFromText(text, null); + PsiParameter mockVar = JavaPsiFacade.getElementFactory(myProject).createParameterFromText(text, null); return myFactory.getVarFactory().createVariableValue(mockVar, false); } }; + } + @Nullable + public ControlFlow buildControlFlow() { myCatchStack = new Stack(); myCurrentFlow = new ControlFlow(myFactory); - try { - codeFragment.accept(this); + myCodeFragment.accept(this); } catch (CannotAnalyzeException e) { return null; } - PsiElement parent = codeFragment.getParent(); - if (parent instanceof PsiLambdaExpression && codeFragment instanceof PsiExpression) { - generateBoxingUnboxingInstructionFor((PsiExpression)codeFragment, + PsiElement parent = myCodeFragment.getParent(); + if (parent instanceof PsiLambdaExpression && myCodeFragment instanceof PsiExpression) { + generateBoxingUnboxingInstructionFor((PsiExpression)myCodeFragment, LambdaUtil.getFunctionalInterfaceReturnType((PsiLambdaExpression)parent)); - addInstruction(new CheckReturnValueInstruction(codeFragment)); + addInstruction(new CheckReturnValueInstruction(myCodeFragment)); } addInstruction(new ReturnInstruction(false, null)); @@ -117,10 +114,10 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { } - private static PsiClassType createClassType(PsiManager manager, GlobalSearchScope scope, String fqn) { - PsiClass aClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(fqn, scope); - if (aClass != null) return JavaPsiFacade.getElementFactory(manager.getProject()).createType(aClass); - return JavaPsiFacade.getElementFactory(manager.getProject()).createTypeByFQClassName(fqn, scope); + private PsiClassType createClassType(GlobalSearchScope scope, String fqn) { + PsiClass aClass = JavaPsiFacade.getInstance(myProject).findClass(fqn, scope); + if (aClass != null) return JavaPsiFacade.getElementFactory(myProject).createType(aClass); + return JavaPsiFacade.getElementFactory(myProject).createTypeByFQClassName(fqn, scope); } private T addInstruction(T i) { @@ -204,7 +201,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { lExpr.accept(this); addInstruction(new DupInstruction()); rExpr.accept(this); - addInstruction(new BinopInstruction(JavaTokenType.PLUS, null, lExpr.getProject())); + addInstruction(new BinopInstruction(JavaTokenType.PLUS, null, myProject)); } else { generateDefaultAssignmentBinOp(lExpr, rExpr, type); @@ -234,7 +231,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { generateBoxingUnboxingInstructionFor(lExpr,exprType); rExpr.accept(this); generateBoxingUnboxingInstructionFor(rExpr, exprType); - addInstruction(new BinopInstruction(null, null, lExpr.getProject())); + addInstruction(new BinopInstruction(null, null, myProject)); } @Override public void visitAssertStatement(PsiAssertStatement statement) { @@ -672,7 +669,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { addInstruction(new PushInstruction(myFactory.createValue(caseExpression), caseExpression)); caseValue.accept(this); - addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, caseExpression.getProject())); + addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, myProject)); } else { pushUnknown(); @@ -750,7 +747,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { addConditionalRuntimeThrow(); addInstruction(new DupInstruction()); addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null)); - addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, statement.getProject())); + addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, myProject)); ConditionalGotoInstruction gotoInstruction = new ConditionalGotoInstruction(null, true, null); addInstruction(gotoInstruction); @@ -972,7 +969,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { //if $exception$==null => continue normal execution addInstruction(new PushInstruction(getExceptionHolder(finallyDescriptor), null)); addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null)); - addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, statement.getProject())); + addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, myProject)); addInstruction(new ConditionalGotoInstruction(getEndOffset(statement), false, null)); // else throw $exception$ @@ -999,7 +996,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { for (PsiType catchType : flattened) { addInstruction(new PushInstruction(exceptionHolder, null)); addInstruction(new PushInstruction(myFactory.createTypeValue(catchType, Nullness.UNKNOWN), null)); - addInstruction(new BinopInstruction(JavaTokenType.INSTANCEOF_KEYWORD, null, section.getProject())); + addInstruction(new BinopInstruction(JavaTokenType.INSTANCEOF_KEYWORD, null, myProject)); addInstruction(new ConditionalGotoInstruction(ControlFlow.deltaOffset(getStartOffset(catchBlock), -5), false, null)); } @@ -1179,7 +1176,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { PsiType rType = rExpr.getType(); acceptBinaryRightOperand(op, type, lExpr, lType, rExpr, rType); - addInstruction(new BinopInstruction(op, expression.isPhysical() ? expression : null, expression.getProject())); + addInstruction(new BinopInstruction(op, expression.isPhysical() ? expression : null, myProject)); lExpr = rExpr; lType = rType; @@ -1256,7 +1253,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { operand.accept(this); generateBoxingUnboxingInstructionFor(operand, exprType); PsiElement psiAnchor = i == operands.length - 1 && expression.isPhysical() ? expression : null; - addInstruction(new BinopInstruction(JavaTokenType.NE, psiAnchor, expression.getProject())); + addInstruction(new BinopInstruction(JavaTokenType.NE, psiAnchor, myProject)); } } @@ -1399,7 +1396,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { type = ((PsiClassType)type).rawType(); } addInstruction(new PushInstruction(myFactory.createTypeValue(type, Nullness.UNKNOWN), null)); - addInstruction(new InstanceofInstruction(expression, expression.getProject(), operand, type)); + addInstruction(new InstanceofInstruction(expression, myProject, operand, type)); } else { pushUnknown(); @@ -1481,7 +1478,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { // if a contract resulted in 'fail', handle it addInstruction(new DupInstruction()); addInstruction(new PushInstruction(myFactory.getConstFactory().getContractFail(), null)); - addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, expression.getProject())); + addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, myProject)); ConditionalGotoInstruction ifNotFail = new ConditionalGotoInstruction(null, true, null); addInstruction(ifNotFail); returnCheckingFinally(true, expression); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java index a88985f0fb09..1adc7fa781d2 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java @@ -34,6 +34,7 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.registry.Registry; import com.intellij.psi.*; +import com.intellij.psi.templateLanguages.OuterLanguageElement; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.Processor; @@ -87,21 +88,23 @@ public class DataFlowRunner { } } - return Arrays.asList(createMemoryState()); + return Collections.singletonList(createMemoryState()); } public final RunnerResult analyzeMethod(@NotNull PsiElement psiBlock, InstructionVisitor visitor) { Collection initialStates = createInitialStates(psiBlock, visitor); return initialStates == null ? RunnerResult.NOT_APPLICABLE : analyzeMethod(psiBlock, visitor, false, initialStates); } - + + @NotNull public final RunnerResult analyzeMethod(@NotNull PsiElement psiBlock, InstructionVisitor visitor, boolean ignoreAssertions, @NotNull Collection initialStates) { + if (PsiTreeUtil.findChildOfType(psiBlock, OuterLanguageElement.class) != null) return RunnerResult.NOT_APPLICABLE; + try { - ControlFlowAnalyzer analyzer = createControlFlowAnalyzer(); - final ControlFlow flow = analyzer.buildControlFlow(psiBlock, ignoreAssertions); + final ControlFlow flow = new ControlFlowAnalyzer(myValueFactory, psiBlock, ignoreAssertions).buildControlFlow(); if (flow == null) return RunnerResult.NOT_APPLICABLE; int[] loopNumber = LoopAnalyzer.calcInLoop(flow); @@ -309,10 +312,6 @@ public class DataFlowRunner { } } - protected ControlFlowAnalyzer createControlFlowAnalyzer() { - return new ControlFlowAnalyzer(myValueFactory); - } - protected DfaMemoryState createMemoryState() { return new DfaMemoryStateImpl(myValueFactory); } From 0834e2ce55d4de5e5fd8a7ab1c8d04fa42158724 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 19 Sep 2015 13:08:34 +0200 Subject: [PATCH 011/138] avoid unnecessary psi.getText in java variable resolve --- .../psi/impl/source/resolve/VariableResolverProcessor.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java index 123e750e0a1a..0630b125125a 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java @@ -42,12 +42,8 @@ public class VariableResolverProcessor extends ConflictFilterProcessor implement private PsiElement myCurrentFileContext = null; public VariableResolverProcessor(@NotNull PsiJavaCodeReferenceElement place, @NotNull PsiFile placeFile) { - super(place.getText(), ourFilter, new PsiConflictResolver[]{new JavaVariableConflictResolver()}, new SmartList(), place, placeFile); + super(place.getReferenceName(), ourFilter, new PsiConflictResolver[]{new JavaVariableConflictResolver()}, new SmartList(), place, placeFile); - PsiElement referenceName = place.getReferenceNameElement(); - if (referenceName instanceof PsiIdentifier){ - setName(referenceName.getText()); - } PsiClass access = null; PsiElement qualifier = place.getQualifier(); if (qualifier instanceof PsiExpression) { @@ -108,6 +104,7 @@ public class VariableResolverProcessor extends ConflictFilterProcessor implement @Override public T getHint(@NotNull Key hintKey) { if (hintKey == ElementClassHint.KEY) { + //noinspection unchecked return (T)this; } From a63061f24aa20555291279fe29c56d0788991623 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 19 Sep 2015 13:13:21 +0200 Subject: [PATCH 012/138] PsiCachedValue mod stamp optimization: perform necessary checks once per cached value calculation, not on every request --- .../com/intellij/psi/impl/PsiCachedValue.java | 27 ++++++++++++++----- .../com/intellij/util/CachedValueBase.java | 6 ++--- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiCachedValue.java b/platform/core-impl/src/com/intellij/psi/impl/PsiCachedValue.java index 67aef5c6c605..f9f6b0d0115a 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiCachedValue.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiCachedValue.java @@ -17,12 +17,15 @@ package com.intellij.psi.impl; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootModificationTracker; +import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.CachedValueBase; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -38,8 +41,23 @@ public abstract class PsiCachedValue extends CachedValueBase { } @Override - protected void valueUpdated() { - myLastPsiTimeStamp = myManager.getModificationTracker().getModificationCount(); + protected void valueUpdated(@Nullable Object[] dependencies) { + myLastPsiTimeStamp = hasOnlyPhysicalPsiDependencies(dependencies) ? myManager.getModificationTracker().getModificationCount() : -1; + } + + private static boolean hasOnlyPhysicalPsiDependencies(@Nullable Object[] dependencies) { + return dependencies != null && dependencies.length > 0 && ContainerUtil.and(dependencies, new Condition() { + @Override + public boolean value(Object o) { + return o instanceof PsiElement && ((PsiElement)o).isValid() && ((PsiElement)o).isPhysical() || + o instanceof ProjectRootModificationTracker || + o instanceof PsiModificationTracker || + o == PsiModificationTracker.MODIFICATION_COUNT || + o == PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT || + o == PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT || + o == PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT; + } + }); } @Nullable @@ -55,10 +73,7 @@ public abstract class PsiCachedValue extends CachedValueBase { @Override protected boolean isDependencyOutOfDate(Object dependency, long oldTimeStamp) { - if (dependency instanceof PsiElement && - myLastPsiTimeStamp == myManager.getModificationTracker().getModificationCount() && - ((PsiElement)dependency).isValid() && - ((PsiElement)dependency).isPhysical()) { + if (myLastPsiTimeStamp != -1 && myLastPsiTimeStamp == myManager.getModificationTracker().getModificationCount()) { return false; } diff --git a/platform/core-impl/src/com/intellij/util/CachedValueBase.java b/platform/core-impl/src/com/intellij/util/CachedValueBase.java index b40dee4b26b6..eae0032d5b20 100644 --- a/platform/core-impl/src/com/intellij/util/CachedValueBase.java +++ b/platform/core-impl/src/com/intellij/util/CachedValueBase.java @@ -182,11 +182,11 @@ public abstract class CachedValueBase { public T setValue(final CachedValueProvider.Result result) { Data data = computeData(result); setData(data); - valueUpdated(); + valueUpdated(result.getDependencyItems()); return data.myValue; } - protected void valueUpdated() {} + protected void valueUpdated(@Nullable Object[] dependencies) {} public abstract boolean isFromMyProject(Project project); @@ -227,7 +227,7 @@ public abstract class CachedValueBase { boolean reuse = alreadyComputed != null && isUpToDate(alreadyComputed); Data toReturn = cacheOrGetData(alreadyComputed, reuse ? null : data); if (toReturn != null) { - valueUpdated(); + valueUpdated(toReturn.myDependencies); return toReturn.myValue; } } From 69720d98b16966be0f80324c34d0e3ff18573590 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 19 Sep 2015 13:17:25 +0200 Subject: [PATCH 013/138] fast-track for static CachedValuesManager.getCachedValue(PsiElement, ...): don't go into getManager if there's already user data --- .../intellij/psi/util/CachedValuesManager.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/platform/core-api/src/com/intellij/psi/util/CachedValuesManager.java b/platform/core-api/src/com/intellij/psi/util/CachedValuesManager.java index 84064746e0b6..a5c23298b670 100644 --- a/platform/core-api/src/com/intellij/psi/util/CachedValuesManager.java +++ b/platform/core-api/src/com/intellij/psi/util/CachedValuesManager.java @@ -123,8 +123,13 @@ public abstract class CachedValuesManager { * @return The cached value */ public static T getCachedValue(@NotNull final PsiElement psi, @NotNull final CachedValueProvider provider) { - CachedValuesManager manager = getManager(psi.getProject()); - return manager.getCachedValue(psi, manager.getKeyForClass(provider.getClass()), new CachedValueProvider() { + Key> key = getKeyForClass(provider.getClass(), globalKeyForProvider); + CachedValue value = psi.getUserData(key); + if (value != null) { + return value.getValue(); + } + + return getManager(psi.getProject()).getCachedValue(psi, key, new CachedValueProvider() { @Nullable @Override public Result compute() { @@ -138,8 +143,15 @@ public abstract class CachedValuesManager { } private final ConcurrentMap> keyForProvider = ContainerUtil.newConcurrentMap(); + private static final ConcurrentMap> globalKeyForProvider = ContainerUtil.newConcurrentMap(); + @NotNull public Key> getKeyForClass(@NotNull Class providerClass) { + return getKeyForClass(providerClass, keyForProvider); + } + + @NotNull + private static Key> getKeyForClass(@NotNull Class providerClass, ConcurrentMap> keyForProvider) { String name = providerClass.getName(); assert name != null : providerClass + " doesn't have a name; can't be used for cache value provider"; Key key = keyForProvider.get(name); From 128a9e0fd270af2c26ed9644c3f9233dcf14e4e8 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 19 Sep 2015 16:34:48 +0200 Subject: [PATCH 014/138] avoid double AST hierarchy traversal in PsiPrimitiveType.getBoxedType --- java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java b/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java index ad6bd78e6165..6a3d5c98ab40 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java @@ -151,7 +151,7 @@ public class PsiPrimitiveType extends PsiType.Stub { //[ven]previous call returns null for NULL, VOID if (boxedQName == null) return null; JavaPsiFacade facade = JavaPsiFacade.getInstance(file.getProject()); - PsiClass aClass = facade.findClass(boxedQName, context.getResolveScope()); + PsiClass aClass = facade.findClass(boxedQName, file.getResolveScope()); if (aClass == null) return null; PsiElementFactory factory = facade.getElementFactory(); From 4447cdf4498ac328e6caf2de58a8190098a78803 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 19 Sep 2015 16:47:19 +0200 Subject: [PATCH 015/138] i18n: calculate psi.getProject() only when it's needed --- .../DuplicateStringLiteralInspection.java | 11 ++- .../codeInspection/i18n/I18nInspection.java | 18 ++--- .../i18n/InvalidPropertyKeyInspection.java | 2 +- .../codeInspection/i18n/JavaI18nUtil.java | 71 +++++++++---------- .../I18nMessageGotoDeclarationHandler.java | 2 +- .../i18n/folding/PropertyFoldingBuilder.java | 39 +++++----- .../PropertiesReferenceProvider.java | 5 +- .../providers/JavaReferenceContributor.java | 2 +- 8 files changed, 70 insertions(+), 80 deletions(-) diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/duplicateStringLiteral/DuplicateStringLiteralInspection.java b/plugins/java-i18n/src/com/intellij/codeInspection/duplicateStringLiteral/DuplicateStringLiteralInspection.java index 3c6a35737812..b696de3aa241 100644 --- a/plugins/java-i18n/src/com/intellij/codeInspection/duplicateStringLiteral/DuplicateStringLiteralInspection.java +++ b/plugins/java-i18n/src/com/intellij/codeInspection/duplicateStringLiteral/DuplicateStringLiteralInspection.java @@ -21,7 +21,6 @@ import com.intellij.codeInspection.*; import com.intellij.codeInspection.ex.BaseLocalInspectionTool; import com.intellij.codeInspection.i18n.JavaI18nUtil; import com.intellij.lang.java.JavaLanguage; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -59,7 +58,6 @@ import java.awt.event.ActionListener; import java.util.*; public class DuplicateStringLiteralInspection extends BaseLocalInspectionTool { - private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.DuplicateStringLiteralInspection"); @SuppressWarnings({"WeakerAccess"}) public int MIN_STRING_LENGTH = 5; @SuppressWarnings({"WeakerAccess"}) public boolean IGNORE_PROPERTY_KEYS = false; @NonNls private static final String BR = "
"; @@ -101,8 +99,7 @@ public class DuplicateStringLiteralInspection extends BaseLocalInspectionTool { final boolean isOnTheFly) { Object value = originalExpression.getValue(); if (!(value instanceof String)) return; - final Project project = holder.getProject(); - if (!shouldCheck(project, originalExpression)) return; + if (!shouldCheck(originalExpression)) return; final String stringToFind = (String)value; if (stringToFind.length() == 0) return; final GlobalSearchScope scope = GlobalSearchScope.projectScope(originalExpression.getProject()); @@ -152,7 +149,7 @@ public class DuplicateStringLiteralInspection extends BaseLocalInspectionTool { PsiElement element = file.findElementAt(offset); if (element == null || !(element.getParent() instanceof PsiLiteralExpression)) return true; PsiLiteralExpression expression = (PsiLiteralExpression)element.getParent(); - if (expression != originalExpression && Comparing.equal(stringToFind, expression.getValue()) && shouldCheck(project, expression)) { + if (expression != originalExpression && Comparing.equal(stringToFind, expression.getValue()) && shouldCheck(expression)) { foundExpr.add(expression); } return true; @@ -215,8 +212,8 @@ public class DuplicateStringLiteralInspection extends BaseLocalInspectionTool { holder.registerProblem(originalExpression, msg, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, array); } - private boolean shouldCheck(@NotNull Project project, @NotNull PsiLiteralExpression expression) { - if (IGNORE_PROPERTY_KEYS && JavaI18nUtil.mustBePropertyKey(project, expression, new THashMap())) return false; + private boolean shouldCheck(@NotNull PsiLiteralExpression expression) { + if (IGNORE_PROPERTY_KEYS && JavaI18nUtil.mustBePropertyKey(expression, new THashMap())) return false; return !SuppressManager.isSuppressedInspectionName(expression); } diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/I18nInspection.java b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/I18nInspection.java index c39f607ec845..986e49d272dd 100644 --- a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/I18nInspection.java +++ b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/I18nInspection.java @@ -568,11 +568,11 @@ public class I18nInspection extends BaseLocalInspectionTool { return false; } - if (JavaI18nUtil.isPassedToAnnotatedParam(project, expression, AnnotationUtil.NON_NLS, new HashMap(), nonNlsTargets)) { + if (JavaI18nUtil.isPassedToAnnotatedParam(expression, AnnotationUtil.NON_NLS, new HashMap(), nonNlsTargets)) { return false; } - if (isInNonNlsCall(project, expression, nonNlsTargets)) { + if (isInNonNlsCall(expression, nonNlsTargets)) { return false; } @@ -580,11 +580,11 @@ public class I18nInspection extends BaseLocalInspectionTool { return false; } - if (isPassedToNonNlsVariable(project, expression, nonNlsTargets)) { + if (isPassedToNonNlsVariable(expression, nonNlsTargets)) { return false; } - if (JavaI18nUtil.mustBePropertyKey(project, expression, new HashMap())) { + if (JavaI18nUtil.mustBePropertyKey(expression, new HashMap())) { return false; } @@ -678,10 +678,9 @@ public class I18nInspection extends BaseLocalInspectionTool { || isPackageNonNls(psiPackage.getParentPackage()); } - private boolean isPassedToNonNlsVariable(@NotNull Project project, - @NotNull PsiLiteralExpression expression, + private boolean isPassedToNonNlsVariable(@NotNull PsiLiteralExpression expression, final Set nonNlsTargets) { - PsiExpression toplevel = JavaI18nUtil.getToplevelExpression(project, expression); + PsiExpression toplevel = JavaI18nUtil.getTopLevelExpression(expression); PsiVariable var = null; if (toplevel instanceof PsiAssignmentExpression) { PsiExpression lExpression = ((PsiAssignmentExpression)toplevel).getLExpression(); @@ -785,8 +784,9 @@ public class I18nInspection extends BaseLocalInspectionTool { return false; } - private static boolean isInNonNlsCall(@NotNull Project project, @NotNull PsiExpression expression, final Set nonNlsTargets) { - expression = JavaI18nUtil.getToplevelExpression(project, expression); + private static boolean isInNonNlsCall(@NotNull PsiExpression expression, + final Set nonNlsTargets) { + expression = JavaI18nUtil.getTopLevelExpression(expression); final PsiElement parent = expression.getParent(); if (parent instanceof PsiExpressionList) { final PsiElement grParent = parent.getParent(); diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/InvalidPropertyKeyInspection.java b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/InvalidPropertyKeyInspection.java index 9017e6bc3765..0e2e5d0a6485 100644 --- a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/InvalidPropertyKeyInspection.java +++ b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/InvalidPropertyKeyInspection.java @@ -219,7 +219,7 @@ public class InvalidPropertyKeyInspection extends BaseJavaLocalInspectionTool { else if (expression.getParent() instanceof PsiExpressionList && expression.getParent().getParent() instanceof PsiMethodCallExpression) { final Map annotationParams = new HashMap(); annotationParams.put(AnnotationUtil.PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER, null); - if (!JavaI18nUtil.mustBePropertyKey(myManager.getProject(), expression, annotationParams)) return; + if (!JavaI18nUtil.mustBePropertyKey(expression, annotationParams)) return; final SortedSet paramsCount = JavaI18nUtil.getPropertyValueParamsCount(expression, resourceBundleName.get()); if (paramsCount.isEmpty() || (paramsCount.size() != 1 && resourceBundleName.get() == null)) { diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/JavaI18nUtil.java b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/JavaI18nUtil.java index 8d3e16047586..3fd56f225c41 100644 --- a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/JavaI18nUtil.java +++ b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/JavaI18nUtil.java @@ -25,7 +25,6 @@ import com.intellij.lang.properties.references.I18nUtil; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; @@ -68,8 +67,7 @@ public class JavaI18nUtil extends I18nUtil { return psiElement.getTextRange(); } - public static boolean mustBePropertyKey(@NotNull Project project, - @NotNull PsiExpression expression, + public static boolean mustBePropertyKey(@NotNull PsiExpression expression, @NotNull Map annotationAttributeValues) { final PsiElement parent = expression.getParent(); if (parent instanceof PsiVariable) { @@ -78,15 +76,14 @@ public class JavaI18nUtil extends I18nUtil { return processAnnotationAttributes(annotationAttributeValues, annotation); } } - return isPassedToAnnotatedParam(project, expression, AnnotationUtil.PROPERTY_KEY, annotationAttributeValues, null); + return isPassedToAnnotatedParam(expression, AnnotationUtil.PROPERTY_KEY, annotationAttributeValues, null); } - static boolean isPassedToAnnotatedParam(@NotNull Project project, - @NotNull PsiExpression expression, + static boolean isPassedToAnnotatedParam(@NotNull PsiExpression expression, final String annFqn, @Nullable Map annotationAttributeValues, @Nullable final Set nonNlsTargets) { - expression = getToplevelExpression(project, expression); + expression = getTopLevelExpression(expression); final PsiElement parent = expression.getParent(); if (!(parent instanceof PsiExpressionList)) return false; @@ -117,49 +114,47 @@ public class JavaI18nUtil extends I18nUtil { return false; } - private static final Key>> TOP_LEVEL_EXPRESSION = Key.create("TOP_LEVEL_EXPRESSION"); - private static final ParameterizedCachedValueProvider> TOP_LEVEL_PROVIDER = - new ParameterizedCachedValueProvider>() { - @Override - public CachedValueProvider.Result compute(Pair pair) { - PsiExpression param = pair.second; - Project project = pair.first; - PsiExpression topLevel = getTopLevel(project, param); - ParameterizedCachedValue> cachedValue = param.getUserData(TOP_LEVEL_EXPRESSION); - assert cachedValue != null; - int i = 0; - for (PsiElement element = param; element != topLevel; element = element.getParent(), i++) { - if (i % 10 == 0) { // optimization: store up link to the top level expression in each 10nth element - element.putUserData(TOP_LEVEL_EXPRESSION, cachedValue); - } - } - return CachedValueProvider.Result.create(topLevel, PsiManager.getInstance(project).getModificationTracker()); - } - }; + private static final Key> TOP_LEVEL_EXPRESSION = Key.create("TOP_LEVEL_EXPRESSION"); @NotNull - static PsiExpression getToplevelExpression(@NotNull final Project project, @NotNull final PsiExpression expression) { + static PsiExpression getTopLevelExpression(@NotNull final PsiExpression expression) { if (expression instanceof PsiBinaryExpression || expression.getParent() instanceof PsiBinaryExpression) { //can be large, cache - return CachedValuesManager.getManager(project).getParameterizedCachedValue(expression, TOP_LEVEL_EXPRESSION, TOP_LEVEL_PROVIDER, true, - Pair.create(project, expression)); + CachedValue cachedValue = expression.getUserData(TOP_LEVEL_EXPRESSION); + if (cachedValue == null) { + expression.putUserData(TOP_LEVEL_EXPRESSION, cachedValue = CachedValuesManager.getManager(expression.getProject()).createCachedValue(new CachedValueProvider() { + @Nullable + @Override + public Result compute() { + PsiExpression topLevel = getTopLevel(expression); + CachedValue cachedValue = expression.getUserData(TOP_LEVEL_EXPRESSION); + assert cachedValue != null; + int i = 0; + for (PsiElement element = expression; element != topLevel; element = element.getParent(), i++) { + if (i % 10 == 0) { // optimization: store up link to the top level expression in each 10nth element + element.putUserData(TOP_LEVEL_EXPRESSION, cachedValue); + } + } + return Result.create(topLevel, expression, PsiModificationTracker.MODIFICATION_COUNT); + } + }, false)); + } + return cachedValue.getValue(); } - return getTopLevel(project, expression); + return getTopLevel(expression); } @NotNull - private static PsiExpression getTopLevel(Project project, @NotNull PsiExpression expression) { - int i = 0; + private static PsiExpression getTopLevel(@NotNull PsiExpression expression) { while (expression.getParent() instanceof PsiExpression) { - i++; final PsiExpression parent = (PsiExpression)expression.getParent(); if (parent instanceof PsiConditionalExpression && ((PsiConditionalExpression)parent).getCondition() == expression) break; expression = parent; if (expression instanceof PsiAssignmentExpression) break; - if (i > 10 && expression instanceof PsiBinaryExpression) { - ParameterizedCachedValue> value = expression.getUserData(TOP_LEVEL_EXPRESSION); - if (value != null && value.hasUpToDateValue()) { - return getToplevelExpression(project, expression); // optimization: use caching for big hierarchies + if (expression instanceof PsiBinaryExpression) { + CachedValue value = expression.getUserData(TOP_LEVEL_EXPRESSION); + if (value != null) { + return value.getValue(); // optimization: use caching for big hierarchies } } } @@ -233,7 +228,7 @@ public class JavaI18nUtil extends I18nUtil { @NotNull Ref outResourceBundle) { final HashMap annotationAttributeValues = new HashMap(); annotationAttributeValues.put(AnnotationUtil.PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER, null); - if (mustBePropertyKey(project, expression, annotationAttributeValues)) { + if (mustBePropertyKey(expression, annotationAttributeValues)) { final Object resourceBundleName = annotationAttributeValues.get(AnnotationUtil.PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER); if (!(resourceBundleName instanceof PsiExpression)) { return false; diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/folding/I18nMessageGotoDeclarationHandler.java b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/folding/I18nMessageGotoDeclarationHandler.java index 155d83767f8b..ac7897a85a23 100644 --- a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/folding/I18nMessageGotoDeclarationHandler.java +++ b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/folding/I18nMessageGotoDeclarationHandler.java @@ -67,7 +67,7 @@ public class I18nMessageGotoDeclarationHandler extends GotoDeclarationHandlerBas if (foldRegion == null || foldRegion.isExpanded()) return null; for (PsiExpression expression : methodCall.getArgumentList().getExpressions()) { - if (expression instanceof PsiLiteralExpression && PropertyFoldingBuilder.isI18nProperty(expression.getProject(), (PsiLiteralExpression)expression)) { + if (expression instanceof PsiLiteralExpression && PropertyFoldingBuilder.isI18nProperty((PsiLiteralExpression)expression)) { return resolve(expression); } } diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/folding/PropertyFoldingBuilder.java b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/folding/PropertyFoldingBuilder.java index fe9940dc1eb9..e7435c0640e7 100644 --- a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/folding/PropertyFoldingBuilder.java +++ b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/folding/PropertyFoldingBuilder.java @@ -28,12 +28,10 @@ import com.intellij.lang.properties.psi.Property; import com.intellij.lang.properties.psi.impl.PropertyImpl; import com.intellij.lang.properties.psi.impl.PropertyStubImpl; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.JavaConstantExpressionEvaluator; -import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; @@ -57,19 +55,18 @@ public class PropertyFoldingBuilder extends FoldingBuilderEx { return FoldingDescriptor.EMPTY; } final PsiJavaFile file = (PsiJavaFile) element; - final Project project = file.getProject(); final List result = new ArrayList(); boolean hasJsp = ContainerUtil.intersects(Arrays.asList(StdLanguages.JSP, StdLanguages.JSPX), file.getViewProvider().getLanguages()); //hack here because JspFile PSI elements are not threaded correctly via nextSibling/prevSibling file.accept(hasJsp ? new JavaRecursiveElementVisitor() { @Override public void visitLiteralExpression(PsiLiteralExpression expression) { - checkLiteral(project, expression, result); + checkLiteral(expression, result); } } : new JavaRecursiveElementWalkingVisitor() { @Override public void visitLiteralExpression(PsiLiteralExpression expression) { - checkLiteral(project, expression, result); + checkLiteral(expression, result); } }); @@ -80,9 +77,9 @@ public class PropertyFoldingBuilder extends FoldingBuilderEx { return JavaCodeFoldingSettings.getInstance().isCollapseI18nMessages(); } - private static void checkLiteral(Project project, PsiLiteralExpression expression, List result) { - if (isI18nProperty(project, expression)) { - final IProperty property = getI18nProperty(project, expression); + private static void checkLiteral(PsiLiteralExpression expression, List result) { + if (isI18nProperty(expression)) { + final IProperty property = getI18nProperty(expression); final HashSet set = new HashSet(); set.add(property != null ? property : PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); final String msg = formatI18nProperty(expression, property); @@ -119,24 +116,24 @@ public class PropertyFoldingBuilder extends FoldingBuilderEx { @Override public String getPlaceholderText(@NotNull ASTNode node) { - final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(node); + final PsiElement element = node.getPsi(); if (element instanceof PsiLiteralExpression) { - return getI18nMessage(element.getProject(), (PsiLiteralExpression)element); + return getI18nMessage((PsiLiteralExpression)element); } else if (element instanceof PsiMethodCallExpression) { - return formatMethodCallExpression(element.getProject(), (PsiMethodCallExpression)element); + return formatMethodCallExpression((PsiMethodCallExpression)element); } return element.getText(); } - private static String formatMethodCallExpression(Project project, PsiMethodCallExpression methodCallExpression) { + private static String formatMethodCallExpression(PsiMethodCallExpression methodCallExpression) { final PsiExpression[] args = methodCallExpression.getArgumentList().getExpressions(); if (args.length > 0 && args[0] instanceof PsiLiteralExpression && args[0].isValid() - && isI18nProperty(project, (PsiLiteralExpression)args[0])) { - final int count = JavaI18nUtil.getPropertyValueParamsMaxCount((PsiLiteralExpression)args[0]); + && isI18nProperty((PsiLiteralExpression)args[0])) { + final int count = JavaI18nUtil.getPropertyValueParamsMaxCount(args[0]); if (args.length == 1 + count) { - String text = getI18nMessage(project, (PsiLiteralExpression)args[0]); + String text = getI18nMessage((PsiLiteralExpression)args[0]); for (int i = 1; i < count + 1; i++) { Object value = JavaConstantExpressionEvaluator.computeConstantExpression(args[i], false); if (value == null) { @@ -162,17 +159,17 @@ public class PropertyFoldingBuilder extends FoldingBuilderEx { return methodCallExpression.getText(); } - private static String getI18nMessage(@NotNull Project project, PsiLiteralExpression literal) { - final IProperty property = getI18nProperty(project, literal); + private static String getI18nMessage(PsiLiteralExpression literal) { + final IProperty property = getI18nProperty(literal); return property == null ? literal.getText() : formatI18nProperty(literal, property); } @Nullable - private static IProperty getI18nProperty(Project project, PsiLiteralExpression literal) { + private static IProperty getI18nProperty(PsiLiteralExpression literal) { final Property property = (Property)literal.getUserData(CACHE); if (property == NULL) return null; if (property != null && isValid(property, literal)) return property; - if (isI18nProperty(project, literal)) { + if (isI18nProperty(literal)) { final PsiReference[] references = literal.getReferences(); for (PsiReference reference : references) { if (reference instanceof PsiPolyVariantReference) { @@ -214,7 +211,7 @@ public class PropertyFoldingBuilder extends FoldingBuilderEx { } - public static boolean isI18nProperty(@NotNull Project project, @NotNull PsiLiteralExpression expr) { + public static boolean isI18nProperty(@NotNull PsiLiteralExpression expr) { if (! isStringLiteral(expr)) return false; final IProperty property = expr.getUserData(CACHE); if (property == NULL) return false; @@ -222,7 +219,7 @@ public class PropertyFoldingBuilder extends FoldingBuilderEx { final Map annotationParams = new HashMap(); annotationParams.put(AnnotationUtil.PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER, null); - final boolean isI18n = JavaI18nUtil.mustBePropertyKey(project, expr, annotationParams); + final boolean isI18n = JavaI18nUtil.mustBePropertyKey(expr, annotationParams); if (!isI18n) { expr.putUserData(CACHE, NULL); } diff --git a/plugins/java-i18n/src/com/intellij/lang/properties/PropertiesReferenceProvider.java b/plugins/java-i18n/src/com/intellij/lang/properties/PropertiesReferenceProvider.java index 6d0f611d605e..5c7fbe65c07f 100644 --- a/plugins/java-i18n/src/com/intellij/lang/properties/PropertiesReferenceProvider.java +++ b/plugins/java-i18n/src/com/intellij/lang/properties/PropertiesReferenceProvider.java @@ -40,6 +40,7 @@ public class PropertiesReferenceProvider extends PsiReferenceProvider { private final boolean myDefaultSoft; + @SuppressWarnings("unused") // invoked by reflection public PropertiesReferenceProvider() { this(false); } @@ -66,7 +67,7 @@ public class PropertiesReferenceProvider extends PsiReferenceProvider { final Map annotationParams = new HashMap(); annotationParams.put(AnnotationUtil.PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER, null); - if (JavaI18nUtil.mustBePropertyKey(element.getProject(), literalExpression, annotationParams)) { + if (JavaI18nUtil.mustBePropertyKey(literalExpression, annotationParams)) { soft = false; final Object resourceBundleName = annotationParams.get(AnnotationUtil.PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER); if (resourceBundleName instanceof PsiExpression) { @@ -93,7 +94,7 @@ public class PropertiesReferenceProvider extends PsiReferenceProvider { if (value instanceof String) { String text = (String)value; PsiReference reference = propertyRefWithPrefix ? - new PrefixBasedPropertyReference(text, element, bundleName, soft): + new PrefixBasedPropertyReference(text, element, null, soft) : new PropertyReference(text, element, bundleName, soft); return new PsiReference[]{reference}; } diff --git a/plugins/java-i18n/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaReferenceContributor.java b/plugins/java-i18n/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaReferenceContributor.java index bff0504509e6..994eb01cf241 100644 --- a/plugins/java-i18n/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaReferenceContributor.java +++ b/plugins/java-i18n/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaReferenceContributor.java @@ -47,7 +47,7 @@ public class JavaReferenceContributor extends PsiReferenceContributor{ PsiLiteralExpression literalExpression = (PsiLiteralExpression) context; final Map annotationParams = new HashMap(); annotationParams.put(AnnotationUtil.PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER, null); - return !JavaI18nUtil.mustBePropertyKey(context.getProject(), literalExpression, annotationParams); + return !JavaI18nUtil.mustBePropertyKey(literalExpression, annotationParams); } public boolean isClassAcceptable(Class hintClass) { From bfe026f5ab049f950c0d92a2bcbd18c3465eda72 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Sat, 19 Sep 2015 21:08:46 +0300 Subject: [PATCH 016/138] FileReferenceSet: support different separators & escaping. last touch --- .../reference/impl/providers/FileReferenceSet.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java index 2429771abab3..29e0cf6c39e6 100644 --- a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java +++ b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java @@ -263,9 +263,10 @@ public class FileReferenceSet { int curSep = findSeparatorOffset(decoded, wsHead); int sepLen = curSep >= wsHead ? findSeparatorLength(decoded, curSep) : 0; - if (curSep >= 0 && decoded.length() == curSep + sepLen + wsTail) { - TextRange r = TextRange.create(startInElement, offset(curSep + sepLen, escaper, valueRange) + 1); - return Collections.singletonList(createFileReference(r, 0, decoded.subSequence(curSep, curSep + sepLen).toString())); + if (curSep >= 0 && decoded.length() == wsHead + sepLen + wsTail) { + // add extra reference for the only & leading "/" + TextRange r = TextRange.create(startInElement, offset(curSep + Math.max(0, sepLen - 1), escaper, valueRange) + 1); + referencesList.add(createFileReference(r, 0, decoded.subSequence(curSep, curSep + sepLen).toString())); } curSep = curSep == wsHead ? curSep + sepLen : wsHead; // reset offsets & start again for simplicity sepLen = 0; @@ -273,7 +274,7 @@ public class FileReferenceSet { int nextSep = findSeparatorOffset(decoded, curSep + sepLen); int start = curSep + sepLen; int endTrimmed = nextSep > 0 ? nextSep : Math.max(start, decoded.length() - wsTail); - int endInclusive = nextSep > 0 ? nextSep : Math.max(start, decoded.length() - 1); + int endInclusive = nextSep > 0 ? nextSep : Math.max(start, decoded.length() - 1 - wsTail); // todo move ${placeholder} support (the str usage below) to a reference implementation // todo reference-set should be bound to exact range & text in a file, consider: ${slash}path${slash}file&.txt String refText = index == 0 && nextSep < 0 && !StringUtil.contains(decoded, str) ? str : From 456e5c2b625b52446d4343a0ee6a827a9220cdec Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Sat, 19 Sep 2015 21:52:02 +0300 Subject: [PATCH 017/138] No files, update... IDEA-CR-5051 --- .../openapi/vcs/changes/ui/ChangesBrowserChangeListNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeListNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeListNode.java index 9cfe1af4032a..2daec8f2fc72 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeListNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeListNode.java @@ -57,7 +57,7 @@ public class ChangesBrowserChangeListNode extends ChangesBrowserNode if (freezed != null) { renderer.append(SPACE_AND_THIN_SPACE + freezed, SimpleTextAttributes.GRAYED_ATTRIBUTES); } else if (myClManager.isInUpdate()) { - renderer.append(SPACE_AND_THIN_SPACE + VcsBundle.message("changes.nodetitle.updating"), SimpleTextAttributes.GRAYED_ATTRIBUTES); + renderer.append(", " + VcsBundle.message("changes.nodetitle.updating"), SimpleTextAttributes.GRAYED_ATTRIBUTES); } if (! myChangeListRemoteState.getState()) { renderer.append(SPACE_AND_THIN_SPACE); From 91a600647f81833d6eb21532a1feb342ce96a6bd Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Sat, 19 Sep 2015 22:14:59 +0300 Subject: [PATCH 018/138] pluralize IDEA-CR-5051 --- .../openapi/vcs/changes/shelf/ShelvedChangesViewManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java index 155783b97000..e74542784c15 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java @@ -40,6 +40,7 @@ import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Couple; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.CommitContext; @@ -463,7 +464,7 @@ public class ShelvedChangesViewManager implements ProjectComponent { myIssueLinkRenderer.appendTextWithLinks(changeListData.DESCRIPTION); } int count = node.getChildCount(); - String numFilesText = SPACE_AND_THIN_SPACE + count + ((count == 1) ? " file" : " files") + ","; + String numFilesText = SPACE_AND_THIN_SPACE + count + " " + StringUtil.pluralize("file", 1) + ","; append(numFilesText, SimpleTextAttributes.GRAYED_ATTRIBUTES); String date = DateFormatUtil.formatPrettyDateTime(changeListData.DATE); From ac0c53bad64b7161d0aff271d4004c306c04044e Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Sat, 19 Sep 2015 22:36:35 +0300 Subject: [PATCH 019/138] GoToLine: live offset<->line:col sync & cleanup --- .../ide/util/GotoLineNumberDialog.java | 111 +++++++++--------- .../src/messages/IdeBundle.properties | 3 - 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/util/GotoLineNumberDialog.java b/platform/platform-impl/src/com/intellij/ide/util/GotoLineNumberDialog.java index 1c8a887bb0d6..2cfe3ec9266a 100644 --- a/platform/platform-impl/src/com/intellij/ide/util/GotoLineNumberDialog.java +++ b/platform/platform-impl/src/com/intellij/ide/util/GotoLineNumberDialog.java @@ -15,88 +15,57 @@ */ package com.intellij.ide.util; -import com.intellij.ide.IdeBundle; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.LogicalPosition; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.ui.DocumentAdapter; +import com.intellij.util.PatternUtil; +import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.DocumentEvent; import java.awt.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class GotoLineNumberDialog extends DialogWrapper { private JTextField myField; private JTextField myOffsetField; private final Editor myEditor; + private final Pattern myPattern = PatternUtil.compileSafe("\\s*(\\d+)\\s*(?:[,:]?\\s*(\\d+)?)?\\s*", null); - public GotoLineNumberDialog(Project project, Editor editor){ + public GotoLineNumberDialog(Project project, Editor editor) { super(project, true); myEditor = editor; - setTitle(IdeBundle.message("title.go.to.line")); + setTitle("Go to Line"); init(); } - protected void doOKAction(){ - final LogicalPosition currentPosition = myEditor.getCaretModel().getLogicalPosition(); - int lineNumber = getLineNumber(currentPosition.line + 1); - if (isInternal() && myOffsetField.getText().length() > 0) { - try { - final int offset = Integer.parseInt(myOffsetField.getText()); - if (offset < myEditor.getDocument().getTextLength()) { - myEditor.getCaretModel().removeSecondaryCarets(); - myEditor.getCaretModel().moveToOffset(offset); - myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER); - myEditor.getSelectionModel().removeSelection(); - IdeFocusManager.getGlobalInstance().requestFocus(myEditor.getContentComponent(), true); - super.doOKAction(); - } - return; - } - catch (NumberFormatException e) { - return; - } - } + protected void doOKAction() { + LogicalPosition position = getLogicalPosition(); + if (position == null) return; - if (lineNumber < 0) return; - - int columnNumber = getColumnNumber(currentPosition.column); myEditor.getCaretModel().removeSecondaryCarets(); - myEditor.getCaretModel().moveToLogicalPosition(new LogicalPosition(Math.max(0, lineNumber - 1), Math.max(0, columnNumber - 1))); + myEditor.getCaretModel().moveToLogicalPosition(position); myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER); myEditor.getSelectionModel().removeSelection(); IdeFocusManager.getGlobalInstance().requestFocus(myEditor.getContentComponent(), true); super.doOKAction(); } - private int getColumnNumber(int defaultValue) { - String text = getText(); - int columnIndex = columnSeparatorIndex(text); - if (columnIndex == -1) return defaultValue; - try { - return Integer.parseInt(text.substring(columnIndex + 1)); - } catch (NumberFormatException e) { - return defaultValue; - } - } + @Nullable + private LogicalPosition getLogicalPosition() { + Matcher m = myPattern.matcher(getText()); + if (!m.matches()) return null; - private static int columnSeparatorIndex(final String text) { - final int colonIndex = text.indexOf(':'); - return colonIndex >= 0 ? colonIndex : text.indexOf(','); - } - - private int getLineNumber(int defaultLine) { - try { - String text = getText(); - int columnIndex = columnSeparatorIndex(text); - text = columnIndex == -1 ? text : text.substring(0, columnIndex); - if (text.trim().length() == 0) return defaultLine; - return Integer.parseInt(text); - } catch (NumberFormatException e) { - return -1; - } + int l = StringUtil.parseInt(m.group(1), -1); + int c = StringUtil.parseInt(m.group(2), -1); + return l > 0 ? new LogicalPosition(l - 1, Math.max(0, c - 1)) : null; } private static boolean isInternal() { @@ -135,14 +104,13 @@ public class GotoLineNumberDialog extends DialogWrapper { gbConstraints.weightx = 0; gbConstraints.weighty = 1; gbConstraints.anchor = GridBagConstraints.EAST; - JLabel label = new JLabel(IdeBundle.message("editbox.line.number")); + JLabel label = new JLabel("Line [:column]:"); panel.add(label, gbConstraints); gbConstraints.fill = GridBagConstraints.BOTH; gbConstraints.weightx = 1; myField = new MyTextField(); panel.add(myField, gbConstraints); - myField.setToolTipText(IdeBundle.message("tooltip.syntax.linenumber.columnnumber")); LogicalPosition position = myEditor.getCaretModel().getLogicalPosition(); myField.setText(String.format("%d:%d", position.line + 1, position.column + 1)); @@ -159,6 +127,41 @@ public class GotoLineNumberDialog extends DialogWrapper { myOffsetField = new MyTextField(); panel.add(myOffsetField, gbConstraints); myOffsetField.setText(String.valueOf(myEditor.getCaretModel().getOffset())); + + DocumentAdapter valueSync = new DocumentAdapter() { + boolean inSync; + + @Override + protected void textChanged(DocumentEvent e) { + if (inSync) return; + inSync = true; + String s = ""; + JTextField f = null; + try { + if (e.getDocument() == myField.getDocument()) { + f = myOffsetField; + LogicalPosition p = getLogicalPosition(); + s = p == null ? s : String.valueOf(myEditor.logicalPositionToOffset(p)); + } + else { + f = myField; + int offset = StringUtil.parseInt(myOffsetField.getText(), -1); + LogicalPosition p = offset >= 0 ? myEditor.offsetToLogicalPosition( + Math.min(myEditor.getDocument().getTextLength() - 1, offset)) : null; + s = p == null ? s : String.format("%d:%d", p.line + 1, p.column + 1); + } + f.setText(s); + } + catch (IndexOutOfBoundsException ignored) { + if (f != null) f.setText(s); + } + finally { + inSync = false; + } + } + }; + myField.getDocument().addDocumentListener(valueSync); + myOffsetField.getDocument().addDocumentListener(valueSync); } return panel; diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 682e3ef9e6db..310ee6487eda 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -818,9 +818,6 @@ error.unable.to.read.tip.of.the.day=Unable to read Tip Of The Day ({ label.did.you.know=Did you know ... ? checkbox.show.tips.on.startup=Show Tips on Startup error.tips.not.found=Tips not found. Make sure you installed {0} correctly. -title.go.to.line=Go to Line -editbox.line.number=Line number: -tooltip.syntax.linenumber.columnnumber=Syntax: [][:] or [][, Date: Sun, 20 Sep 2015 01:21:42 +0300 Subject: [PATCH 020/138] introduce ILazyParsable#parseLight() --- .../psi/tree/ILazyParseableElementType.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/platform/core-api/src/com/intellij/psi/tree/ILazyParseableElementType.java b/platform/core-api/src/com/intellij/psi/tree/ILazyParseableElementType.java index 27a39aeec605..6c64dd0165cf 100644 --- a/platform/core-api/src/com/intellij/psi/tree/ILazyParseableElementType.java +++ b/platform/core-api/src/com/intellij/psi/tree/ILazyParseableElementType.java @@ -47,6 +47,23 @@ public class ILazyParseableElementType extends IElementType { super(debugName, language, register); } + /** + * Parses the contents of the specified chameleon node and returns PsiBuilder. + * In future this method should deprecate all other parsing methods: parseContents(), doParseContents(), etc. + * It provides more flexible and CPU/memory efficient access to parser algorithms for all needs: + * editing, indexing and analysis. + *

+ * + * The parseContent() implementation in terms of parseLight() is just the following: + * {@code}parseLight().getTreeBuilt().getFirstChildNode(){@code} + * + * @param chameleon the node to parse. + * @return the parsed contents of the node in the form PsiBuilder. + */ + public PsiBuilder parseLight(ASTNode chameleon) { + throw new UnsupportedOperationException(String.valueOf(chameleon)); + } + /** * Parses the contents of the specified chameleon node and returns the AST tree * representing the parsed contents. @@ -54,13 +71,13 @@ public class ILazyParseableElementType extends IElementType { * @param chameleon the node to parse. * @return the parsed contents of the node. */ - public ASTNode parseContents(final ASTNode chameleon) { - final PsiElement parentElement = chameleon.getTreeParent().getPsi(); - assert parentElement != null : "Bad chameleon: " + chameleon; + public ASTNode parseContents(ASTNode chameleon) { + PsiElement parentElement = chameleon.getTreeParent().getPsi(); + assert parentElement != null : "parent psi is null: " + chameleon; return doParseContents(chameleon, parentElement); } - protected ASTNode doParseContents(@NotNull final ASTNode chameleon, @NotNull final PsiElement psi) { + protected ASTNode doParseContents(@NotNull ASTNode chameleon, @NotNull PsiElement psi) { Project project = psi.getProject(); Language languageForParser = getLanguageForParser(psi); PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, chameleon, null, languageForParser, chameleon.getChars()); From 3a21ce0b678fb5a19e809b4c9b9f37c8b2064d18 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sun, 20 Sep 2015 15:43:33 +0200 Subject: [PATCH 021/138] allow to split try-with-multiple-resources with a finally block --- ...plitTryWithMultipleResourcesIntention.java | 4 +++ .../TryWithMultipleResourcesPredicate.java | 4 --- ...TryWithMultipleResourcesIntentionTest.java | 27 +++++++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntention.java index 2977d6b00f05..2f6003e476ac 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntention.java @@ -61,6 +61,10 @@ public class SplitTryWithMultipleResourcesIntention extends Intention { for (PsiCatchSection catchSection : catchSections) { newTryStatementText.append(catchSection.getText()); } + final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); + if (finallyBlock != null) { + newTryStatementText.append("finally").append(finallyBlock.getText()); + } PsiReplacementUtil.replaceStatement(tryStatement, newTryStatementText.toString()); } } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/TryWithMultipleResourcesPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/TryWithMultipleResourcesPredicate.java index 6e2b34ea0a5f..6643f47cf285 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/TryWithMultipleResourcesPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/TryWithMultipleResourcesPredicate.java @@ -42,10 +42,6 @@ class TryWithMultipleResourcesPredicate implements PsiElementPredicate { return false; } final PsiTryStatement tryStatement = (PsiTryStatement)parent; - final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); - if (finallyBlock != null) { - return false; - } final PsiResourceList resourceList = tryStatement.getResourceList(); if (resourceList == null) { return false; diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntentionTest.java index 8507e8666f9b..505c0c5f4a62 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntentionTest.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntentionTest.java @@ -73,6 +73,33 @@ public class SplitTryWithMultipleResourcesIntentionTest extends IPPTestCase { "}"); } + public void testWithFinally() { + doTest( + "import java.io.*;\n" + + "class C {\n" + + " void foo(File file1, File file2) throws IOException {\n" + + " /*_Split 'try' statement with multiple resources*/try (FileInputStream in = new FileInputStream(file1); FileOutputStream out = new FileOutputStream(file2)) {\n" + + " System.out.println(in + \", \" + out);\n" + + " } finally {\n" + + " System.out.println();\n" + + " }\n" + + " }\n" + + "}", + + "import java.io.*;\n" + + "class C {\n" + + " void foo(File file1, File file2) throws IOException {\n" + + " try (FileInputStream in = new FileInputStream(file1)) {\n" + + " try (FileOutputStream out = new FileOutputStream(file2)) {\n" + + " System.out.println(in + \", \" + out);\n" + + " }\n" + + " } finally {\n" + + " System.out.println();\n" + + " }\n" + + " }\n" + + "}"); + } + public void testMixedResources() { doTest( "import java.io.*;\n" + From d154f3b8e9118331f641e7fc2e8490597425ea27 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 19 Sep 2015 22:38:31 +0200 Subject: [PATCH 022/138] reuse duplicate resolve context psi anchors in java symbol cache --- .../source/resolve/SymbolCollectingProcessor.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java index 8a1f32ce83f4..642cbe6fcd79 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java @@ -26,6 +26,7 @@ import com.intellij.psi.scope.JavaScopeProcessorEvent; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.util.containers.MostlySingularMultiMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author max @@ -33,6 +34,7 @@ import org.jetbrains.annotations.NotNull; public class SymbolCollectingProcessor extends BaseScopeProcessor implements ElementClassHint { private final MostlySingularMultiMap myResult = new MostlySingularMultiMap(); private PsiElement myCurrentFileContext = null; + private PsiAnchor myCurrentContextAnchor = null; @Override public T getHint(@NotNull Key hintKey) { @@ -47,6 +49,7 @@ public class SymbolCollectingProcessor extends BaseScopeProcessor implements Ele public void handleEvent(@NotNull PsiScopeProcessor.Event event, Object associated) { if (event == JavaScopeProcessorEvent.SET_CURRENT_FILE_CONTEXT) { myCurrentFileContext = (PsiElement)associated; + myCurrentContextAnchor = null; } } @@ -56,7 +59,11 @@ public class SymbolCollectingProcessor extends BaseScopeProcessor implements Ele PsiNamedElement named = (PsiNamedElement)element; String name = named.getName(); if (name != null) { - myResult.add(name, new ResultWithContext(named, myCurrentFileContext)); + PsiAnchor context = myCurrentContextAnchor; + if (context == null && myCurrentFileContext != null) { + myCurrentContextAnchor = context = PsiAnchor.create(myCurrentFileContext); + } + myResult.add(name, new ResultWithContext(named, context)); } } return true; @@ -75,9 +82,9 @@ public class SymbolCollectingProcessor extends BaseScopeProcessor implements Ele private final PsiAnchor myElement; private final PsiAnchor myFileContext; - public ResultWithContext(@NotNull PsiNamedElement element, PsiElement fileContext) { + public ResultWithContext(@NotNull PsiNamedElement element, @Nullable PsiAnchor fileContext) { myElement = PsiAnchor.create(element); - myFileContext = fileContext == null ? null : PsiAnchor.create(fileContext); + myFileContext = fileContext; } @NotNull From 46b675cf914331975556cb18132319d95ba8a809 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 19 Sep 2015 22:40:01 +0200 Subject: [PATCH 023/138] reduce stub-based PsiAnchor size by removing debug info that has well served its purpose --- .../src/com/intellij/psi/PsiAnchor.java | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java index 635754871769..e99ef0920388 100644 --- a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java +++ b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java @@ -38,7 +38,6 @@ import com.intellij.psi.stubs.StubElement; import com.intellij.psi.stubs.StubTree; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IStubFileElementType; -import com.intellij.psi.util.PsiModificationTracker; import com.intellij.psi.util.PsiUtilCore; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -456,8 +455,6 @@ public abstract class PsiAnchor { private final int myIndex; private final Language myLanguage; private final IStubElementType myElementType; - private final short myCreationModCount; - private final short myCreationStamp; private StubIndexReference(@NotNull final PsiFile file, final int index, @NotNull Language language, IStubElementType elementType) { myLanguage = language; @@ -465,16 +462,6 @@ public abstract class PsiAnchor { myVirtualFile = file.getVirtualFile(); myProject = file.getProject(); myIndex = index; - myCreationModCount = getModCount(); - myCreationStamp = (short)file.getModificationStamp(); - } - - private short getModCount() { - final PsiModificationTracker tracker = PsiManager.getInstance(getProject()).getModificationTracker(); - if (myVirtualFile.getName().endsWith(".java")) { - return (short)tracker.getJavaStructureModificationCount(); - } - return (short)tracker.getModificationCount(); } @Override @@ -521,11 +508,10 @@ public abstract class PsiAnchor { } catch (AssertionError e) { String msg = e.getMessage(); - msg += "\n current (java)modCount=" + getModCount() + "; creation (java)modCount=" + myCreationModCount; if (file == null) { msg += "\n no PSI file"; } else { - msg += "\n current file stamp=" + (short)file.getModificationStamp() + "; creation file stamp=" + myCreationStamp; + msg += "\n current file stamp=" + (short)file.getModificationStamp(); } final Document document = FileDocumentManager.getInstance().getCachedDocument(myVirtualFile); if (document != null) { From 5cc1fca47c3b85356aff06c5afb7bcc0d4146002 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Sep 2015 08:05:44 +0200 Subject: [PATCH 024/138] pass containingFile to smart pointer factories --- .../ImplicitVariableElementInfoFactory.java | 9 +++++---- .../impl/smartPointers/ImportListElementInfoFactory.java | 7 ++++--- .../psi/impl/smartPointers/AnchorElementInfoFactory.java | 5 ++--- .../smartPointers/SmartPointerElementInfoFactory.java | 7 ++++--- .../impl/smartPointers/SmartPsiElementPointerImpl.java | 2 +- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java index 29da83455ee1..a52f6b467f75 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java @@ -19,16 +19,17 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Segment; import com.intellij.psi.ImplicitVariable; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.PsiIdentifier; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class ImplicitVariableElementInfoFactory implements SmartPointerElementInfoFactory { +public class ImplicitVariableElementInfoFactory extends SmartPointerElementInfoFactory { @Override @Nullable - public SmartPointerElementInfo createElementInfo(@NotNull final PsiElement element) { - if (element instanceof ImplicitVariable && element.isValid()) { - return new ImplicitVariableInfo((ImplicitVariable) element, element.getProject()); + public SmartPointerElementInfo createElementInfo(@NotNull final PsiElement element, @NotNull PsiFile containingFile) { + if (element instanceof ImplicitVariable) { + return new ImplicitVariableInfo((ImplicitVariable) element, containingFile.getProject()); } return null; } diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java index b2c76903ae03..2677ec64de8a 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java @@ -16,17 +16,18 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.PsiImportList; import com.intellij.psi.PsiJavaFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class ImportListElementInfoFactory implements SmartPointerElementInfoFactory { +public class ImportListElementInfoFactory extends SmartPointerElementInfoFactory { @Override @Nullable - public SmartPointerElementInfo createElementInfo(@NotNull final PsiElement element) { + public SmartPointerElementInfo createElementInfo(@NotNull final PsiElement element, @NotNull PsiFile containingFile) { if (element instanceof PsiImportList) { - return new ImportListInfo((PsiJavaFile)element.getContainingFile()); + return new ImportListInfo((PsiJavaFile)containingFile); } return null; } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java index 4c45d1ceed16..a58a58e4aa9b 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java @@ -29,11 +29,10 @@ import com.intellij.psi.util.PsiUtilCore; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class AnchorElementInfoFactory implements SmartPointerElementInfoFactory { +public class AnchorElementInfoFactory extends SmartPointerElementInfoFactory { @Override @Nullable - public SmartPointerElementInfo createElementInfo(@NotNull PsiElement element) { - PsiFile containingFile = element.getContainingFile(); + public SmartPointerElementInfo createElementInfo(@NotNull PsiElement element, @NotNull PsiFile containingFile) { if (element instanceof StubBasedPsiElement && containingFile instanceof PsiFileWithStubSupport) { PsiFileWithStubSupport stubFile = (PsiFileWithStubSupport)containingFile; StubTree stubTree = stubFile.getStubTree(); diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfoFactory.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfoFactory.java index 0cc69adb1972..55047f44f9f3 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfoFactory.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfoFactory.java @@ -18,15 +18,16 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * @author yole */ -public interface SmartPointerElementInfoFactory { - ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.smartPointerElementInfoFactory"); +public abstract class SmartPointerElementInfoFactory { + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.smartPointerElementInfoFactory"); @Nullable - SmartPointerElementInfo createElementInfo(@NotNull PsiElement element); + public abstract SmartPointerElementInfo createElementInfo(@NotNull PsiElement element, @NotNull PsiFile containingFile); } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java index e19b364f3cc3..6a0260d5c6f0 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java @@ -183,7 +183,7 @@ class SmartPsiElementPointerImpl implements SmartPointerEx } for(SmartPointerElementInfoFactory factory: Extensions.getExtensions(SmartPointerElementInfoFactory.EP_NAME)) { - final SmartPointerElementInfo result = factory.createElementInfo(element); + final SmartPointerElementInfo result = factory.createElementInfo(element, containingFile); if (result != null) return result; } From 1a2eb1741476d35c1c09756301568398e8a38234 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Sep 2015 08:07:56 +0200 Subject: [PATCH 025/138] don't hold all PsiFile's with found references during find usages --- .../intellij/psi/search/searches/ReferenceDescriptor.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/indexing-api/src/com/intellij/psi/search/searches/ReferenceDescriptor.java b/platform/indexing-api/src/com/intellij/psi/search/searches/ReferenceDescriptor.java index 153b34b8a46b..64fd476aaa16 100644 --- a/platform/indexing-api/src/com/intellij/psi/search/searches/ReferenceDescriptor.java +++ b/platform/indexing-api/src/com/intellij/psi/search/searches/ReferenceDescriptor.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.search.searches; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; @@ -31,13 +32,13 @@ public class ReferenceDescriptor { public ReferenceDescriptor fun(PsiReference psiReference) { final PsiElement element = psiReference.getElement(); final PsiFile file = element.getContainingFile(); - return new ReferenceDescriptor(file, element.getTextRange().getStartOffset() + psiReference.getRangeInElement().getStartOffset()); + return new ReferenceDescriptor(file.getViewProvider().getVirtualFile(), element.getTextRange().getStartOffset() + psiReference.getRangeInElement().getStartOffset()); } }; - private final PsiFile file; + private final VirtualFile file; private final int offset; - private ReferenceDescriptor(@NotNull PsiFile file, int offset) { + private ReferenceDescriptor(@NotNull VirtualFile file, int offset) { this.file = file; this.offset = offset; } From a3c6cc39422bac0bce7c354e1561f6a46419208b Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Sep 2015 08:14:51 +0200 Subject: [PATCH 026/138] don't leak PSI via GroovyPsiManager.myCompileStatic --- .../plugins/groovy/lang/psi/impl/GroovyPsiManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiManager.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiManager.java index d0fd0c22c8fe..a2b367459739 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiManager.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiManager.java @@ -61,7 +61,7 @@ public class GroovyPsiManager { private final Map myArrayClass = new HashMap(); private final ConcurrentMap myCalculatedTypes = ContainerUtil.createConcurrentWeakMap(); - private final ConcurrentMap myCompileStatic = ContainerUtil.newConcurrentMap(); + private final ConcurrentMap myCompileStatic = ContainerUtil.createConcurrentWeakMap(); private static final RecursionGuard ourGuard = RecursionManager.createGuard("groovyPsiManager"); From 97e4a9a550263ab2abb6b9cd343f1713b1b4ef6c Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Sep 2015 08:18:44 +0200 Subject: [PATCH 027/138] cache groovy dgm methods per scope --- .../groovy/dgm/DGMMemberContributor.java | 77 +++++++++++-------- 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dgm/DGMMemberContributor.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dgm/DGMMemberContributor.java index e265644d9191..53e05009bcfc 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dgm/DGMMemberContributor.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dgm/DGMMemberContributor.java @@ -17,17 +17,19 @@ package org.jetbrains.plugins.groovy.dgm; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Couple; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiType; -import com.intellij.psi.ResolveState; +import com.intellij.psi.*; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import com.intellij.psi.util.PsiModificationTracker; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor; import java.util.List; +import java.util.concurrent.ConcurrentMap; /** * Provides members from extension classes referenced in {@code META-INF/services/org.codehaus.groovy.runtime.ExtensionModule}. @@ -40,34 +42,49 @@ public class DGMMemberContributor extends NonCodeMembersContributor { @NotNull PsiScopeProcessor processor, @NotNull PsiElement place, @NotNull ResolveState state) { - Project project = place.getProject(); - GlobalSearchScope resolveScope = place.getResolveScope(); - GroovyPsiManager groovyPsiManager = GroovyPsiManager.getInstance(project); + final Project project = place.getProject(); - Couple> extensions = GroovyExtensionProvider.getInstance(project).collectExtensions(resolveScope); - - List instanceCategories = extensions.getFirst(); - List staticCategories = extensions.getSecond(); - - if (!processCategories(qualifierType, processor, state, project, resolveScope, groovyPsiManager, instanceCategories, false)) return; - if (!processCategories(qualifierType, processor, state, project, resolveScope, groovyPsiManager, staticCategories, true)) return; - } - - private static boolean processCategories(PsiType qualifierType, - PsiScopeProcessor processor, - @NotNull ResolveState state, - Project project, - GlobalSearchScope resolveScope, - GroovyPsiManager groovyPsiManager, List instanceCategories, - boolean isStatic) { - for (String category : instanceCategories) { - PsiClass clazz = groovyPsiManager.findClassWithCache(category, resolveScope); - if (clazz != null) { - if (!GdkMethodHolder.getHolderForClass(clazz, isStatic, resolveScope).processMethods(processor, state, qualifierType, project)) { - return false; + ConcurrentMap> map = CachedValuesManager.getManager(project).getCachedValue( + project, new CachedValueProvider>>() { + @Nullable + @Override + public Result>> compute() { + ConcurrentMap> value = ContainerUtil.createConcurrentSoftValueMap(); + return Result.create(value, PsiModificationTracker.MODIFICATION_COUNT); } + }); + + GlobalSearchScope scope = place.getResolveScope(); + List gdkMethods = map.get(scope); + if (gdkMethods == null) { + map.put(scope, gdkMethods = calcGdkMethods(project, scope)); + } + + for (GdkMethodHolder holder : gdkMethods) { + if (!holder.processMethods(processor, state, qualifierType, project)) { + return; } } - return true; + } + + @NotNull + private static List calcGdkMethods(Project project, GlobalSearchScope resolveScope) { + List gdkMethods = ContainerUtil.newArrayList(); + + JavaPsiFacade facade = JavaPsiFacade.getInstance(project); + Couple> extensions = GroovyExtensionProvider.getInstance(project).collectExtensions(resolveScope); + for (String category : extensions.getFirst()) { + PsiClass clazz = facade.findClass(category, resolveScope); + if (clazz != null) { + gdkMethods.add(GdkMethodHolder.getHolderForClass(clazz, false, resolveScope)); + } + } + for (String category : extensions.getSecond()) { + PsiClass clazz = facade.findClass(category, resolveScope); + if (clazz != null) { + gdkMethods.add(GdkMethodHolder.getHolderForClass(clazz, true, resolveScope)); + } + } + return gdkMethods; } } From 176c131753121756dda88a955ae4b73f04599029 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Sep 2015 09:01:56 +0200 Subject: [PATCH 028/138] add API method PsiDocumentManager.getLastCommittedDocument(PsiFile) --- .../src/com/intellij/psi/PsiDocumentManager.java | 11 +++++++++++ .../com/intellij/psi/impl/PsiDocumentManagerBase.java | 7 +++++++ .../src/com/intellij/mock/MockPsiDocumentManager.java | 6 ++++++ 3 files changed, 24 insertions(+) diff --git a/platform/core-api/src/com/intellij/psi/PsiDocumentManager.java b/platform/core-api/src/com/intellij/psi/PsiDocumentManager.java index 36299685bc51..7ae80097923f 100644 --- a/platform/core-api/src/com/intellij/psi/PsiDocumentManager.java +++ b/platform/core-api/src/com/intellij/psi/PsiDocumentManager.java @@ -125,6 +125,17 @@ public abstract class PsiDocumentManager { */ public abstract long getLastCommittedStamp(@NotNull Document document); + /** + * Returns the document for specified PsiFile intended to be used when working with committed PSI, e.g. outside dispatch thread. + * @param file the file for which the document is requested. + * @return an immutable document corresponding to the current PSI state. For committed documents, the contents and timestamp are equal to + * the ones of {@link #getDocument(PsiFile)}. For uncommitted documents, the text is {@link #getLastCommittedText(Document)} and + * the modification stamp is {@link #getLastCommittedStamp(Document)}. + * @since 143.* builds + */ + @Nullable + public abstract Document getLastCommittedDocument(@NotNull PsiFile file); + /** * Returns the list of documents which have been modified but not committed. * diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java index 6422e6203f1d..2180454bc6c5 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java @@ -578,6 +578,13 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen return getLastCommittedDocument(document).getModificationStamp(); } + @Override + @Nullable + public Document getLastCommittedDocument(@NotNull PsiFile file) { + Document document = getDocument(file); + return document == null ? null : getLastCommittedDocument(document); + } + @NotNull public DocumentEx getLastCommittedDocument(@NotNull Document document) { if (document instanceof FrozenDocument) return (DocumentEx)document; diff --git a/platform/testFramework/src/com/intellij/mock/MockPsiDocumentManager.java b/platform/testFramework/src/com/intellij/mock/MockPsiDocumentManager.java index 1318032fdcb6..3c655748bc71 100644 --- a/platform/testFramework/src/com/intellij/mock/MockPsiDocumentManager.java +++ b/platform/testFramework/src/com/intellij/mock/MockPsiDocumentManager.java @@ -67,6 +67,12 @@ public class MockPsiDocumentManager extends PsiDocumentManager { return document.getModificationStamp(); } + @Nullable + @Override + public Document getLastCommittedDocument(@NotNull PsiFile file) { + return null; + } + @Override @NotNull public Document[] getUncommittedDocuments() { From bdd2371e2594029c78200013a6ef7d4e4816ed97 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Sat, 19 Sep 2015 20:54:31 +0200 Subject: [PATCH 029/138] cleanup --- .../impl/JavaScratchRunConfigurationExtension.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java b/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java index d8c1a40a14bb..f0a17365a9b5 100644 --- a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java +++ b/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java @@ -43,13 +43,6 @@ import org.jetbrains.annotations.Nullable; import java.io.File; - -/* -execution-impl -> lang-impl(scratches are here) -compiler-impl -> lang-impl - -java-impl ->execution-impl, compiler-impl - */ public class JavaScratchRunConfigurationExtension extends RunConfigurationExtension{ private static final Key SCRATCH_FILE_ID = Key.create("_scratch_file_id_"); From de535511f8e12a25f923a89d936a87330fd60e86 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 21 Sep 2015 09:52:32 +0200 Subject: [PATCH 030/138] configure limited resolve scope for out-of-sources java classes via ResolveScopeProvider instead of hacking PsiJavaFileImpl (IDEA-143728) --- .../JavaOutOfSourcesResolveScopeProvider.java | 49 +++++++++++++++++++ .../psi/impl/source/PsiJavaFileImpl.java | 18 ------- resources/src/META-INF/IdeaPlugin.xml | 1 + 3 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaOutOfSourcesResolveScopeProvider.java diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaOutOfSourcesResolveScopeProvider.java b/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaOutOfSourcesResolveScopeProvider.java new file mode 100644 index 000000000000..a3e9e87f3a4c --- /dev/null +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaOutOfSourcesResolveScopeProvider.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ +package com.intellij.psi.impl.file.impl; + +import com.intellij.lang.java.JavaLanguage; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.LanguageFileType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.ResolveScopeProvider; +import com.intellij.psi.search.GlobalSearchScope; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Limited resolve scope for all java files in module content, but not under source roots. + * For example, java files from test data. + * There is still a possibility to modify this scope choice with the ResolveScopeEnlarger. + */ +public class JavaOutOfSourcesResolveScopeProvider extends ResolveScopeProvider { + @Nullable + @Override + public GlobalSearchScope getResolveScope(@NotNull VirtualFile file, Project project) { + // For java only! For other languages resolve may be implemented with different rules, requiring larger scope. + final FileType type = file.getFileType(); + if (type instanceof LanguageFileType && ((LanguageFileType)type).getLanguage() == JavaLanguage.INSTANCE) { + ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex(); + if (index.isInContent(file) && !index.isInSource(file)) { + return GlobalSearchScope.fileScope(project, file); + } + } + return null; + } +} diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileImpl.java index e56f53cbfbdf..97b43b4db570 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileImpl.java @@ -16,14 +16,9 @@ package com.intellij.psi.impl.source; import com.intellij.ide.highlighter.JavaFileType; -import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.roots.FileIndexFacade; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.FileViewProvider; import com.intellij.psi.impl.java.stubs.JavaStubElementTypes; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.testFramework.LightVirtualFile; import org.jetbrains.annotations.NotNull; public class PsiJavaFileImpl extends PsiJavaFileBaseImpl { @@ -31,19 +26,6 @@ public class PsiJavaFileImpl extends PsiJavaFileBaseImpl { super(JavaStubElementTypes.JAVA_FILE, JavaStubElementTypes.JAVA_FILE, file); } - @NotNull - @Override - public GlobalSearchScope getResolveScope() { - final VirtualFile file = getVirtualFile(); - if (file != null && !(file instanceof LightVirtualFile)) { - final FileIndexFacade index = ServiceManager.getService(getProject(), FileIndexFacade.class); - if (!index.isInSource(file) && !index.isInLibraryClasses(file)) { - return GlobalSearchScope.fileScope(this); - } - } - return super.getResolveScope(); - } - @Override @NotNull public FileType getFileType() { diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index dc491169370d..f4ee697a1045 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -1548,6 +1548,7 @@ + From ebbf81061ede265840a20a04af951fdb2a6300e1 Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Mon, 21 Sep 2015 12:05:18 +0300 Subject: [PATCH 031/138] IllegalStateException fix --- .../com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index 3eda40a485ee..10dba93165a8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -2583,7 +2583,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } public boolean isShowStripeButton(String id) { - checkId(id); - return getInfo(id).isShowStripeButton(); + WindowInfoImpl info = getInfo(id); + return info == null || info.isShowStripeButton(); } } From a79d5171e07b617d9b20ffb99aa44fc86a793464 Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Mon, 21 Sep 2015 12:25:03 +0300 Subject: [PATCH 032/138] UIInspector: set correct text string in the tree cell renderer component. --- .../intellij/internal/inspector/UiInspectorAction.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorAction.java b/platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorAction.java index 65c1c14861ae..c4c18045e9ea 100644 --- a/platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorAction.java +++ b/platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorAction.java @@ -302,6 +302,7 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { if (component.isDoubleBuffered()) { append(", double-buffered", SimpleTextAttributes.GRAYED_ATTRIBUTES); } + componentNode.setText(toString()); setIcon(new TwoColorsIcon(11, component.getForeground(), component.getBackground())); } @@ -366,6 +367,7 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { private static class ComponentNode extends DefaultMutableTreeNode { private final Component myComponent; + String myText; private ComponentNode(@NotNull Component component) { super(component); @@ -379,7 +381,11 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { @Override public String toString() { - return myComponent.getClass().getName(); + return myText != null ? myText : myComponent.getClass().getName(); + } + + public void setText(String value) { + myText = value; } @Override From da6505fd208aae3ba8ff762d13bb77b9cb8000f3 Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Mon, 21 Sep 2015 12:44:23 +0300 Subject: [PATCH 033/138] IDEA-145149 [follow-up]: remove extra spaces from the accessible name. --- .../src/com/intellij/ui/SimpleColoredComponent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java index b65b8a8836f6..1a2587543d99 100644 --- a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java +++ b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java @@ -1033,7 +1033,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible, Co private class MyAccessibleContext extends JComponent.AccessibleJComponent { @Override public String getAccessibleName() { - return StringUtil.join(myFragments, " "); + return SimpleColoredComponent.this.toString(); } } From 8fa4467182073895fe1d16b3563dfc89184e58eb Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Mon, 21 Sep 2015 12:59:01 +0300 Subject: [PATCH 034/138] Minor change (cleanup) --- .../options/colors/ColorAndFontDescriptionPanel.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontDescriptionPanel.java b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontDescriptionPanel.java index 983677cb4b42..3f21ca9344aa 100644 --- a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontDescriptionPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontDescriptionPanel.java @@ -23,10 +23,7 @@ import com.intellij.openapi.options.colors.AttributesDescriptor; import com.intellij.openapi.options.colors.ColorSettingsPage; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Pair; -import com.intellij.ui.CollectionComboBoxModel; -import com.intellij.ui.ColorPanel; -import com.intellij.ui.HyperlinkAdapter; -import com.intellij.ui.ListCellRendererWrapper; +import com.intellij.ui.*; import com.intellij.ui.components.JBCheckBox; import com.intellij.util.FontUtil; import com.intellij.util.containers.ContainerUtil; @@ -152,7 +149,7 @@ public class ColorAndFontDescriptionPanel extends JPanel { colorPanel.setSelectedColor(color); } else { - colorPanel.setSelectedColor(Color.white); + colorPanel.setSelectedColor(JBColor.WHITE); } colorPanel.setEnabled(isChecked); } From d5990f5f02075d366940669fa623e14867c1ea41 Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Mon, 21 Sep 2015 13:30:41 +0300 Subject: [PATCH 035/138] Fix a bug with 'read-only scheme' message when text attribute selection changes --- .../colors/ColorAndFontDescriptionPanel.java | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontDescriptionPanel.java b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontDescriptionPanel.java index 3f21ca9344aa..2fcf41cc7901 100644 --- a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontDescriptionPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontDescriptionPanel.java @@ -28,6 +28,7 @@ import com.intellij.ui.components.JBCheckBox; import com.intellij.util.FontUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -35,8 +36,8 @@ import javax.swing.event.HyperlinkEvent; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.Collections; -import java.util.Map; +import java.util.*; +import java.util.List; /** * @author cdr @@ -67,6 +68,7 @@ public class ColorAndFontDescriptionPanel extends JPanel { myEffectsMap = Collections.unmodifiableMap(map); } private JComboBox myEffectsCombo; + private final EffectsComboModel myEffectsModel; private JBCheckBox myCbBold; private JBCheckBox myCbItalic; @@ -80,7 +82,10 @@ public class ColorAndFontDescriptionPanel extends JPanel { add(myPanel, BorderLayout.CENTER); setBorder(BorderFactory.createEmptyBorder(4, 0, 4, 4)); - myEffectsCombo.setModel(new CollectionComboBoxModel(ContainerUtil.newArrayList(myEffectsMap.keySet()))); + myEffectsModel = new EffectsComboModel(ContainerUtil.newArrayList(myEffectsMap.keySet())); + //noinspection unchecked + myEffectsCombo.setModel(myEffectsModel); + //noinspection unchecked myEffectsCombo.setRenderer(new ListCellRendererWrapper() { @Override public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) { @@ -186,7 +191,7 @@ public class ColorAndFontDescriptionPanel extends JPanel { if (description.isEffectsColorEnabled() && description.isEffectsColorChecked()) { myEffectsCombo.setEnabled(true); - myEffectsCombo.getModel().setSelectedItem(ContainerUtil.reverseMap(myEffectsMap).get(effectType)); + myEffectsModel.setEffectName(ContainerUtil.reverseMap(myEffectsMap).get(effectType)); } else { myEffectsCombo.setEnabled(false); @@ -290,4 +295,20 @@ public class ColorAndFontDescriptionPanel extends JPanel { description.apply(scheme); } } + + private static class EffectsComboModel extends CollectionComboBoxModel { + public EffectsComboModel(List names) { + super(names); + } + + /** + * Set the current effect name when a text attribute selection changes without notifying the listeners since otherwise it will + * be considered as an actual change and lead to unnecessary evens including 'read-only scheme' check. + * + * @param effectName + */ + public void setEffectName(@NotNull String effectName) { + mySelection = effectName; + } + } } From a598de1a920e91e5d44daa475c3a93f761b34fe5 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 21 Sep 2015 13:36:43 +0300 Subject: [PATCH 036/138] [platform] LC_CTYPE added to a shell environment if missing (IDEA-121713) --- .../com/intellij/util/EnvironmentUtil.java | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/platform/util/src/com/intellij/util/EnvironmentUtil.java b/platform/util/src/com/intellij/util/EnvironmentUtil.java index 7cb0a5216335..2f5b853e07a3 100644 --- a/platform/util/src/com/intellij/util/EnvironmentUtil.java +++ b/platform/util/src/com/intellij/util/EnvironmentUtil.java @@ -24,6 +24,7 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.util.concurrency.FixedFuture; import com.intellij.util.text.CaseInsensitiveStringHashingStrategy; import gnu.trove.THashMap; @@ -32,6 +33,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import java.io.File; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -43,6 +45,10 @@ public class EnvironmentUtil { private static final int SHELL_ENV_READING_TIMEOUT = 20000; + private static final String LANG = "LANG"; + private static final String LC_ALL = "LC_ALL"; + private static final String LC_CTYPE = "LC_CTYPE"; + private static final Future> ourEnvGetter; static { if (SystemInfo.isMac && "unlocked".equals(System.getProperty("__idea.mac.env.lock")) && Registry.is("idea.fix.mac.env")) { @@ -50,7 +56,7 @@ public class EnvironmentUtil { ourEnvGetter = executor.submit(new Callable>() { @Override public Map call() throws Exception { - return getShellEnv(); + return setCharsetVar(getShellEnv()); } }); executor.shutdown(); @@ -97,9 +103,13 @@ public class EnvironmentUtil { * On Mac OS X things are complicated.
* An app launched by a GUI launcher (Finder, Dock, Spotlight etc.) receives a pretty empty and useless environment, * since standard Unix ways of setting variables via e.g. ~/.profile do not work. What's more important, there are no - * sane alternatives. This causes a lot of user complains about tools working in a terminal not working when launched + * sane alternatives. This causes a lot of user complaints about tools working in a terminal not working when launched * from the IDE. To ease their pain, the IDE loads a shell environment (see {@link #getShellEnv()} for gory details) - * and returns it as the result. + * and returns it as the result.
+ * And one more thing (c): locale variables on OS X are usually set by a terminal app - meaning they are missing + * even from a shell environment above. This again causes user complaints about tools being unable to output anything + * outside ASCII range when launched from the IDE. Resolved by adding LC_CTYPE variable to the map if it doesn't contain + * explicitly set locale variables (LANG/LC_ALL/LC_CTYPE). See {@link #setCharsetVar(Map)} for details. * * @return unmodifiable map of the process environment. */ @@ -230,6 +240,22 @@ public class EnvironmentUtil { return null; } + private static Map setCharsetVar(@NotNull Map env) { + if (!isCharsetVarDefined(env)) { + Locale locale = Locale.getDefault(); + Charset charset = CharsetToolkit.getDefaultSystemCharset(); + String language = locale.getLanguage(); + String country = locale.getCountry(); + String value = (language.isEmpty() || country.isEmpty() ? "en_US" : language + '_' + country) + '.' + charset.name(); + env.put(LC_CTYPE, value); + } + return env; + } + + private static boolean isCharsetVarDefined(@NotNull Map env) { + return !env.isEmpty() && (env.containsKey(LANG) || env.containsKey(LC_ALL) || env.containsKey(LC_CTYPE)); + } + public static void inlineParentOccurrences(@NotNull Map envs) { Map parentParams = new HashMap(System.getenv()); for (Map.Entry entry : envs.entrySet()) { From 02aa3a4ce0baf3ef715039ab495e436895dd9eda Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Mon, 21 Sep 2015 13:52:49 +0300 Subject: [PATCH 037/138] IDEA-145308 ExpandedItemRendererComponentWrapper is broken --- .../intellij/ui/ExpandedItemRendererComponentWrapper.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/ExpandedItemRendererComponentWrapper.java b/platform/platform-api/src/com/intellij/ui/ExpandedItemRendererComponentWrapper.java index b743d444157a..0c7996b3573b 100644 --- a/platform/platform-api/src/com/intellij/ui/ExpandedItemRendererComponentWrapper.java +++ b/platform/platform-api/src/com/intellij/ui/ExpandedItemRendererComponentWrapper.java @@ -47,15 +47,16 @@ public class ExpandedItemRendererComponentWrapper extends JComponent { public static ExpandedItemRendererComponentWrapper wrap(@NotNull Component rendererComponent) { if (rendererComponent instanceof Accessible) { - return new MyAccessibleComponent((Accessible)rendererComponent); + return new MyAccessibleComponent(rendererComponent, (Accessible)rendererComponent); } return new ExpandedItemRendererComponentWrapper(rendererComponent); } private static class MyAccessibleComponent extends ExpandedItemRendererComponentWrapper implements Accessible { private Accessible myAccessible; - MyAccessibleComponent(Accessible comp) { - myAccessible = comp; + MyAccessibleComponent(@NotNull Component comp, @NotNull Accessible accessible) { + super(comp); + myAccessible = accessible; } @Override public AccessibleContext getAccessibleContext() { From ee08149ae219ef678d6b09544835249c916df087 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 21 Sep 2015 14:03:50 +0300 Subject: [PATCH 038/138] diff: do not share JPanels among viewers * fix project leak in tests --- .../intellij/diff/merge/TextMergeTool.java | 2 +- .../tools/binary/OnesideBinaryDiffViewer.java | 2 +- .../tools/binary/TwosideBinaryDiffViewer.java | 6 +-- .../tools/fragmented/UnifiedDiffViewer.java | 2 +- .../diff/tools/simple/SimpleDiffViewer.java | 6 +-- .../simple/SimpleThreesideDiffViewer.java | 4 +- .../diff/tools/util/DiffNotifications.java | 51 ++++++++++++++----- 7 files changed, 50 insertions(+), 23 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java index 4bef4e6374d2..b4c332bbdabe 100644 --- a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java +++ b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java @@ -417,7 +417,7 @@ public class TextMergeTool implements MergeTool { return apply(mergeFragments, outputModificationStamp); } catch (DiffTooBigException e) { - return applyNotification(DiffNotifications.DIFF_TOO_BIG); + return applyNotification(DiffNotifications.createDiffTooBig()); } catch (ProcessCanceledException e) { throw e; diff --git a/platform/diff-impl/src/com/intellij/diff/tools/binary/OnesideBinaryDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/binary/OnesideBinaryDiffViewer.java index 685244df70d9..faad7f9b8ff7 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/binary/OnesideBinaryDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/binary/OnesideBinaryDiffViewer.java @@ -43,7 +43,7 @@ public class OnesideBinaryDiffViewer extends OnesideDiffViewer() { @@ -98,14 +98,14 @@ public class TwosideBinaryDiffViewer extends TwosideDiffViewer Date: Mon, 21 Sep 2015 14:32:28 +0300 Subject: [PATCH 039/138] IDEA-145356 activity in a Scratch window triggers auto-refresh of tests --- .../execution/testframework/autotest/AutoTestManager.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java index bcd0388cb4bd..e21f36f4d913 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java @@ -26,6 +26,7 @@ import com.intellij.execution.runners.ExecutionUtil; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.ui.RunContentManager; import com.intellij.ide.DataManager; +import com.intellij.ide.scratch.ScratchFileService; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.application.ApplicationManager; @@ -79,6 +80,9 @@ public class AutoTestManager { }, new Condition() { @Override public boolean value(VirtualFile file) { + if (ScratchFileService.getInstance().getRootType(file) != null) { + return false; + } // Vladimir.Krivosheev - I don't know, why AutoTestManager checks it, but old behavior is preserved return FileEditorManager.getInstance(myProject).isFileOpen(file); } From 78f3b1c5b6eb5073864f8ede3b53fdca0916dcdb Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Mon, 21 Sep 2015 14:34:15 +0300 Subject: [PATCH 040/138] filter out project configuration files silently --- .../src/com/intellij/execution/DelayedDocumentWatcher.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java index 1a573cd5b663..787d60fbdaeb 100644 --- a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java +++ b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java @@ -26,6 +26,7 @@ import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectCoreUtil; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; @@ -128,7 +129,9 @@ public class DelayedDocumentWatcher { return; } if (!myChangedFiles.contains(file)) { - // optimization: if possible, avoid possible expensive 'myChangedFileFilter.value(file)' call + if (ProjectCoreUtil.isProjectOrWorkspaceFile(file)) { + return; + } if (myChangedFileFilter != null && !myChangedFileFilter.value(file)) { return; } From 6159e94bdf7f30ccc67aa9d0023d30965343669f Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Mon, 21 Sep 2015 13:25:55 +0300 Subject: [PATCH 041/138] Do not expand indents for group of blocks with smart indent, if each one of them has no linefeed before, and block going right after group has linefeed and has smaller indent than any new line children of any block in the group. This will prevent from inserting double continuation indents when it is not needed (see tests) --- ...ormatterMultilineMethodCallParamsTest.java | 27 ++++++++++++- .../intellij/formatting/FormatProcessor.java | 40 +++++++++++++++++-- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterMultilineMethodCallParamsTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterMultilineMethodCallParamsTest.java index d80b29c25191..1596c605d986 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterMultilineMethodCallParamsTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterMultilineMethodCallParamsTest.java @@ -29,7 +29,7 @@ public class JavaFormatterMultilineMethodCallParamsTest extends AbstractJavaForm ); } - public void IGNORED_testChainedMethodInsideCall_WithRParenOnNewLine() { + public void testChainedMethodInsideCall_WithRParenOnNewLine() { doMethodTest( "call(new StringBuilder()\n" + ".append(\"aaa\")\n" + @@ -41,6 +41,31 @@ public class JavaFormatterMultilineMethodCallParamsTest extends AbstractJavaForm ");" ); } + + public void testLambdas() { + doTextTest( + "public class Main {\n" + + " public static void main(String... args) throws Exception {\n" + + " RatpackServer.start(server -> server\n" + + " .handlers(chain -> chain\n" + + " .get(ctx -> ctx.render(\"Hello World!\"))\n" + + " .get(\":name\", ctx -> ctx.render(\"Hello \" + ctx.getPathTokens().get(\"name\") + \"!\"))\n" + + " )\n" + + " );\n" + + " }\n" + + "}", + "public class Main {\n" + + " public static void main(String... args) throws Exception {\n" + + " RatpackServer.start(server -> server\n" + + " .handlers(chain -> chain\n" + + " .get(ctx -> ctx.render(\"Hello World!\"))\n" + + " .get(\":name\", ctx -> ctx.render(\"Hello \" + ctx.getPathTokens().get(\"name\") + \"!\"))\n" + + " )\n" + + " );\n" + + " }\n" + + "}" + ); + } public void testChainedMethodInsideCall_Shifted() { doMethodTest( diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java index 162f64c2008b..cc076c5d1708 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java @@ -1629,14 +1629,48 @@ public class FormatProcessor { } if (last != null) { - AbstractBlockWrapper prev = getPreviousBlock(last); - return prev != null && prev.getWhiteSpace().containsLineFeeds(); + AbstractBlockWrapper next = getNextBlock(last); + if (next != null && next.getWhiteSpace().containsLineFeeds()) { + int nextNewLineBlockIndent = next.getNumberOfSymbolsBeforeBlock().getTotalSpaces(); + if (nextNewLineBlockIndent >= finMinNewLineIndent(blocksToExpandIndent)) { + return true; + } + } } return false; } + + private int finMinNewLineIndent(@NotNull Collection wrappers) { + int totalMinimum = Integer.MAX_VALUE; + for (AbstractBlockWrapper wrapper : wrappers) { + int minNewLineIndent = findMinNewLineIndent(wrapper); + if (minNewLineIndent < totalMinimum) { + totalMinimum = minNewLineIndent; + } + } + return totalMinimum; + } - private AbstractBlockWrapper getPreviousBlock(AbstractBlockWrapper block) { + private int findMinNewLineIndent(@NotNull AbstractBlockWrapper block) { + if (block instanceof LeafBlockWrapper && block.getWhiteSpace().containsLineFeeds()) { + return block.getNumberOfSymbolsBeforeBlock().getTotalSpaces(); + } + else if (block instanceof CompositeBlockWrapper) { + List children = ((CompositeBlockWrapper)block).getChildren(); + int currentMin = Integer.MAX_VALUE; + for (AbstractBlockWrapper child : children) { + int childIndent = findMinNewLineIndent(child); + if (childIndent < currentMin) { + currentMin = childIndent; + } + } + return currentMin; + } + return Integer.MAX_VALUE; + } + + private AbstractBlockWrapper getNextBlock(AbstractBlockWrapper block) { List children = block.getParent().getChildren(); int nextBlockIndex = children.indexOf(block) + 1; if (nextBlockIndex < children.size()) { From 56669bda353f518bad8ce132a51574f63675ce13 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Sep 2015 12:50:17 +0200 Subject: [PATCH 042/138] more diagnostics for invalid lookup item sources (EA-60626 - assert: CompletionServiceImpl$CompletionResultSetImpl.addElement) --- .../codeInsight/completion/LegacyCompletionContributor.java | 4 ++++ .../codeInsight/completion/impl/CompletionServiceImpl.java | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java index 2568dca92ffe..3a71bd4129c4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java @@ -73,6 +73,10 @@ public class LegacyCompletionContributor extends CompletionContributor { completionData.completeReference(reference, lookupSet, parameters.getPosition(), parameters.getOriginalFile()); for (final LookupElement item : lookupSet) { if (resultSet.getPrefixMatcher().prefixMatches(item)) { + if (!item.isValid()) { + LOG.error(completionData + " has returned an invalid lookup element " + item + " of " + item.getClass() + + " in " + parameters.getOriginalFile() + " of " + parameters.getOriginalFile().getClass()); + } hasVariants.set(true); resultSet.addElement(item); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java index 3714449054b1..d84f431a65aa 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java @@ -125,7 +125,8 @@ public class CompletionServiceImpl extends CompletionService{ @Override public void addElement(@NotNull final LookupElement element) { if (!element.isValid()) { - LOG.error("Invalid lookup element: " + element); + LOG.error("Invalid lookup element: " + element + " of " + element.getClass() + + " in " + myParameters.getOriginalFile() + " of " + myParameters.getOriginalFile().getClass()); return; } From d36b026982859ba08dab33ddadc30c4ffafdb6a6 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Sep 2015 13:07:18 +0200 Subject: [PATCH 043/138] template language structure views: tolerate unexpected view providers (EA-61884 - assert: TemplateLanguageStructureViewBuilder.getNotNullViewProvider) --- .../TemplateLanguageStructureViewBuilder.java | 47 +++++++++---------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/impl/TemplateLanguageStructureViewBuilder.java b/platform/lang-impl/src/com/intellij/ide/structureView/impl/TemplateLanguageStructureViewBuilder.java index 849b01b703b9..c3f74727270e 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/impl/TemplateLanguageStructureViewBuilder.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/impl/TemplateLanguageStructureViewBuilder.java @@ -50,7 +50,7 @@ import java.util.List; public abstract class TemplateLanguageStructureViewBuilder implements StructureViewBuilder { private final VirtualFile myVirtualFile; private final Project myProject; - private Language myTemplateDataLanguage; + @Nullable private Language myTemplateDataLanguage; private StructureViewComposite.StructureViewDescriptor myBaseStructureViewDescriptor; private FileEditor myFileEditor; private StructureViewComposite myStructureViewComposite; @@ -59,8 +59,7 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV protected TemplateLanguageStructureViewBuilder(PsiElement psiElement) { myVirtualFile = psiElement.getContainingFile().getVirtualFile(); myProject = psiElement.getProject(); - - myTemplateDataLanguage = getNotNullViewProvider().getTemplateDataLanguage(); + myTemplateDataLanguage = getTemplateDataLanguage(); } private void updateAfterPsiChange() { @@ -69,15 +68,12 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV ApplicationManager.getApplication().runReadAction(new Runnable(){ @Override public void run() { - if (!myVirtualFile.isValid()) return; - - final TemplateLanguageFileViewProvider provider = getViewProvider(); - if (provider == null) return; + if (!myVirtualFile.isValid() || getViewProvider() == null) return; StructureViewWrapper structureViewWrapper = StructureViewFactoryEx.getInstanceEx(myProject).getStructureViewWrapper(); if (structureViewWrapper == null) return; - Language baseLanguage = provider.getTemplateDataLanguage(); + Language baseLanguage = getTemplateDataLanguage(); if (baseLanguage == myTemplateDataLanguage && (myBaseStructureViewDescriptor == null || isPsiValid(myBaseStructureViewDescriptor))) { updateBaseLanguageView(); @@ -108,18 +104,15 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV } @Nullable - private TemplateLanguageFileViewProvider getViewProvider() { - final FileViewProvider provider = PsiManager.getInstance(myProject).findViewProvider(myVirtualFile); - return provider instanceof TemplateLanguageFileViewProvider ? (TemplateLanguageFileViewProvider)provider : null; + private FileViewProvider getViewProvider() { + return PsiManager.getInstance(myProject).findViewProvider(myVirtualFile); } - @NotNull - private TemplateLanguageFileViewProvider getNotNullViewProvider() { - final FileViewProvider provider = PsiManager.getInstance(myProject).findViewProvider(myVirtualFile); - if (provider == null || !(provider instanceof TemplateLanguageFileViewProvider)) { - throw new AssertionError("Not a template view provider for " + myVirtualFile + ": " + provider); - } - return (TemplateLanguageFileViewProvider)provider; + @Nullable + private Language getTemplateDataLanguage() { + FileViewProvider provider = getViewProvider(); + return provider instanceof TemplateLanguageFileViewProvider + ? ((TemplateLanguageFileViewProvider)provider).getTemplateDataLanguage() : null; } private void updateBaseLanguageView() { @@ -165,13 +158,13 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV public StructureView createStructureView(FileEditor fileEditor, @NotNull Project project) { myFileEditor = fileEditor; List viewDescriptors = new ArrayList(); - final TemplateLanguageFileViewProvider provider = getNotNullViewProvider(); + final FileViewProvider provider = getViewProvider(); + assert provider != null : myVirtualFile; final StructureViewComposite.StructureViewDescriptor structureViewDescriptor = createMainView(fileEditor, provider.getPsi(provider.getBaseLanguage())); if (structureViewDescriptor != null) viewDescriptors.add(structureViewDescriptor); myBaseLanguageViewDescriptorIndex = -1; - final Language dataLanguage = provider.getTemplateDataLanguage(); updateTemplateDataFileView(); if (myBaseStructureViewDescriptor != null) { @@ -179,9 +172,12 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV myBaseLanguageViewDescriptorIndex = viewDescriptors.size() - 1; } - for (final Language language : provider.getLanguages()) { - if (language != dataLanguage && language != provider.getBaseLanguage()) { - ContainerUtil.addIfNotNull(createBaseLanguageStructureView(fileEditor, language), viewDescriptors); + if (provider instanceof TemplateLanguageFileViewProvider) { + final Language dataLanguage = ((TemplateLanguageFileViewProvider)provider).getTemplateDataLanguage(); + for (final Language language : provider.getLanguages()) { + if (language != dataLanguage && language != provider.getBaseLanguage()) { + ContainerUtil.addIfNotNull(createBaseLanguageStructureView(fileEditor, language), viewDescriptors); + } } } @@ -210,7 +206,7 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV private StructureViewComposite.StructureViewDescriptor createBaseLanguageStructureView(final FileEditor fileEditor, final Language language) { if (!myVirtualFile.isValid()) return null; - final TemplateLanguageFileViewProvider viewProvider = getViewProvider(); + final FileViewProvider viewProvider = getViewProvider(); if (viewProvider == null) return null; final PsiFile dataFile = viewProvider.getPsi(language); @@ -231,8 +227,7 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV } private void updateTemplateDataFileView() { - final TemplateLanguageFileViewProvider provider = getViewProvider(); - final Language newDataLanguage = provider == null ? null : provider.getTemplateDataLanguage(); + final Language newDataLanguage = getTemplateDataLanguage(); if (myBaseStructureViewDescriptor != null) { if (myTemplateDataLanguage == newDataLanguage) return; From df87d127679986413f640512c5c71646f4125079 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Sep 2015 13:45:14 +0200 Subject: [PATCH 044/138] no log.info from injected file invalidation on reparse --- .../impl/source/tree/injected/MultiHostRegistrarImpl.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java index 954d0532cbc9..4984df7d49e7 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java @@ -312,7 +312,13 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT @NotNull SmartPsiElementPointer pointer) { FileDocumentManagerImpl.registerDocument(documentWindow, viewProvider.getVirtualFile()); - viewProvider.forceCachedPsi(psiFile); + DebugUtil.startPsiModification("MultiHostRegistrar cacheEverything"); + try { + viewProvider.forceCachedPsi(psiFile); + } + finally { + DebugUtil.finishPsiModification(); + } psiFile.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, pointer); PsiDocumentManagerBase.cachePsi(documentWindow, psiFile); From d69025dc220884d4f328a6a5e9447f6873c68a27 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Mon, 21 Sep 2015 15:10:29 +0300 Subject: [PATCH 045/138] NPE --- .../src/com/intellij/ui/messages/SheetController.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java index 6efa86e292bf..3ce09cb88210 100755 --- a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java +++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java @@ -187,7 +187,11 @@ public class SheetController { IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(new Runnable() { @Override public void run() { - myFocusedComponent.requestFocus(); + if (myFocusedComponent != null) { + myFocusedComponent.requestFocus(); + } else { + LOG.debug("My focused component is null for the next message: " + messageTextPane.getText()); + } } }); } From 15cd3c70188d101aed7f116b427fe0899781cb17 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 21 Sep 2015 15:30:01 +0300 Subject: [PATCH 046/138] Cleanup (formatting; dead code) --- .../util/src/com/intellij/util/Restarter.java | 49 +++++++------------ 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/platform/util/src/com/intellij/util/Restarter.java b/platform/util/src/com/intellij/util/Restarter.java index ab4a5ce7bfec..c0e3968df4b2 100644 --- a/platform/util/src/com/intellij/util/Restarter.java +++ b/platform/util/src/com/intellij/util/Restarter.java @@ -18,7 +18,6 @@ package com.intellij.util; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtilRt; -import com.intellij.openapi.util.io.StreamUtil; import com.intellij.openapi.util.text.StringUtil; import com.sun.jna.Native; import com.sun.jna.Pointer; @@ -27,12 +26,10 @@ import com.sun.jna.ptr.IntByReference; import com.sun.jna.win32.StdCallLibrary; import org.jetbrains.annotations.NotNull; +import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; -import java.io.BufferedWriter; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -89,16 +86,26 @@ public class Restarter { if (beforeRestart.length == 0) return; File restartDir = new File(System.getProperty("user.home") + "/." + System.getProperty("idea.paths.selector") + "/restart"); - if (! FileUtilRt.createDirectory(restartDir)) throw new IOException("Cannot create dir: " + restartDir); - File restarter = new File(restartDir.getPath() + "/restarter.sh"); + if (!FileUtilRt.createDirectory(restartDir)) { + throw new IOException("Cannot create dir: " + restartDir); + } + + File restarter = new File(restartDir, "restarter.sh"); BufferedWriter output = new BufferedWriter(new FileWriter(restarter)); - output.write("#!/bin/sh\n"); - for (String command : beforeRestart ){ - output.write(command); - output.write(" "); + try { + output.write("#!/bin/sh\n"); + for (int i = 0; i < beforeRestart.length; i++) { + output.write(beforeRestart[i]); + output.write(i == beforeRestart.length - 1 ? '\n' : ' '); + } + } + finally { + output.close(); + } + + if (!restarter.setExecutable(true, true)) { + throw new IOException("Cannot make file executable: " + restarter); } - output.close(); - if (! restarter.setExecutable(true, true)) throw new IOException("Cannot make file executable: " + restarter); } private static void restartOnWindows(@NotNull final String... beforeRestart) throws IOException { @@ -175,22 +182,4 @@ public class Restarter { private interface Shell32 extends StdCallLibrary { Pointer CommandLineToArgvW(WString command_line, IntByReference argc); } - - private static class StreamRedirector implements Runnable { - private final InputStream myIn; - private final OutputStream myOut; - - private StreamRedirector(InputStream in, OutputStream out) { - myIn = in; - myOut = out; - } - - @Override - public void run() { - try { - StreamUtil.copyStreamContent(myIn, myOut); - } - catch (IOException ignore) { } - } - } } \ No newline at end of file From f577515cbce75e8fd7eaa2fe0d48a20460c73f9f Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 21 Sep 2015 14:40:51 +0200 Subject: [PATCH 047/138] Mac LaF: disabled checkbox graphite --- .../ui/laf/icons/graphite/checkBoxDisabled.png | Bin 0 -> 216 bytes .../ui/laf/icons/graphite/checkBoxDisabled@2x.png | Bin 0 -> 449 bytes .../icons/graphite/checkBoxSelectedDisabled.png | Bin 0 -> 341 bytes .../graphite/checkBoxSelectedDisabled@2x.png | Bin 0 -> 730 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxDisabled.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxDisabled@2x.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxSelectedDisabled.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxSelectedDisabled@2x.png diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxDisabled.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxDisabled.png new file mode 100644 index 0000000000000000000000000000000000000000..ad426c88fe64c36c1de773723dc87e15393cdd2d GIT binary patch literal 216 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqEXErrFe8FhL z^5yNa9cvpcSUQwB9|)|7Dyw0eC2Lz{^7!xX?_1;d*X15)cg*UOwVuX!srkIa`}gAh9a_$^pUL1*h-tuYcWP%Ckgl z3H$uUU*YRwJe7_GOpuxoH9@Y1Z4=W*IRR_tjoOTFctTHGwVZa&N?_P=e_PNa*$F_G PGB9|$`njxgN@xNARvlSx literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxDisabled@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxDisabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7ae37c9093c1261924481a2dd33181c885a68919 GIT binary patch literal 449 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1|)m_?Z{&7J)?o*Mw%X=&-u=v`hB`jKb*vyCo!FIKU>Bjg6h$$c{hQX+RBqd(sa;cBwLj6#egGJd1cE_82nK-w34{;8AV`on6hXo5JOWAE zv@`5x&59#ta_`B@%w!}0(lwE8ODN0omhs5gGu{R4=j@gzd`Q#u(6;So*L5czl*zK} zKpmd&t?&EeIF2W_=0X|DQimse70JRdglU>sq}1UFUwE>jD8MrCJP*s>+__9>7zQ*= zLtWSB3!A3FcUcrg({y>B|JYwG)O8)c?@#5jETJe0T-U|#saFewAebhK;~2JWLseB& zRdu4-Q4hhcn!V)6`rW+fEWgT00000NkvXXu0mjf$zzyo literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxSelectedDisabled@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxSelectedDisabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6432647323bfd234033002f04e583f92cb0ed720 GIT binary patch literal 730 zcmV<00ww*4P)#b`7V z8qAi01rs(In|gAsAVY9@c`0GD*-Sht>o6U+q zARtPm(z9o<$so(JV58AEX1=Hjo}HZux7#f%7!1A;B!eu=f)^JTzf=X;R_HlhFqg}{ zDoEDe1^Heol``Z`Pfz81`!s^uyfWmdX0!QfBR)is{Vg008*=G%dTlT7U69XbG8scI z5{Zc6aJXMVHrRFI45ioWH3S*zO^vZ#FrUv0pU)?f$)x;UHDA-|R4xWxjz#iTZ`&?t z?i~co&)G)wXQ5C?^!xq&3(|w;)mbPM zN6xOOOn*EDLHcGza`du^M-EqJ~WdS(XI{ zgTasM>uWiu^mh?E|OIsutqoKy=IOxR?Q^{y9p?NIOy0Ig&w z^jA-nf&mLAY%-Mo`k-|T0rP~(%!*Sf7_eY&>N)4%El1E1{9gqB0ZQoPRNt) Date: Mon, 21 Sep 2015 14:43:50 +0200 Subject: [PATCH 048/138] Mac LaF: disabled checkbox blue theme --- .../ide/ui/laf/icons/checkBoxDisabled.png | Bin 0 -> 216 bytes .../ide/ui/laf/icons/checkBoxDisabled@2x.png | Bin 0 -> 449 bytes .../ide/ui/laf/icons/checkBoxSelectedDisabled.png | Bin 0 -> 341 bytes .../ui/laf/icons/checkBoxSelectedDisabled@2x.png | Bin 0 -> 730 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxDisabled.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxDisabled@2x.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxSelectedDisabled.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxSelectedDisabled@2x.png diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxDisabled.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxDisabled.png new file mode 100644 index 0000000000000000000000000000000000000000..ad426c88fe64c36c1de773723dc87e15393cdd2d GIT binary patch literal 216 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqEXErrFe8FhL z^5yNa9cvpcSUQwB9|)|7Dyw0eC2Lz{^7!xX?_1;d*X15)cg*UOwVuX!srkIa`}gAh9a_$^pUL1*h-tuYcWP%Ckgl z3H$uUU*YRwJe7_GOpuxoH9@Y1Z4=W*IRR_tjoOTFctTHGwVZa&N?_P=e_PNa*$F_G PGB9|$`njxgN@xNARvlSx literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxDisabled@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxDisabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7ae37c9093c1261924481a2dd33181c885a68919 GIT binary patch literal 449 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1|)m_?Z{&7J)?o*Mw%X=&-u=v`hB`jKb*vyCo!FIKU>Bjg6h$$c{hQX+RBqd(sa;cBwLj6#egGJd1cE_82nK-w34{;8AV`on6hXo5JOWAE zv@`5x&59#ta_`B@%w!}0(lwE8ODN0omhs5gGu{R4=j@gzd`Q#u(6;So*L5czl*zK} zKpmd&t?&EeIF2W_=0X|DQimse70JRdglU>sq}1UFUwE>jD8MrCJP*s>+__9>7zQ*= zLtWSB3!A3FcUcrg({y>B|JYwG)O8)c?@#5jETJe0T-U|#saFewAebhK;~2JWLseB& zRdu4-Q4hhcn!V)6`rW+fEWgT00000NkvXXu0mjf$zzyo literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxSelectedDisabled@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxSelectedDisabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6432647323bfd234033002f04e583f92cb0ed720 GIT binary patch literal 730 zcmV<00ww*4P)#b`7V z8qAi01rs(In|gAsAVY9@c`0GD*-Sht>o6U+q zARtPm(z9o<$so(JV58AEX1=Hjo}HZux7#f%7!1A;B!eu=f)^JTzf=X;R_HlhFqg}{ zDoEDe1^Heol``Z`Pfz81`!s^uyfWmdX0!QfBR)is{Vg008*=G%dTlT7U69XbG8scI z5{Zc6aJXMVHrRFI45ioWH3S*zO^vZ#FrUv0pU)?f$)x;UHDA-|R4xWxjz#iTZ`&?t z?i~co&)G)wXQ5C?^!xq&3(|w;)mbPM zN6xOOOn*EDLHcGza`du^M-EqJ~WdS(XI{ zgTasM>uWiu^mh?E|OIsutqoKy=IOxR?Q^{y9p?NIOy0Ig&w z^jA-nf&mLAY%-Mo`k-|T0rP~(%!*Sf7_eY&>N)4%El1E1{9gqB0ZQoPRNt) Date: Mon, 21 Sep 2015 14:47:57 +0200 Subject: [PATCH 049/138] support disabled state for Mac checkbox --- .../com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java index d36e84d36bcb..63c9b97fafd3 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java @@ -42,7 +42,7 @@ public class MacIntelliJCheckBoxUI extends IntelliJCheckBoxUI { @Override protected void drawCheckIcon(JComponent c, Graphics2D g, JCheckBox b, Rectangle iconRect, boolean selected, boolean enabled) { MacIntelliJIconCache - .getIcon("checkBox", selected, c.hasFocus()) + .getIcon("checkBox", selected, c.hasFocus(), !b.isEnabled()) .paintIcon(c, g, iconRect.x, iconRect.y); } From dad1a490c6c66b2c71b567b47c46afdb0cf2a3d3 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Mon, 21 Sep 2015 15:49:20 +0300 Subject: [PATCH 050/138] IDEA-145363 ConcurrentModificationException when a widget is added or removed in the status bar --- .../com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java index 5c7202df1414..7c5c475f8fba 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java @@ -36,6 +36,7 @@ import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.popup.NotificationPopup; import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; From bcb0c0524dbd2be1d4890523c2b3bba102e615b2 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 17 Sep 2015 20:16:37 +0300 Subject: [PATCH 051/138] [git] Multi-root rebase IDEA-85842 Introduce GitRebaseProcess to perform multi-root rebase, gracefully handling frequent failures like dirty tree, merge conflict, and no changes errors. When needed, display notifications with links to retry/abort/resolve conflicts. Detect skipped commits and mention them in the notification as well to let user review them. For now utilize the process only in the GitBranchPopupActions, but later it will be used in all rebase-related processes. --- .../com/intellij/openapi/vcs/Executor.java | 2 +- plugins/git4idea/src/git4idea/GitUtil.java | 7 + .../src/git4idea/branch/GitBranchWorker.java | 8 + .../src/git4idea/branch/GitBrancher.java | 5 + .../src/git4idea/branch/GitBrancherImpl.java | 10 + .../src/git4idea/branch/GitRebaseParams.java | 84 +++ .../git4idea/src/git4idea/commands/Git.java | 4 + .../src/git4idea/commands/GitImpl.java | 16 +- .../git4idea/merge/GitConflictResolver.java | 2 + .../rebase/GitAbortRebaseProcess.java | 226 ++++++++ .../src/git4idea/rebase/GitRebaseProcess.java | 548 ++++++++++++++++++ .../src/git4idea/rebase/GitRebaseUtils.java | 78 +++ .../ui/branch/GitBranchPopupActions.java | 22 + .../git4idea/log/GitLogProviderTest.java | 6 - .../push/GitPushResultNotificationTest.java | 11 +- .../git4idea/rebase/GitMultiRepoRebaseTest.kt | 210 +++++++ .../git4idea/rebase/GitRebaseBaseTest.kt | 223 +++++++ .../rebase/GitSingleRepoRebaseTest.kt | 405 +++++++++++++ .../tests/git4idea/test/GitExecutor.java | 62 ++ .../tests/git4idea/test/GitTestUtil.java | 24 + .../tests/git4idea/test/MockVcsHelper.java | 239 -------- .../tests/git4idea/test/MockVcsHelper.kt | 180 ++++++ .../tests/git4idea/test/RepoBuilder.kt | 98 ++++ .../git4idea/tests/git4idea/test/TestGit.kt | 45 ++ 24 files changed, 2258 insertions(+), 257 deletions(-) create mode 100644 plugins/git4idea/src/git4idea/branch/GitRebaseParams.java create mode 100644 plugins/git4idea/src/git4idea/rebase/GitAbortRebaseProcess.java create mode 100644 plugins/git4idea/src/git4idea/rebase/GitRebaseProcess.java create mode 100644 plugins/git4idea/tests/git4idea/rebase/GitMultiRepoRebaseTest.kt create mode 100644 plugins/git4idea/tests/git4idea/rebase/GitRebaseBaseTest.kt create mode 100644 plugins/git4idea/tests/git4idea/rebase/GitSingleRepoRebaseTest.kt delete mode 100644 plugins/git4idea/tests/git4idea/test/MockVcsHelper.java create mode 100644 plugins/git4idea/tests/git4idea/test/MockVcsHelper.kt create mode 100644 plugins/git4idea/tests/git4idea/test/RepoBuilder.kt create mode 100644 plugins/git4idea/tests/git4idea/test/TestGit.kt diff --git a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/Executor.java b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/Executor.java index cdc052faec89..4ebe0245f9e7 100644 --- a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/Executor.java +++ b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/Executor.java @@ -291,7 +291,7 @@ public class Executor { return path; } - private static File child(String fileName) { + protected static File child(String fileName) { assert ourCurrentDir != null : "Current dir hasn't been initialized yet. Call cd at least once before any other command."; return new File(ourCurrentDir, fileName); } diff --git a/plugins/git4idea/src/git4idea/GitUtil.java b/plugins/git4idea/src/git4idea/GitUtil.java index 0a52c63299e7..141d3c95fd4f 100644 --- a/plugins/git4idea/src/git4idea/GitUtil.java +++ b/plugins/git4idea/src/git4idea/GitUtil.java @@ -66,6 +66,8 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.*; +import static com.intellij.dvcs.DvcsUtil.getShortRepositoryName; + /** * Git utility/helper methods */ @@ -993,4 +995,9 @@ public class GitUtil { } }, "
"); } + + @NotNull + public static String mention(@NotNull GitRepository repository) { + return getRepositoryManager(repository.getProject()).moreThanOneRoot() ? " in " + getShortRepositoryName(repository) : ""; + } } diff --git a/plugins/git4idea/src/git4idea/branch/GitBranchWorker.java b/plugins/git4idea/src/git4idea/branch/GitBranchWorker.java index 67e8d2e5f8cc..88a6c8088204 100644 --- a/plugins/git4idea/src/git4idea/branch/GitBranchWorker.java +++ b/plugins/git4idea/src/git4idea/branch/GitBranchWorker.java @@ -17,6 +17,7 @@ package git4idea.branch; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Condition; @@ -32,6 +33,7 @@ import git4idea.GitPlatformFacade; import git4idea.changes.GitChangeUtils; import git4idea.commands.Git; import git4idea.history.GitHistoryUtils; +import git4idea.rebase.GitRebaseUtils; import git4idea.repo.GitRepository; import git4idea.ui.branch.GitCompareBranchesDialog; import git4idea.util.GitCommitCompareInfo; @@ -121,6 +123,12 @@ public final class GitBranchWorker { new GitMergeOperation(myProject, myFacade, myGit, myUiHandler, repositories, branchName, deleteOnMerge, revisions).execute(); } + public void rebase(@NotNull List repositories, @NotNull String branchName) { + updateInfo(repositories); + GitRebaseUtils.rebase(myProject, repositories, new GitRebaseParams(branchName), + ProgressManager.getInstance().getProgressIndicator()); + } + public void compare(@NotNull final String branchName, @NotNull final List repositories, @NotNull final GitRepository selectedRepository) { final GitCommitCompareInfo myCompareInfo = loadCommitsToCompare(repositories, branchName); diff --git a/plugins/git4idea/src/git4idea/branch/GitBrancher.java b/plugins/git4idea/src/git4idea/branch/GitBrancher.java index 80cea7e3ee89..4a18e10f8332 100644 --- a/plugins/git4idea/src/git4idea/branch/GitBrancher.java +++ b/plugins/git4idea/src/git4idea/branch/GitBrancher.java @@ -129,6 +129,11 @@ public interface GitBrancher { */ void merge(@NotNull String branchName, @NotNull DeleteOnMergeOption deleteOnMerge, @NotNull List repositories); + /** + * Call {@code git rebase } for each of the given repositories. + */ + void rebase(@NotNull List repositories, @NotNull String branchName); + /** * What should be done after successful merging a branch: delete the merged branch, propose to delete or do nothing. */ diff --git a/plugins/git4idea/src/git4idea/branch/GitBrancherImpl.java b/plugins/git4idea/src/git4idea/branch/GitBrancherImpl.java index a1be7b8fea0f..51a072273f79 100644 --- a/plugins/git4idea/src/git4idea/branch/GitBrancherImpl.java +++ b/plugins/git4idea/src/git4idea/branch/GitBrancherImpl.java @@ -131,6 +131,16 @@ class GitBrancherImpl implements GitBrancher { }.runInBackground(); } + @Override + public void rebase(@NotNull final List repositories, @NotNull final String branchName) { + new CommonBackgroundTask(myProject, "Rebasing " + branchName, null) { + @Override + void execute(@NotNull ProgressIndicator indicator) { + newWorker(indicator).rebase(repositories, branchName); + } + }.runInBackground(); + } + /** * Executes common operations before/after executing the actual branch operation. */ diff --git a/plugins/git4idea/src/git4idea/branch/GitRebaseParams.java b/plugins/git4idea/src/git4idea/branch/GitRebaseParams.java new file mode 100644 index 000000000000..c6a836cba78a --- /dev/null +++ b/plugins/git4idea/src/git4idea/branch/GitRebaseParams.java @@ -0,0 +1,84 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ +package git4idea.branch; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +import static java.util.Collections.singletonList; + +public class GitRebaseParams { + + public enum Mode { + STANDARD, + CONTINUE, + SKIP, + ABORT; + + @NotNull + @SuppressWarnings("StringToUpperCaseOrToLowerCaseWithoutLocale") + String asArgument() { + if (this == STANDARD) return ""; + return "--" + this.name().toLowerCase(); + } + } + + @Nullable private final String myBase; + @NotNull private final Mode myMode; + + @NotNull + public static GitRebaseParams abort() { + return new GitRebaseParams(null, Mode.ABORT); + } + + public GitRebaseParams(@NotNull String base) { + this(base, Mode.STANDARD); + } + + private GitRebaseParams(@Nullable String base, @NotNull Mode mode) { + myBase = base; + myMode = mode; + } + + @NotNull + public GitRebaseParams withMode(@NotNull Mode mode) { + return mode == myMode ? this : new GitRebaseParams(myBase, mode); + } + + @NotNull + public String getBase() { + return StringUtil.notNullize(myBase); + } + + @NotNull + public Mode getMode() { + return myMode; + } + + @NotNull + public List getCommandLineArguments() { + if (myMode != Mode.STANDARD) { + return singletonList(myMode.asArgument()); + } + List args = ContainerUtil.newArrayList(); + args.add(myBase); + return args; + } +} diff --git a/plugins/git4idea/src/git4idea/commands/Git.java b/plugins/git4idea/src/git4idea/commands/Git.java index e23541338af8..011f70a4fbc0 100644 --- a/plugins/git4idea/src/git4idea/commands/Git.java +++ b/plugins/git4idea/src/git4idea/commands/Git.java @@ -20,6 +20,7 @@ import com.intellij.openapi.util.Computable; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; import git4idea.GitCommit; +import git4idea.branch.GitRebaseParams; import git4idea.repo.GitRemote; import git4idea.repo.GitRepository; import git4idea.reset.GitResetMode; @@ -168,4 +169,7 @@ public interface Git { @NotNull GitCommandResult remotePrune(@NotNull GitRepository repository, @NotNull GitRemote remote); + + @NotNull + GitCommandResult rebase(@NotNull GitRepository repository, @NotNull GitRebaseParams params, @NotNull GitLineHandlerListener... listeners); } diff --git a/plugins/git4idea/src/git4idea/commands/GitImpl.java b/plugins/git4idea/src/git4idea/commands/GitImpl.java index 3b1d1bbc6ebd..ff3a48f4c0d3 100644 --- a/plugins/git4idea/src/git4idea/commands/GitImpl.java +++ b/plugins/git4idea/src/git4idea/commands/GitImpl.java @@ -31,6 +31,7 @@ import com.intellij.vcsUtil.VcsFileUtil; import git4idea.GitCommit; import git4idea.GitExecutionException; import git4idea.GitVcs; +import git4idea.branch.GitRebaseParams; import git4idea.config.GitVersionSpecialty; import git4idea.history.GitHistoryUtils; import git4idea.repo.GitRemote; @@ -137,7 +138,7 @@ public class GitImpl implements Git { return untrackedFiles; } - + @Override @NotNull public GitCommandResult clone(@NotNull final Project project, @NotNull final File parentDirectory, @NotNull final String url, @@ -268,7 +269,7 @@ public class GitImpl implements Git { } if (newBranch == null) { // simply checkout h.addParameters(detach ? reference + "^0" : reference); // we could use `--detach` here, but it is supported only since 1.7.5. - } + } else { // checkout reference as new branch h.addParameters("-b", newBranch, reference); } @@ -557,6 +558,17 @@ public class GitImpl implements Git { }); } + @NotNull + @Override + public GitCommandResult rebase(@NotNull GitRepository repository, + @NotNull GitRebaseParams params, + @NotNull GitLineHandlerListener... listeners) { + GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.REBASE); + handler.addParameters(params.getCommandLineArguments()); + addListeners(handler, listeners); + return run(handler); + } + @NotNull private static GitCommandResult doLsRemote(@NotNull final Project project, @NotNull final File workingDir, diff --git a/plugins/git4idea/src/git4idea/merge/GitConflictResolver.java b/plugins/git4idea/src/git4idea/merge/GitConflictResolver.java index 99cd3eb0c386..9abae4f49fcc 100644 --- a/plugins/git4idea/src/git4idea/merge/GitConflictResolver.java +++ b/plugins/git4idea/src/git4idea/merge/GitConflictResolver.java @@ -39,6 +39,7 @@ import git4idea.commands.GitCommandResult; import git4idea.repo.GitRepository; import git4idea.repo.GitRepositoryManager; import git4idea.util.StringScanner; +import org.jetbrains.annotations.CalledInBackground; import org.jetbrains.annotations.NotNull; import javax.swing.event.HyperlinkEvent; @@ -153,6 +154,7 @@ public class GitConflictResolver { * In the basic implementation no action is performed, {@code true} is returned. * @return Return value is returned from {@link #merge()} */ + @CalledInBackground protected boolean proceedAfterAllMerged() throws VcsException { return true; } diff --git a/plugins/git4idea/src/git4idea/rebase/GitAbortRebaseProcess.java b/plugins/git4idea/src/git4idea/rebase/GitAbortRebaseProcess.java new file mode 100644 index 000000000000..981a9e9496b2 --- /dev/null +++ b/plugins/git4idea/src/git4idea/rebase/GitAbortRebaseProcess.java @@ -0,0 +1,226 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ +package git4idea.rebase; + +import com.intellij.dvcs.DvcsUtil; +import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.vcs.VcsNotifier; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import git4idea.DialogManager; +import git4idea.GitPlatformFacade; +import git4idea.GitUtil; +import git4idea.branch.GitRebaseParams; +import git4idea.commands.Git; +import git4idea.commands.GitCommandResult; +import git4idea.repo.GitRepository; +import git4idea.reset.GitResetMode; +import git4idea.stash.GitChangesSaver; +import git4idea.util.GitFreezingProcess; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import static com.intellij.CommonBundle.getCancelButtonText; +import static com.intellij.dvcs.DvcsUtil.getShortRepositoryName; +import static com.intellij.openapi.ui.Messages.getQuestionIcon; +import static com.intellij.openapi.vfs.VfsUtil.markDirtyAndRefresh; +import static com.intellij.openapi.vfs.VfsUtilCore.toVirtualFileArray; +import static git4idea.GitUtil.getRootsFromRepositories; +import static git4idea.rebase.GitRebaseUtils.mentionLocalChangesRemainingInStash; + +class GitAbortRebaseProcess { + private static final Logger LOG = Logger.getInstance(GitAbortRebaseProcess.class); + + @NotNull private final Project myProject; + @NotNull private final Git myGit; + @NotNull private final VcsNotifier myNotifier; + + @Nullable private final GitRepository myRepositoryToAbort; + @NotNull private final Map myRepositoriesToRollback; + @NotNull private final ProgressIndicator myIndicator; + @Nullable private final GitChangesSaver mySaver; + + GitAbortRebaseProcess(@NotNull Project project, + @Nullable GitRepository repositoryToAbort, + @NotNull Map repositoriesToRollback, + @NotNull ProgressIndicator progressIndicator, + @Nullable GitChangesSaver changesSaver) { + myProject = project; + myRepositoryToAbort = repositoryToAbort; + myRepositoriesToRollback = repositoriesToRollback; + myIndicator = progressIndicator; + mySaver = changesSaver; + + myGit = ServiceManager.getService(Git.class); + myNotifier = VcsNotifier.getInstance(myProject); + } + + void abortWithConfirmation() { + LOG.debug("Abort rebase. " + (myRepositoryToAbort == null ? "Nothing to abort" : getShortRepositoryName(myRepositoryToAbort)) + + ". Roots to rollback: " + mention(myRepositoriesToRollback.keySet())); + final Ref ref = Ref.create(); + ApplicationManager.getApplication().invokeAndWait(new Runnable() { + @Override + public void run() { + ref.set(confirmAbort()); + } + }, ModalityState.defaultModalityState()); + + LOG.debug("User choice: " + ref.get()); + if (ref.get() == AbortChoice.ROLLBACK_AND_ABORT) { + doAbort(true); + } + else if (ref.get() == AbortChoice.ABORT) { + doAbort(false); + } + } + + @NotNull + private AbortChoice confirmAbort() { + String title = "Abort Rebase"; + if (myRepositoryToAbort != null) { + if (myRepositoriesToRollback.isEmpty()) { + String message = "Are you sure you want to abort rebase" + GitUtil.mention(myRepositoryToAbort) + "?"; + int choice = DialogManager.showOkCancelDialog(myProject, message, title, "Abort", getCancelButtonText(), getQuestionIcon()); + if (choice == Messages.OK) { + return AbortChoice.ABORT; + } + } + else { + String message = "Do you want just to abort rebase" + GitUtil.mention(myRepositoryToAbort) + ",\n" + + "or also rollback the successful rebase in " + mention(myRepositoriesToRollback.keySet()) + "?"; + int choice = DialogManager.showYesNoCancelDialog(myProject, message, title, "Abort & Rollback", "Abort", + getCancelButtonText(), getQuestionIcon()); + if (choice == Messages.YES) { + return AbortChoice.ROLLBACK_AND_ABORT; + } + else if (choice == Messages.NO) { + return AbortChoice.ABORT; + } + } + } + else { + if (myRepositoriesToRollback.isEmpty()) { + LOG.error("", new Throwable()); + } + else { + String description = "Do you want rollback the successful rebase in " + mention(myRepositoriesToRollback.keySet()) + "?"; + int choice = DialogManager.showOkCancelDialog(myProject, description, title, "Rollback", getCancelButtonText(), getQuestionIcon()); + if (choice == Messages.YES) { + return AbortChoice.ROLLBACK_AND_ABORT; + } + } + } + return AbortChoice.CANCEL; + } + + enum AbortChoice { + ABORT, + ROLLBACK_AND_ABORT, + CANCEL + } + + private void doAbort(final boolean rollback) { + new GitFreezingProcess(myProject, ServiceManager.getService(GitPlatformFacade.class), "rebase", new Runnable() { + public void run() { + AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject); + List repositoriesToRefresh = ContainerUtil.newArrayList(); + try { + if (myRepositoryToAbort != null) { + myIndicator.setText2("git rebase --abort" + GitUtil.mention(myRepositoryToAbort)); + GitCommandResult result = myGit.rebase(myRepositoryToAbort, GitRebaseParams.abort()); + repositoriesToRefresh.add(myRepositoryToAbort); + if (!result.success()) { + myNotifier.notifyError("Rebase Abort Failed", + result.getErrorOutputAsHtmlString() + mentionLocalChangesRemainingInStash(mySaver)); + return; + } + } + + if (rollback) { + for (GitRepository repo : myRepositoriesToRollback.keySet()) { + myIndicator.setText2("git reset --keep" + GitUtil.mention(repo)); + GitCommandResult res = myGit.reset(repo, GitResetMode.KEEP, myRepositoriesToRollback.get(repo)); + repositoriesToRefresh.add(repo); + if (!res.success()) { + String description = myRepositoryToAbort != null ? + "Rebase abort was successful" + GitUtil.mention(myRepositoryToAbort) + ", but rollback failed": + "Rollback failed"; + description += GitUtil.mention(repo) + ":" + res.getErrorOutputAsHtmlString() + + mentionLocalChangesRemainingInStash(mySaver); + myNotifier.notifyImportantWarning("Rebase Rollback Failed", description); + return; + } + } + } + + if (mySaver != null) { + mySaver.load(); + } + myNotifier.notifySuccess("Rebase abort succeeded"); + } + finally { + refresh(repositoriesToRefresh); + DvcsUtil.workingTreeChangeFinished(myProject, token); + } + } + }).execute(); + } + + private static void refresh(@NotNull List toRefresh) { + for (GitRepository repository : toRefresh) { + repository.update(); + } + markDirtyAndRefresh(false, true, false, toVirtualFileArray(getRootsFromRepositories(toRefresh))); + } + + @NotNull + private static String mention(@NotNull Collection repositories) { + return joinWithAnd(ContainerUtil.map(repositories, new Function() { + @Override + public String fun(@NotNull GitRepository repository) { + return getShortRepositoryName(repository); + } + })); + } + + @NotNull + private static String joinWithAnd(@NotNull List strings) { + int size = strings.size(); + if (size == 0) return ""; + if (size == 1) return strings.get(0); + if (size == 2) return strings.get(0) + " and " + strings.get(1); + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < size - 2; i++) { + sb.append(strings.get(i)).append(", "); + } + sb.append(strings.get(size - 2)).append(" and ").append(strings.get(size - 1)); + return sb.toString(); + } +} diff --git a/plugins/git4idea/src/git4idea/rebase/GitRebaseProcess.java b/plugins/git4idea/src/git4idea/rebase/GitRebaseProcess.java new file mode 100644 index 000000000000..d63ff9a13b44 --- /dev/null +++ b/plugins/git4idea/src/git4idea/rebase/GitRebaseProcess.java @@ -0,0 +1,548 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ +package git4idea.rebase; + +import com.google.common.annotations.VisibleForTesting; +import com.intellij.dvcs.DvcsUtil; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationListener; +import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.VcsNotifier; +import com.intellij.openapi.vcs.changes.ChangeListManager; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Function; +import com.intellij.util.ThreeState; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.MultiMap; +import git4idea.GitPlatformFacade; +import git4idea.GitUtil; +import git4idea.branch.GitRebaseParams; +import git4idea.commands.Git; +import git4idea.commands.GitCommandResult; +import git4idea.commands.GitUntrackedFilesOverwrittenByOperationDetector; +import git4idea.merge.GitConflictResolver; +import git4idea.repo.GitRepository; +import git4idea.stash.GitChangesSaver; +import git4idea.stash.GitStashChangesSaver; +import git4idea.util.GitFreezingProcess; +import git4idea.util.GitUntrackedFilesHelper; +import org.jetbrains.annotations.CalledInBackground; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.event.HyperlinkEvent; +import java.util.*; + +import static com.intellij.dvcs.DvcsUtil.getShortRepositoryName; +import static com.intellij.openapi.vfs.VfsUtilCore.toVirtualFileArray; +import static git4idea.GitUtil.getRootsFromRepositories; +import static git4idea.GitUtil.mention; +import static java.util.Collections.singleton; + +public class GitRebaseProcess { + + private static final Logger LOG = Logger.getInstance(GitRebaseProcess.class); + + @NotNull private final Project myProject; + @NotNull private final Git myGit; + @NotNull private final ChangeListManager myChangeListManager; + @NotNull private final VcsNotifier myNotifier; + @NotNull private final GitPlatformFacade myFacade; + + @NotNull private final List myAllRepositories; + @NotNull private final GitRebaseParams myParams; + @NotNull private final GitChangesSaver mySaver; + @NotNull private final Map mySuccessfulRepositories; + @NotNull private final Map myInitialHeadPositions; + + @NotNull private final MultiMap mySkippedCommits; + + protected GitRebaseProcess(@NotNull Project project, + @NotNull List repositories, + @NotNull GitRebaseParams params, + @NotNull ProgressIndicator indicator) { + this(project, repositories, params, newSaver(project, indicator), + MultiMap.create(), Collections.emptyMap()); + } + + private GitRebaseProcess(@NotNull Project project, + @NotNull List allRepositories, + @NotNull GitRebaseParams params, + @NotNull GitChangesSaver saver, + @NotNull MultiMap skippedCommits, + @NotNull Map successfulRepositories) { + myProject = project; + myAllRepositories = allRepositories; + myParams = params; + mySaver = saver; + mySuccessfulRepositories = successfulRepositories; + + myGit = ServiceManager.getService(Git.class); + myChangeListManager = ChangeListManager.getInstance(myProject); + myNotifier = VcsNotifier.getInstance(myProject); + myFacade = ServiceManager.getService(GitPlatformFacade.class); + + myInitialHeadPositions = readInitialHeadPositions(myAllRepositories); + mySkippedCommits = skippedCommits; + } + + void rebase() { + new GitFreezingProcess(myProject, myFacade, "rebase", new Runnable() { + public void run() { + doRebase(); + } + }).execute(); + } + + void abort(@Nullable GitRepository repositoryToAbort, + @NotNull final Collection successfulRepositories, + @NotNull ProgressIndicator indicator) { + new GitAbortRebaseProcess(myProject, repositoryToAbort, ContainerUtil.filter(myInitialHeadPositions, new Condition() { + @Override + public boolean value(GitRepository repository) { + return successfulRepositories.contains(repository); + } + }), indicator, mySaver).abortWithConfirmation(); + } + + void retry(final boolean continueRebase) { + new GitFreezingProcess(myProject, myFacade, "rebase", new Runnable() { + public void run() { + GitRebaseParams params = continueRebase ? myParams.withMode(GitRebaseParams.Mode.CONTINUE) : myParams; + new GitRebaseProcess(myProject, myAllRepositories, params, mySaver, mySkippedCommits, mySuccessfulRepositories).doRebase(); + } + }).execute(); + } + + private void doRebase() { + LOG.debug("Started rebase."); + Map successfulWithTypes = ContainerUtil.newLinkedHashMap(mySuccessfulRepositories); + List repositories = ContainerUtil.newArrayList(myAllRepositories); + repositories.removeAll(successfulWithTypes.keySet()); + ListIterator iterator = repositories.listIterator(); + + AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject); + try { + if (!saveDirtyRootsInitially(repositories)) return; + + GitRepository facedDirtyError = null; + Map customModes = ContainerUtil.newLinkedHashMap(); + while (iterator.hasNext()) { + GitRepository repository = iterator.next(); + VirtualFile root = repository.getRoot(); + String repoName = getShortRepositoryName(repository); + LOG.debug("Rebase iteration. Root: " + repoName); + Collection successful = successfulWithTypes.keySet(); + + GitRebaseProblemDetector rebaseDetector = new GitRebaseProblemDetector(); + GitUntrackedFilesOverwrittenByOperationDetector untrackedDetector = new GitUntrackedFilesOverwrittenByOperationDetector(root); + GitRebaseLineListener progressListener = new GitRebaseLineListener(); + + GitRebaseParams.Mode customMode = customModes.get(repository); + GitRebaseParams rebaseParams = customMode != null ? myParams.withMode(customMode) : myParams; + GitCommandResult result = myGit.rebase(repository, rebaseParams, rebaseDetector, untrackedDetector, progressListener); + boolean nonStandardMode = rebaseParams.getMode() != GitRebaseParams.Mode.STANDARD; + boolean somethingRebased = nonStandardMode || progressListener.getResult().current > 1; + + if (result.success()) { + LOG.debug("Successfully rebased " + repoName); + successfulWithTypes.put(repository, SuccessType.fromOutput(result.getOutput())); + } + else if (rebaseDetector.isDirtyTree() && !nonStandardMode && repository != facedDirtyError) { + // if the initial dirty tree check doesn't find all local changes, we are still ready to stash-on-demand, + // but only once per repository (if the error happens again, that means that the previous stash attempt failed for some reason), + // and not in the case of --continue (where all local changes are expected to be committed) or --skip. + + LOG.debug("Dirty tree detected in " + repoName); + String saveError = saveLocalChanges(singleton(repository.getRoot())); + if (saveError == null) { + iterator.previous(); // try same repository again + facedDirtyError = repository; + } + else { + LOG.warn("Couldn't " + mySaver.getOperationName() + " root " + repository.getRoot() + ": " + saveError); + showFatalError(saveError, repository, somethingRebased, successful); + return; + } + } + else if (rebaseDetector.isMergeConflict()) { + LOG.debug("Merge conflict in " + repoName); + boolean allResolved = showConflictResolver(repository, false); + if (allResolved) { + iterator.previous(); // continue with the same repository + customModes.put(repository, GitRebaseParams.Mode.CONTINUE); + } + else { + notifyNotAllConflictsResolved(repository, successful); + return; + } + } + else if (rebaseDetector.isNoChangeError()) { + LOG.info("'No changes' situation detected in " + repoName); + mySkippedCommits.putValue(repository, GitRebaseUtils.getCurrentRebaseCommit(root)); + iterator.previous(); + customModes.put(repository, GitRebaseParams.Mode.SKIP); + } + else if (untrackedDetector.wasMessageDetected()) { + LOG.debug("Untracked files detected in " + repoName); + showUntrackedFilesError(untrackedDetector.getRelativeFilePaths(), repository, somethingRebased, successful); + return; + } + else { + LOG.info("Error rebasing root " + repoName + ": " + result.getErrorOutputAsJoinedString()); + showFatalError(result.getErrorOutputAsHtmlString(), repository, somethingRebased, successful); + return; + } + } // while + + LOG.debug("Rebase completed successfully."); + mySaver.load(); + } + finally { + refresh(getRepositoriesToRefresh(successfulWithTypes, iterator.previous())); + DvcsUtil.workingTreeChangeFinished(myProject, token); + } + notifySuccess(successfulWithTypes); // refresh _before_ showing the notification + } + + @VisibleForTesting + @NotNull + protected Collection getDirtyRoots(@NotNull Collection repositories) { + return findRootsWithLocalChanges(repositories); + } + + @NotNull + private static Map readInitialHeadPositions(@NotNull Collection repositories) { + updateRepositoriesInfo(repositories); + return ContainerUtil.map2Map(repositories, new Function>() { + @Override + public Pair fun(@NotNull GitRepository repository) { + String currentRevision = repository.getCurrentRevision(); + LOG.debug("Current revision in [" + repository.getRoot().getName() + "] is [" + currentRevision + "]"); + return Pair.create(repository, currentRevision); + } + }); + } + + @NotNull + private static Collection getRepositoriesToRefresh(@NotNull final Map successfulWithTypes, + @NotNull GitRepository latestProcessed) { + Collection toRefresh = ContainerUtil.newHashSet(ContainerUtil.filter(successfulWithTypes.keySet(), + new Condition() { + @Override + public boolean value(GitRepository repository) { + return successfulWithTypes.get(repository) != SuccessType.UP_TO_DATE; + } + })); + toRefresh.add(latestProcessed); + return toRefresh; + } + + private static void refresh(@NotNull Collection repositories) { + updateRepositoriesInfo(repositories); + VfsUtil.markDirtyAndRefresh(false, true, false, toVirtualFileArray(getRootsFromRepositories(repositories))); + } + + private static void updateRepositoriesInfo(@NotNull Collection repositories) { + for (GitRepository repository : repositories) { + repository.update(); + } + } + + @NotNull + private static GitStashChangesSaver newSaver(@NotNull Project project, @NotNull ProgressIndicator indicator) { + Git git = ServiceManager.getService(Git.class); + GitPlatformFacade facade = ServiceManager.getService(GitPlatformFacade.class); + return new GitStashChangesSaver(project, facade, git, indicator, "Uncommitted changes before rebase"); + } + + private boolean saveDirtyRootsInitially(@NotNull List repositories) { + if (myParams.getMode() != GitRebaseParams.Mode.STANDARD) { + LOG.debug("No need to pre-save dirty roots in the " + myParams.getMode() + " mode"); + return true; + } + Collection rootsToSave = getRootsFromRepositories(getDirtyRoots(repositories)); + String error = saveLocalChanges(rootsToSave); + if (error != null) { + myNotifier.notifyError("Rebase not Started", error); + return false; + } + return true; + } + + @Nullable + private String saveLocalChanges(@NotNull Collection rootsToSave) { + try { + mySaver.saveLocalChanges(rootsToSave); + return null; + } + catch (VcsException e) { + LOG.warn(e); + return "Couldn't " + mySaver.getSaverName() + " local uncommitted changes:
" + e.getMessage(); + } + } + + private Collection findRootsWithLocalChanges(@NotNull Collection repositories) { + return ContainerUtil.filter(repositories, new Condition() { + @Override + public boolean value(GitRepository repository) { + return myChangeListManager.haveChangesUnder(repository.getRoot()) != ThreeState.NO; + } + }); + } + + private void notifySuccess(@NotNull Map successful) { + String rebasedBranch = getCommonCurrentBranchNameIfAllTheSame(myAllRepositories); + SuccessType commonType = getItemIfAllTheSame(successful.values(), SuccessType.REBASED); + String message = commonType.formatMessage(rebasedBranch, myParams.getBase()); + message += mentionSkippedCommits(); + myNotifier.notifyMinorInfo("Rebase Successful", message, new NotificationListener.Adapter() { + @Override + protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent e) { + handlePossibleCommitLinks(e.getDescription()); + } + }); + } + + @Nullable + private static String getCommonCurrentBranchNameIfAllTheSame(@NotNull Collection repositories) { + return getItemIfAllTheSame(ContainerUtil.map(repositories, new Function() { + @Override + public String fun(@NotNull GitRepository repository) { + return repository.getCurrentBranchName(); + } + }), null); + } + + @Contract("_, !null -> !null") + private static T getItemIfAllTheSame(@NotNull Collection collection, @Nullable T defaultItem) { + return ContainerUtil.newHashSet(collection).size() == 1 ? ContainerUtil.getFirstItem(collection) : defaultItem; + } + + private void notifyNotAllConflictsResolved(@NotNull GitRepository conflictingRepository, @NotNull Collection successful) { + String description = "You have to resolve the conflicts and continue rebase.
" + + "If you want to start from the beginning, you can abort rebase."; + description += GitRebaseUtils.mentionLocalChangesRemainingInStash(mySaver); + myNotifier.notifyImportantWarning("Rebase Suspended", description, + new RebaseNotificationListener(conflictingRepository, true, successful)); + } + + private boolean showConflictResolver(@NotNull GitRepository conflicting, boolean calledFromNotification) { + GitConflictResolver.Params params = new GitConflictResolver.Params().setReverse(true); + RebaseConflictResolver conflictResolver = new RebaseConflictResolver(myProject, myGit, myFacade, conflicting, params, + calledFromNotification); + return conflictResolver.merge(); + } + + private void showFatalError(@NotNull final String error, + @NotNull final GitRepository currentRepository, + boolean somethingWasRebased, + @NotNull final Collection successful) { + String description = "Rebase failed with error" + mention(currentRepository) + ": " + error + "
" + + mentionRetryAndAbort(somethingWasRebased, successful) + + mentionSkippedCommits() + + GitRebaseUtils.mentionLocalChangesRemainingInStash(mySaver); + myNotifier.notifyError("Rebase Failed", description, + new RebaseNotificationListener(currentRepository, somethingWasRebased, successful)); + } + + private void showUntrackedFilesError(@NotNull Set untrackedPaths, + @NotNull GitRepository currentRepository, + boolean somethingWasRebased, + @NotNull Collection successful) { + String message = GitUntrackedFilesHelper.createUntrackedFilesOverwrittenDescription("rebase", true) + + mentionRetryAndAbort(somethingWasRebased, successful) + + mentionSkippedCommits() + + GitRebaseUtils.mentionLocalChangesRemainingInStash(mySaver); + GitUntrackedFilesHelper.notifyUntrackedFilesOverwrittenBy(myProject, currentRepository.getRoot(), untrackedPaths, "rebase", message); + } + + @NotNull + private static String mentionRetryAndAbort(boolean somethingWasRebased, @NotNull Collection successful) { + return somethingWasRebased || !successful.isEmpty() + ? "You can retry or abort rebase." + : "Retry."; + } + + @NotNull + private String mentionSkippedCommits() { + if (mySkippedCommits.isEmpty()) return ""; + String message = "
"; + if (mySkippedCommits.size() == 1) { + message += "The following commit was skipped during rebase:
"; + } + else { + message += "The following commits were skipped during rebase:
"; + } + message += StringUtil.join(mySkippedCommits.values(), new Function() { + @Override + public String fun(@NotNull GitRebaseUtils.CommitInfo commitInfo) { + String commitMessage = StringUtil.shortenPathWithEllipsis(commitInfo.subject, 72, true); + String hash = commitInfo.revision.asString(); + String shortHash = DvcsUtil.getShortHash(commitInfo.revision.asString()); + return String.format("%s %s", hash, shortHash, commitMessage); + } + }, "
"); + return message; + } + + private enum SuccessType { + REBASED { + @NotNull + @Override + public String formatMessage(@Nullable String currentBranch, @NotNull String baseBranch) { + return "Rebased" + notNullize(currentBranch) + " on " + baseBranch; + } + }, + UP_TO_DATE { + @NotNull + @Override + public String formatMessage(@Nullable String currentBranch, @NotNull String baseBranch) { + return currentBranch != null ? currentBranch + " is up-to-date with " + baseBranch : "Up-to-date with " + baseBranch; + } + }, + FAST_FORWARDED { + @NotNull + @Override + public String formatMessage(@Nullable String currentBranch, @NotNull String baseBranch) { + return "Fast-forwarded" + notNullize(currentBranch) + " to " + baseBranch; + } + }; + + @NotNull + private static String notNullize(@Nullable String currentBranch) { + return currentBranch != null ? " " + currentBranch : ""; + } + + @NotNull + abstract String formatMessage(@Nullable String currentBranch, @NotNull String baseBranch); + + @NotNull + static SuccessType fromOutput(@NotNull List output) { + for (String line : output) { + if (StringUtil.containsIgnoreCase(line, "Fast-forwarded")) { + return FAST_FORWARDED; + } + if (StringUtil.containsIgnoreCase(line, "is up to date")) { + return UP_TO_DATE; + } + } + return REBASED; + } + } + + private class RebaseConflictResolver extends GitConflictResolver { + private final boolean myCalledFromNotification; + + RebaseConflictResolver(@NotNull Project project, + @NotNull Git git, + @NotNull GitPlatformFacade platformFacade, + @NotNull GitRepository repository, + @NotNull Params params, boolean calledFromNotification) { + super(project, git, platformFacade, singleton(repository.getRoot()), params); + myCalledFromNotification = calledFromNotification; + } + + @Override + protected void notifyUnresolvedRemain() { + // will be handled in the common notification + } + + @CalledInBackground + @Override + protected boolean proceedAfterAllMerged() throws VcsException { + if (myCalledFromNotification) retry(true); + return true; + } + } + + private class RebaseNotificationListener extends NotificationListener.Adapter { + @NotNull private final GitRepository myCurrentRepository; + private final boolean mySomethingWasRebased; + @NotNull private final Collection mySuccessful; + + RebaseNotificationListener(@NotNull GitRepository currentRepository, + boolean somethingWasRebased, + @NotNull Collection successful) { + myCurrentRepository = currentRepository; + mySomethingWasRebased = somethingWasRebased; + mySuccessful = successful; + } + + @Override + protected void hyperlinkActivated(@NotNull Notification notification, @NotNull final HyperlinkEvent e) { + final String href = e.getDescription(); + if ("abort".equals(href)) { + new Task.Backgroundable(myProject, "Aborting Rebase...") { + @Override + public void run(@NotNull ProgressIndicator indicator) { + abort(mySomethingWasRebased ? myCurrentRepository : null, mySuccessful, indicator); + } + }.queue(); + } + else if ("retry".equals(href) || "continue".equals(href)) { + new Task.Backgroundable(myProject, "Rebasing...") { + @Override + public void run(@NotNull ProgressIndicator indicator) { + retry(mySomethingWasRebased); + } + }.queue(); + } + else if ("resolve".equals(href)) { + showConflictResolver(myCurrentRepository, true); + } + else if ("stash".equals(href)) { + mySaver.showSavedChanges(); + } + else { + handlePossibleCommitLinks(href); + } + } + } + + private void handlePossibleCommitLinks(@NotNull String href) { + GitRepository repository = findRootBySkippedCommit(href); + if (repository != null) { + GitUtil.showSubmittedFiles(myProject, href, repository.getRoot(), true, false); + } + } + + @Nullable + private GitRepository findRootBySkippedCommit(@NotNull final String hash) { + return ContainerUtil.find(mySkippedCommits.keySet(), new Condition() { + @Override + public boolean value(GitRepository repository) { + return ContainerUtil.exists(mySkippedCommits.get(repository), new Condition() { + @Override + public boolean value(GitRebaseUtils.CommitInfo info) { + return info.revision.asString().equals(hash); + } + }); + } + }); + } +} diff --git a/plugins/git4idea/src/git4idea/rebase/GitRebaseUtils.java b/plugins/git4idea/src/git4idea/rebase/GitRebaseUtils.java index 798472f162ef..5db5e0f75c38 100644 --- a/plugins/git4idea/src/git4idea/rebase/GitRebaseUtils.java +++ b/plugins/git4idea/src/git4idea/rebase/GitRebaseUtils.java @@ -15,20 +15,31 @@ */ package git4idea.rebase; +import com.intellij.dvcs.repo.Repository; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vcs.VcsNotifier; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import git4idea.GitRevisionNumber; import git4idea.GitUtil; +import git4idea.branch.GitRebaseParams; +import git4idea.repo.GitRepository; import git4idea.repo.GitRepositoryFiles; +import git4idea.stash.GitChangesSaver; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; +import java.util.Collection; +import java.util.List; +import java.util.Map; /** * The utilities related to rebase functionality @@ -45,6 +56,61 @@ public class GitRebaseUtils { private GitRebaseUtils() { } + public static void rebase(@NotNull final Project project, + @NotNull final List repositories, + @NotNull final GitRebaseParams params, + @NotNull final ProgressIndicator indicator) { + if (!isRebaseAllowed(project, repositories)) return; // TODO maybe move to the outside + new GitRebaseProcess(project, repositories, params, indicator).rebase(); + } + + /** + * Abort the ongoing rebase process in the {@code repositoryToAbort}, + * and optionally rollback rebase which has already successfully completed in some other repositories. + * + * @param repositoryToAbort Repository to perform {@code git rebase --abort}. + * @param repositoriesToRollback Repositories to rollback the successful rebase, together with commit hashes which were HEAD revisions + * before that successful rebase started - these are the revisions which the method will rollback to + * via {@code git reset --keep}. + */ + public static void abort(@NotNull final Project project, + @Nullable final GitRepository repositoryToAbort, + @NotNull final Map repositoriesToRollback, + @NotNull ProgressIndicator progressIndicator) { + new GitAbortRebaseProcess(project, repositoryToAbort, repositoriesToRollback, progressIndicator, null).abortWithConfirmation(); + } + + private static boolean isRebaseAllowed(@NotNull Project project, @NotNull Collection repositories) { + // TODO links to 'rebase', 'resolve conflicts', etc. + for (GitRepository repository : repositories) { + Repository.State state = repository.getState(); + if (state != Repository.State.NORMAL) { + String in = GitUtil.mention(repository); + String message; + switch (state) { + case MERGING: + message = "There is an unfinished merge process" + in + ".
You should complete the merge before starting a rebase"; + break; + case REBASING: + message = "There is an unfinished rebase process" + in + ".
You should complete it before starting another rebase"; + break; + case GRAFTING: + message = "There is an unfinished cherry-pick process" + in + ".
You should finish it before starting a rebase."; + break; + case DETACHED: + message = "You are in the detached HEAD state" + in + ".
Rebase is not possible."; + break; + default: + LOG.error("Unknown state [" + state.name() + "]"); + message = "Rebase is not possible" + in; + } + VcsNotifier.getInstance(project).notifyError("Rebase not Allowed", message); + return false; + } + } + return true; + } + /** * Checks if the rebase is in the progress for the specified git root * @@ -140,6 +206,18 @@ public class GitRebaseUtils { return new CommitInfo(new GitRevisionNumber(hash), subject); } + @NotNull + static String mentionLocalChangesRemainingInStash(@Nullable GitChangesSaver saver) { + return saver != null && saver.wereChangesSaved() ? + "
Note that some local changes were " + toPast(saver.getOperationName()) + " before rebase." : + ""; + } + + @NotNull + private static String toPast(@NotNull String word) { + return word.endsWith("e") ? word + "d" : word + "ed"; + } + /** * Short commit info */ diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopupActions.java b/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopupActions.java index ac591d1f39ef..d253f82de947 100644 --- a/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopupActions.java +++ b/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopupActions.java @@ -172,6 +172,7 @@ class GitBranchPopupActions { new CheckoutAction(myProject, myRepositories, myBranchName), new CheckoutAsNewBranch(myProject, myRepositories, myBranchName), new CompareAction(myProject, myRepositories, myBranchName, mySelectedRepository), + new RebaseAction(myProject, myRepositories, myBranchName), new MergeAction(myProject, myRepositories, myBranchName, true), new DeleteAction(myProject, myRepositories, myBranchName) }; @@ -268,6 +269,7 @@ class GitBranchPopupActions { return new AnAction[] { new CheckoutRemoteBranchAction(myProject, myRepositories, myBranchName), new CompareAction(myProject, myRepositories, myBranchName, mySelectedRepository), + new RebaseAction(myProject, myRepositories, myBranchName), new MergeAction(myProject, myRepositories, myBranchName, false), new RemoteDeleteAction(myProject, myRepositories, myBranchName) }; @@ -378,4 +380,24 @@ class GitBranchPopupActions { return GitBrancher.DeleteOnMergeOption.NOTHING; } } + + private static class RebaseAction extends DumbAwareAction { + + private final Project myProject; + private final List myRepositories; + private final String myBranchName; + + public RebaseAction(@NotNull Project project, @NotNull List repositories, @NotNull String branchName) { + super("Rebase"); + myProject = project; + myRepositories = repositories; + myBranchName = branchName; + } + + @Override + public void actionPerformed(AnActionEvent e) { + GitBrancher brancher = ServiceManager.getService(myProject, GitBrancher.class); + brancher.rebase(myRepositories, myBranchName); + } + } } diff --git a/plugins/git4idea/tests/git4idea/log/GitLogProviderTest.java b/plugins/git4idea/tests/git4idea/log/GitLogProviderTest.java index d36b9081132c..9501ddc03ce6 100644 --- a/plugins/git4idea/tests/git4idea/log/GitLogProviderTest.java +++ b/plugins/git4idea/tests/git4idea/log/GitLogProviderTest.java @@ -39,7 +39,6 @@ import java.util.Collections; import java.util.List; import java.util.Set; -import static com.intellij.openapi.vcs.Executor.touch; import static git4idea.test.GitExecutor.*; import static git4idea.test.GitTestUtil.setupUsername; import static java.util.Collections.singleton; @@ -229,11 +228,6 @@ public class GitLogProviderTest extends GitSingleRepoTest { tac("b.txt"); } - private static String tac(@NotNull String file) { - touch(file, "content" + Math.random()); - return addCommit("touched " + file); - } - private static void createTaggedBranch() { String hash = last(); tac("c.txt"); diff --git a/plugins/git4idea/tests/git4idea/push/GitPushResultNotificationTest.java b/plugins/git4idea/tests/git4idea/push/GitPushResultNotificationTest.java index 46f84b8a3daf..6f568c4e5a9e 100644 --- a/plugins/git4idea/tests/git4idea/push/GitPushResultNotificationTest.java +++ b/plugins/git4idea/tests/git4idea/push/GitPushResultNotificationTest.java @@ -15,7 +15,6 @@ */ package git4idea.push; -import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; @@ -42,6 +41,7 @@ import java.util.Map; import static git4idea.push.GitPushNativeResult.Type.*; import static git4idea.push.GitPushRepoResult.convertFromNative; +import static git4idea.test.GitTestUtil.assertNotification; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; @@ -124,7 +124,7 @@ public class GitPushResultNotificationTest extends GitPlatformTest { GitPushResultNotification notification = notification(convertFromNative(branchResult, singletonList(tagResult), 1, from("master"), to("origin/master"))); assertNotification(NotificationType.INFORMATION, "Push successful", - "Pushed 1 commit to origin/master, and tag v0.1 to origin", notification); + "Pushed 1 commit to origin/master, and tag v0.1 to origin", notification); } public void test_nothing() { @@ -245,11 +245,4 @@ public class GitPushResultNotificationTest extends GitPlatformTest { }); return new MockGitRepository(ourProject, root); } - - private static void assertNotification(NotificationType type, String title, String content, Notification actual) { - assertEquals(type, actual.getType()); - assertEquals(title, actual.getTitle()); - assertEquals(content, actual.getContent()); - } - } \ No newline at end of file diff --git a/plugins/git4idea/tests/git4idea/rebase/GitMultiRepoRebaseTest.kt b/plugins/git4idea/tests/git4idea/rebase/GitMultiRepoRebaseTest.kt new file mode 100644 index 000000000000..5836da0958ad --- /dev/null +++ b/plugins/git4idea/tests/git4idea/rebase/GitMultiRepoRebaseTest.kt @@ -0,0 +1,210 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ +package git4idea.rebase + +import com.intellij.openapi.progress.EmptyProgressIndicator +import com.intellij.openapi.ui.Messages +import com.intellij.openapi.vcs.Executor +import com.intellij.openapi.vcs.Executor.mkdir +import com.intellij.openapi.vcs.Executor.touch +import git4idea.branch.GitRebaseParams +import git4idea.rebase.GitRebaseBaseTest.LocalChange +import git4idea.repo.GitRepository +import git4idea.test.GitExecutor.git +import git4idea.test.GitTestUtil.cleanupForAssertion +import git4idea.test.UNKNOWN_ERROR_TEXT +import kotlin.properties.Delegates +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + +public class GitMultiRepoRebaseTest : GitRebaseBaseTest() { + + private var myUltimate: GitRepository by Delegates.notNull() + private var myCommunity: GitRepository by Delegates.notNull() + private var myContrib: GitRepository by Delegates.notNull() + private var myAllRepositories: List by Delegates.notNull() + + override fun setUp() { + super.setUp() + + Executor.cd(myProjectRoot) + val community = mkdir("community") + val contrib = mkdir("contrib") + + myUltimate = createRepository(myProjectPath) + myCommunity = createRepository(community.path) + myContrib = createRepository(contrib.path) + myAllRepositories = listOf(myUltimate, myCommunity, myContrib) + + Executor.cd(myProjectRoot) + touch(".gitignore", "community\ncontrib") + git("add .gitignore") + git("commit -m gitignore") + } + + public fun `test all successful`() { + myUltimate.`place feature above master`() + myCommunity.`diverge feature and master`() + myContrib.`place feature on master`() + + rebase("master") + + assertSuccessfulNotification("Rebased feature on master") + assertAllRebased() + assertNoRebaseInProgress(myAllRepositories) + } + + public fun `test abort from critical error during rebasing 2nd root, before any commits were applied`() { + val localChange = LocalChange(myUltimate, "new.txt", "Some content") + val rebaseProcess = `fail with critical error while rebasing 2nd root`(localChange) + + assertErrorNotification("Rebase Failed", + """ + Rebase failed with error in community:
+ $UNKNOWN_ERROR_TEXT + You can retry or abort rebase. + $LOCAL_CHANGES_WARNING + """) + + myUltimate.`assert feature rebased on master`() + myCommunity.`assert feature not rebased on master`() + myContrib.`assert feature not rebased on master`() + assertNoRebaseInProgress(myAllRepositories) + myUltimate.assertNoLocalChanges() + + var confirmation: String? = null + myDialogManager.onMessage { + confirmation = it + Messages.YES; + } + + rebaseProcess.abort(null, listOf(myUltimate), EmptyProgressIndicator()) + + assertNotNull(confirmation, "Abort confirmation message was not shown") + assertEquals(cleanupForAssertion("Do you want rollback the successful rebase in project?"), + cleanupForAssertion(confirmation!!), + "Incorrect confirmation message text"); + assertNoRebaseInProgress(myAllRepositories) + myAllRepositories.forEach { it.`assert feature not rebased on master`() } + + localChange.verify() + } + + public fun `test abort from critical error while rebasing 2nd root, after some commits were applied`() { + val localChange = LocalChange(myUltimate, "new.txt", "Some content") + val rebaseProcess = `fail with critical error while rebasing 2nd root after some commits are applied`(localChange) + + myVcsNotifier.lastNotification + + var confirmation: String? = null + myDialogManager.onMessage { + confirmation = it + Messages.YES; + } + + rebaseProcess.abort(myCommunity, listOf(myUltimate), EmptyProgressIndicator()) + + assertNotNull(confirmation, "Abort confirmation message was not shown") + assertEquals(cleanupForAssertion("Do you want just to abort rebase in community, or also rollback the successful rebase in project?"), + cleanupForAssertion(confirmation!!), + "Incorrect confirmation message text"); + assertNoRebaseInProgress(myAllRepositories) + myAllRepositories.forEach { it.`assert feature not rebased on master`() } + + localChange.verify() + } + + public fun `test conflicts in multiple repositories are resolved separately`() { + myUltimate.`prepare simple conflict`() + myCommunity.`prepare simple conflict`() + myContrib.`diverge feature and master`() + + var conflictInUltimate = false + var conflictInCommunity = false + myVcsHelper.onMerge({ + if (!conflictInUltimate) { + myUltimate.assertConflict("c.txt") + assertNoRebaseInProgress(myCommunity) + resolveConflicts(myUltimate) + conflictInUltimate = true + } + else { + assertFalse(conflictInCommunity) + myCommunity.assertConflict("c.txt") + assertNoRebaseInProgress(myUltimate) + resolveConflicts(myCommunity) + conflictInCommunity = true + } + }) + + rebase("master") + + assertTrue(conflictInUltimate) + assertTrue(conflictInCommunity) + myAllRepositories.forEach { + it.`assert feature rebased on master`() + assertNoRebaseInProgress(it) + it.assertNoLocalChanges() + } + } + + public fun `test retry doesn't touch successful repositories`() { + val rebaseProcess = `fail with critical error while rebasing 2nd root`() + + rebaseProcess.retry(false) + + assertSuccessfulNotification("Rebased feature on master") + assertAllRebased() + assertNoRebaseInProgress(myAllRepositories) + } + + private fun `fail with critical error while rebasing 2nd root`(localChange: LocalChange? = null): GitRebaseProcess { + myAllRepositories.forEach { it.`diverge feature and master`() } + localChange?.generate() + + myFailingGit.setShouldFail { it == myCommunity } + val rebaseProcess = rebase("master") + + myFailingGit.setShouldFail { false } + return rebaseProcess + } + + private fun `fail with critical error while rebasing 2nd root after some commits are applied`(localChange: LocalChange? = null): GitRebaseProcess { + myUltimate.`diverge feature and master`() + myCommunity.`make rebase fail on 2nd commit`() + myContrib.`diverge feature and master`() + localChange?.generate() + + val rebaseProcess = rebase("master") + + myFailingGit.setShouldFail { false } + return rebaseProcess + } + + private fun rebase(onto: String): GitRebaseProcess { + val rebaseProcess = GitRebaseProcess(myProject, myAllRepositories, GitRebaseParams(onto), EmptyProgressIndicator()) + rebaseProcess.rebase() + return rebaseProcess + } + + private fun assertAllRebased() { + assertRebased(myUltimate, "feature", "master") + assertRebased(myCommunity, "feature", "master") + assertRebased(myContrib, "feature", "master") + } +} diff --git a/plugins/git4idea/tests/git4idea/rebase/GitRebaseBaseTest.kt b/plugins/git4idea/tests/git4idea/rebase/GitRebaseBaseTest.kt new file mode 100644 index 000000000000..f96e7c876a16 --- /dev/null +++ b/plugins/git4idea/tests/git4idea/rebase/GitRebaseBaseTest.kt @@ -0,0 +1,223 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ +package git4idea.rebase + +import com.intellij.dvcs.repo.Repository +import com.intellij.notification.Notification +import com.intellij.notification.NotificationType.ERROR +import com.intellij.notification.NotificationType.INFORMATION +import com.intellij.notification.NotificationType.WARNING +import com.intellij.openapi.vcs.AbstractVcsHelper +import com.intellij.openapi.vcs.Executor +import git4idea.GitUtil +import git4idea.commands.Git +import git4idea.repo.GitRepository +import git4idea.test.* +import git4idea.test.GitExecutor.cd +import git4idea.test.GitExecutor.git +import git4idea.test.GitTestUtil.assertNotification +import kotlin.test.assertEquals +import kotlin.test.assertFalse + +public abstract class GitRebaseBaseTest : GitPlatformTest() { + + protected val LOCAL_CHANGES_WARNING : String = "Note that some local changes were stashed before rebase." + + lateinit protected var myVcsHelper: MockVcsHelper + lateinit protected var myFailingGit: TestGitImpl + + override fun setUp() { + super.setUp() + + myVcsHelper = GitTestUtil.overrideService(myProject, AbstractVcsHelper::class.java, MockVcsHelper::class.java) + myFailingGit = GitTestUtil.overrideService(Git::class.java, TestGitImpl::class.java) + } + + override fun tearDown() { + try { + myFailingGit.setShouldFail { false } // to do check for null + } + finally { + super.tearDown() + } + } + + override fun createRepository(path: String) = GitTestUtil.createRepository(myProject, path, false) + + override fun getDebugLogCategories() = listOf("#" + GitRebaseProcess::class.java.name) + + protected fun GitRepository.`diverge feature and master`() { + build(this) { + master { + 0() + 1() + } + feature(0) { + 2() + } + } + } + + protected fun GitRepository.`place feature above master`() { + build(this) { + master { + 0() + 1() + } + feature { + 2() + } + } + } + + protected fun GitRepository.`place feature below master`() { + build(this) { + master { + 0() + 1() + } + feature(0) { + } + } + } + + protected fun GitRepository.`place feature on master`() { + build(this) { + master { + 0() + 1() + } + feature {} + } + } + + protected fun GitRepository.`prepare simple conflict`() { + build(this) { + master { + 0("c.txt") + 1("c.txt") + } + feature(0) { + 2("c.txt") + } + } + } + + protected fun assertSuccessfulNotification(message: String) { + assertNotification(INFORMATION, "Rebase Successful", message, myVcsNotifier.lastNotification) + } + + protected fun assertWarningNotification(title: String, message: String) { + assertNotification(WARNING, title, message, myVcsNotifier.lastNotification) + } + + protected fun assertErrorNotification(title: String, message: String) : Notification { + val notification = myVcsNotifier.lastNotification + assertNotification(ERROR, title, message, notification) + return notification + } + + protected fun GitRepository.`make rebase fail on 2nd commit`() { + build(this) { + master { + 0() + 1("m.txt") + } + feature(0) { + 2() + 3("m.txt") + } + } + `make rebase fail after resolving conflicts`() + } + + protected fun GitRepository.`make rebase fail after resolving conflicts`() { + myVcsHelper.onMerge { + resolveConflicts(this) + myFailingGit.setShouldFail { true } + } + } + + protected fun resolveConflicts(repository: GitRepository) { + cd(repository) + git("add -u .") + } + + protected fun GitRepository.`assert feature rebased on master`() { + assertRebased(this, "feature", "master") + } + + protected fun GitRepository.`assert feature not rebased on master`() { + assertNotRebased("feature", "master", this) + } + + protected fun assertRebased(repository: GitRepository, feature: String, master: String) { + cd(repository) + assertEquals(git("rev-parse " + master), git("merge-base $feature $master")) + } + + protected fun assertNotRebased(feature: String, master: String, repository: GitRepository) { + cd(repository) + assertFalse(git("rev-parse " + master) == git("merge-base $feature $master"), + "$feature is unexpectedly rebased on $master" + GitUtil.mention(repository)) + } + + protected fun assertNoRebaseInProgress(repository: GitRepository) { + assertEquals(Repository.State.NORMAL, repository.state) + } + + protected fun assertNoRebaseInProgress(repositories: Collection) { + for (repository in repositories) { + assertNoRebaseInProgress(repository) + } + } + + protected fun GitRepository.assertRebaseInProgress() { + assertEquals(Repository.State.REBASING, this.state) + } + + protected fun GitRepository.assertNoLocalChanges() { + assertEquals("", gitStatus(), "There should be no local changes!") + } + + protected fun GitRepository.isDirty(): Boolean { + return !gitStatus().isEmpty(); + } + + private fun GitRepository.gitStatus() = git(this, "status --porcelain").trim() + + protected fun GitRepository.assertConflict(file: String) { + assertEquals("UU " + file, git(this, "status --porcelain")) + } + + public class LocalChange(val repository: GitRepository, val filePath: String, val content: String = "Some content") { + fun generate() : LocalChange { + cd(repository) + GitExecutor.file(filePath).create(content).add() + return this + } + + fun verify() { + assertNewFile(repository, filePath, content) + } + + public fun assertNewFile(repository: GitRepository, file: String, content: String) { + cd(repository) + assertEquals("A " + file, git("status --porcelain"), "Incorrect git status output") + assertEquals(content, Executor.cat(file), "Incorrect content of the file [$file]") + } + } +} diff --git a/plugins/git4idea/tests/git4idea/rebase/GitSingleRepoRebaseTest.kt b/plugins/git4idea/tests/git4idea/rebase/GitSingleRepoRebaseTest.kt new file mode 100644 index 000000000000..d232f98bdef2 --- /dev/null +++ b/plugins/git4idea/tests/git4idea/rebase/GitSingleRepoRebaseTest.kt @@ -0,0 +1,405 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ +package git4idea.rebase + +import com.intellij.dvcs.DvcsUtil +import com.intellij.openapi.progress.EmptyProgressIndicator +import com.intellij.openapi.ui.Messages +import git4idea.branch.GitRebaseParams +import git4idea.rebase.GitRebaseBaseTest.LocalChange +import git4idea.repo.GitRepository +import git4idea.test.GitExecutor.file +import git4idea.test.GitExecutor.git +import git4idea.test.RepoBuilder +import git4idea.test.UNKNOWN_ERROR_TEXT +import git4idea.test.build +import kotlin.properties.Delegates +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +public class GitSingleRepoRebaseTest : GitRebaseBaseTest() { + + protected var myRepo: GitRepository by Delegates.notNull() + + override fun setUp() { + super.setUp() + myRepo = createRepository(myProjectPath) + } + + fun `test simple case`() { + myRepo.`diverge feature and master`() + + rebaseOnMaster() + + assertSuccessfulNotification("Rebased feature on master") + myRepo.`assert feature rebased on master`() + assertNoRebaseInProgress(myRepo) + } + + fun `test up-to-date`() { + myRepo.`place feature above master`() + + rebaseOnMaster() + + assertSuccessfulNotification("feature is up-to-date with master") + myRepo.`assert feature rebased on master`() + assertNoRebaseInProgress(myRepo) + } + + fun test_ff() { + myRepo.`place feature below master`() + + rebaseOnMaster() + + assertSuccessfulNotification("Fast-forwarded feature to master") + myRepo.`assert feature rebased on master`() + assertNoRebaseInProgress(myRepo) + } + + fun `test conflict resolver is shown`() { + myRepo.`prepare simple conflict`() + `do nothing on merge`() + + rebaseOnMaster() + + assertTrue(myVcsHelper.mergeDialogWasShown()) + } + + fun `test fail on 2nd commit should show notification with proposal to abort`() { + myRepo.`make rebase fail on 2nd commit`() + + rebaseOnMaster() + + `assert unknown error notification with link to abort`() + } + + fun `test multiple conflicts`() { + build { + master { + 0("c.txt") + 1("c.txt") + } + feature(0) { + 2("c.txt") + 3("c.txt") + } + } + + var conflicts = 0 + myVcsHelper.onMerge { + conflicts++ + myRepo.assertConflict("c.txt") + resolveConflicts(myRepo) + } + + rebaseOnMaster() + + assertEquals(2, conflicts, "Incorrect number of conflicting patches") + myRepo.`assert feature rebased on master`() + assertSuccessfulNotification("Rebased feature on master") + } + + fun `test continue rebase after resolving all conflicts`() { + myRepo.`prepare simple conflict`() + + myVcsHelper.onMerge { + resolveConflicts(myRepo) + } + + rebaseOnMaster() + assertSuccessfulNotification("Rebased feature on master") + myRepo.`assert feature rebased on master`() + assertNoRebaseInProgress(myRepo) + } + + fun `test warning notification if conflicts were not resolved`() { + myRepo.`prepare simple conflict`() + `do nothing on merge`() + + rebaseOnMaster() + `assert conflict not resolved notification`() + myRepo.assertRebaseInProgress() + } + + fun `test rebase failed for unknown reason`() { + myRepo.`diverge feature and master`() + myFailingGit.setShouldFail { true } + rebaseOnMaster() + `assert unknown error notification`() + } + + fun `test propose to abort when rebase failed after continue`() { + myRepo.`prepare simple conflict`() + `do nothing on merge`() + + rebaseOnMaster() + + myRepo.`assert feature not rebased on master`() + myRepo.assertRebaseInProgress() + resolveConflicts(myRepo) + + myFailingGit.setShouldFail { true } + val continueRebase = GitRebaseParams("master").withMode(GitRebaseParams.Mode.CONTINUE) + GitTestingRebaseProcess(continueRebase).rebase() + + `assert unknown error notification with link to abort`() + myRepo.`assert feature not rebased on master`() + myRepo.assertRebaseInProgress() + } + + fun `test local changes auto-saved`() { + myRepo.`diverge feature and master`() + val localChange = LocalChange(myRepo, "new.txt").generate() + + rebaseOnMaster() + + assertSuccessfulNotification("Rebased feature on master") + assertRebased(myRepo, "feature", "master") + assertNoRebaseInProgress(myRepo) + localChange.verify() + } + + fun `test local changes are saved even if not detected initially`() { + myRepo.`diverge feature and master`() + val localChange = LocalChange(myRepo, "new.txt").generate() + + object : GitTestingRebaseProcess(GitRebaseParams("master")) { + override fun getDirtyRoots(repositories: Collection): Collection { + return emptyList() + } + }.rebase() + + assertSuccessfulNotification("Rebased feature on master") + assertRebased(myRepo, "feature", "master") + assertNoRebaseInProgress(myRepo) + localChange.verify() + } + + fun `test local changes are not restored in case of error even if nothing was rebased`() { + myRepo.`diverge feature and master`() + LocalChange(myRepo, "new.txt", "content").generate() + + myFailingGit.setShouldFail { true } + + rebaseOnMaster() + + assertErrorNotification("Rebase Failed", + """ + Rebase failed with error: $UNKNOWN_ERROR_TEXT
+ Retry.
+ Note that some local changes were stashed before rebase. + """) + assertNoRebaseInProgress(myRepo) + myRepo.assertNoLocalChanges() + assertFalse(file("new.txt").exists()) + } + + fun `test critical error should show notification and not restore local changes`() { + myRepo.`diverge feature and master`() + LocalChange(myRepo, "new.txt", "content").generate() + myFailingGit.setShouldFail { true } + + rebaseOnMaster() + + `assert unknown error notification with link to stash`() + myRepo.assertNoLocalChanges() + } + + fun `test successful retry from notification on critical error restores local changes`() { + myRepo.`diverge feature and master`() + val localChange = LocalChange(myRepo, "new.txt", "content").generate() + + var attempt = 0 + myFailingGit.setShouldFail { attempt == 0 } + + val rebaseProcess = rebaseOnMaster() + + attempt++ + myVcsNotifier.lastNotification + + rebaseProcess.retry(false) + + assertNoRebaseInProgress(myRepo) + myRepo.`assert feature rebased on master`() + localChange.verify() + } + + fun `test local changes are restored after successful abort`() { + myRepo.`prepare simple conflict`() + val localChange = LocalChange(myRepo, "new.txt", "content").generate() + myVcsHelper.onMerge {} + myDialogManager.onMessage { Messages.YES } + + val rebaseProcess = rebaseOnMaster() + + `assert conflict not resolved notification with link to stash`() + + rebaseProcess.abort(myRepo, emptyList(), EmptyProgressIndicator()) + + assertNoRebaseInProgress(myRepo) + myRepo.`assert feature not rebased on master`() + localChange.verify() + } + + fun `test local changes are not restored after failed abort`() { + myRepo.`prepare simple conflict`() + LocalChange(myRepo, "new.txt", "content").generate() + myVcsHelper.onMerge {} + myDialogManager.onMessage { Messages.YES } + + val rebaseProcess = rebaseOnMaster() + + `assert conflict not resolved notification with link to stash`() + + myFailingGit.setShouldFail { true } + rebaseProcess.abort(myRepo, emptyList(), EmptyProgressIndicator()) + + myRepo.assertRebaseInProgress() + myRepo.`assert feature not rebased on master`() + myRepo.assertConflict("c.txt") + assertErrorNotification("Rebase Abort Failed", + """ + unknown error
+ $LOCAL_CHANGES_WARNING + """) + } + + // git rebase --continue should be either called from a commit dialog, either from the GitRebaseProcess. + // both should prepare the working tree themselves by adding all necessary changes to the index. + fun `test local changes should not be saved when continue rebase`() { + myRepo.`prepare simple conflict`() + `do nothing on merge`() + + rebaseOnMaster() + myRepo.assertConflict("c.txt") + + //manually resolve conflicts + resolveConflicts(myRepo) + file("c.txt").append("more changes after resolving") + // forget to git add afterwards + + val continueRebase = GitRebaseParams("master").withMode(GitRebaseParams.Mode.CONTINUE) + GitTestingRebaseProcess(continueRebase).rebase() + + assertErrorNotification("Rebase Failed", + """ + Rebase failed with error: c.txt: needs update + You must edit all merge conflicts + and then mark them as resolved using git add + You can retry or abort rebase. + """) + + myRepo.`assert feature not rebased on master`() + myRepo.assertRebaseInProgress() + } + + fun `test skipped commit`() { + build { + master { + 0("c.txt", "base") + 1("c.txt", "\nmaster") + } + feature(0) { + 2("c.txt", "feature", "commit to be skipped") + 3() + } + } + + val hash2skip = DvcsUtil.getShortHash(git("log -2 --pretty=%H").lines().get(1)) + + myVcsHelper.onMerge { + file("c.txt").write("base\nmaster") + resolveConflicts(myRepo) + } + + rebaseOnMaster() + + assertRebased(myRepo, "feature", "master") + assertNoRebaseInProgress(myRepo) + + assertSuccessfulNotification( + """ + Rebased feature on master
+ The following commit was skipped during rebase:
+ $hash2skip commit to be skipped + """) + } + + private fun build(f: RepoBuilder.() -> Unit) { + build(myRepo, f) + } + + private fun `do nothing on merge`() { + myVcsHelper.onMerge{} + } + + private open inner class GitTestingRebaseProcess(params: GitRebaseParams) : + GitRebaseProcess(myProject, listOf(myRepo), params, EmptyProgressIndicator()) { + override fun getDirtyRoots(repositories: Collection): Collection { + return if (myRepo.isDirty()) listOf(myRepo) else emptyList() + } + } + + private fun rebaseOnMaster() : GitRebaseProcess { + val rebaseProcess = GitTestingRebaseProcess(GitRebaseParams("master")) + rebaseProcess.rebase() + return rebaseProcess + } + + private fun `assert conflict not resolved notification`() { + assertWarningNotification("Rebase Suspended", + """ + You have to resolve the conflicts and continue rebase.
+ If you want to start from the beginning, you can abort rebase. + """) + } + + private fun `assert conflict not resolved notification with link to stash`() { + assertWarningNotification("Rebase Suspended", + """ + You have to resolve the conflicts and continue rebase.
+ If you want to start from the beginning, you can abort rebase.
+ $LOCAL_CHANGES_WARNING + """) + } + + private fun `assert unknown error notification`() { + assertErrorNotification("Rebase Failed", + """ + Rebase failed with error: $UNKNOWN_ERROR_TEXT
+ Retry. + """) + } + + private fun `assert unknown error notification with link to abort`() { + assertErrorNotification("Rebase Failed", + """ + Rebase failed with error: $UNKNOWN_ERROR_TEXT
+ You can retry or abort rebase. + """) + } + + private fun `assert unknown error notification with link to stash`() { + assertErrorNotification("Rebase Failed", + """ + Rebase failed with error: $UNKNOWN_ERROR_TEXT
+ Retry.
+ $LOCAL_CHANGES_WARNING + """) + } +} + diff --git a/plugins/git4idea/tests/git4idea/test/GitExecutor.java b/plugins/git4idea/tests/git4idea/test/GitExecutor.java index bde7ca388677..3a952a0281a6 100644 --- a/plugins/git4idea/tests/git4idea/test/GitExecutor.java +++ b/plugins/git4idea/tests/git4idea/test/GitExecutor.java @@ -15,15 +15,19 @@ */ package git4idea.test; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.Executor; import git4idea.repo.GitRepository; import org.jetbrains.annotations.NotNull; import java.io.File; +import java.io.IOException; import java.util.Arrays; import java.util.List; +import static org.junit.Assert.assertFalse; + /** * * @author Kirill Likhodedov @@ -116,6 +120,12 @@ public class GitExecutor extends Executor { return last(); } + @NotNull + public static String tac(@NotNull String file) { + touch(file, "content" + Math.random()); + return addCommit("touched " + file); + } + @NotNull public static String last() { return git("log -1 --pretty=%H"); @@ -141,4 +151,56 @@ public class GitExecutor extends Executor { } } + @NotNull + public static TestFile file(@NotNull String fileName) { + File f = child(fileName); + return new TestFile(f); + } + + public static class TestFile { + @NotNull private final File myFile; + + private TestFile(@NotNull File file) { + myFile = file; + } + + public TestFile append(@NotNull String content) throws IOException { + FileUtil.writeToFile(myFile, content.getBytes(), true); + return this; + } + + public TestFile write(@NotNull String content) throws IOException { + FileUtil.writeToFile(myFile, content.getBytes(), false); + return this; + } + + public TestFile create(@NotNull String content) throws IOException { + assertNotExists(); + FileUtil.writeToFile(myFile, content.getBytes(), false); + return this; + } + + public TestFile assertNotExists() { + assertFalse(myFile.exists()); + return this; + } + + public TestFile add() { + GitExecutor.add(myFile.getPath()); + return this; + } + + public TestFile commit() { + return commit("Some message"); + } + + public TestFile commit(String message) { + GitExecutor.commit(message); + return this; + } + + public boolean exists() { + return myFile.exists(); + } + } } diff --git a/plugins/git4idea/tests/git4idea/test/GitTestUtil.java b/plugins/git4idea/tests/git4idea/test/GitTestUtil.java index 257cff8d4dc5..4244d9410e86 100644 --- a/plugins/git4idea/tests/git4idea/test/GitTestUtil.java +++ b/plugins/git4idea/tests/git4idea/test/GitTestUtil.java @@ -15,6 +15,8 @@ */ package git4idea.test; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; @@ -43,6 +45,7 @@ import static com.intellij.openapi.vcs.Executor.mkdir; import static com.intellij.openapi.vcs.Executor.touch; import static git4idea.test.GitExecutor.*; import static junit.framework.Assert.assertNotNull; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assume.assumeTrue; @@ -125,6 +128,7 @@ public class GitTestUtil { } @SuppressWarnings("unchecked") + @NotNull public static T overrideService(@NotNull Project project, Class serviceInterface, Class serviceImplementation) { String key = serviceInterface.getName(); MutablePicoContainer picoContainer = (MutablePicoContainer) project.getPicoContainer(); @@ -134,6 +138,7 @@ public class GitTestUtil { } @SuppressWarnings("unchecked") + @NotNull public static T overrideService(Class serviceInterface, Class serviceImplementation) { String key = serviceInterface.getName(); MutablePicoContainer picoContainer = (MutablePicoContainer) ApplicationManager.getApplication().getPicoContainer(); @@ -158,4 +163,23 @@ public class GitTestUtil { addCommit("some message"); return last(); } + + public static void assertNotification(@NotNull NotificationType type, + @NotNull String title, + @NotNull String content, + @NotNull Notification actual) { + assertEquals("Incorrect type of notification: " + tos(actual), type, actual.getType()); + assertEquals(title, actual.getTitle()); + assertEquals(cleanupForAssertion(content), cleanupForAssertion(actual.getContent())); + } + + @NotNull + public static String cleanupForAssertion(@NotNull String content) { + return content.replace("
", "\n").replace("\n", " ").replaceAll("[ ]{2,}", " ").replaceAll(" href='[^']*'", "").trim(); + } + + @NotNull + private static String tos(@NotNull Notification notification) { + return notification.getTitle() + "|" + notification.getContent(); + } } diff --git a/plugins/git4idea/tests/git4idea/test/MockVcsHelper.java b/plugins/git4idea/tests/git4idea/test/MockVcsHelper.java deleted file mode 100644 index 15bc061c7d29..000000000000 --- a/plugins/git4idea/tests/git4idea/test/MockVcsHelper.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * 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 - * - * http://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. - */ -package git4idea.test; - -import com.intellij.ide.errorTreeView.HotfixData; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vcs.*; -import com.intellij.openapi.vcs.annotate.AnnotationProvider; -import com.intellij.openapi.vcs.annotate.FileAnnotation; -import com.intellij.openapi.vcs.changes.Change; -import com.intellij.openapi.vcs.changes.CommitResultHandler; -import com.intellij.openapi.vcs.changes.LocalChangeList; -import com.intellij.openapi.vcs.history.VcsFileRevision; -import com.intellij.openapi.vcs.history.VcsHistoryProvider; -import com.intellij.openapi.vcs.history.VcsRevisionNumber; -import com.intellij.openapi.vcs.merge.MergeDialogCustomizer; -import com.intellij.openapi.vcs.merge.MergeProvider; -import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings; -import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; -import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.awt.*; -import java.io.File; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public class MockVcsHelper extends AbstractVcsHelper { - private volatile boolean myCommitDialogShown; - private volatile boolean myMergeDialogShown; - - private CommitHandler myCommitHandler; - private MergeHandler myMergeHandler; - - public MockVcsHelper(@NotNull Project project) { - super(project); - } - - @Override - public void showErrors(List abstractVcsExceptions, @NotNull String tabDisplayName) { - throw new UnsupportedOperationException(); - } - - @Override - public void showErrors(Map> exceptionGroups, @NotNull String tabDisplayName) { - throw new UnsupportedOperationException(); - } - - @Override - public List runTransactionRunnable(AbstractVcs vcs, TransactionRunnable runnable, Object vcsParameters) { - throw new UnsupportedOperationException(); - } - - @Override - public void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs, int line) { - throw new UnsupportedOperationException(); - } - - @Override - public void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs) { - throw new UnsupportedOperationException(); - } - - @Override - public void showDifferences(VcsFileRevision cvsVersionOn, VcsFileRevision cvsVersionOn1, File file) { - throw new UnsupportedOperationException(); - } - - @Override - public void showChangesListBrowser(CommittedChangeList changelist, @Nls String title) { - throw new UnsupportedOperationException(); - } - - @Override - public void showChangesBrowser(List changelists) { - throw new UnsupportedOperationException(); - } - - @Override - public void showChangesBrowser(List changelists, @Nls String title) { - throw new UnsupportedOperationException(); - } - - @Override - public void showChangesBrowser(CommittedChangesProvider provider, - RepositoryLocation location, - @Nls String title, - @Nullable Component parent) { - throw new UnsupportedOperationException(); - } - - @Override - public void showWhatDiffersBrowser(@Nullable Component parent, Collection changes, @Nls String title) { - throw new UnsupportedOperationException(); - } - - @Override - public T chooseCommittedChangeList(@NotNull CommittedChangesProvider provider, - RepositoryLocation location) { - throw new UnsupportedOperationException(); - } - - @Override - public void openCommittedChangesTab(AbstractVcs vcs, VirtualFile root, ChangeBrowserSettings settings, int maxCount, String title) { - throw new UnsupportedOperationException(); - } - - @Override - public void openCommittedChangesTab(CommittedChangesProvider provider, - RepositoryLocation location, - ChangeBrowserSettings settings, - int maxCount, - String title) { - throw new UnsupportedOperationException(); - } - - @NotNull - @Override - public List showMergeDialog(List files, - MergeProvider provider, - @NotNull MergeDialogCustomizer mergeDialogCustomizer) { - myMergeDialogShown = true; - if (myMergeHandler != null) { - myMergeHandler.showMergeDialog(); - } - return Collections.emptyList(); - } - - public boolean mergeDialogWasShown() { - return myMergeDialogShown; - } - - @Override - public void showFileHistory(@NotNull VcsHistoryProvider historyProvider, @NotNull FilePath path, @NotNull AbstractVcs vcs, String repositoryPath) { - throw new UnsupportedOperationException(); - } - - @Override - public void showFileHistory(@NotNull VcsHistoryProvider historyProvider, - AnnotationProvider annotationProvider, - @NotNull FilePath path, - String repositoryPath, - @NotNull AbstractVcs vcs) { - throw new UnsupportedOperationException(); - } - - @Override - public void showRollbackChangesDialog(List changes) { - throw new UnsupportedOperationException(); - } - - @Override - public Collection selectFilesToProcess(List files, - String title, - @Nullable String prompt, - String singleFileTitle, - String singleFilePromptTemplate, - VcsShowConfirmationOption confirmationOption) { - throw new UnsupportedOperationException(); - } - - @Override - public Collection selectFilePathsToProcess(List files, - String title, - @Nullable String prompt, - String singleFileTitle, - String singleFilePromptTemplate, - VcsShowConfirmationOption confirmationOption) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean commitChanges(@NotNull Collection changes, @NotNull LocalChangeList initialChangeList, - @NotNull String commitMessage, @Nullable CommitResultHandler customResultHandler) { - myCommitDialogShown = true; - if (myCommitHandler != null) { - boolean success = myCommitHandler.commit(commitMessage); - if (customResultHandler != null) { - if (success) { - customResultHandler.onSuccess(commitMessage); - } - else { - customResultHandler.onFailure(); - } - } - return success; - } - if (customResultHandler != null) { - customResultHandler.onFailure(); - } - return false; - } - - public void registerHandler(CommitHandler handler) { - myCommitHandler = handler; - } - - public void registerHandler(MergeHandler handler) { - myMergeHandler = handler; - } - - public boolean commitDialogWasShown() { - return myCommitDialogShown; - } - - public interface CommitHandler { - boolean commit(String commitMessage); - } - - public interface MergeHandler { - void showMergeDialog(); - } - - @Override - public void loadAndShowCommittedChangesDetails(@NotNull Project project, - @NotNull VcsRevisionNumber revision, - @NotNull VirtualFile file, - @NotNull VcsKey key, - @Nullable RepositoryLocation location, - boolean local) { - } -} diff --git a/plugins/git4idea/tests/git4idea/test/MockVcsHelper.kt b/plugins/git4idea/tests/git4idea/test/MockVcsHelper.kt new file mode 100644 index 000000000000..9d559f9d354f --- /dev/null +++ b/plugins/git4idea/tests/git4idea/test/MockVcsHelper.kt @@ -0,0 +1,180 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ +package git4idea.test + +import com.intellij.ide.errorTreeView.HotfixData +import com.intellij.openapi.project.Project +import com.intellij.openapi.vcs.* +import com.intellij.openapi.vcs.annotate.AnnotationProvider +import com.intellij.openapi.vcs.annotate.FileAnnotation +import com.intellij.openapi.vcs.changes.Change +import com.intellij.openapi.vcs.changes.CommitResultHandler +import com.intellij.openapi.vcs.changes.LocalChangeList +import com.intellij.openapi.vcs.history.VcsFileRevision +import com.intellij.openapi.vcs.history.VcsHistoryProvider +import com.intellij.openapi.vcs.history.VcsRevisionNumber +import com.intellij.openapi.vcs.merge.MergeDialogCustomizer +import com.intellij.openapi.vcs.merge.MergeProvider +import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings +import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList +import com.intellij.openapi.vfs.VirtualFile +import java.awt.Component +import java.io.File + +public class MockVcsHelper(project: Project) : AbstractVcsHelper(project) { + @Volatile private var myCommitDialogShown: Boolean = false + @Volatile private var myMergeDialogShown: Boolean = false + @Volatile private var myMergeDelegate: () -> Unit = { throw IllegalStateException() } + @Volatile private var myCommitDelegate: (String) -> Boolean = { throw IllegalStateException() } + + override fun runTransactionRunnable(vcs: AbstractVcs<*>?, runnable: TransactionRunnable?, vcsParameters: Any?): MutableList? { + throw UnsupportedOperationException() + } + + override fun showAnnotation(annotation: FileAnnotation?, file: VirtualFile?, vcs: AbstractVcs<*>?) { + throw UnsupportedOperationException() + } + + override fun showAnnotation(annotation: FileAnnotation?, file: VirtualFile?, vcs: AbstractVcs<*>?, line: Int) { + throw UnsupportedOperationException() + } + + override fun showChangesBrowser(provider: CommittedChangesProvider<*, *>?, location: RepositoryLocation?, title: String?, parent: Component?) { + throw UnsupportedOperationException() + } + + override fun openCommittedChangesTab(vcs: AbstractVcs<*>?, root: VirtualFile?, settings: ChangeBrowserSettings?, maxCount: Int, title: String?) { + throw UnsupportedOperationException() + } + + override fun openCommittedChangesTab(provider: CommittedChangesProvider<*, *>?, location: RepositoryLocation?, settings: ChangeBrowserSettings?, maxCount: Int, title: String?) { + throw UnsupportedOperationException() + } + + override fun showFileHistory(historyProvider: VcsHistoryProvider, path: FilePath, vcs: AbstractVcs<*>, repositoryPath: String?) { + throw UnsupportedOperationException() + } + + override fun showFileHistory(historyProvider: VcsHistoryProvider, annotationProvider: AnnotationProvider?, path: FilePath, repositoryPath: String?, vcs: AbstractVcs<*>) { + throw UnsupportedOperationException() + } + + override fun showErrors(abstractVcsExceptions: List, tabDisplayName: String) { + throw UnsupportedOperationException() + } + + override fun showErrors(exceptionGroups: Map>, tabDisplayName: String) { + throw UnsupportedOperationException() + } + + override fun showDifferences(cvsVersionOn: VcsFileRevision, cvsVersionOn1: VcsFileRevision, file: File) { + throw UnsupportedOperationException() + } + + override fun showChangesListBrowser(changelist: CommittedChangeList, title: String) { + throw UnsupportedOperationException() + } + + override fun showChangesBrowser(changelists: List) { + throw UnsupportedOperationException() + } + + override fun showChangesBrowser(changelists: List, title: String) { + throw UnsupportedOperationException() + } + + override fun showWhatDiffersBrowser(parent: Component?, changes: Collection, title: String) { + throw UnsupportedOperationException() + } + + override fun chooseCommittedChangeList(provider: CommittedChangesProvider, location: RepositoryLocation): T? { + throw UnsupportedOperationException() + } + + override fun showRollbackChangesDialog(changes: List) { + throw UnsupportedOperationException() + } + + override fun selectFilesToProcess(files: List, title: String, prompt: String?, singleFileTitle: String, singleFilePromptTemplate: String, confirmationOption: VcsShowConfirmationOption): Collection? { + throw UnsupportedOperationException() + } + + override fun selectFilePathsToProcess(files: List, title: String, prompt: String?, singleFileTitle: String, singleFilePromptTemplate: String, confirmationOption: VcsShowConfirmationOption): Collection? { + throw UnsupportedOperationException() + } + + override fun loadAndShowCommittedChangesDetails(project: Project, revision: VcsRevisionNumber, file: VirtualFile, key: VcsKey, location: RepositoryLocation?, local: Boolean) { + throw UnsupportedOperationException() + } + + override fun showMergeDialog(files: List, provider: MergeProvider, mergeDialogCustomizer: MergeDialogCustomizer): List { + myMergeDialogShown = true + myMergeDelegate() + return emptyList() + } + + override fun commitChanges(changes: Collection, initialChangeList: LocalChangeList, commitMessage: String, customResultHandler: CommitResultHandler?): Boolean { + myCommitDialogShown = true + + val success = myCommitDelegate(commitMessage) + if (customResultHandler != null) { + if (success) { + customResultHandler.onSuccess(commitMessage) + } + else { + customResultHandler.onFailure() + } + } + return success + } + + public fun mergeDialogWasShown(): Boolean { + return myMergeDialogShown + } + + public fun commitDialogWasShown(): Boolean { + return myCommitDialogShown + } + + public fun onMerge(delegate : () -> Unit) { + myMergeDelegate = delegate + } + + public fun onCommit(delegate : (String) -> Boolean) { + myCommitDelegate = delegate + } + + @Deprecated("use onCommit") + public fun registerHandler(handler: CommitHandler) { + myCommitDelegate = { handler.commit(it) } + } + + @Deprecated("use onMerge") + public fun registerHandler(handler: MergeHandler) { + myMergeDelegate = { handler.showMergeDialog() } + } + + @Deprecated("use onCommit") + public interface CommitHandler { + public fun commit(commitMessage: String): Boolean + } + + @Deprecated("use onMerge") + public interface MergeHandler { + public fun showMergeDialog() + } + +} diff --git a/plugins/git4idea/tests/git4idea/test/RepoBuilder.kt b/plugins/git4idea/tests/git4idea/test/RepoBuilder.kt new file mode 100644 index 000000000000..9114d5642b74 --- /dev/null +++ b/plugins/git4idea/tests/git4idea/test/RepoBuilder.kt @@ -0,0 +1,98 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ +package git4idea.test + +import com.intellij.openapi.vcs.Executor.append +import com.intellij.openapi.vcs.Executor.touch +import git4idea.repo.GitRepository +import git4idea.test.GitExecutor.addCommit +import git4idea.test.GitExecutor.cd +import git4idea.test.GitExecutor.git +import java.io.File +import java.util.* + +public fun build(repo: GitRepository, f: RepoBuilder.() -> Unit) { + val builder = RepoBuilder(repo) + builder.f() + builder.build() +} + +public class RepoBuilder(val repo: GitRepository) { + init { + cd(repo) + } + + public val master: String = "master" + public val feature: String = "feature" + + private val myCommitIndices = HashMap() + private var myCurrentBranch : String = master + + fun String.invoke(commands: RepoBuilder.() -> Unit) { // switch branch + createOrCheckout(this) + myCurrentBranch = this + commands() + } + + private fun createOrCheckout(branch: String) { + if (isFresh()) { + if (branch != "master") { + git("checkout -b $branch") + } + } + else { + if (git("branch").splitBy("\n").map({ it.replace("*", "") }).contains(branch)) { + git("checkout $branch") + } + else { + git("checkout -b $branch") + } + } + } + + private fun isFresh(): Boolean = myCommitIndices.isEmpty() + + fun String.invoke(fromCommit: Int, commands: RepoBuilder.() -> Unit) { + git("checkout -b $this ${myCommitIndices[fromCommit]}") + myCurrentBranch = this + commands() + } + + fun Int.invoke(file: String = this.toString() + ".txt", + content: String = "More content in $myCurrentBranch: ${randomHash()}", + commitMessage: String = if (File(repo.getRoot().getPath(), file).exists()) "Created $file" else "Modified $file") { + modifyAndCommit(this, file, content, commitMessage) + } + + fun build() { + repo.update() + } + + private fun modifyAndCommit(id: Int, file: String, content: String, commitMessage: String) { + val hash: String + if (File(repo.getRoot().getPath(), file).exists()) { + append(file, content) + } + else { + touch(file, content) + } + hash = addCommit(commitMessage) + assert(!myCommitIndices.containsKey(id)) { "commit $id is already in the map!" } + myCommitIndices.put(id, hash) + } +} + +fun randomHash() = Integer.toHexString(Random().nextInt()) diff --git a/plugins/git4idea/tests/git4idea/test/TestGit.kt b/plugins/git4idea/tests/git4idea/test/TestGit.kt new file mode 100644 index 000000000000..d50186d39efe --- /dev/null +++ b/plugins/git4idea/tests/git4idea/test/TestGit.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ +package git4idea.test + +import git4idea.branch.GitRebaseParams +import git4idea.commands.GitCommandResult +import git4idea.commands.GitImpl +import git4idea.commands.GitLineHandlerListener +import git4idea.repo.GitRepository + +/** + * Any unknown error that could be returned by Git. + */ +public val UNKNOWN_ERROR_TEXT: String = "unknown error" + +public class TestGitImpl : GitImpl() { + + private var myShouldFail: (GitRepository) -> Boolean = { false } + + override fun rebase(repository: GitRepository, params: GitRebaseParams, vararg listeners: GitLineHandlerListener): GitCommandResult { + return if (myShouldFail(repository)) + GitCommandResult(false, 128, listOf("fatal: error: $UNKNOWN_ERROR_TEXT"), emptyList(), null) + else + super.rebase(repository, params, *listeners) + } + + public fun setShouldFail(shouldFail: (GitRepository) -> Boolean) { + myShouldFail = shouldFail + } +} + + From 885584c45dd77f4ba4cc71500f1ca9ee794369b7 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 17 Sep 2015 20:14:58 +0300 Subject: [PATCH 052/138] IDEA-110941 diff: do not paint icons mirrored in mirrored mode --- .../impl/EditorGutterComponentImpl.java | 116 ++++++++++-------- 1 file changed, 62 insertions(+), 54 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java index 97c1203b8af2..fc3aa066684e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java @@ -353,23 +353,15 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse paintBackground(g, clip, getAnnotationsAreaOffset(), w, backgroundColor); } - private void paintAnnotations(Graphics g, Rectangle clip) { + private void paintAnnotations(Graphics2D g, Rectangle clip) { int x = getAnnotationsAreaOffset(); int w = getAnnotationsAreaWidthEx(); if (w == 0) return; - Graphics2D g2 = (Graphics2D)g; - AffineTransform old = g2.getTransform(); + AffineTransform old = g.getTransform(); + g.setTransform(getMirrorTransform(old, x, w)); try { - if (isMirrored()) { - final AffineTransform transform = new AffineTransform(old); - transform.scale(-1, 1); - int shift = -getWidth() + (getWidth() - x - getAnnotationsAreaWidth()) - x; - transform.translate(shift, 0); - g2.setTransform(transform); - } - Color color = myEditor.getColorsScheme().getColor(EditorColors.ANNOTATIONS_COLOR); g.setColor(color != null ? color : JBColor.blue); g.setFont(myEditor.getColorsScheme().getFont(EditorFontType.PLAIN)); @@ -410,7 +402,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } finally { - g2.setTransform(old); + g.setTransform(old); } } @@ -426,7 +418,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } } - private void paintLineMarkers(Graphics g, int firstVisibleOffset, int lastVisibleOffset) { + private void paintLineMarkers(Graphics2D g, int firstVisibleOffset, int lastVisibleOffset) { if (isLineMarkersShown()) { paintGutterRenderers(g, firstVisibleOffset, lastVisibleOffset); } @@ -454,7 +446,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } } - private void paintLineNumbers(Graphics g, Rectangle clip) { + private void paintLineNumbers(Graphics2D g, Rectangle clip) { if (isLineNumbersShown()) { int offset = getLineNumberAreaOffset() + myLineNumberAreaWidth; doPaintLineNumbers(g, clip, offset, myLineNumberConvertor); @@ -479,7 +471,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse return color != null ? color : EditorColors.GUTTER_BACKGROUND.getDefaultColor(); } - private void doPaintLineNumbers(Graphics g, Rectangle clip, int offset, @NotNull TIntFunction convertor) { + private void doPaintLineNumbers(Graphics2D g, Rectangle clip, int offset, @NotNull TIntFunction convertor) { if (!isLineNumbersShown()) { return; } @@ -498,41 +490,36 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse g.setColor(color != null ? color : JBColor.blue); g.setFont(myEditor.getColorsScheme().getFont(EditorFontType.PLAIN)); - Graphics2D g2 = (Graphics2D)g; - AffineTransform old = g2.getTransform(); - - if (isMirrored()) { - AffineTransform originalTransform = new AffineTransform(old); - originalTransform.scale(-1, 1); - originalTransform.translate(-getLineNumberAreaWidth() - 1, 0); - g2.setTransform(originalTransform); - } - - for (int i = startLineNumber; i < endLineNumber; i++) { - LogicalPosition logicalPosition = myEditor.visualToLogicalPosition(new VisualPosition(i, 0)); - if (EditorUtil.getSoftWrapCountAfterLineStart(myEditor, logicalPosition) > 0) { - continue; - } - int logLine = convertor.execute(logicalPosition.line); - if (logLine >= 0) { - String s = String.valueOf(logLine + 1); - int startY = (i + 1) * lineHeight; - if (myEditor.isInDistractionFreeMode()) { - Color fgColor = myTextFgColors.get(i); - g.setColor(fgColor != null ? fgColor : color != null ? color : JBColor.blue); + AffineTransform old = g.getTransform(); + g.setTransform(getMirrorTransform(old, getLineNumberAreaOffset(), getLineNumberAreaWidth())); + try { + for (int i = startLineNumber; i < endLineNumber; i++) { + LogicalPosition logicalPosition = myEditor.visualToLogicalPosition(new VisualPosition(i, 0)); + if (EditorUtil.getSoftWrapCountAfterLineStart(myEditor, logicalPosition) > 0) { + continue; } + int logLine = convertor.execute(logicalPosition.line); + if (logLine >= 0) { + String s = String.valueOf(logLine + 1); + int startY = (i + 1) * lineHeight; + if (myEditor.isInDistractionFreeMode()) { + Color fgColor = myTextFgColors.get(i); + g.setColor(fgColor != null ? fgColor : color != null ? color : JBColor.blue); + } - int textOffset = isMirrored() ? - offset - getLineNumberAreaWidth() + GAP_AFTER_LINE_NUMBERS : - offset - myEditor.getFontMetrics(Font.PLAIN).stringWidth(s) - GAP_AFTER_LINE_NUMBERS; + int textOffset = isMirrored() ? + offset - getLineNumberAreaWidth() + GAP_AFTER_LINE_NUMBERS - 1 : + offset - myEditor.getFontMetrics(Font.PLAIN).stringWidth(s) - GAP_AFTER_LINE_NUMBERS; - g.drawString(s, - textOffset, - startY - myEditor.getDescent()); + g.drawString(s, + textOffset, + startY - myEditor.getDescent()); + } } } - - g2.setTransform(old); + finally { + g.setTransform(old); + } } private int endLineNumber() { @@ -779,11 +766,9 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse return foldRegion == null || foldRegion.getEndOffset() < endOffset; } - private void paintGutterRenderers(final Graphics g, int firstVisibleOffset, int lastVisibleOffset) { - Graphics2D g2 = (Graphics2D)g; - - Object hint = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + private void paintGutterRenderers(final Graphics2D g, int firstVisibleOffset, int lastVisibleOffset) { + Object hint = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); try { processRangeHighlighters(firstVisibleOffset, lastVisibleOffset, new RangeHighlighterProcessor() { @Override @@ -793,7 +778,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse }); } finally { - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, hint); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, hint); } int firstVisibleLine = myEditor.getDocument().getLineNumber(firstVisibleOffset); @@ -801,7 +786,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse paintIcons(firstVisibleLine, lastVisibleLine, g); } - private void paintIcons(final int firstVisibleLine, final int lastVisibleLine, final Graphics g) { + private void paintIcons(final int firstVisibleLine, final int lastVisibleLine, final Graphics2D g) { for (int line = firstVisibleLine; line <= lastVisibleLine; line++) { List renderers = myLineToGutterRenderers.get(line); if (renderers != null) { @@ -810,12 +795,20 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } } - private void paintIconRow(int line, List row, final Graphics g) { + private void paintIconRow(int line, List row, final Graphics2D g) { processIconsRow(line, row, new LineGutterIconRendererProcessor() { @Override public void process(int x, int y, GutterMark renderer) { Icon icon = scaleIcon(renderer.getIcon()); - icon.paintIcon(EditorGutterComponentImpl.this, g, x, y); + + AffineTransform old = g.getTransform(); + g.setTransform(getMirrorTransform(old, x, icon.getIconWidth())); + try { + icon.paintIcon(EditorGutterComponentImpl.this, g, x, y); + } + finally { + g.setTransform(old); + } } }); } @@ -1264,6 +1257,21 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse return myEditor.getVerticalScrollbarOrientation() != EditorEx.VERTICAL_SCROLLBAR_RIGHT; } + @NotNull + private AffineTransform getMirrorTransform(@NotNull AffineTransform old, int offset, int width) { + final AffineTransform transform = new AffineTransform(old); + if (isMirrored()) { + //transform.translate(getWidth(), 0); // revert mirroring transform + //transform.scale(-1, 1); // revert mirroring transform + //transform.translate(getWidth() - offset - width, 0); // move range start to the X==0 + //transform.translate(-offset, 0); + + transform.scale(-1, 1); + transform.translate(-offset * 2 - width, 0); + } + return transform; + } + @Nullable @Override public FoldRegion findFoldingAnchorAt(int x, int y) { From 52680374ca45de717f4cd899079ba3d93c729063 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 17 Sep 2015 20:16:08 +0300 Subject: [PATCH 053/138] IDEA-110941 diff: paint gutter arrow icons with the right direction --- .../intellij/diff/merge/TextMergeChange.java | 2 +- .../tools/fragmented/UnifiedDiffViewer.java | 4 ++-- .../diff/tools/simple/SimpleDiffChange.java | 4 ++-- .../diff/tools/simple/SimpleDiffViewer.java | 4 ++-- .../src/com/intellij/diff/util/DiffUtil.java | 15 +++++++++++++++ .../openapi/diff/actions/MergeOperations.java | 18 +++++++++--------- .../fragments/FragmentHighlighterImpl.java | 10 ++++++---- .../diff/impl/incrementalMerge/MergeList.java | 4 +++- 8 files changed, 40 insertions(+), 21 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeChange.java b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeChange.java index 65ca19ba277f..d73116dd8d71 100644 --- a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeChange.java +++ b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeChange.java @@ -299,7 +299,7 @@ public class TextMergeChange extends ThreesideDiffChangeBase { @Nullable private GutterIconRenderer createApplyRenderer(@NotNull final Side side, final boolean modifier) { if (isResolved(side)) return null; - Icon icon = isOnesideAppliedConflict() ? AllIcons.Diff.ArrowLeftDown : AllIcons.Diff.Arrow; + Icon icon = isOnesideAppliedConflict() ? DiffUtil.getArrowDownIcon(side) : DiffUtil.getArrowIcon(side); return createIconRenderer(DiffBundle.message("merge.dialog.apply.change.action.name"), icon, isConflict(), new Runnable() { @Override public void run() { diff --git a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffViewer.java index a9165ea2ce64..7ead8d21f3ea 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffViewer.java @@ -724,7 +724,7 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase { setShortcutSet(ActionManager.getInstance().getAction(focusedSide.select("Diff.ApplyLeftSide", "Diff.ApplyRightSide")).getShortcutSet()); getTemplatePresentation().setText("Replace"); - getTemplatePresentation().setIcon(focusedSide.select(AllIcons.Diff.ArrowRight, AllIcons.Diff.Arrow)); + getTemplatePresentation().setIcon(DiffUtil.getArrowIcon(focusedSide)); } @Override @@ -741,7 +741,7 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase { setShortcutSet(ActionManager.getInstance().getAction(focusedSide.select("Diff.AppendLeftSide", "Diff.AppendRightSide")).getShortcutSet()); getTemplatePresentation().setText("Insert"); - getTemplatePresentation().setIcon(focusedSide.select(AllIcons.Diff.ArrowRightDown, AllIcons.Diff.ArrowLeftDown)); + getTemplatePresentation().setIcon(DiffUtil.getArrowDownIcon(focusedSide)); } @Override diff --git a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffChange.java b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffChange.java index 1e4c1f15476a..18fca2dd16e6 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffChange.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffChange.java @@ -267,7 +267,7 @@ public class SimpleDiffChange { @Nullable private GutterIconRenderer createApplyRenderer(@NotNull final Side side) { - return createIconRenderer(side, "Replace", AllIcons.Diff.Arrow, new Runnable() { + return createIconRenderer(side, "Replace", DiffUtil.getArrowIcon(side), new Runnable() { @Override public void run() { myViewer.replaceChange(SimpleDiffChange.this, side); @@ -277,7 +277,7 @@ public class SimpleDiffChange { @Nullable private GutterIconRenderer createAppendRenderer(@NotNull final Side side) { - return createIconRenderer(side, "Insert", AllIcons.Diff.ArrowLeftDown, new Runnable() { + return createIconRenderer(side, "Insert", DiffUtil.getArrowDownIcon(side), new Runnable() { @Override public void run() { myViewer.appendChange(SimpleDiffChange.this, side); diff --git a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffViewer.java index fc2786294d95..362e67da80a8 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffViewer.java @@ -589,7 +589,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer { setShortcutSet(ActionManager.getInstance().getAction(focusedSide.select("Diff.ApplyLeftSide", "Diff.ApplyRightSide")).getShortcutSet()); getTemplatePresentation().setText("Replace"); - getTemplatePresentation().setIcon(focusedSide.select(AllIcons.Diff.ArrowRight, AllIcons.Diff.Arrow)); + getTemplatePresentation().setIcon(DiffUtil.getArrowIcon(focusedSide)); } @Override @@ -611,7 +611,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer { setShortcutSet(ActionManager.getInstance().getAction(focusedSide.select("Diff.AppendLeftSide", "Diff.AppendRightSide")).getShortcutSet()); getTemplatePresentation().setText("Insert"); - getTemplatePresentation().setIcon(focusedSide.select(AllIcons.Diff.ArrowRightDown, AllIcons.Diff.ArrowLeftDown)); + getTemplatePresentation().setIcon(DiffUtil.getArrowDownIcon(focusedSide)); } @Override diff --git a/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java b/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java index d23457c4e25a..f420755e73b0 100644 --- a/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java +++ b/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java @@ -32,6 +32,7 @@ import com.intellij.diff.requests.ContentDiffRequest; import com.intellij.diff.requests.DiffRequest; import com.intellij.diff.tools.util.base.HighlightPolicy; import com.intellij.diff.tools.util.base.IgnorePolicy; +import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.DefaultActionGroup; @@ -241,6 +242,20 @@ public class DiffUtil { return editor != null ? editor.getCaretModel().getLogicalPosition() : new LogicalPosition(0, 0); } + // + // Icons + // + + @NotNull + public static Icon getArrowIcon(@NotNull Side sourceSide) { + return sourceSide.select(AllIcons.Diff.ArrowRight, AllIcons.Diff.Arrow); + } + + @NotNull + public static Icon getArrowDownIcon(@NotNull Side sourceSide) { + return sourceSide.select(AllIcons.Diff.ArrowRightDown, AllIcons.Diff.ArrowLeftDown); + } + // // UI // diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/actions/MergeOperations.java b/platform/platform-impl/src/com/intellij/openapi/diff/actions/MergeOperations.java index b68c3fb251b1..8fdd8438af49 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/actions/MergeOperations.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/actions/MergeOperations.java @@ -64,8 +64,8 @@ public class MergeOperations { if (isWritable(mySide)) operations.add(removeOperation(range, getDocument())); TextRange otherRange = fragment.getRange(mySide.otherSide()); boolean otherIsWritable = isWritable(mySide.otherSide()); - if (otherIsWritable) operations.add(insertOperation(range, otherRange.getEndOffset(), getDocument(), getOtherDocument())); - if (otherRange.getLength() > 0 && otherIsWritable) operations.add(replaceOperation(range, otherRange, getDocument(), getOtherDocument())); + if (otherIsWritable) operations.add(insertOperation(range, otherRange.getEndOffset(), getDocument(), getOtherDocument(), mySide)); + if (otherRange.getLength() > 0 && otherIsWritable) operations.add(replaceOperation(range, otherRange, getDocument(), getOtherDocument(), mySide)); } return operations; } @@ -99,21 +99,21 @@ public class MergeOperations { myDiffPanel.getEditor(side).getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset()); } - private static Operation replaceOperation(TextRange range, TextRange otherRange, Document document, Document otherDocument) { + private static Operation replaceOperation(TextRange range, TextRange otherRange, Document document, Document otherDocument, FragmentSide base) { return new Operation(DiffBundle.message("merge.editor.replace.operation.name"), - AllIcons.Diff.Arrow, + base == FragmentSide.SIDE1 ? AllIcons.Diff.ArrowRight : AllIcons.Diff.Arrow, otherDocument, replaceModification(range, document, otherRange, otherDocument)); } @Nullable - public static Operation mostSensible(Document document, Document otherDocument, TextRange range, TextRange otherRange) { + public static Operation mostSensible(Document document, Document otherDocument, TextRange range, TextRange otherRange, FragmentSide base) { if (!canMakeWritable(document) && !canMakeWritable(otherDocument)) return null; if (range.getLength() != 0) { if (canMakeWritable(otherDocument)) return otherRange.getLength() != 0 ? - replaceOperation(range, otherRange, document, otherDocument) : - insertOperation(range, otherRange.getEndOffset(), document, otherDocument); + replaceOperation(range, otherRange, document, otherDocument, base) : + insertOperation(range, otherRange.getEndOffset(), document, otherDocument, base); else return otherRange.getLength() == 0 ? removeOperation(range, document) : null; } return null; @@ -129,9 +129,9 @@ public class MergeOperations { }; } - private static Operation insertOperation(TextRange range, int offset, Document document, Document otherDocument) { + private static Operation insertOperation(TextRange range, int offset, Document document, Document otherDocument, FragmentSide base) { return new Operation(DiffBundle.message("merge.editor.insert.operation.name"), - AllIcons.Diff.ArrowLeftDown, + base == FragmentSide.SIDE1 ? AllIcons.Diff.ArrowRightDown : AllIcons.Diff.ArrowLeftDown, otherDocument, insertModification(range, document, offset, otherDocument)); } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/fragments/FragmentHighlighterImpl.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/fragments/FragmentHighlighterImpl.java index a376b03dc70b..0223afb133eb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/fragments/FragmentHighlighterImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/fragments/FragmentHighlighterImpl.java @@ -18,6 +18,7 @@ package com.intellij.openapi.diff.impl.fragments; import com.intellij.openapi.diff.actions.MergeOperations; import com.intellij.openapi.diff.impl.DiffUtil; import com.intellij.openapi.diff.impl.highlighting.DiffMarkup; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; import com.intellij.openapi.diff.impl.util.TextDiffTypeEnum; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.markup.SeparatorPlacement; @@ -69,12 +70,13 @@ public class FragmentHighlighterImpl implements FragmentHighlighter { private static void addModifyActions(final LineFragment fragment, DiffMarkup wrapper, DiffMarkup otherWrapper) { if (fragment.isEqual()) return; if (fragment.isHasLineChildren()) return; - TextRange range = fragment.getRange(wrapper.getSide()); - TextRange otherRange = fragment.getRange(wrapper.getSide().otherSide()); + FragmentSide side = wrapper.getSide(); + TextRange range = fragment.getRange(side); + TextRange otherRange = fragment.getRange(side.otherSide()); Document document = wrapper.getDocument(); Document otherDocument = otherWrapper.getDocument(); - wrapper.addAction(MergeOperations.mostSensible(document, otherDocument, range, otherRange), range.getStartOffset()); - otherWrapper.addAction(MergeOperations.mostSensible(otherDocument, document, otherRange, range), otherRange.getStartOffset()); + wrapper.addAction(MergeOperations.mostSensible(document, otherDocument, range, otherRange, side), range.getStartOffset()); + otherWrapper.addAction(MergeOperations.mostSensible(otherDocument, document, otherRange, range, side.otherSide()), otherRange.getStartOffset()); } private static void addSeparatingLine(@NotNull LineFragment fragment, @NotNull DiffMarkup appender, int startLine, int endLine) { diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java index 106daac84ee8..82d79e0d8766 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java @@ -42,6 +42,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; @@ -237,7 +238,8 @@ public class MergeList implements UserDataHolder { for (int i = 0; i < changeList.getCount(); i++) { final Change change = changeList.getChange(i); if (!change.canHasActions(originalSide)) continue; - AnAction applyAction = new DumbAwareAction(DiffBundle.message("merge.dialog.apply.change.action.name"), null, AllIcons.Diff.Arrow) { + Icon arrowIcon = side == FragmentSide.SIDE1 ? AllIcons.Diff.ArrowRight : AllIcons.Diff.Arrow; + AnAction applyAction = new DumbAwareAction(DiffBundle.message("merge.dialog.apply.change.action.name"), null, arrowIcon) { @Override public void actionPerformed(@Nullable AnActionEvent e) { apply(change); From 99d230427cc53cf52440476a278121e06d9d2aaa Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 21 Sep 2015 15:19:10 +0200 Subject: [PATCH 054/138] change signature of getIcon in MacIntelliJIconCache --- .../ide/ui/laf/intellij/MacIntelliJButtonUI.java | 4 ++-- .../ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java | 2 +- .../ide/ui/laf/intellij/MacIntelliJComboBoxUI.java | 10 +++++----- .../ide/ui/laf/intellij/MacIntelliJIconCache.java | 8 ++++---- .../ide/ui/laf/intellij/MacIntelliJRadioButtonUI.java | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJButtonUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJButtonUI.java index 39f384c30933..f6c919566fc8 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJButtonUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJButtonUI.java @@ -43,7 +43,7 @@ public class MacIntelliJButtonUI extends DarculaButtonUI { int w = c.getWidth(); int h = c.getHeight(); if (isHelpButton(c)) { - Icon icon = MacIntelliJIconCache.getIcon("helpButton", false, c.hasFocus(), false); + Icon icon = MacIntelliJIconCache.getIcon("helpButton", false, c.hasFocus()); int x = (w - icon.getIconWidth()) / 2; int y = (h - icon.getIconHeight()) / 2; icon.paintIcon(c, g, x, y); @@ -114,7 +114,7 @@ public class MacIntelliJButtonUI extends DarculaButtonUI { boolean combo = button.getClientProperty("styleCombo") == Boolean.TRUE; String comboPrefix = combo ? "Combo" : ""; String iconName = "button" + comboPrefix + suffix; - return MacIntelliJIconCache.getIcon(iconName, isDefault, isFocused && !combo, false); + return MacIntelliJIconCache.getIcon(iconName, isDefault, isFocused && !combo); } private String layout(AbstractButton b, FontMetrics fm, diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java index 63c9b97fafd3..3604d1b96b12 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java @@ -42,7 +42,7 @@ public class MacIntelliJCheckBoxUI extends IntelliJCheckBoxUI { @Override protected void drawCheckIcon(JComponent c, Graphics2D g, JCheckBox b, Rectangle iconRect, boolean selected, boolean enabled) { MacIntelliJIconCache - .getIcon("checkBox", selected, c.hasFocus(), !b.isEnabled()) + .getIcon("checkBox", selected, c.hasFocus(), b.isEnabled()) .paintIcon(c, g, iconRect.x, iconRect.y); } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJComboBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJComboBoxUI.java index e795023a53b5..4ef6f71f8f3c 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJComboBoxUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJComboBoxUI.java @@ -61,7 +61,7 @@ public class MacIntelliJComboBoxUI extends BasicComboBoxUI { JButton button = new BasicArrowButton(SwingConstants.SOUTH, bg, fg, fg, fg) { @Override public void paint(Graphics g2) { - Icon icon = MacIntelliJIconCache.getIcon("comboRight", false, myComboBox.hasFocus(), !myComboBox.isEnabled()); + Icon icon = MacIntelliJIconCache.getIcon("comboRight", false, myComboBox.hasFocus(), myComboBox.isEnabled()); icon.paintIcon(this, g2, 0, 0); } @@ -239,18 +239,18 @@ public class MacIntelliJComboBoxUI extends BasicComboBoxUI { int stop = r.x; Insets clip = getInsets(); Graphics gg = g.create(clip.left, r.y, stop - clip.left, DEFAULT_ICON.getIconHeight()); - boolean disabled = !c.isEnabled(); + boolean enabled = c.isEnabled(); boolean hasFocus = c.hasFocus(); - Icon icon = MacIntelliJIconCache.getIcon("comboLeft", false, hasFocus, disabled); + Icon icon = MacIntelliJIconCache.getIcon("comboLeft", false, hasFocus, enabled); icon.paintIcon(c,gg,0,0); int x = icon.getIconWidth(); - icon = MacIntelliJIconCache.getIcon("comboMiddle", false, hasFocus, disabled); + icon = MacIntelliJIconCache.getIcon("comboMiddle", false, hasFocus, enabled); while (x < stop) { icon.paintIcon(c, gg, x, 0); x+=icon.getIconWidth(); } gg.dispose(); - icon = MacIntelliJIconCache.getIcon("comboRight", false, hasFocus, disabled); + icon = MacIntelliJIconCache.getIcon("comboRight", false, hasFocus, enabled); icon.paintIcon(c, g, r.x, r.y); if ( !comboBox.isEditable() ) { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJIconCache.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJIconCache.java index 100ccbd61a4e..15cc44cf8ed1 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJIconCache.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJIconCache.java @@ -27,11 +27,11 @@ import javax.swing.*; public class MacIntelliJIconCache { private static final HashMap cache = new HashMap(); - public static Icon getIcon(String name, boolean selected, boolean focused, boolean disabled) { + public static Icon getIcon(String name, boolean selected, boolean focused, boolean enabled) { String key = name; if (selected) key+= "Selected"; if (focused) key+= "Focused"; - else if (disabled) key+="Disabled"; + else if (!enabled) key+="Disabled"; if (IntelliJLaf.isGraphite()) key= "graphite/" + key; Icon icon = cache.get(key); if (icon == null) { @@ -42,9 +42,9 @@ public class MacIntelliJIconCache { } public static Icon getIcon(String name, boolean selected, boolean focused) { - return getIcon(name, selected, focused, false); + return getIcon(name, selected, focused, true); } public static Icon getIcon(String name) { - return getIcon(name, false, false, false); + return getIcon(name, false, false, true); } } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJRadioButtonUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJRadioButtonUI.java index b8b3c1a21de9..fd86f4e86376 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJRadioButtonUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJRadioButtonUI.java @@ -35,7 +35,7 @@ public class MacIntelliJRadioButtonUI extends DarculaRadioButtonUI { @Override protected void paintIcon(JComponent c, Graphics2D g, Rectangle viewRect, Rectangle iconRect) { - Icon icon = MacIntelliJIconCache.getIcon("radio", ((AbstractButton)c).isSelected(), c.hasFocus(), !c.isEnabled()); + Icon icon = MacIntelliJIconCache.getIcon("radio", ((AbstractButton)c).isSelected(), c.hasFocus(), c.isEnabled()); icon.paintIcon(c, g, iconRect.x, iconRect.y); } From fa18facf25a26c2793fa4373cc551b730c28f3ab Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 21 Sep 2015 15:01:29 +0300 Subject: [PATCH 055/138] IDEA-145365 diff: remove duplicated methods in Unified diff * "Revert" completely duplicates "Replace" * better action names --- .../tools/fragmented/UnifiedDiffViewer.java | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffViewer.java index 7ead8d21f3ea..a219092e0fcb 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffViewer.java @@ -30,7 +30,6 @@ import com.intellij.diff.tools.util.base.*; import com.intellij.diff.tools.util.side.TwosideTextDiffViewer; import com.intellij.diff.util.*; import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy; -import com.intellij.icons.AllIcons; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; @@ -220,11 +219,9 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase { List group = new ArrayList(); group.add(new ReplaceSelectedChangesAction(Side.LEFT, false)); - group.add(new AppendSelectedChangesAction(Side.LEFT, false)); group.add(new ReplaceSelectedChangesAction(Side.RIGHT, false)); + group.add(new AppendSelectedChangesAction(Side.LEFT, false)); group.add(new AppendSelectedChangesAction(Side.RIGHT, false)); - group.add(new RevertSelectedChangesAction(Side.LEFT)); - group.add(new RevertSelectedChangesAction(Side.RIGHT)); group.add(Separator.getInstance()); group.addAll(TextDiffViewerUtil.createEditorPopupActions()); @@ -648,7 +645,7 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase { private abstract class ApplySelectedChangesActionBase extends AnAction implements DumbAware { @NotNull protected final Side myModifiedSide; - private final boolean myShortcut; + protected final boolean myShortcut; public ApplySelectedChangesActionBase(@NotNull Side modifiedSide, boolean shortcut) { myModifiedSide = modifiedSide; @@ -674,6 +671,7 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase { return; } + e.getPresentation().setText(getText()); e.getPresentation().setVisible(true); e.getPresentation().setEnabled(isSomeChangeSelected()); } @@ -714,6 +712,9 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase { return false; } + @NotNull + public abstract String getText(); + @CalledWithWriteLock protected abstract void apply(@NotNull List changes); } @@ -723,10 +724,21 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase { super(focusedSide.other(), shortcut); setShortcutSet(ActionManager.getInstance().getAction(focusedSide.select("Diff.ApplyLeftSide", "Diff.ApplyRightSide")).getShortcutSet()); - getTemplatePresentation().setText("Replace"); getTemplatePresentation().setIcon(DiffUtil.getArrowIcon(focusedSide)); } + @NotNull + @Override + public String getText() { + boolean bothEditable = isEditable(Side.LEFT, true) && isEditable(Side.RIGHT, true); + if (bothEditable) { + return myModifiedSide.select("Apply After", "Apply Before"); + } + else { + return "Apply"; + } + } + @Override protected void apply(@NotNull List changes) { for (UnifiedDiffChange change : changes) { @@ -740,10 +752,21 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase { super(focusedSide.other(), shortcut); setShortcutSet(ActionManager.getInstance().getAction(focusedSide.select("Diff.AppendLeftSide", "Diff.AppendRightSide")).getShortcutSet()); - getTemplatePresentation().setText("Insert"); getTemplatePresentation().setIcon(DiffUtil.getArrowDownIcon(focusedSide)); } + @NotNull + @Override + public String getText() { + boolean bothEditable = isEditable(Side.LEFT, true) && isEditable(Side.RIGHT, true); + if (bothEditable) { + return myModifiedSide.select("Append Right Side", "Append Left Side"); + } + else { + return "Append"; + } + } + @Override protected void apply(@NotNull List changes) { for (UnifiedDiffChange change : changes) { @@ -752,21 +775,6 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase { } } - private class RevertSelectedChangesAction extends ApplySelectedChangesActionBase { - public RevertSelectedChangesAction(@NotNull Side focusedSide) { - super(focusedSide, false); - getTemplatePresentation().setText("Revert"); - getTemplatePresentation().setIcon(AllIcons.Diff.Remove); - } - - @Override - protected void apply(@NotNull List changes) { - for (UnifiedDiffChange change : changes) { - replaceChange(change, myModifiedSide.other()); - } - } - } - @CalledWithWriteLock public void replaceChange(@NotNull UnifiedDiffChange change, @NotNull Side sourceSide) { Side outputSide = sourceSide.other(); From e20772a4a47e7fc1bdb629472a2e62ec20b4a66a Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Mon, 21 Sep 2015 16:21:31 +0300 Subject: [PATCH 056/138] [Patch]: IDEA-75177 Create Patch: 'file name length cannot exceed 100 chars' message and limit for patch creation improved * keep MAX limit for filename created from shelve manager; * It's not necessary to detect a file path length according to Windows restrictions in other places (shelf), because it may produce unreasonably big amount of code for a minor case. --- .../intellij/openapi/vcs/changes/patch/PatchNameChecker.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/PatchNameChecker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/PatchNameChecker.java index 935747ecfe84..1ec5dbba450f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/PatchNameChecker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/PatchNameChecker.java @@ -19,6 +19,7 @@ import java.io.File; public class PatchNameChecker { public final static int MAX = 100; + private final static int MAX_PATH = 255; // Windows path len restrictions private final String myName; private boolean myPreventsOk; private String myError; @@ -35,8 +36,8 @@ public class PatchNameChecker { myError = "File name cannot be empty"; myPreventsOk = true; return false; - } else if (myName.length() > MAX) { - myError = "File name length cannot exceed " + MAX + " characters"; + } else if (myPath.length() > MAX_PATH) { + myError = "File path should not be too long."; myPreventsOk = true; return false; } else if (new File(myPath).exists()) { From cfa7fde14cdfc7035c40c9a6710caddf256dd3d1 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Mon, 21 Sep 2015 16:21:50 +0300 Subject: [PATCH 057/138] Suppress too verbose debugging messages --- .../com/intellij/ide/ApplicationActivationStateManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ApplicationActivationStateManager.java b/platform/platform-impl/src/com/intellij/ide/ApplicationActivationStateManager.java index 68376bf37518..4a216b7557f6 100644 --- a/platform/platform-impl/src/com/intellij/ide/ApplicationActivationStateManager.java +++ b/platform/platform-impl/src/com/intellij/ide/ApplicationActivationStateManager.java @@ -99,7 +99,7 @@ public class ApplicationActivationStateManager { // windowEvent could just be showing a popup or another transient window. // So let's postpone the application deactivation for a while state = State.DEACTIVATING; - LOG.info("SET APP DEACTIVATING"); + LOG.debug("The app is in the deactivating state"); Timer timer = new Timer(Registry.intValue("application.deactivation.timeout"), new ActionListener() { public void actionPerformed(ActionEvent evt) { @@ -107,7 +107,7 @@ public class ApplicationActivationStateManager { if (state.equals(State.DEACTIVATING)) { state = State.DEACTIVATED; - LOG.info("SET APP DEACTIVATED"); + LOG.debug("The app is in the deactivated state"); IdeFrame ideFrame = getIdeFrameFromWindow(windowEvent.getWindow()); if (ideFrame != null) { @@ -129,7 +129,7 @@ public class ApplicationActivationStateManager { IdeFrame ideFrame = getIdeFrameFromWindow(window); state = State.ACTIVE; - LOG.info("SET APP ACTIVE"); + LOG.debug("The app is in the active state"); if (ideFrame != null) { application.getMessageBus().syncPublisher(ApplicationActivationListener.TOPIC).applicationActivated(ideFrame); From b47ec5cc86fc2bf30a31e3c336df6cd5e0e83b9f Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 21 Sep 2015 16:20:05 +0300 Subject: [PATCH 058/138] Force early return initial --- .../actions/ForceEarlyReturnAction.java | 216 ++++++++++++++++++ .../debugger/actions/PopFrameAction.java | 15 +- .../debugger/engine/JavaStackFrame.java | 1 + .../jdi/ThreadReferenceProxyImpl.java | 11 + .../debugger/jdi/VirtualMachineProxyImpl.java | 11 +- .../src/messages/ActionsBundle.properties | 2 + .../src/messages/DebuggerBundle.properties | 3 +- resources/src/idea/JavaActions.xml | 4 + 8 files changed, 249 insertions(+), 14 deletions(-) create mode 100644 java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java new file mode 100644 index 000000000000..0545dd5a1ce9 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java @@ -0,0 +1,216 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ + +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.JavaStackFrame; +import com.intellij.debugger.engine.JavaValue; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.idea.ActionsBundle; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.util.ui.UIUtil; +import com.intellij.xdebugger.XDebuggerBundle; +import com.intellij.xdebugger.XExpression; +import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; +import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; +import com.intellij.xdebugger.frame.XValue; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; +import com.intellij.xdebugger.impl.ui.XDebuggerExpressionEditor; +import com.sun.jdi.Method; +import com.sun.jdi.Value; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class ForceEarlyReturnAction extends DebuggerAction { + public void actionPerformed(@NotNull AnActionEvent e) { + final Project project = e.getProject(); + final JavaStackFrame stackFrame = PopFrameAction.getStackFrame(e); + if (stackFrame == null || project == null) { + return; + } + final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext()); + final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); + if (debugProcess == null) { + return; + } + + final StackFrameProxyImpl proxy = stackFrame.getStackFrameProxy(); + final ThreadReferenceProxyImpl thread = proxy.threadProxy(); + + debugProcess.getManagerThread().schedule(new DebuggerContextCommandImpl(debuggerContext, thread) { + @Override + public void threadAction() { + Method method; + try { + method = proxy.location().method(); + } + catch (EvaluateException e) { + showError(project, DebuggerBundle.message("error.early.return", e.getLocalizedMessage())); + return; + } + + if ("void".equals(method.returnTypeName())) { + forceEarlyReturn(thread.getVirtualMachine().mirrorOf(), thread, debugProcess, null); + } + else { + //noinspection SSBasedInspection + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + new ReturnExpressionDialog(project, debugProcess.getXdebugProcess().getEditorsProvider(), debugProcess, stackFrame).show(); + } + }); + } + } + }); + } + + private static void forceEarlyReturn(Value value, + ThreadReferenceProxyImpl thread, + final DebugProcessImpl debugProcess, + @Nullable final DialogWrapper dialog) { + try { + thread.forceEarlyReturn(value); + } + catch (Exception e) { + showError(debugProcess.getProject(), DebuggerBundle.message("error.early.return", e.getLocalizedMessage())); + return; + } + //noinspection SSBasedInspection + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (dialog != null) { + dialog.close(DialogWrapper.OK_EXIT_CODE); + } + debugProcess.getSession().stepInto(true, null); + } + }); + } + + private static void evaluateAndReturn(final Project project, + final JavaStackFrame stackFrame, + final DebugProcessImpl debugProcess, + XExpression expression, + final DialogWrapper dialog) { + XDebuggerEvaluator evaluator = stackFrame.getEvaluator(); + if (evaluator != null) { + evaluator.evaluate(expression, + new XDebuggerEvaluator.XEvaluationCallback() { + @Override + public void evaluated(@NotNull XValue result) { + if (result instanceof JavaValue) { + forceEarlyReturn(((JavaValue)result).getDescriptor().getValue(), + stackFrame.getDescriptor().getFrameProxy().threadProxy(), + debugProcess, + dialog); + } + } + + @Override + public void errorOccurred(@NotNull final String errorMessage) { + showError(project, DebuggerBundle.message("error.unable.to.evaluate.expression") + ": " + errorMessage); + } + }, stackFrame.getSourcePosition()); + } + else { + showError(project, XDebuggerBundle.message("xdebugger.evaluate.stack.frame.has.not.evaluator")); + } + } + + private static void showError(final Project project, final String message) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + Messages.showMessageDialog(project, + message, + UIUtil.removeMnemonic(ActionsBundle.actionText("Debugger.ForceEarlyReturn")), + Messages.getErrorIcon()); + } + }, ModalityState.any()); + } + + public void update(@NotNull AnActionEvent e) { + boolean enable = false; + + JavaStackFrame stackFrame = PopFrameAction.getStackFrame(e); + if (stackFrame != null && stackFrame.getDescriptor().getUiIndex() == 0) { + enable = stackFrame.getStackFrameProxy().getVirtualMachine().canForceEarlyReturn(); + } + + if (ActionPlaces.isMainMenuOrActionSearch(e.getPlace()) || ActionPlaces.DEBUGGER_TOOLBAR.equals(e.getPlace())) { + e.getPresentation().setEnabled(enable); + } + else { + e.getPresentation().setVisible(enable); + } + } + + private static class ReturnExpressionDialog extends DialogWrapper { + private final Project myProject; + private final XDebuggerEditorsProvider myEditorsProvider; + private final DebugProcessImpl myProcess; + private final JavaStackFrame myFrame; + private final XDebuggerExpressionEditor myEditor; + + public ReturnExpressionDialog(@NotNull Project project, + XDebuggerEditorsProvider provider, + DebugProcessImpl process, + JavaStackFrame frame) { + super(project); + myProject = project; + myEditorsProvider = provider; + myProcess = process; + myFrame = frame; + myEditor = new XDebuggerExpressionEditor(myProject, myEditorsProvider, "forceReturnValue", myFrame.getSourcePosition(), + XExpressionImpl.EMPTY_EXPRESSION, false); + + setTitle("Return Value"); + init(); + } + + @Nullable + @Override + protected JComponent createCenterPanel() { + return myEditor.getComponent(); + } + + @Nullable + @Override + public JComponent getPreferredFocusedComponent() { + return myEditor.getPreferredFocusedComponent(); + } + + @Override + protected void doOKAction() { + evaluateAndReturn(myProject, myFrame, myProcess, myEditor.getExpression(), this); + } + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java index 5b4048129cba..f18200161a4d 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java @@ -70,7 +70,7 @@ public class PopFrameAction extends DebuggerAction { public void actionPerformed(@NotNull AnActionEvent e) { final Project project = e.getData(CommonDataKeys.PROJECT); final JavaStackFrame stackFrame = getStackFrame(e); - if(stackFrame == null) { + if (stackFrame == null || stackFrame.getStackFrameProxy().isBottom()) { return; } try { @@ -214,21 +214,12 @@ public class PopFrameAction extends DebuggerAction { return res; } - private static JavaStackFrame getStackFrame(AnActionEvent e) { + static JavaStackFrame getStackFrame(AnActionEvent e) { StackFrameDescriptorImpl descriptor = getSelectedStackFrameDescriptor(e); if (descriptor != null) { - if (descriptor.getFrameProxy().isBottom()) { - return null; - } return new JavaStackFrame(descriptor, false); } - JavaStackFrame frame = getSelectedStackFrame(e); - if (frame != null) { - StackFrameProxyImpl proxy = frame.getStackFrameProxy(); - if (proxy == null || proxy.isBottom()) return null; - return frame; - } - return null; + return getSelectedStackFrame(e); } static StackFrameProxyImpl getStackFrameProxy(AnActionEvent e) { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java index b4cfc1680d26..3a8c2b6bac48 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java @@ -397,6 +397,7 @@ public class JavaStackFrame extends XStackFrame { } } + @NotNull public StackFrameProxyImpl getStackFrameProxy() { return myDescriptor.getFrameProxy(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java index 7b8b1d1f9df0..b9b4e57b24f2 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java @@ -309,6 +309,17 @@ public final class ThreadReferenceProxyImpl extends ObjectReferenceProxyImpl imp } } + public void forceEarlyReturn(Value value) throws ClassNotLoadedException, IncompatibleThreadStateException, InvalidTypeException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + try { + getThreadReference().forceEarlyReturn(value); + } + finally { + clearCaches(); + getVirtualMachineProxy().clearCaches(); + } + } + public boolean isSuspended() throws ObjectCollectedException { try { DebuggerManagerThreadImpl.assertIsManagerThread(); diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java index c2211fe1c648..982964678413 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java @@ -278,7 +278,7 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy { return myVirtualMachine.eventRequestManager(); } - public VoidValue mirrorOf() throws EvaluateException { + public VoidValue mirrorOf() { return myVirtualMachine.mirrorOfVoid(); } @@ -461,6 +461,15 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy { return myPopFrames.isAvailable(); } + private final Capability myForceEarlyReturn = new Capability() { + protected boolean calcValue() { + return myVirtualMachine.canForceEarlyReturn(); + } + }; + public boolean canForceEarlyReturn() { + return myForceEarlyReturn.isAvailable(); + } + private final Capability myCanGetInstanceInfo = new Capability() { protected boolean calcValue() { if (!myVersionHigher_15) { diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 35af1b7ecf06..cd52bace6af4 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -709,6 +709,8 @@ action.ForceRunToCursor.text=Force Run to Cur_sor action.ForceRunToCursor.description=Run to the line where the caret is, ignoring any breakpoints action.Debugger.PopFrame.text=Drop _Frame action.Debugger.PopFrame.description=Moves execution point back to the method call dropping current method frames from the stack +action.Debugger.ForceEarlyReturn.text=Force Early Return +action.Debugger.ForceEarlyReturn.description=Force a method to return before it reaches a return statement action.Debugger.ShowLibraryFrames.text=Show/Hide Library Frames action.Pause.text=_Pause Program action.Pause.description=Suspend program execution and enable debugging diff --git a/resources-en/src/messages/DebuggerBundle.properties b/resources-en/src/messages/DebuggerBundle.properties index 0ccde1aa3a48..d0c2d8834f89 100644 --- a/resources-en/src/messages/DebuggerBundle.properties +++ b/resources-en/src/messages/DebuggerBundle.properties @@ -28,6 +28,7 @@ title.evaluating=Evaluating... error.modification.watchpoints.not.supported=Target VM does not support modification watchpoints error.native.method.exception=None of the frames through and including frame may be native error.executing.finally=Error while executing finally blocks: {0} +error.early.return=Error while doing early return: {0} warning.finally.block.detected=Non-empty finally blocks detected: button.drop.anyway=Drop frame anyway button.execute.finally=Execute finally blocks and drop frame @@ -335,7 +336,7 @@ method.breakpoints.tab.title=Java Method Breakpoints title.error.evaluating.breakpoint.condition=Breakpoint Condition Error title.error.evaluating.breakpoint.action=Breakpoint Action Error error.evaluating.breakpoint.condition.or.action=Problem processing VM event:\nBreakpoint: ''{0}''\nError: {1}\nWould you like to stop at the breakpoint? -error.unable.to.evaluate.expression=unable to evaluate the expression +error.unable.to.evaluate.expression=Unable to evaluate the expression breakpoint.properties.panel.option.pass.count=&Pass count: breakpoint.properties.panel.option.class.filters=C&lass filters: breakpoint.properties.panel.option.instance.filters=&Instance filters: diff --git a/resources/src/idea/JavaActions.xml b/resources/src/idea/JavaActions.xml index 2f511f16f876..6f675109b883 100644 --- a/resources/src/idea/JavaActions.xml +++ b/resources/src/idea/JavaActions.xml @@ -110,6 +110,10 @@ + + + + From fb2a1051a2c9cefc828ee4837ea5885666e31e84 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 17 Sep 2015 20:09:16 +0300 Subject: [PATCH 059/138] compare text attributes properly --- .../src/com/intellij/ui/tabs/TabInfo.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java b/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java index acd90ef58dcb..91536d53deaa 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java @@ -17,6 +17,7 @@ package com.intellij.ui.tabs; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.ui.Queryable; import com.intellij.openapi.util.Comparing; import com.intellij.reference.SoftReference; @@ -107,22 +108,24 @@ public final class TabInfo implements Queryable, PlaceProvider { public TabInfo setText(String text) { List attributes = myText.getAttributes(); - SimpleTextAttributes textAttributes = attributes.isEmpty() ? null : attributes.get(0); - SimpleTextAttributes defaultAttributes = getDefaultAttributes(); + TextAttributes textAttributes = attributes.isEmpty() ? null : attributes.get(0).toTextAttributes(); + TextAttributes defaultAttributes = getDefaultAttributes().toTextAttributes(); if (!myText.toString().equals(text) || !Comparing.equal(textAttributes, defaultAttributes)) { clearText(false); - append(text, defaultAttributes); + append(text, getDefaultAttributes()); } return this; } + @NotNull private SimpleTextAttributes getDefaultAttributes() { - if (myDefaultAttributes != null) return myDefaultAttributes; + SimpleTextAttributes attributes = myDefaultAttributes; + if (attributes == null) { + myDefaultAttributes = attributes = new SimpleTextAttributes(myDefaultStyle != -1 ? myDefaultStyle : SimpleTextAttributes.STYLE_PLAIN, + myDefaultForeground, myDefaultWaveColor); - myDefaultAttributes = new SimpleTextAttributes(myDefaultStyle != -1 ? myDefaultStyle : SimpleTextAttributes.STYLE_PLAIN, - myDefaultForeground, myDefaultWaveColor); - - return myDefaultAttributes; + } + return attributes; } public TabInfo clearText(final boolean invalidate) { From 3d908a24f4ea395fc8cc08d638b1159a66feb61a Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 18 Sep 2015 16:51:57 +0300 Subject: [PATCH 060/138] use our common thread pool instead of a separate single thread pool --- .../application/impl/TransferToPooledThreadQueue.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/TransferToPooledThreadQueue.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/TransferToPooledThreadQueue.java index 79435a4c7166..d07aeb2b6e6e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/TransferToPooledThreadQueue.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/TransferToPooledThreadQueue.java @@ -16,13 +16,14 @@ package com.intellij.openapi.application.impl; import com.intellij.openapi.util.Condition; -import com.intellij.util.ConcurrencyUtil; import com.intellij.util.Processor; +import com.intellij.util.concurrency.BoundedTaskExecutor; import com.intellij.util.containers.TransferToEDTQueue; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.ide.PooledThreadExecutor; -import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.Executor; /** * Passes elements for processing in the dedicated thread. @@ -30,14 +31,14 @@ import java.util.concurrent.ThreadPoolExecutor; * Usage: {@link #offer(Object)}} : schedules element for processing in a pooled thread */ public class TransferToPooledThreadQueue extends TransferToEDTQueue { - private final ThreadPoolExecutor myExecutor; + private final Executor myExecutor; public TransferToPooledThreadQueue(@NonNls @NotNull String name, @NotNull Condition shutUpCondition, int maxUnitOfWorkThresholdMs, @NotNull Processor processor) { super(name, processor, shutUpCondition, maxUnitOfWorkThresholdMs); - myExecutor = ConcurrencyUtil.newSingleThreadExecutor(name); + myExecutor = new BoundedTaskExecutor(PooledThreadExecutor.INSTANCE, 1); } @Override From cfc0226642460985e2ca1f2d3be9d12af1432d8c Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Sat, 19 Sep 2015 15:19:55 +0300 Subject: [PATCH 061/138] more checkCanceled --- .../intellij/psi/impl/FindSuperElementsHelper.java | 4 ++++ .../psi/impl/search/JavaClassInheritorsSearcher.java | 7 ++++--- .../impl/search/JavaDirectInheritorsSearcher.java | 12 ++++++++---- .../psi/impl/search/MethodUsagesSearcher.java | 4 ++-- .../src/com/intellij/util/ExecutorsQuery.java | 4 +++- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/psi/impl/FindSuperElementsHelper.java b/java/java-analysis-impl/src/com/intellij/psi/impl/FindSuperElementsHelper.java index 7d5bfda6dfec..8a468bd71614 100644 --- a/java/java-analysis-impl/src/com/intellij/psi/impl/FindSuperElementsHelper.java +++ b/java/java-analysis-impl/src/com/intellij/psi/impl/FindSuperElementsHelper.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.impl; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; @@ -84,11 +85,14 @@ public class FindSuperElementsHelper { ClassInheritorsSearch.search(containingClass, containingClass.getUseScope(), true, true, false).forEach(new Processor() { @Override public boolean process(PsiClass inheritor) { + ProgressManager.checkCanceled(); for (PsiClassType interfaceType : inheritor.getImplementsListTypes()) { + ProgressManager.checkCanceled(); PsiClassType.ClassResolveResult resolved = interfaceType.resolveGenerics(); PsiClass anInterface = resolved.getElement(); if (anInterface == null || !checkedInterfaces.add(PsiAnchor.create(anInterface))) continue; for (PsiMethod superMethod : anInterface.findMethodsByName(method.getName(), true)) { + ProgressManager.checkCanceled(); PsiClass superInterface = superMethod.getContainingClass(); if (superInterface == null) { continue; diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java index 7846f74651e2..b6f1d08b2111 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java @@ -21,6 +21,7 @@ import com.intellij.openapi.application.ReadActionProcessor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressIndicatorProvider; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Ref; @@ -81,7 +82,7 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase() { @Override public boolean process(final PsiClass aClass) { - ProgressIndicatorProvider.checkCanceled(); + ProgressManager.checkCanceled(); return isJavaLangObject(aClass) || consumer.process(aClass); } }); @@ -95,7 +96,7 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase processor = new ReadActionProcessor() { @Override public boolean processInReadAction(PsiClass candidate) { - ProgressIndicatorProvider.checkCanceled(); + ProgressManager.checkCanceled(); if (parameters.isCheckInheritance() || parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass)) { if (!candidate.isInheritor(currentBase.get(), false)) { @@ -130,7 +131,7 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase() { @Override public boolean process(final PsiClass psiClass) { + ProgressManager.checkCanceled(); if (psiClass.isInterface()) { return consumer.process(psiClass); } @@ -113,7 +114,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor> classes = new HashMap>(); for (final PsiReferenceList referenceList : candidates) { - ProgressIndicatorProvider.checkCanceled(); + ProgressManager.checkCanceled(); final PsiClass candidate = (PsiClass)ApplicationManager.getApplication().runReadAction(new Computable() { @Override public PsiElement compute() { @@ -139,6 +140,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor sameNamedClasses : classes.values()) { + ProgressManager.checkCanceled(); if (!processSameNamedClasses(consumer, sameNamedClasses, jarFile)) return false; } } @@ -155,7 +157,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor() { @@ -210,6 +213,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor 1) { for (PsiClass sameNamedClass : sameNamedClasses) { + ProgressManager.checkCanceled(); boolean fromSameJar = Comparing.equal(getJarFile(sameNamedClass), jarFile); if (fromSameJar) { sameJarClassFound = true; diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java index 8ab27b1b4286..0bc09d7b52f7 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,7 +119,7 @@ public class MethodUsagesSearcher extends QueryExecutorBase T resolveInReadAction(@NotNull Project p, Computable computable) { + static T resolveInReadAction(@NotNull Project p, @NotNull Computable computable) { return ApplicationManager.getApplication().isReadAccessAllowed() ? computable.compute() : DumbService.getInstance(p).runReadActionInSmartMode(computable); } diff --git a/platform/core-api/src/com/intellij/util/ExecutorsQuery.java b/platform/core-api/src/com/intellij/util/ExecutorsQuery.java index 1b4bedc24fbb..fda929cc77ab 100644 --- a/platform/core-api/src/com/intellij/util/ExecutorsQuery.java +++ b/platform/core-api/src/com/intellij/util/ExecutorsQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.intellij.util; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.IndexNotReadyException; import org.jetbrains.annotations.NotNull; @@ -40,6 +41,7 @@ public final class ExecutorsQuery extends AbstractQuery consumer) { for (QueryExecutor executor : myExecutors) { try { + ProgressManager.checkCanceled(); if (!executor.execute(myParameters, consumer)) { return false; } From 9e04cb1e17221d3590b466993a0552f2e2039797 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Sat, 19 Sep 2015 15:20:56 +0300 Subject: [PATCH 062/138] notnull --- .../com/intellij/openapi/command/impl/UndoManagerImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java index af6da88acfb6..466c0f8d431b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -647,11 +647,12 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap } @TestOnly - public void setEditorProvider(CurrentEditorProvider p) { + public void setEditorProvider(@NotNull CurrentEditorProvider p) { myEditorProvider = p; } @TestOnly + @NotNull public CurrentEditorProvider getEditorProvider() { return myEditorProvider; } From 9e8add124428f5cee52cce899bf95d9d6c7286ea Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 21 Sep 2015 14:33:41 +0300 Subject: [PATCH 063/138] new read/write lock which is twice as fast for mostly reads --- .../application/impl/ApplicationImpl.java | 92 ++--- .../application/ApplicationImplTest.java | 322 ++++++++---------- 2 files changed, 189 insertions(+), 225 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index b8bfe9ff8765..411d22db8932 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -67,6 +67,7 @@ import com.intellij.util.io.storage.HeavyProcessLatch; import com.intellij.util.ui.UIUtil; import gnu.trove.TLongArrayList; import gnu.trove.TLongProcedure; +import jsr166e.StampedLock; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; @@ -78,22 +79,18 @@ import java.awt.*; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.locks.ReentrantReadWriteLock; public class ApplicationImpl extends PlatformComponentManagerImpl implements ApplicationEx { private static final Logger LOG = Logger.getInstance("#com.intellij.application.impl.ApplicationImpl"); private final ModalityState MODALITY_STATE_NONE = ModalityState.NON_MODAL; - // about writer preference: the way the j.u.c.l.ReentrantReadWriteLock.NonfairSync is implemented, the - // writer thread will be always at the queue head and therefore, j.u.c.l.ReentrantReadWriteLock.NonfairSync.readerShouldBlock() - // will return true if the write action is pending, exactly as we need - private final ReentrantReadWriteLock myLock = new ReentrantReadWriteLock(false); + private final StampedLock myLock = new StampedLock(); private final ModalityInvokator myInvokator = new ModalityInvokatorImpl(); @@ -126,12 +123,13 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App private static final String WAS_EVER_SHOWN = "was.ever.shown"; private static final int IS_EDT_FLAG = 1<<30; // we don't mess with sign bit since we want to do arithmetic - private static final int IS_READ_LOCK_ACQUIRED_FLAG = 1<<29; private static class Status { // higher three bits are for IS_* flags // lower bits are for edtSafe counter private int flags; + // StampedLock' acquired sequence or zero if not locked + private long stamp; } private static final ThreadLocal status = new ThreadLocal(){ @@ -145,9 +143,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App private static Status getStatus() { return status.get(); } - private static void setReadLockAcquired(Status status, boolean acquired) { - status.flags = BitUtil.set(status.flags, IS_READ_LOCK_ACQUIRED_FLAG, acquired); - } private static final ModalityState ANY = new ModalityState() { @Override @@ -319,7 +314,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App } private static boolean holdsReadLock(Status status) { - return BitUtil.isSet(status.flags, IS_READ_LOCK_ACQUIRED_FLAG); + return status.stamp != 0; } @NotNull @@ -981,8 +976,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App private void startRead(Status status) { assertNoPsiLock(); try { - myLock.readLock().lockInterruptibly(); - setReadLockAcquired(status, true); + status.stamp = myLock.readLockInterruptibly(); } catch (InterruptedException e) { throw new RuntimeInterruptedException(e); @@ -990,8 +984,8 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App } private void endRead(Status status) { - setReadLockAcquired(status, false); - myLock.readLock().unlock(); + myLock.unlockRead(status.stamp); + status.stamp = 0; } @Override @@ -1074,7 +1068,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App } private static boolean isReadAccessAllowed(Status status) { - return (status.flags & (IS_EDT_FLAG | IS_READ_LOCK_ACQUIRED_FLAG)) != 0; + return BitUtil.isSet(status.flags, IS_EDT_FLAG) || status.stamp != 0; } @Override @@ -1155,14 +1149,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App if (mustAcquire) { assertNoPsiLock(); - try { - // timed version of tryLock() respects fairness unlike the no-args method - if (!myLock.readLock().tryLock(0, TimeUnit.MILLISECONDS)) return false; - setReadLockAcquired(status, true); - } - catch (InterruptedException e) { - throw new RuntimeInterruptedException(e); - } + if ((status.stamp = myLock.tryReadLock()) == 0) return false; } try { @@ -1209,7 +1196,8 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App private final TLongArrayList writePauses = new TLongArrayList(); private void startWrite(@Nullable Class clazz) { - assertIsDispatchThread(getStatus(), "Write access is allowed from event dispatch thread only"); + Status status = getStatus(); + assertIsDispatchThread(status, "Write access is allowed from event dispatch thread only"); boolean writeActionPending = myWriteActionPending; myWriteActionPending = true; long start = System.currentTimeMillis(); @@ -1218,26 +1206,26 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App fireBeforeWriteActionStart(clazz); try { - if (!isWriteAccessAllowed()) { + if (!myLock.isWriteLocked()) { assertNoPsiLock(); - } - if (!myLock.writeLock().tryLock()) { - final AtomicBoolean lockAcquired = new AtomicBoolean(false); - if (ourDumpThreadsOnLongWriteActionWaiting > 0) { - executeOnPooledThread(new Runnable() { - @Override - public void run() { - while (!lockAcquired.get()) { - TimeoutUtil.sleep(ourDumpThreadsOnLongWriteActionWaiting); - if (!lockAcquired.get()) { - PerformanceWatcher.getInstance().dumpThreads("waiting", true); + if ((status.stamp = myLock.tryWriteLock()) == 0) { + final AtomicBoolean lockAcquired = new AtomicBoolean(false); + if (ourDumpThreadsOnLongWriteActionWaiting > 0) { + executeOnPooledThread(new Runnable() { + @Override + public void run() { + while (!lockAcquired.get()) { + TimeoutUtil.sleep(ourDumpThreadsOnLongWriteActionWaiting); + if (!lockAcquired.get()) { + PerformanceWatcher.getInstance().dumpThreads("waiting", true); + } } } - } - }); + }); + } + status.stamp = myLock.writeLockInterruptibly(); + lockAcquired.set(true); } - myLock.writeLock().lockInterruptibly(); - lockAcquired.set(true); } } catch (InterruptedException e) { @@ -1258,11 +1246,15 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App private void endWrite(@Nullable Class clazz) { try { - myWriteActionsStack.pop(); fireWriteActionFinished(clazz); } finally { - myLock.writeLock().unlock(); + myWriteActionsStack.pop(); + if (myWriteActionsStack.isEmpty()) { + Status status = getStatus(); + myLock.unlockWrite(status.stamp); + status.stamp = 0; + } } } @@ -1363,7 +1355,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App @Override public boolean isWriteAccessAllowed() { - return myLock.isWriteLockedByCurrentThread(); + return isDispatchThread() && myLock.isWriteLocked(); } // cheaper version of isWriteAccessAllowed(). must be called from EDT @@ -1494,4 +1486,16 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App (isHeadlessEnvironment() ? " (Headless)" : "") + (isCommandLine() ? " (Command line)" : ""); } + + @TestOnly + public void disableEventsUntil(@NotNull Disposable disposable) { + final List listeners = new ArrayList(myDispatcher.getListeners()); + myDispatcher.getListeners().removeAll(listeners); + Disposer.register(disposable, new Disposable() { + @Override + public void dispose() { + myDispatcher.getListeners().addAll(listeners); + } + }); + } } diff --git a/platform/platform-tests/testSrc/com/intellij/application/ApplicationImplTest.java b/platform/platform-tests/testSrc/com/intellij/application/ApplicationImplTest.java index 6ba1cceca1d4..38114c10f651 100644 --- a/platform/platform-tests/testSrc/com/intellij/application/ApplicationImplTest.java +++ b/platform/platform-tests/testSrc/com/intellij/application/ApplicationImplTest.java @@ -15,20 +15,22 @@ */ package com.intellij.application; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.openapi.application.impl.ApplicationImpl; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.progress.impl.ProgressManagerImpl; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.util.ThrowableComputable; import com.intellij.testFramework.PlatformTestCase; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.Timings; -import com.intellij.util.ThrowableRunnable; import com.intellij.util.TimeoutUtil; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -58,50 +60,38 @@ public class ApplicationImplTest extends PlatformTestCase { String err = null; for (int i=0; i<4; i++) { - Callable runnable = new Callable() { - @Override - public String call() throws Exception { - try { - assertFalse(application.isReadAccessAllowed()); - long l2 = PlatformTestUtil.measure(new Runnable() { - @Override - public void run() { - for (int i = 0; i < N; i++) { - AccessToken token = application.acquireReadActionLock(); - try { - // do it - } - finally { - token.finish(); - } - } + Callable runnable = () -> { + try { + assertFalse(application.isReadAccessAllowed()); + long l2 = PlatformTestUtil.measure(() -> { + for (int i1 = 0; i1 < N; i1++) { + AccessToken token = application.acquireReadActionLock(); + try { + // do it } - }); - - long l1 = PlatformTestUtil.measure(new Runnable() { - @Override - public void run() { - for (int i=0; i 20) { - return "Suspiciously different times for acquireReadActionLock(" +l2 + "ms) vs runReadAction(" + l1 + "ms). Ratio: "+ ratioPercent + "%"; } + }); + + long l1 = PlatformTestUtil.measure(() -> { + for (int i1 = 0; i1 < N; i1++) { + application.runReadAction(() -> { + }); + } + }); + + assertFalse(application.isReadAccessAllowed()); + int ratioPercent = (int)((l1 - l2) * 100.0 / l1); + if (Math.abs(ratioPercent) > 20) { + return "Suspiciously different times for acquireReadActionLock(" +l2 + "ms) vs runReadAction(" + l1 + "ms). Ratio: "+ ratioPercent + "%"; } - catch (Throwable e) { - exception = e; - } - return null; } + catch (Throwable e) { + exception = e; + } + return null; }; err = application.executeOnPooledThread(runnable).get(); @@ -114,49 +104,61 @@ public class ApplicationImplTest extends PlatformTestCase { } - public void testLockPerformance() throws InterruptedException { - int iterations = Timings.adjustAccordingToMySpeed(3000, true); + public void testReadWriteLockPerformance() throws InterruptedException { + int iterations = Timings.adjustAccordingToMySpeed(300000, true); System.out.println("iterations = " + iterations); final int readIterations = iterations; final int writeIterations = iterations; - final int numOfThreads = 10; - PlatformTestUtil.startPerformanceTest("lock performance", 200, new ThrowableRunnable() { - @Override - public void run() throws Throwable { + runReadWrites(readIterations, writeIterations, 2000); + } + + public void testReadLockPerformance() throws InterruptedException { + int iterations = Timings.adjustAccordingToMySpeed(300000, true); + System.out.println("iterations = " + iterations); + final int readIterations = iterations; + final int writeIterations = 0; + + runReadWrites(readIterations, writeIterations, 1000); + } + + private static void runReadWrites(final int readIterations, final int writeIterations, int expectedMs) { + final ApplicationImpl application = (ApplicationImpl)ApplicationManager.getApplication(); + Disposable disposable = Disposer.newDisposable(); + application.disableEventsUntil(disposable); + + try { + final int numOfThreads = 10; + PlatformTestUtil.startPerformanceTest("lock performance", expectedMs, () -> { final CountDownLatch reads = new CountDownLatch(numOfThreads); for (int i = 0; i < numOfThreads; i++) { final String name = "stress thread " + i; - new Thread(new Runnable() { - @Override - public void run() { - System.out.println(name); - for (int i = 0; i < readIterations; i++) { - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { + new Thread(() -> { + System.out.println(name); + for (int i1 = 0; i1 < readIterations; i1++) { + application.runReadAction(() -> { - } - }); - } - - reads.countDown(); + }); } + + reads.countDown(); }, name).start(); } - System.out.println("write start"); - for (int i = 0; i < writeIterations; i++) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - } - }); + if (writeIterations > 0) { + System.out.println("write start"); + for (int i = 0; i < writeIterations; i++) { + ApplicationManager.getApplication().runWriteAction(() -> { + }); + } + System.out.println("write end"); } - System.out.println("write end"); reads.await(); - } - }).assertTiming(); + }).assertTiming(); + } + finally { + Disposer.dispose(disposable); + } } private volatile boolean tryingToStartWriteAction; @@ -170,62 +172,50 @@ public class ApplicationImplTest extends PlatformTestCase { anotherThreadStarted[i] = new AtomicBoolean(); } final StringBuffer LOG = new StringBuffer(); - new Thread(new Runnable() { - @Override - public void run() { - try { - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - LOG.append("inside read action\n"); - readStarted = true; - while (!tryingToStartWriteAction); - TimeoutUtil.sleep(100); + new Thread(() -> { + try { + ApplicationManager.getApplication().runReadAction(() -> { + LOG.append("inside read action\n"); + readStarted = true; + while (!tryingToStartWriteAction); + TimeoutUtil.sleep(100); - for (int i = 0; i < anotherReadActionStarted.length; i++) { - final int finalI = i; - new Thread(new Runnable() { - @Override - public void run() { - LOG.append("\nanother thread started " + finalI); - anotherThreadStarted[finalI].set(true); - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - LOG.append("\ninside another thread read action " + finalI); - anotherReadActionStarted[finalI].set(true); - try { - Thread.sleep(100); - } - catch (InterruptedException e) { - throw new RuntimeException(e); - } - anotherReadActionStarted[finalI].set(false); - LOG.append("\nfinished another thread read action " + finalI); - } - }); - LOG.append("\nanother thread finished " + finalI); - } - },"another read action "+i).start(); - } - - for (AtomicBoolean threadStarted : anotherThreadStarted) { - while (!threadStarted.get()) ; - } - // now the other threads try to get read lock. we should not let them - for (int i=0; i<10; i++) { - for (AtomicBoolean readStarted : anotherReadActionStarted) { - assertThat(!readStarted.get(), "must not start another read action while write is pending"); + for (int i = 0; i < anotherReadActionStarted.length; i++) { + final int finalI = i; + new Thread(() -> { + LOG.append("\nanother thread started " + finalI); + anotherThreadStarted[finalI].set(true); + ApplicationManager.getApplication().runReadAction(() -> { + LOG.append("\ninside another thread read action " + finalI); + anotherReadActionStarted[finalI].set(true); + try { + Thread.sleep(100); } - TimeoutUtil.sleep(20); - } - LOG.append("\nfinished read action"); + catch (InterruptedException e) { + throw new RuntimeException(e); + } + anotherReadActionStarted[finalI].set(false); + LOG.append("\nfinished another thread read action " + finalI); + }); + LOG.append("\nanother thread finished " + finalI); + }, "another read action " + i).start(); + } + + for (AtomicBoolean threadStarted : anotherThreadStarted) { + while (!threadStarted.get()) ; + } + // now the other threads try to get read lock. we should not let them + for (int i=0; i<10; i++) { + for (AtomicBoolean readStarted1 : anotherReadActionStarted) { + assertThat(!readStarted1.get(), "must not start another read action while write is pending"); } - }); - } - catch (Throwable e) { - exception = e; - } + TimeoutUtil.sleep(20); + } + LOG.append("\nfinished read action"); + }); + } + catch (Throwable e) { + exception = e; } }, "read").start(); @@ -233,15 +223,12 @@ public class ApplicationImplTest extends PlatformTestCase { while (!readStarted); tryingToStartWriteAction = true; LOG.append("\nwrite about to start"); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - LOG.append("\ninside write action"); - for (AtomicBoolean readStarted : anotherReadActionStarted) { - assertThat(!readStarted.get(), "must not start another read action while write is running"); - } - LOG.append("\nfinished write action"); + ApplicationManager.getApplication().runWriteAction(() -> { + LOG.append("\ninside write action"); + for (AtomicBoolean readStarted1 : anotherReadActionStarted) { + assertThat(!readStarted1.get(), "must not start another read action while write is running"); } + LOG.append("\nfinished write action"); }); if (exception != null) { System.err.println(LOG); @@ -257,37 +244,23 @@ public class ApplicationImplTest extends PlatformTestCase { } public void testProgressVsReadAction() throws Throwable { - ProgressManager.getInstance().runProcessWithProgressSynchronously(new ThrowableComputable() { - @Override - public Void compute() throws Exception { - try { - assertFalse(ApplicationManager.getApplication().isReadAccessAllowed()); - assertFalse(ApplicationManager.getApplication().isDispatchThread()); - for (int i=0; i<100;i++) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - TimeoutUtil.sleep(20); - } - }); - } - }); - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - TimeoutUtil.sleep(20); - } - }); - } + ProgressManager.getInstance().runProcessWithProgressSynchronously((ThrowableComputable)() -> { + try { + assertFalse(ApplicationManager.getApplication().isReadAccessAllowed()); + assertFalse(ApplicationManager.getApplication().isDispatchThread()); + for (int i=0; i<100;i++) { + SwingUtilities.invokeLater(() -> ApplicationManager.getApplication().runWriteAction(() -> { + TimeoutUtil.sleep(20); + })); + ApplicationManager.getApplication().runReadAction(() -> { + TimeoutUtil.sleep(20); + }); } - catch (Exception e) { - exception = e; - } - return null; } + catch (Exception e) { + exception = e; + } + return null; }, "cc", false, getProject()); if (exception != null) throw exception; } @@ -329,16 +302,13 @@ public class ApplicationImplTest extends PlatformTestCase { public void testRunProcessWithProgressSynchronouslyInReadAction() throws Throwable { boolean result = ((ApplicationEx)ApplicationManager.getApplication()) - .runProcessWithProgressSynchronouslyInReadAction(getProject(), "title", true, "cancel", null, new Runnable() { - @Override - public void run() { - try { - assertFalse(SwingUtilities.isEventDispatchThread()); - assertTrue(ApplicationManager.getApplication().isReadAccessAllowed()); - } - catch (Throwable e) { - exception = e; - } + .runProcessWithProgressSynchronouslyInReadAction(getProject(), "title", true, "cancel", null, () -> { + try { + assertFalse(SwingUtilities.isEventDispatchThread()); + assertTrue(ApplicationManager.getApplication().isReadAccessAllowed()); + } + catch (Throwable e) { + exception = e; } }); assertTrue(result); @@ -346,19 +316,9 @@ public class ApplicationImplTest extends PlatformTestCase { } public void testRunProcessWithProgressSynchronouslyInReadActionWithPendingWriteAction() throws Throwable { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().runWriteAction(EmptyRunnable.getInstance()); - } - }); + SwingUtilities.invokeLater(() -> ApplicationManager.getApplication().runWriteAction(EmptyRunnable.getInstance())); boolean result = ((ApplicationEx)ApplicationManager.getApplication()) - .runProcessWithProgressSynchronouslyInReadAction(getProject(), "title", true, "cancel", null, new Runnable() { - @Override - public void run() { - TimeoutUtil.sleep(10000); - } - }); + .runProcessWithProgressSynchronouslyInReadAction(getProject(), "title", true, "cancel", null, () -> TimeoutUtil.sleep(10000)); assertTrue(result); UIUtil.dispatchAllInvocationEvents(); if (exception != null) throw exception; From 679a4b3f193c8dcda33ec509f45d09b559ba506f Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 21 Sep 2015 14:41:56 +0300 Subject: [PATCH 064/138] int array instead of long --- .../application/impl/ApplicationImpl.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 411d22db8932..7b51b4af34de 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -65,8 +65,8 @@ import com.intellij.util.concurrency.Semaphore; import com.intellij.util.containers.Stack; import com.intellij.util.io.storage.HeavyProcessLatch; import com.intellij.util.ui.UIUtil; -import gnu.trove.TLongArrayList; -import gnu.trove.TLongProcedure; +import gnu.trove.TIntArrayList; +import gnu.trove.TIntProcedure; import jsr166e.StampedLock; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -537,10 +537,10 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App Disposer.dispose(myLastDisposable); // dispose it last if (LOG.isDebugEnabled()) { - final long[] sum = {0}; - writePauses.forEach(new TLongProcedure() { + final int[] sum = {0}; + writePauses.forEach(new TIntProcedure() { @Override - public boolean execute(long value) { + public boolean execute(int value) { sum[0] += value; return true; } @@ -549,8 +549,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App "\nTotal write actions: " + writePauses.size() + "\nTotal write pauses : " + sum[0] + "ms"+ "\nAverage write pause: " + sum[0] / writePauses.size() + "ms" + - "\nMedian write pause: " + ArrayUtil.averageAmongMedians(writePauses.toNativeArray(), 3) + "ms" + - "" + "\nMedian write pause: " + ArrayUtil.averageAmongMedians(writePauses.toNativeArray(), 3) + "ms" ); } } @@ -1194,7 +1193,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App return myWriteActionPending; } - private final TLongArrayList writePauses = new TLongArrayList(); + private final TIntArrayList writePauses = new TIntArrayList(); private void startWrite(@Nullable Class clazz) { Status status = getStatus(); assertIsDispatchThread(status, "Write access is allowed from event dispatch thread only"); @@ -1239,7 +1238,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App myWriteActionsStack.push(clazz); if (LOG.isDebugEnabled()) { long end = System.currentTimeMillis(); - writePauses.add(end - start); + writePauses.add((int)(end - start)); } fireWriteActionStarted(clazz); } From 54ffb7157dd0f62997bc5b7c8315770badf7ad37 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 21 Sep 2015 14:49:28 +0300 Subject: [PATCH 065/138] make temporary names more nice-looking, remove project files cached in VFS from the previous tests --- .../unusedLibrary/simple/expected.xml | 2 +- .../testFramework/PlatformTestCase.java | 14 +++++- .../testFramework/UsefulTestCase.java | 3 +- .../intellij/openapi/util/io/FileUtilRt.java | 47 +++++++------------ 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/java/java-tests/testData/inspection/unusedLibrary/simple/expected.xml b/java/java-tests/testData/inspection/unusedLibrary/simple/expected.xml index 8184735d55cf..9cd23b0df42b 100644 --- a/java/java-tests/testData/inspection/unusedLibrary/simple/expected.xml +++ b/java/java-tests/testData/inspection/unusedLibrary/simple/expected.xml @@ -1,7 +1,7 @@ - testSimple_0.iml + testSimple.iml Unused library Unused library 'JUnit' diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index ab2d6ce3cc49..0b4798d70354 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -53,6 +53,7 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl; +import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl; import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS; import com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl; @@ -185,6 +186,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro @Override protected void setUp() throws Exception { super.setUp(); + myFilesToDelete.add(new File(FileUtilRt.getTempDirectory())); if (ourTestCase != null) { String message = "Previous test " + ourTestCase + " hasn't called tearDown(). Probably overridden without super call."; ourTestCase = null; @@ -250,7 +252,15 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } @NotNull - public static Project createProject(File projectFile, String creationPlace) { + public static Project createProject(@NotNull File projectFile, @NotNull String creationPlace) { + VirtualFile projectBase = LocalFileSystem.getInstance().findFileByIoFile(projectFile.getName().endsWith( + ProjectFileType.DOT_DEFAULT_EXTENSION) ? projectFile.getParentFile() : projectFile); + if (projectBase != null) { + // must be leftovers from the previous test run + for (VirtualFile file : ((NewVirtualFile)projectBase).iterInDbChildren()) { + delete(file); + } + } try { Project project = ProjectManagerEx.getInstanceEx().newProject(FileUtil.getNameWithoutExtension(projectFile), projectFile.getPath(), false, false); assert project != null; @@ -293,7 +303,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } protected File getIprFile() throws IOException { - File tempFile = FileUtil.createTempFile(getName() + "_", ProjectFileType.DOT_DEFAULT_EXTENSION); + File tempFile = FileUtil.createTempFile(getName(), ProjectFileType.DOT_DEFAULT_EXTENSION); myFilesToDelete.add(tempFile); return tempFile; } diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java index aad28bc65d90..97adee22ac48 100644 --- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java @@ -139,7 +139,8 @@ public abstract class UsefulTestCase extends TestCase { String testName = getTestName(true); if (StringUtil.isEmptyOrSpaces(testName)) testName = ""; testName = new File(testName).getName(); // in case the test name contains file separators - myTempDir = FileUtil.toSystemDependentName(ORIGINAL_TEMP_DIR + "/" + TEMP_DIR_MARKER + testName + "_"+ RNG.nextInt(1000)); + File tempDirectory = FileUtil.createTempDirectory(new File(ORIGINAL_TEMP_DIR), TEMP_DIR_MARKER + testName, ""); + myTempDir = tempDirectory.getPath(); FileUtil.resetCanonicalTempPathCache(myTempDir); } ApplicationInfoImpl.setInPerformanceTest(isPerformanceTest()); diff --git a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java index 8a48ba176218..fe7fdf648c90 100644 --- a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java +++ b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java @@ -385,12 +385,14 @@ public class FileUtilRt { if (suffix == null) { suffix = ".tmp"; } + // normalize and use only the file name from the prefix + prefix = new File(prefix).getName(); int exceptionsCount = 0; + int i = 0; while (true) { try { - // If there was an IOException, there's no reason to do sequential search - fallback to random - final File temp = createTemp(prefix, suffix, dir, isDirectory, exceptionsCount > 0); + final File temp = callCreate(dir, prefix, suffix, isDirectory, i); return normalizeFile(temp); } catch (IOException e) { // Win32 createFileExclusively access denied @@ -398,41 +400,28 @@ public class FileUtilRt { throw e; } } + i++; // for some reason the file1 can't be created (previous file1 was deleted but got locked by anti-virus?). try file2. + if (i > 2) { + i = 2 + (int)(System.nanoTime() % 998); // generate random suffix if too many failures + } } } @NotNull - private static File createTemp(@NotNull String prefix, + private static File callCreate(@NotNull File directory, + @NotNull String prefix, @NotNull String suffix, - @NotNull File directory, boolean isDirectory, - boolean randomName) throws IOException { - // Fallback to the original File.createTempFile - if (randomName) { - @SuppressWarnings("SSBasedInspection") - File res = File.createTempFile(prefix, suffix, directory); - if (isDirectory) { - if (!res.delete() || !res.mkdir()) { - throw new IOException("Cannot create directory: " + res); - } - } - return res; + int i) throws IOException { + prefix += i == 0 ? "" : i; + if (prefix.endsWith(".") && suffix.startsWith(".")) { + prefix = prefix.substring(0, prefix.length() - 1); } - - // normalize and use only the file name from the prefix - prefix = new File(prefix).getName(); - - File f; - int i = 0; - do { - String name = prefix + i + suffix; - f = new File(directory, name); - if (!name.equals(f.getName())) { - throw new IOException("Unable to create temporary file " + f + " for name " + name); - } - i++; + String name = prefix + suffix; + File f = new File(directory, name); + if (!name.equals(f.getName())) { + throw new IOException("Unable to create temporary file " + f + " for name " + name); } - while (f.exists()); boolean success = isDirectory ? f.mkdir() : f.createNewFile(); if (!success) { From 8a937e613cd6c9d562abe65c86b32ad620c4ff94 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Mon, 21 Sep 2015 16:24:47 +0300 Subject: [PATCH 066/138] @NotNull --- .../com/intellij/openapi/vcs/Executor.java | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/Executor.java b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/Executor.java index 4ebe0245f9e7..7acc62e9ae5d 100644 --- a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/Executor.java +++ b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/Executor.java @@ -26,6 +26,7 @@ import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; @@ -62,12 +63,12 @@ public class Executor { private static String ourCurrentDir; - private static void cdAbs(String absolutePath) { + private static void cdAbs(@NotNull String absolutePath) { ourCurrentDir = absolutePath; debug("# cd " + shortenPath(absolutePath)); } - private static void cdRel(String relativePath) { + private static void cdRel(@NotNull String relativePath) { cdAbs(ourCurrentDir + "/" + relativePath); } @@ -75,7 +76,7 @@ public class Executor { cdAbs(dir.getAbsolutePath()); } - public static void cd(String relativeOrAbsolutePath) { + public static void cd(@NotNull String relativeOrAbsolutePath) { if (relativeOrAbsolutePath.startsWith("/") || relativeOrAbsolutePath.charAt(1) == ':') { cdAbs(relativeOrAbsolutePath); } @@ -84,7 +85,7 @@ public class Executor { } } - public static void cd(VirtualFile dir) { + public static void cd(@NotNull VirtualFile dir) { cd(dir.getPath()); } @@ -110,13 +111,13 @@ public class Executor { } @NotNull - public static File touch(String fileName, String content) { + public static File touch(@NotNull String fileName, @NotNull String content) { File filePath = touch(fileName); echo(fileName, content); return filePath; } - public static void echo(String fileName, String content) { + public static void echo(@NotNull String fileName, @NotNull String content) { try { FileUtil.writeToFile(child(fileName), content.getBytes(), true); } @@ -152,7 +153,8 @@ public class Executor { return file; } - public static String cat(String fileName) { + @NotNull + public static String cat(@NotNull String fileName) { try { String content = FileUtil.loadFile(child(fileName)); debug("# cat " + fileName); @@ -163,7 +165,7 @@ public class Executor { } } - public static void cp(String fileName, File destinationDir) { + public static void cp(@NotNull String fileName, @NotNull File destinationDir) { try { FileUtil.copy(child(fileName), new File(destinationDir, fileName)); } @@ -172,8 +174,10 @@ public class Executor { } } - protected static String run(@NotNull File workingDir, @NotNull List params, - boolean ignoreNonZeroExitCode) throws ExecutionException { + @NotNull + protected static String run(@NotNull File workingDir, @NotNull List params, boolean ignoreNonZeroExitCode) + throws ExecutionException + { final ProcessBuilder builder = new ProcessBuilder().command(params); builder.directory(workingDir); builder.redirectErrorStream(true); @@ -207,7 +211,8 @@ public class Executor { return stdout; } - public static List splitCommandInParameters(String command) { + @NotNull + public static List splitCommandInParameters(@NotNull String command) { List split = new ArrayList(); boolean insideParam = false; @@ -248,7 +253,11 @@ public class Executor { return split; } - protected static String findExecutable(String programName, String unixExec, String winExec, Collection envs) { + @NotNull + protected static String findExecutable(@NotNull String programName, + @NotNull String unixExec, + @NotNull String winExec, + @NotNull Collection envs) { String exec = findEnvValue(programName, envs); if (exec != null) { return exec; @@ -265,7 +274,8 @@ public class Executor { " executable." : "")); } - public static String findEnvValue(String programNameForLog, Collection envs) { + @Nullable + public static String findEnvValue(@NotNull String programNameForLog, @NotNull Collection envs) { for (String env : envs) { String val = System.getenv(env); if (val != null && new File(val).canExecute()) { @@ -276,13 +286,14 @@ public class Executor { return null; } - public static void debug(String msg) { + public static void debug(@NotNull String msg) { if (!StringUtil.isEmptyOrSpaces(msg)) { LOG.info(msg); } } - private static String shortenPath(String path) { + @NotNull + private static String shortenPath(@NotNull String path) { String[] split = path.split("/"); if (split.length > 3) { // split[0] is empty, because the path starts from / @@ -291,7 +302,8 @@ public class Executor { return path; } - protected static File child(String fileName) { + @NotNull + protected static File child(@NotNull String fileName) { assert ourCurrentDir != null : "Current dir hasn't been initialized yet. Call cd at least once before any other command."; return new File(ourCurrentDir, fileName); } From 5538159a814f0e96634de0b79b363c549fa6e71b Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Mon, 21 Sep 2015 16:26:33 +0300 Subject: [PATCH 067/138] [git] remove empty assertion message: the situation is clear (and can't really happen) --- plugins/git4idea/src/git4idea/rebase/GitAbortRebaseProcess.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/git4idea/src/git4idea/rebase/GitAbortRebaseProcess.java b/plugins/git4idea/src/git4idea/rebase/GitAbortRebaseProcess.java index 981a9e9496b2..a8abc3591ed3 100644 --- a/plugins/git4idea/src/git4idea/rebase/GitAbortRebaseProcess.java +++ b/plugins/git4idea/src/git4idea/rebase/GitAbortRebaseProcess.java @@ -126,7 +126,7 @@ class GitAbortRebaseProcess { } else { if (myRepositoriesToRollback.isEmpty()) { - LOG.error("", new Throwable()); + LOG.error(new Throwable()); } else { String description = "Do you want rollback the successful rebase in " + mention(myRepositoriesToRollback.keySet()) + "?"; From a09dfa7545bdc9bafed9e832d542bc438f2b3c5d Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Mon, 21 Sep 2015 16:40:23 +0300 Subject: [PATCH 068/138] [git] don't allow to rebase the fresh repository --- .../src/git4idea/rebase/GitRebaseUtils.java | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/plugins/git4idea/src/git4idea/rebase/GitRebaseUtils.java b/plugins/git4idea/src/git4idea/rebase/GitRebaseUtils.java index 5db5e0f75c38..04edbd7db2ed 100644 --- a/plugins/git4idea/src/git4idea/rebase/GitRebaseUtils.java +++ b/plugins/git4idea/src/git4idea/rebase/GitRebaseUtils.java @@ -84,26 +84,31 @@ public class GitRebaseUtils { // TODO links to 'rebase', 'resolve conflicts', etc. for (GitRepository repository : repositories) { Repository.State state = repository.getState(); - if (state != Repository.State.NORMAL) { - String in = GitUtil.mention(repository); - String message; - switch (state) { - case MERGING: - message = "There is an unfinished merge process" + in + ".
You should complete the merge before starting a rebase"; - break; - case REBASING: - message = "There is an unfinished rebase process" + in + ".
You should complete it before starting another rebase"; - break; - case GRAFTING: - message = "There is an unfinished cherry-pick process" + in + ".
You should finish it before starting a rebase."; - break; - case DETACHED: - message = "You are in the detached HEAD state" + in + ".
Rebase is not possible."; - break; - default: - LOG.error("Unknown state [" + state.name() + "]"); - message = "Rebase is not possible" + in; - } + String in = GitUtil.mention(repository); + String message = null; + switch (state) { + case NORMAL: + if (repository.isFresh()) { + message = "Repository" + in + " is empty."; + } + break; + case MERGING: + message = "There is an unfinished merge process" + in + ".
You should complete the merge before starting a rebase"; + break; + case REBASING: + message = "There is an unfinished rebase process" + in + ".
You should complete it before starting another rebase"; + break; + case GRAFTING: + message = "There is an unfinished cherry-pick process" + in + ".
You should finish it before starting a rebase."; + break; + case DETACHED: + message = "You are in the detached HEAD state" + in + ".
Rebase is not possible."; + break; + default: + LOG.error("Unknown state [" + state.name() + "]"); + message = "Rebase is not possible" + in; + } + if (message != null) { VcsNotifier.getInstance(project).notifyError("Rebase not Allowed", message); return false; } From c0fd8f798f71855c9db6d32b7c65afff56c59e09 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Mon, 21 Sep 2015 11:37:14 +0300 Subject: [PATCH 069/138] cleanup --- .../StructureViewComponent.java | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java index ac5eef43e7cf..a3b45f166fc3 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,6 @@ import com.intellij.ide.ui.customization.CustomizationUtil; import com.intellij.ide.util.FileStructurePopup; import com.intellij.ide.util.treeView.*; import com.intellij.ide.util.treeView.smartTree.*; -import com.intellij.ide.util.treeView.smartTree.TreeModel; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; @@ -60,7 +59,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.tree.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -518,17 +520,6 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre return false; } - private static DefaultMutableTreeNode findInChildren(DefaultMutableTreeNode currentTreeNode, AbstractTreeNode topPathElement) { - for (int i = 0; i < currentTreeNode.getChildCount(); i++) { - TreeNode child = currentTreeNode.getChildAt(i); - if (((DefaultMutableTreeNode)child).getUserObject().equals(topPathElement)) - { - return (DefaultMutableTreeNode)child; - } - } - return null; - } - private void scrollToSelectedElement() { if (myAutoscrollFeedback) { myAutoscrollFeedback = false; @@ -814,8 +805,6 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre return value == null ? this : value; } - - @Override @NotNull public Collection getChildren() { @@ -910,7 +899,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre return o != null ? o.hashCode() : 0; } - private class StructureViewGroup extends GroupWrapper { + private static class StructureViewGroup extends GroupWrapper { public StructureViewGroup(Project project, Group group, TreeModel treeModel) { super(project, group, treeModel); } From 1f71edef180fe42410254788adc2c58371a45959 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 21 Sep 2015 16:52:25 +0300 Subject: [PATCH 070/138] mirrorOf renamed --- .../com/intellij/debugger/actions/ForceEarlyReturnAction.java | 2 +- .../engine/evaluation/expression/BlockStatementEvaluator.java | 4 ++-- .../evaluation/expression/DoWhileStatementEvaluator.java | 2 +- .../evaluation/expression/ForStatementEvaluatorBase.java | 2 +- .../engine/evaluation/expression/IfStatementEvaluator.java | 2 +- .../com/intellij/debugger/jdi/VirtualMachineProxyImpl.java | 3 +-- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java index 0545dd5a1ce9..4bf18a9e45a8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java @@ -77,7 +77,7 @@ public class ForceEarlyReturnAction extends DebuggerAction { } if ("void".equals(method.returnTypeName())) { - forceEarlyReturn(thread.getVirtualMachine().mirrorOf(), thread, debugProcess, null); + forceEarlyReturn(thread.getVirtualMachine().mirrorOfVoid(), thread, debugProcess, null); } else { //noinspection SSBasedInspection diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java index 57b1a44bb3c5..8956138882d9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ public class BlockStatementEvaluator implements Evaluator { @Override public Object evaluate(EvaluationContextImpl context) throws EvaluateException { - Object result = context.getSuspendContext().getDebugProcess().getVirtualMachineProxy().mirrorOf(); + Object result = context.getSuspendContext().getDebugProcess().getVirtualMachineProxy().mirrorOfVoid(); for (Evaluator statement : myStatements) { result = statement.evaluate(context); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DoWhileStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DoWhileStatementEvaluator.java index 1e48568a8dd8..c7de16e59362 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DoWhileStatementEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DoWhileStatementEvaluator.java @@ -37,7 +37,7 @@ public class DoWhileStatementEvaluator extends LoopEvaluator { } public Object evaluate(EvaluationContextImpl context) throws EvaluateException { - Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf(); + Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOfVoid(); while (true) { if (body(context)) break; diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java index 1064d0747b2b..4a7eee833d38 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java @@ -29,7 +29,7 @@ public abstract class ForStatementEvaluatorBase extends LoopEvaluator { } public Object evaluate(EvaluationContextImpl context) throws EvaluateException { - Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf(); + Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOfVoid(); value = evaluateInitialization(context, value); while (true) { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java index a48e960008ee..31c3aab00d42 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java @@ -54,7 +54,7 @@ public class IfStatementEvaluator implements Evaluator { value = myElseEvaluator.evaluate(context); myModifier = myElseEvaluator.getModifier(); } else { - value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf(); + value = context.getDebugProcess().getVirtualMachineProxy().mirrorOfVoid(); myModifier = null; } } diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java index 982964678413..b99f340787dd 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java @@ -22,7 +22,6 @@ package com.intellij.debugger.jdi; import com.intellij.debugger.engine.DebugProcess; import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.DebuggerManagerThreadImpl; -import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.jdi.VirtualMachineProxy; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; @@ -278,7 +277,7 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy { return myVirtualMachine.eventRequestManager(); } - public VoidValue mirrorOf() { + public VoidValue mirrorOfVoid() { return myVirtualMachine.mirrorOfVoid(); } From 7c9dbf436ae08ab49a19cbc6d7aa3e4e4fecdce3 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 21 Sep 2015 16:54:05 +0300 Subject: [PATCH 071/138] ThreeState instead of Boolean --- .../intellij/debugger/jdi/StackFrameProxyImpl.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java index e24067f711d3..4f4130ac83e5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java @@ -25,6 +25,7 @@ import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; import com.intellij.debugger.engine.jdi.StackFrameProxy; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.ThreeState; import com.sun.jdi.*; import gnu.trove.THashMap; import org.jetbrains.annotations.NonNls; @@ -46,7 +47,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { private StackFrame myStackFrame; private ObjectReference myThisReference; private ClassLoaderReference myClassLoader; - private Boolean myIsObsolete = null; + private ThreeState myIsObsolete = ThreeState.UNSURE; private Map myAllValues; public StackFrameProxyImpl(ThreadReferenceProxyImpl threadProxy, @NotNull StackFrame frame, int fromBottomIndex /* 1-based */) { @@ -59,14 +60,14 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { public boolean isObsolete() throws EvaluateException { DebuggerManagerThreadImpl.assertIsManagerThread(); checkValid(); - if (myIsObsolete != null) { - return myIsObsolete.booleanValue(); + if (myIsObsolete != ThreeState.UNSURE) { + return myIsObsolete.toBoolean(); } InvalidStackFrameException error = null; for (int attempt = 0; attempt < 2; attempt++) { try { boolean isObsolete = (getVirtualMachine().canRedefineClasses() && location().method().isObsolete()); - myIsObsolete = isObsolete? Boolean.TRUE : Boolean.FALSE; + myIsObsolete = ThreeState.fromBoolean(isObsolete); return isObsolete; } catch (InvalidStackFrameException e) { @@ -75,7 +76,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { } catch (InternalException e) { if (e.errorCode() == 23 /*INVALID_METHODID according to JDI sources*/) { - myIsObsolete = Boolean.TRUE; + myIsObsolete = ThreeState.YES; return true; } throw e; @@ -108,7 +109,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { } myFrameIndex = -1; myStackFrame = null; - myIsObsolete = null; + myIsObsolete = ThreeState.UNSURE; myThisReference = null; myClassLoader = null; myAllValues = null; From 1caf9193a39b968f74ce57b99d54a1f44dc472b0 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 21 Sep 2015 16:57:00 +0300 Subject: [PATCH 072/138] NotNulls --- .../impl/src/com/intellij/debugger/jdi/JdiProxy.java | 8 +++++--- .../com/intellij/debugger/jdi/StackFrameProxyImpl.java | 3 ++- .../intellij/debugger/jdi/ThreadReferenceProxyImpl.java | 1 + .../intellij/debugger/jdi/VirtualMachineProxyImpl.java | 1 + 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/JdiProxy.java b/java/debugger/impl/src/com/intellij/debugger/jdi/JdiProxy.java index ab8a3ce5ec26..1552cdeae648 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/JdiProxy.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/JdiProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ */ package com.intellij.debugger.jdi; +import org.jetbrains.annotations.NotNull; + /** * Created by IntelliJ IDEA. * User: lex @@ -23,10 +25,10 @@ package com.intellij.debugger.jdi; * To change this template use Options | File Templates. */ public abstract class JdiProxy { - protected JdiTimer myTimer; + @NotNull protected JdiTimer myTimer; private int myTimeStamp = 0; - public JdiProxy(JdiTimer timer) { + public JdiProxy(@NotNull JdiTimer timer) { myTimer = timer; myTimeStamp = myTimer.getCurrentTime(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java index 4f4130ac83e5..957ada3482a2 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java @@ -50,7 +50,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { private ThreeState myIsObsolete = ThreeState.UNSURE; private Map myAllValues; - public StackFrameProxyImpl(ThreadReferenceProxyImpl threadProxy, @NotNull StackFrame frame, int fromBottomIndex /* 1-based */) { + public StackFrameProxyImpl(@NotNull ThreadReferenceProxyImpl threadProxy, @NotNull StackFrame frame, int fromBottomIndex /* 1-based */) { super(threadProxy.getVirtualMachine()); myThreadProxy = threadProxy; myFrameFromBottomIndex = fromBottomIndex; @@ -172,6 +172,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { // return false; // } + @NotNull @Override public VirtualMachineProxyImpl getVirtualMachine() { return (VirtualMachineProxyImpl) myTimer; diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java index b9b4e57b24f2..1f53846f3ce3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java @@ -65,6 +65,7 @@ public final class ThreadReferenceProxyImpl extends ObjectReferenceProxyImpl imp return (ThreadReference)getObjectReference(); } + @NotNull @Override public VirtualMachineProxyImpl getVirtualMachine() { DebuggerManagerThreadImpl.assertIsManagerThread(); diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java index b99f340787dd..68ef3cd6aeb5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java @@ -87,6 +87,7 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy { } } + @NotNull public VirtualMachine getVirtualMachine() { return myVirtualMachine; } From 73daf8d8d6fc5ee26ea787a61e6ae0c66e1921c1 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Mon, 21 Sep 2015 17:26:59 +0300 Subject: [PATCH 073/138] [git] fix 'no local changes to stash' detection This is not an error message, but a simple output one. But check both just in case. --- .../src/git4idea/stash/GitStashChangesSaver.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java b/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java index fd0967976660..38db08222aea 100644 --- a/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java +++ b/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java @@ -20,6 +20,7 @@ import com.intellij.notification.NotificationListener; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.VcsNotifier; import com.intellij.openapi.vcs.history.VcsRevisionNumber; @@ -48,6 +49,7 @@ import java.util.Set; public class GitStashChangesSaver extends GitChangesSaver { private static final Logger LOG = Logger.getInstance(GitStashChangesSaver.class); + private static final String NO_LOCAL_CHANGES_TO_SAVE = "No local changes to save"; @NotNull private final GitRepositoryManager myRepositoryManager; @NotNull private final Set myStashedRoots = ContainerUtil.newHashSet(); // save stashed roots to unstash only them @@ -76,7 +78,7 @@ public class GitStashChangesSaver extends GitChangesSaver { } else { GitCommandResult result = myGit.stashSave(repository, myStashMessage); - if (result.success() && !result.getErrorOutputAsJoinedString().contains("No local changes to save")) { + if (result.success() && somethingWasStashed(result)) { myStashedRoots.add(root); } else { @@ -93,6 +95,11 @@ public class GitStashChangesSaver extends GitChangesSaver { } } + private static boolean somethingWasStashed(@NotNull GitCommandResult result) { + return !StringUtil.containsIgnoreCase(result.getErrorOutputAsJoinedString(), NO_LOCAL_CHANGES_TO_SAVE) && + !StringUtil.containsIgnoreCase(result.getOutputAsJoinedString(), NO_LOCAL_CHANGES_TO_SAVE); + } + @Override public void load() { for (VirtualFile root : myStashedRoots) { From 4a4d59e65d2fd0b5172c6bf3a789a2fe19b74cb0 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Mon, 21 Sep 2015 17:28:05 +0300 Subject: [PATCH 074/138] IDEA-145352 VersionControl | Local Changes toolwindow: space symbols are shown as squares --- platform/vcs-api/src/com/intellij/vcsUtil/UIVcsUtil.java | 9 +++++++-- .../vcs/changes/shelf/ShelvedChangesViewManager.java | 6 +++--- .../vcs/changes/ui/ChangesBrowserChangeListNode.java | 6 +++--- .../openapi/vcs/changes/ui/ChangesBrowserChangeNode.java | 8 ++++---- .../openapi/vcs/changes/ui/ChangesBrowserFileNode.java | 4 ++-- .../vcs/changes/ui/ChangesBrowserFilePathNode.java | 4 ++-- .../vcs/changes/ui/ChangesBrowserLocallyDeletedNode.java | 4 ++-- .../vcs/changes/ui/ChangesBrowserLockedFoldersNode.java | 4 ++-- .../changes/ui/ChangesBrowserLogicallyLockedFile.java | 4 ++-- .../openapi/vcs/changes/ui/ChangesBrowserNode.java | 9 +++++---- 10 files changed, 32 insertions(+), 26 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/vcsUtil/UIVcsUtil.java b/platform/vcs-api/src/com/intellij/vcsUtil/UIVcsUtil.java index 6ab106673a8f..bb36b35e7f82 100644 --- a/platform/vcs-api/src/com/intellij/vcsUtil/UIVcsUtil.java +++ b/platform/vcs-api/src/com/intellij/vcsUtil/UIVcsUtil.java @@ -17,18 +17,23 @@ package com.intellij.vcsUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.SimpleTextAttributes; +import com.intellij.util.FontUtil; import com.intellij.util.ui.UIUtil; import com.intellij.xml.util.XmlStringUtil; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; public class UIVcsUtil { - public static final String SPACE_AND_THIN_SPACE = " \u2009"; - private UIVcsUtil() { } + @NotNull + public static String spaceAndThinSpace() { + return " " + FontUtil.canDisplay(UIUtil.getLabelFont(), '\u2009', ""); + } + public static JPanel errorPanel(final String text, boolean isError) { final JLabel label = new JLabel(XmlStringUtil.wrapInHtml(escapeXmlAndAddBr(text))); label.setForeground(isError ? SimpleTextAttributes.ERROR_ATTRIBUTES.getFgColor() : UIUtil.getInactiveTextColor()); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java index e74542784c15..59f725885afa 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java @@ -80,7 +80,7 @@ import java.io.IOException; import java.util.*; import java.util.List; -import static com.intellij.vcsUtil.UIVcsUtil.SPACE_AND_THIN_SPACE; +import static com.intellij.vcsUtil.UIVcsUtil.spaceAndThinSpace; public class ShelvedChangesViewManager implements ProjectComponent { private final ChangesViewContentManager myContentManager; @@ -464,7 +464,7 @@ public class ShelvedChangesViewManager implements ProjectComponent { myIssueLinkRenderer.appendTextWithLinks(changeListData.DESCRIPTION); } int count = node.getChildCount(); - String numFilesText = SPACE_AND_THIN_SPACE + count + " " + StringUtil.pluralize("file", 1) + ","; + String numFilesText = spaceAndThinSpace() + count + " " + StringUtil.pluralize("file", 1) + ","; append(numFilesText, SimpleTextAttributes.GRAYED_ATTRIBUTES); String date = DateFormatUtil.formatPrettyDateTime(changeListData.DATE); @@ -504,7 +504,7 @@ public class ShelvedChangesViewManager implements ProjectComponent { if (movedMessage != null) { append(movedMessage, SimpleTextAttributes.REGULAR_ATTRIBUTES); } - append(SPACE_AND_THIN_SPACE + directory, SimpleTextAttributes.GRAYED_ATTRIBUTES); + append(spaceAndThinSpace() + directory, SimpleTextAttributes.GRAYED_ATTRIBUTES); setIcon(FileTypeManager.getInstance().getFileTypeByFileName(fileName).getIcon()); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeListNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeListNode.java index 2daec8f2fc72..c13227df13a1 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeListNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeListNode.java @@ -26,7 +26,7 @@ import com.intellij.ui.SimpleTextAttributes; import java.util.ArrayList; import java.util.List; -import static com.intellij.vcsUtil.UIVcsUtil.SPACE_AND_THIN_SPACE; +import static com.intellij.vcsUtil.UIVcsUtil.spaceAndThinSpace; /** * @author yole @@ -55,12 +55,12 @@ public class ChangesBrowserChangeListNode extends ChangesBrowserNode } final String freezed = myClManager.isFreezed(); if (freezed != null) { - renderer.append(SPACE_AND_THIN_SPACE + freezed, SimpleTextAttributes.GRAYED_ATTRIBUTES); + renderer.append(spaceAndThinSpace() + freezed, SimpleTextAttributes.GRAYED_ATTRIBUTES); } else if (myClManager.isInUpdate()) { renderer.append(", " + VcsBundle.message("changes.nodetitle.updating"), SimpleTextAttributes.GRAYED_ATTRIBUTES); } if (! myChangeListRemoteState.getState()) { - renderer.append(SPACE_AND_THIN_SPACE); + renderer.append(spaceAndThinSpace()); renderer.append(VcsBundle.message("changes.nodetitle.have.outdated.files"), SimpleTextAttributes.ERROR_ATTRIBUTES); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeNode.java index bea00b0470cd..7a50151ad687 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeNode.java @@ -32,7 +32,7 @@ import javax.swing.*; import java.awt.*; import java.io.File; -import static com.intellij.vcsUtil.UIVcsUtil.SPACE_AND_THIN_SPACE; +import static com.intellij.vcsUtil.UIVcsUtil.spaceAndThinSpace; /** * @author yole @@ -71,13 +71,13 @@ public class ChangesBrowserChangeNode extends ChangesBrowserNode impleme final String originText = change.getOriginText(myProject); if (originText != null) { - renderer.append(SPACE_AND_THIN_SPACE + originText, SimpleTextAttributes.REGULAR_ATTRIBUTES); + renderer.append(spaceAndThinSpace() + originText, SimpleTextAttributes.REGULAR_ATTRIBUTES); } if (renderer.isShowFlatten()) { final File parentFile = filePath.getIOFile().getParentFile(); if (parentFile != null) { - renderer.append(SPACE_AND_THIN_SPACE + FileUtil.getLocationRelativeToUserHome(parentFile.getPath()), SimpleTextAttributes.GRAYED_ATTRIBUTES); + renderer.append(spaceAndThinSpace() + FileUtil.getLocationRelativeToUserHome(parentFile.getPath()), SimpleTextAttributes.GRAYED_ATTRIBUTES); } appendSwitched(renderer); } @@ -111,7 +111,7 @@ public class ChangesBrowserChangeNode extends ChangesBrowserNode impleme if (virtualFile != null && ! myProject.isDefault()) { String branch = ChangeListManager.getInstance(myProject).getSwitchedBranch(virtualFile); if (branch != null) { - renderer.append(SPACE_AND_THIN_SPACE + "[switched to " + branch + "]", SimpleTextAttributes.REGULAR_ATTRIBUTES); + renderer.append(spaceAndThinSpace() + "[switched to " + branch + "]", SimpleTextAttributes.REGULAR_ATTRIBUTES); } } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserFileNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserFileNode.java index eb7ef8cb77e2..f5a584e75c2a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserFileNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserFileNode.java @@ -27,7 +27,7 @@ import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.PlatformIcons; import org.jetbrains.annotations.NotNull; -import static com.intellij.vcsUtil.UIVcsUtil.SPACE_AND_THIN_SPACE; +import static com.intellij.vcsUtil.UIVcsUtil.spaceAndThinSpace; /** * @author yole @@ -62,7 +62,7 @@ public class ChangesBrowserFileNode extends ChangesBrowserNode impl if (renderer.isShowFlatten() && file.isValid()) { final VirtualFile parentFile = file.getParent(); assert parentFile != null; - renderer.append(SPACE_AND_THIN_SPACE + FileUtil.getLocationRelativeToUserHome(parentFile.getPresentableUrl()), SimpleTextAttributes.GRAYED_ATTRIBUTES); + renderer.append(spaceAndThinSpace() + FileUtil.getLocationRelativeToUserHome(parentFile.getPresentableUrl()), SimpleTextAttributes.GRAYED_ATTRIBUTES); } else if (getCount() != 1 || getDirectoryCount() != 0) { appendCount(renderer); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserFilePathNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserFilePathNode.java index d582f039e134..f53f94f24537 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserFilePathNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserFilePathNode.java @@ -25,7 +25,7 @@ import com.intellij.util.PlatformIcons; import java.io.File; -import static com.intellij.vcsUtil.UIVcsUtil.SPACE_AND_THIN_SPACE; +import static com.intellij.vcsUtil.UIVcsUtil.spaceAndThinSpace; /** * @author yole @@ -58,7 +58,7 @@ public class ChangesBrowserFilePathNode extends ChangesBrowserNode { if (renderer.isShowFlatten()) { renderer.append(path.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); FilePath parentPath = path.getParentPath(); - renderer.append(SPACE_AND_THIN_SPACE + FileUtil.getLocationRelativeToUserHome(parentPath.getPresentableUrl()), SimpleTextAttributes.GRAYED_ATTRIBUTES); + renderer.append(spaceAndThinSpace() + FileUtil.getLocationRelativeToUserHome(parentPath.getPresentableUrl()), SimpleTextAttributes.GRAYED_ATTRIBUTES); } else { renderer.append(getRelativePath(safeCastToFilePath(((ChangesBrowserNode)getParent()).getUserObject()), path), diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserLocallyDeletedNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserLocallyDeletedNode.java index 5d72c0a8da78..8113558678f0 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserLocallyDeletedNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserLocallyDeletedNode.java @@ -28,7 +28,7 @@ import javax.swing.*; import java.awt.*; import java.io.File; -import static com.intellij.vcsUtil.UIVcsUtil.SPACE_AND_THIN_SPACE; +import static com.intellij.vcsUtil.UIVcsUtil.spaceAndThinSpace; public class ChangesBrowserLocallyDeletedNode extends ChangesBrowserNode implements TreeLinkMouseListener.HaveTooltip { public ChangesBrowserLocallyDeletedNode(LocallyDeletedChange userObject) { @@ -66,7 +66,7 @@ public class ChangesBrowserLocallyDeletedNode extends ChangesBrowserNode impleme if (renderer.isShowFlatten()) { final File parentFile = filePath.getIOFile().getParentFile(); if (parentFile != null) { - renderer.append(SPACE_AND_THIN_SPACE + parentFile.getPath(), SimpleTextAttributes.GRAYED_ATTRIBUTES); + renderer.append(spaceAndThinSpace() + parentFile.getPath(), SimpleTextAttributes.GRAYED_ATTRIBUTES); } } else if (getCount() != 1 || getDirectoryCount() != 0) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserLockedFoldersNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserLockedFoldersNode.java index d0592e8d377b..9ff2969b0b43 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserLockedFoldersNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserLockedFoldersNode.java @@ -31,7 +31,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import static com.intellij.vcsUtil.UIVcsUtil.SPACE_AND_THIN_SPACE; +import static com.intellij.vcsUtil.UIVcsUtil.spaceAndThinSpace; public class ChangesBrowserLockedFoldersNode extends ChangesBrowserNode implements TreeLinkMouseListener.HaveTooltip { private final Project myProject; @@ -55,7 +55,7 @@ public class ChangesBrowserLockedFoldersNode extends ChangesBrowserNode implemen public void render(final ChangesBrowserNodeRenderer renderer, final boolean selected, final boolean expanded, final boolean hasFocus) { renderer.append(userObject.toString(), SimpleTextAttributes.REGULAR_ATTRIBUTES); renderer.append(getCountText(), SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES); - renderer.append(SPACE_AND_THIN_SPACE, SimpleTextAttributes.REGULAR_ATTRIBUTES); + renderer.append(spaceAndThinSpace(), SimpleTextAttributes.REGULAR_ATTRIBUTES); final CleanupStarter starter = new CleanupStarter(myProject, this); renderer.append("do cleanup...", new SimpleTextAttributes(SimpleTextAttributes.STYLE_UNDERLINE, JBColor.RED), starter); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserLogicallyLockedFile.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserLogicallyLockedFile.java index 7458203e4858..669f35303253 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserLogicallyLockedFile.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserLogicallyLockedFile.java @@ -20,7 +20,7 @@ import com.intellij.openapi.vcs.changes.LogicalLock; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.SimpleTextAttributes; -import static com.intellij.vcsUtil.UIVcsUtil.SPACE_AND_THIN_SPACE; +import static com.intellij.vcsUtil.UIVcsUtil.spaceAndThinSpace; public class ChangesBrowserLogicallyLockedFile extends ChangesBrowserFileNode { private final LogicalLock myLogicalLock; @@ -33,7 +33,7 @@ public class ChangesBrowserLogicallyLockedFile extends ChangesBrowserFileNode { @Override public void render(ChangesBrowserNodeRenderer renderer, boolean selected, boolean expanded, boolean hasFocus) { super.render(renderer, selected, expanded, hasFocus); - renderer.append(SPACE_AND_THIN_SPACE + "locked by ", SimpleTextAttributes.REGULAR_ATTRIBUTES); + renderer.append(spaceAndThinSpace() + "locked by ", SimpleTextAttributes.REGULAR_ATTRIBUTES); renderer.append(myLogicalLock.getOwner(), SimpleTextAttributes.REGULAR_ATTRIBUTES); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserNode.java index c3f8c5662adf..c004a5f2308a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserNode.java @@ -24,7 +24,6 @@ import com.intellij.openapi.vcs.changes.LocallyDeletedChange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; -import com.intellij.vcsUtil.UIVcsUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -34,6 +33,8 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.List; +import static com.intellij.vcsUtil.UIVcsUtil.spaceAndThinSpace; + /** * @author max */ @@ -213,13 +214,13 @@ public class ChangesBrowserNode extends DefaultMutableTreeNode { int count = getCount(); int dirCount = getDirectoryCount(); if (dirCount == 0) { - return UIVcsUtil.SPACE_AND_THIN_SPACE + VcsBundle.message("changes.nodetitle.changecount", count); + return spaceAndThinSpace() + VcsBundle.message("changes.nodetitle.changecount", count); } else if (count == 0 && dirCount > 0) { - return UIVcsUtil.SPACE_AND_THIN_SPACE + VcsBundle.message("changes.nodetitle.directory.changecount", dirCount); + return spaceAndThinSpace() + VcsBundle.message("changes.nodetitle.directory.changecount", dirCount); } else { - return UIVcsUtil.SPACE_AND_THIN_SPACE + VcsBundle.message("changes.nodetitle.directory.file.changecount", dirCount, count); + return spaceAndThinSpace() + VcsBundle.message("changes.nodetitle.directory.file.changecount", dirCount, count); } } From df73aa2f43e707237429563a8fef4c5688a05f27 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 7 Sep 2015 11:49:14 +0200 Subject: [PATCH 075/138] NPE if no components (unreal case) --- platform/configuration-store-impl/src/ComponentStoreImpl.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/configuration-store-impl/src/ComponentStoreImpl.kt b/platform/configuration-store-impl/src/ComponentStoreImpl.kt index 39a54ea75114..16ec1c2e56d6 100644 --- a/platform/configuration-store-impl/src/ComponentStoreImpl.kt +++ b/platform/configuration-store-impl/src/ComponentStoreImpl.kt @@ -129,7 +129,9 @@ abstract class ComponentStoreImpl : IComponentStore { } } - errors = doSave(externalizationSession!!.createSaveSessions(), readonlyFiles, errors) + if (externalizationSession != null) { + errors = doSave(externalizationSession.createSaveSessions(), readonlyFiles, errors) + } CompoundRuntimeException.doThrow(errors) } From 3e11cba55fdd5e1f3d89657d6adc8928a74534cc Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 7 Sep 2015 13:20:57 +0200 Subject: [PATCH 076/138] simplify --- .../util/descriptors/impl/ConfigFileContainerImpl.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java index a236694c6c4f..e16a28933aca 100644 --- a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java +++ b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import com.intellij.openapi.util.MultiValuesMap; import com.intellij.openapi.util.SimpleModificationTracker; import com.intellij.openapi.vfs.*; import com.intellij.util.EventDispatcher; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.descriptors.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -77,11 +78,7 @@ public class ConfigFileContainerImpl extends SimpleModificationTracker implement @Override @Nullable public ConfigFile getConfigFile(ConfigFileMetaData metaData) { - final Collection descriptors = myConfigFiles.get(metaData); - if (descriptors == null || descriptors.isEmpty()) { - return null; - } - return descriptors.iterator().next(); + return ContainerUtil.getFirstItem(myConfigFiles.get(metaData)); } @Override From b3d605437d039da95b6538c507f3748d688cd954 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 7 Sep 2015 14:34:59 +0200 Subject: [PATCH 077/138] avoid empty set creation --- .../impl/ConfigFileContainerImpl.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java index e16a28933aca..fa799ed3dbf8 100644 --- a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java +++ b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java @@ -25,13 +25,11 @@ import com.intellij.openapi.vfs.*; import com.intellij.util.EventDispatcher; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.descriptors.*; +import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * @author nik @@ -129,9 +127,9 @@ public class ConfigFileContainerImpl extends SimpleModificationTracker implement return myMetaDataProvider; } - public void updateDescriptors(final MultiValuesMap descriptorsMap) { - Set toDelete = new HashSet(myConfigFiles.values()); - Set added = new HashSet(); + public void updateDescriptors(@NotNull MultiValuesMap descriptorsMap) { + Set toDelete = myConfigFiles.isEmpty() ? Collections.emptySet() : new HashSet(myConfigFiles.values()); + Set added = null; for (Map.Entry> entry : descriptorsMap.entrySet()) { ConfigFileMetaData metaData = entry.getKey(); @@ -139,8 +137,7 @@ public class ConfigFileContainerImpl extends SimpleModificationTracker implement final Collection oldDescriptors = myConfigFiles.get(metaData); if (oldDescriptors != null) { for (ConfigFile descriptor : oldDescriptors) { - if (newDescriptors.contains(descriptor.getInfo())) { - newDescriptors.remove(descriptor.getInfo()); + if (newDescriptors.remove(descriptor.getInfo())) { toDelete.remove(descriptor); } } @@ -149,6 +146,9 @@ public class ConfigFileContainerImpl extends SimpleModificationTracker implement final ConfigFileImpl configFile = new ConfigFileImpl(this, configuration); Disposer.register(this, configFile); myConfigFiles.put(metaData, configFile); + if (added == null) { + added = new THashSet(); + } added.add(configFile); } } @@ -159,9 +159,11 @@ public class ConfigFileContainerImpl extends SimpleModificationTracker implement } myCachedConfigFiles = null; - for (ConfigFile configFile : added) { - incModificationCount(); - myDispatcher.getMulticaster().configFileAdded(configFile); + if (added != null) { + for (ConfigFile configFile : added) { + incModificationCount(); + myDispatcher.getMulticaster().configFileAdded(configFile); + } } for (ConfigFile configFile : toDelete) { incModificationCount(); From 836b01a05c77775bc84c591e9e85183949ca65a2 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 7 Sep 2015 15:51:57 +0200 Subject: [PATCH 078/138] as test sources because it is test framework in any case we cannot put own module tests in this module because in this case all dependent modules will inherit it --- java/testFramework/testFramework-java.iml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/testFramework/testFramework-java.iml b/java/testFramework/testFramework-java.iml index 2ffc1004c739..06a46c65abad 100644 --- a/java/testFramework/testFramework-java.iml +++ b/java/testFramework/testFramework-java.iml @@ -3,7 +3,7 @@ - + From 7f2134149abb5632920769af75f90f0315651f7d Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 7 Sep 2015 15:52:50 +0200 Subject: [PATCH 079/138] assertJ in devkit tests --- .idea/modules.xml | 1 + plugins/devkit/devkit-tests.iml | 22 ++++++++++++++++++++++ plugins/devkit/devkit.iml | 4 +--- 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 plugins/devkit/devkit-tests.iml diff --git a/.idea/modules.xml b/.idea/modules.xml index 5a29a2a547ff..7d37961600ad 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -64,6 +64,7 @@ + diff --git a/plugins/devkit/devkit-tests.iml b/plugins/devkit/devkit-tests.iml new file mode 100644 index 000000000000..9387a1d87b6d --- /dev/null +++ b/plugins/devkit/devkit-tests.iml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/devkit/devkit.iml b/plugins/devkit/devkit.iml index 62aa16567062..385c3b6b6f82 100644 --- a/plugins/devkit/devkit.iml +++ b/plugins/devkit/devkit.iml @@ -4,7 +4,6 @@ - @@ -47,5 +46,4 @@ - - + \ No newline at end of file From c99c7f3eec4beb96954d3b9b60046b201191e302 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 7 Sep 2015 17:26:38 +0200 Subject: [PATCH 080/138] cleanup --- .../testSrc/com/intellij/roots/RootsChangedTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java b/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java index cddb960084d4..9abd3dafb8c6 100644 --- a/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java @@ -131,6 +131,11 @@ public class RootsChangedTest extends ModuleTestCase { PathManagerEx.findFileUnderProjectHome("java/java-tests/testData/moduleRootManager/rootsChanged/emptyModule/a.iml", RootsChangedTest.this.getClass()); Module a = loadModule(moduleFile, true); assertEventsCount(1); + ApplicationManager.getApplication().runWriteAction(() -> { + File moduleFile = + PathManagerEx.findFileUnderProjectHome("java/java-tests/testData/moduleRootManager/rootsChanged/emptyModule/a.iml", this.getClass()); + Module a = loadModule(moduleFile, true); + assertEventsCount(1); final Sdk jdk = IdeaTestUtil.getMockJdk17(); ProjectJdkTable.getInstance().addJdk(jdk); From 99f843bcb9baf8bbffa94ffb904d6c15ef5b0a87 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 7 Sep 2015 17:26:59 +0200 Subject: [PATCH 081/138] cleanup --- platform/configuration-store-impl/testSrc/StoreTestSuite.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/configuration-store-impl/testSrc/StoreTestSuite.kt b/platform/configuration-store-impl/testSrc/StoreTestSuite.kt index 07759bbd03fb..e9cfdcae4c69 100644 --- a/platform/configuration-store-impl/testSrc/StoreTestSuite.kt +++ b/platform/configuration-store-impl/testSrc/StoreTestSuite.kt @@ -19,8 +19,8 @@ import org.junit.runner.RunWith import org.junit.runners.Suite // All in package is very slow, so, we have to use Suite to speedup -RunWith(Suite::class) -Suite.SuiteClasses( +@RunWith(Suite::class) +@Suite.SuiteClasses( ApplicationStoreTest::class, ProjectStoreTest::class, DefaultProjectStoreTest::class, ModuleStoreTest::class, ModuleStoreRenameTest::class, From a9ab1455e756bfbbd75d1fcc191beecec3bae5ae Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 7 Sep 2015 17:27:26 +0200 Subject: [PATCH 082/138] notnull --- plugins/devkit/src/build/PluginBuildConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/devkit/src/build/PluginBuildConfiguration.java b/plugins/devkit/src/build/PluginBuildConfiguration.java index 5adffafc5d41..a7f27c92b923 100644 --- a/plugins/devkit/src/build/PluginBuildConfiguration.java +++ b/plugins/devkit/src/build/PluginBuildConfiguration.java @@ -68,7 +68,7 @@ public class PluginBuildConfiguration implements PersistentStateComponent Date: Tue, 8 Sep 2015 13:25:48 +0200 Subject: [PATCH 083/138] cleanup --- plugins/devkit/src/projectRoots/Sandbox.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/plugins/devkit/src/projectRoots/Sandbox.java b/plugins/devkit/src/projectRoots/Sandbox.java index f148c82e7fd6..d8232ced4070 100644 --- a/plugins/devkit/src/projectRoots/Sandbox.java +++ b/plugins/devkit/src/projectRoots/Sandbox.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,14 @@ package org.jetbrains.idea.devkit.projectRoots; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.projectRoots.*; +import com.intellij.openapi.projectRoots.ProjectJdkTable; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.SdkModel; +import com.intellij.openapi.projectRoots.ValidatableSdkAdditionalData; import com.intellij.openapi.util.DefaultJDOMExternalizer; import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.JDOMExternalizable; import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -32,7 +35,7 @@ import org.jetbrains.idea.devkit.DevKitBundle; * User: anna * Date: Nov 22, 2004 */ -public class Sandbox implements ValidatableSdkAdditionalData, JDOMExternalizable{ +public class Sandbox implements ValidatableSdkAdditionalData { private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.devkit.projectRoots.Sandbox"); @SuppressWarnings({"WeakerAccess"}) @@ -68,7 +71,7 @@ public class Sandbox implements ValidatableSdkAdditionalData, JDOMExternalizable } public void checkValid(SdkModel sdkModel) throws ConfigurationException { - if (mySandboxHome == null || mySandboxHome.length() == 0 || getJavaSdk() == null){ + if (StringUtil.isEmpty(mySandboxHome) || getJavaSdk() == null) { throw new ConfigurationException(DevKitBundle.message("sandbox.specification")); } } From 81c4a5c5817d696d2b61532aa43fe5520828207e Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 8 Sep 2015 13:26:28 +0200 Subject: [PATCH 084/138] cleanup --- platform/configuration-store-impl/testSrc/ModuleStoreTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt b/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt index 4a6e417e69e7..6ef7d9026071 100644 --- a/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt @@ -47,7 +47,7 @@ class ModuleStoreTest { private val tempDirManager = TemporaryDirectory() private val ruleChain = RuleChain(tempDirManager, EdtRule(), ActiveStoreRule(projectRule), DisposeModulesRule(projectRule)) - public Rule fun getChain(): RuleChain = ruleChain + @Rule fun getChain() = ruleChain @Test fun `set option`() { val moduleFile = runWriteAction { From 7922186f29ef2226cebd9c18c1a1530dc36f7906 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 8 Sep 2015 13:31:48 +0200 Subject: [PATCH 085/138] cleanup, use EdtTestUtil.runInEdtAndWait --- .../compiler/BaseCompilerTestCase.java | 17 ++--- .../intellij/compiler/CompilerTestUtil.java | 63 +++++++++++-------- .../test/ExternalSystemTestCase.java | 19 ++---- .../com/intellij/testFramework/EdtTestUtil.kt | 4 ++ .../testFramework/UsefulTestCase.java | 23 +------ .../repo/GitRepositoryReaderTest.java | 30 ++++++--- 6 files changed, 83 insertions(+), 73 deletions(-) diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java index 0351ca66c6ab..bc63355134a6 100644 --- a/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java +++ b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java @@ -90,15 +90,18 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { @Override protected void tearDown() throws Exception { - for (Artifact artifact : getArtifactManager().getArtifacts()) { - final String outputPath = artifact.getOutputPath(); - if (!StringUtil.isEmpty(outputPath)) { - FileUtil.delete(new File(FileUtil.toSystemDependentName(outputPath))); + try { + for (Artifact artifact : getArtifactManager().getArtifacts()) { + final String outputPath = artifact.getOutputPath(); + if (!StringUtil.isEmpty(outputPath)) { + FileUtil.delete(new File(FileUtil.toSystemDependentName(outputPath))); + } } + CompilerTestUtil.disableExternalCompiler(getProject()); + } + finally { + super.tearDown(); } - CompilerTestUtil.disableExternalCompiler(getProject()); - - super.tearDown(); } protected ArtifactManager getArtifactManager() { diff --git a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java index 60c06b99de2c..5b4f69d6a4ab 100644 --- a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java +++ b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java @@ -16,8 +16,8 @@ package com.intellij.compiler; import com.intellij.compiler.server.BuildManager; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.application.ex.ApplicationManagerEx; @@ -31,9 +31,11 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ModuleRootModificationUtil; +import com.intellij.testFramework.EdtTestUtil; +import com.intellij.util.SmartList; +import com.intellij.util.ThrowableRunnable; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; import java.util.List; /** @@ -55,22 +57,22 @@ public class CompilerTestUtil { } public static void saveApplicationSettings() { - ApplicationManager.getApplication().invokeAndWait(new Runnable() { + EdtTestUtil.runInEdtAndWait(new Runnable() { @Override public void run() { doSaveComponent(ProjectJdkTable.getInstance()); doSaveComponent(FileTypeManager.getInstance()); } - }, ModalityState.any()); + }); } public static void saveApplicationComponent(final Object appComponent) { - ApplicationManager.getApplication().invokeAndWait(new Runnable() { + EdtTestUtil.runInEdtAndWait(new Runnable() { @Override public void run() { doSaveComponent(appComponent); } - }, ModalityState.any()); + }); } private static void doSaveComponent(Object appComponent) { @@ -89,27 +91,36 @@ public class CompilerTestUtil { }.execute(); } - public static void disableExternalCompiler(final Project project) { - ApplicationManagerEx.getApplicationEx().doNotSave(true); - final JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx(); - new WriteAction() { - @Override - protected void run(@NotNull final Result result) { - Module[] modules = ModuleManager.getInstance(project).getModules(); - Sdk internalJdk = table.getInternalJdk(); - List modulesToRestore = new ArrayList(); - for (Module module : modules) { - Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); - if (sdk != null && sdk.equals(internalJdk)) { - modulesToRestore.add(module); + public static void disableExternalCompiler(@NotNull final Project project) { + try { + EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { + @Override + public void run() throws Throwable { + JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx(); + AccessToken token = WriteAction.start(); + try { + Sdk internalJdk = table.getInternalJdk(); + List modulesToRestore = new SmartList(); + for (Module module : ModuleManager.getInstance(project).getModules()) { + Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); + if (sdk != null && sdk.equals(internalJdk)) { + modulesToRestore.add(module); + } + } + table.removeJdk(internalJdk); + for (Module module : modulesToRestore) { + ModuleRootModificationUtil.setModuleSdk(module, internalJdk); + } + BuildManager.getInstance().clearState(project); + } + finally { + token.finish(); } } - table.removeJdk(internalJdk); - for (Module module : modulesToRestore) { - ModuleRootModificationUtil.setModuleSdk(module, internalJdk); - } - BuildManager.getInstance().clearState(project); - } - }.execute(); + }); + } + finally { + ApplicationManagerEx.getApplicationEx().doNotSave(true); + } } } diff --git a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java index a49845557889..8f7b66b9fec7 100644 --- a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java +++ b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java @@ -44,13 +44,11 @@ import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess; import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.impl.compiler.ArtifactCompileScope; -import com.intellij.testFramework.CompilerTester; -import com.intellij.testFramework.IdeaTestUtil; -import com.intellij.testFramework.PsiTestUtil; -import com.intellij.testFramework.UsefulTestCase; +import com.intellij.testFramework.*; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; import com.intellij.util.ArrayUtil; +import com.intellij.util.ThrowableRunnable; import com.intellij.util.io.TestFileSystemItem; import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; @@ -176,16 +174,11 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase { @Override public void tearDown() throws Exception { try { - edt(new Runnable() { + EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { @Override - public void run() { - try { - CompilerTestUtil.disableExternalCompiler(myProject); - tearDownFixtures(); - } - catch (Exception e) { - throw new RuntimeException(e); - } + public void run() throws Throwable { + CompilerTestUtil.disableExternalCompiler(myProject); + tearDownFixtures(); } }); myProject = null; diff --git a/platform/testFramework/src/com/intellij/testFramework/EdtTestUtil.kt b/platform/testFramework/src/com/intellij/testFramework/EdtTestUtil.kt index 82d09e99bb03..70b4c93274dc 100644 --- a/platform/testFramework/src/com/intellij/testFramework/EdtTestUtil.kt +++ b/platform/testFramework/src/com/intellij/testFramework/EdtTestUtil.kt @@ -26,6 +26,10 @@ class EdtTestUtil { runInEdtAndWait({ runnable.run() }) } + public platformStatic fun runInEdtAndWait(runnable: Runnable) { + runInEdtAndWait({ runnable.run() }) + } + // Test only because in production you must use Application.invokeAndWait(Runnable, ModalityState). // The problem is - Application logs errors, but not throws. But in tests must be thrown. // In any case name "runInEdtAndWait" is better than "invokeAndWait". diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java index 97adee22ac48..923c32e39daf 100644 --- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java @@ -349,29 +349,12 @@ public abstract class UsefulTestCase extends TestCase { return PlatformTestUtil.canRunTest(getClass()); } - public static void edt(@NotNull final ThrowableRunnable r) { - try { - UIUtil.invokeAndWaitIfNeeded(r); - } - catch (RuntimeException re) { - throw re; - } - catch (Throwable throwable) { - throw new RuntimeException(throwable); - } - } - - public static void edt(@NotNull final Runnable r) { - edt(new ThrowableRunnable() { - @Override - public void run() throws Throwable { - r.run(); - } - }); + public static void edt(@NotNull Runnable r) { + EdtTestUtil.runInEdtAndWait(r); } protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception { - edt(runnable); + EdtTestUtil.runInEdtAndWait(runnable); } protected void defaultRunBare() throws Throwable { diff --git a/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderTest.java b/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderTest.java index cefbdb7a6192..599bbd9b1001 100644 --- a/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderTest.java +++ b/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ package git4idea.repo; import com.intellij.openapi.application.PluginPathManager; @@ -5,6 +20,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.VcsTestUtil; +import com.intellij.testFramework.EdtTestUtil; import com.intellij.util.Function; import com.intellij.util.ThrowableRunnable; import com.intellij.util.containers.ContainerUtil; @@ -57,7 +73,7 @@ public class GitRepositoryReaderTest extends GitPlatformTest { @Override @Before public void setUp() throws Exception { - edt(new ThrowableRunnable() { + EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { @Override public void run() throws Exception { GitRepositoryReaderTest.super.setUp(); @@ -76,12 +92,12 @@ public class GitRepositoryReaderTest extends GitPlatformTest { } } finally { - edt(new ThrowableRunnable() { - @Override - public void run() throws Throwable { - GitRepositoryReaderTest.super.tearDown(); - } - }); + EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { + @Override + public void run() throws Throwable { + GitRepositoryReaderTest.super.tearDown(); + } + }); } } From c21e54f22422074a9be1878a283cd91eec2fd6fc Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 8 Sep 2015 13:34:17 +0200 Subject: [PATCH 086/138] ability to specify test service implementation --- .../com/intellij/openapi/components/ServiceDescriptor.java | 6 +++++- .../openapi/components/impl/ServiceManagerImpl.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/components/ServiceDescriptor.java b/platform/platform-impl/src/com/intellij/openapi/components/ServiceDescriptor.java index 16105e50d367..86c5669f6bf3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/ServiceDescriptor.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/ServiceDescriptor.java @@ -16,6 +16,7 @@ package com.intellij.openapi.components; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.util.xmlb.annotations.Attribute; public class ServiceDescriptor { @@ -25,6 +26,9 @@ public class ServiceDescriptor { @Attribute("serviceImplementation") public String serviceImplementation; + @Attribute("testServiceImplementation") + public String testServiceImplementation; + @Attribute("overrides") public boolean overrides; @@ -36,6 +40,6 @@ public class ServiceDescriptor { } public String getImplementation() { - return serviceImplementation; + return testServiceImplementation != null && ApplicationManager.getApplication().isUnitTestMode() ? testServiceImplementation : serviceImplementation; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java index 9798cb0a86d7..cd4904a749c2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java @@ -86,7 +86,7 @@ public class ServiceManagerImpl implements BaseComponent { } // empty serviceImplementation means we want to unregister service - if (!StringUtil.isEmpty(descriptor.serviceImplementation)) { + if (!StringUtil.isEmpty(descriptor.getImplementation())) { picoContainer.registerComponent(new MyComponentAdapter(descriptor, pluginDescriptor, (ComponentManagerEx)componentManager)); } } From 3883c210c10e021f12f4eb3281185c9db0c42a62 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 8 Sep 2015 16:34:35 +0200 Subject: [PATCH 087/138] cleanup --- .../testFramework/PlatformTestCase.java | 2 +- .../intellij/testFramework/PsiTestUtil.java | 47 ++++++++++--------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 0b4798d70354..5ae21f15b5b6 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -126,7 +126,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro * If a temp directory is reused from some previous test run, there might be cached children in its VFS. * Ensure they're removed */ - public static void synchronizeTempDirVfs(VirtualFile tempDir) { + public static void synchronizeTempDirVfs(@NotNull VirtualFile tempDir) { tempDir.getChildren(); tempDir.refresh(false, true); } diff --git a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java index afa500ee4c7e..5a69144fe091 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java +++ b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java @@ -15,10 +15,7 @@ */ package com.intellij.testFramework; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.Result; -import com.intellij.openapi.application.RunResult; -import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.application.*; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; @@ -43,6 +40,7 @@ import com.intellij.psi.PsiFileFactory; import com.intellij.psi.impl.DebugUtil; import com.intellij.util.Consumer; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ThrowableRunnable; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -53,6 +51,7 @@ import org.jetbrains.jps.model.module.JpsModuleSourceRootType; import org.junit.Assert; import java.io.File; +import java.io.IOException; import java.util.*; @@ -65,7 +64,7 @@ public class PsiTestUtil { return createTestProjectStructure(project, module, rootPath, filesToDelete, true); } - public static VirtualFile createTestProjectStructure(Project project, Module module, Collection filesToDelete) throws Exception { + public static VirtualFile createTestProjectStructure(Project project, Module module, Collection filesToDelete) throws IOException { return createTestProjectStructure(project, module, null, filesToDelete, true); } @@ -73,7 +72,7 @@ public class PsiTestUtil { Module module, String rootPath, Collection filesToDelete, - boolean addProjectRoots) throws Exception { + boolean addProjectRoots) throws IOException { VirtualFile vDir = createTestProjectStructure(module, rootPath, filesToDelete, addProjectRoots); PsiDocumentManager.getInstance(project).commitAllDocuments(); return vDir; @@ -82,7 +81,7 @@ public class PsiTestUtil { public static VirtualFile createTestProjectStructure(Module module, String rootPath, Collection filesToDelete, - boolean addProjectRoots) throws Exception { + boolean addProjectRoots) throws IOException { return createTestProjectStructure("unitTest", module, rootPath, filesToDelete, addProjectRoots); } @@ -90,33 +89,37 @@ public class PsiTestUtil { final Module module, final String rootPath, final Collection filesToDelete, - final boolean addProjectRoots) throws Exception { + final boolean addProjectRoots) throws IOException { File dir = FileUtil.createTempDirectory(tempName, null, false); filesToDelete.add(dir); final VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByPath(dir.getCanonicalPath().replace(File.separatorChar, '/')); - PlatformTestCase.synchronizeTempDirVfs(vDir); assert vDir != null && vDir.isDirectory() : dir; + PlatformTestCase.synchronizeTempDirVfs(vDir); - Project project = module != null ? module.getProject() : null; - new WriteCommandAction.Simple(project) { + EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { @Override - protected void run() throws Throwable { - if (rootPath != null) { - VirtualFile vDir1 = LocalFileSystem.getInstance().findFileByPath(rootPath.replace(File.separatorChar, '/')); - if (vDir1 == null) { - throw new Exception(rootPath + " not found"); + public void run() throws Throwable { + AccessToken token = WriteAction.start(); + try { + if (rootPath != null) { + VirtualFile vDir1 = LocalFileSystem.getInstance().findFileByPath(rootPath.replace(File.separatorChar, '/')); + if (vDir1 == null) { + throw new Exception(rootPath + " not found"); + } + VfsUtil.copyDirectory(null, vDir1, vDir, null); } - VfsUtil.copyDirectory(null, vDir1, vDir, null); - } - if (addProjectRoots) { - addSourceContentToRoots(module, vDir); + if (addProjectRoots) { + addSourceContentToRoots(module, vDir); + } + } + finally { + token.finish(); } } - }.execute().throwException(); - + }); return vDir; } From c777f3e988370e9952010460844d09d386b1bf6c Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 8 Sep 2015 16:45:15 +0200 Subject: [PATCH 088/138] =?UTF-8?q?fix=20PluginModuleCompilationTest=20?= =?UTF-8?q?=E2=80=94=20get=20rid=20of=20explict=20isOptimiseTestLoadSpeed?= =?UTF-8?q?=20flag=20manipulation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit don't load app components state — Compiler tests doesn't remove configs on tear down and, so, old jdk table is loaded --- .../com/intellij/roots/RootsChangedTest.java | 9 +- .../testFramework/ModuleTestCase.java | 106 ++++++++---------- .../src/ApplicationStoreImpl.kt | 3 + .../src/ComponentStoreImpl.kt | 74 ++++++------ .../src/DefaultProjectStoreImpl.kt | 3 + .../src/ModuleStoreImpl.kt | 22 +++- .../src/ProjectStoreImpl.kt | 19 +++- .../testSrc/DefaultProjectStoreTest.kt | 23 ++-- .../testSrc/ProjectStoreTest.kt | 34 +++--- .../components/impl/stores/IProjectStore.java | 4 + .../openapi/project/ex/ProjectEx.java | 4 - .../openapi/project/impl/DefaultProject.java | 4 +- .../openapi/project/impl/ProjectImpl.java | 13 --- .../project/impl/ProjectManagerImpl.java | 24 ++-- .../src/META-INF/LangExtensions.xml | 3 + .../src/com/intellij/mock/MockProjectEx.java | 10 -- .../com/intellij/testFramework/FixtureRule.kt | 39 ++++--- 17 files changed, 202 insertions(+), 192 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java b/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java index 9abd3dafb8c6..9cf5c67a3b05 100644 --- a/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java @@ -127,14 +127,7 @@ public class RootsChangedTest extends ModuleTestCase { public void testEditLibraryForModuleLoadFromXml() throws IOException { final File tempDirectory = createTempDirectory(); ApplicationManager.getApplication().runWriteAction(() -> { - File moduleFile = - PathManagerEx.findFileUnderProjectHome("java/java-tests/testData/moduleRootManager/rootsChanged/emptyModule/a.iml", RootsChangedTest.this.getClass()); - Module a = loadModule(moduleFile, true); - assertEventsCount(1); - ApplicationManager.getApplication().runWriteAction(() -> { - File moduleFile = - PathManagerEx.findFileUnderProjectHome("java/java-tests/testData/moduleRootManager/rootsChanged/emptyModule/a.iml", this.getClass()); - Module a = loadModule(moduleFile, true); + Module a = loadModule(PathManagerEx.getHomePath(getClass()) + "/java/java-tests/testData/moduleRootManager/rootsChanged/emptyModule/a.iml"); assertEventsCount(1); final Sdk jdk = IdeaTestUtil.getMockJdk17(); diff --git a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java index 2d6859cb83e6..589b04c0aa79 100644 --- a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java +++ b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java @@ -16,17 +16,15 @@ package com.intellij.testFramework; import com.intellij.ide.highlighter.ModuleFileType; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.components.ComponentsPackage; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.module.StdModuleTypes; import com.intellij.openapi.module.impl.ModuleImpl; -import com.intellij.openapi.project.ex.ProjectEx; -import com.intellij.openapi.project.impl.ProjectImpl; -import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.FileUtil; @@ -34,6 +32,9 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileVisitor; +import com.intellij.util.Consumer; +import com.intellij.util.SmartList; +import com.intellij.util.lang.CompoundRuntimeException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,7 +42,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; +import java.util.List; public abstract class ModuleTestCase extends IdeaTestCase { protected final Collection myModulesToDispose = new ArrayList(); @@ -55,18 +56,30 @@ public abstract class ModuleTestCase extends IdeaTestCase { @Override protected void tearDown() throws Exception { try { - final ModuleManager moduleManager = ModuleManager.getInstance(myProject); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - for (Module module : myModulesToDispose) { + ModuleManager moduleManager = ModuleManager.getInstance(myProject); + List errors = null; + AccessToken token = WriteAction.start(); + try { + for (Module module : myModulesToDispose) { + try { String moduleName = module.getName(); if (moduleManager.findModuleByName(moduleName) != null) { moduleManager.disposeModule(module); } } + catch (Throwable e) { + if (errors == null) { + errors = new SmartList(); + } + errors.add(e); + } } - }); + } + finally { + token.finish(); + } + + CompoundRuntimeException.doThrow(errors); } finally { myModulesToDispose.clear(); @@ -97,53 +110,45 @@ public abstract class ModuleTestCase extends IdeaTestCase { return module; } - protected Module loadModule(final File moduleFile) { - return loadModule(moduleFile, false); - } + protected Module loadModule(@NotNull String modulePath) { + String normalizedPath = FileUtil.toSystemIndependentName(modulePath); + LocalFileSystem.getInstance().refreshAndFindFileByPath(normalizedPath); - protected Module loadModule(final File moduleFile, final boolean loadComponentStates) { - Module module = ApplicationManager.getApplication().runWriteAction( - new Computable() { - @Override - public Module compute() { - ProjectImpl project = (ProjectImpl)myProject; - boolean oldOptimiseTestLoadSpeed = project.isOptimiseTestLoadSpeed(); - if (loadComponentStates) { - project.setOptimiseTestLoadSpeed(false); - } - try { - LocalFileSystem.getInstance().refreshIoFiles(Collections.singletonList(moduleFile)); - return ModuleManager.getInstance(myProject).loadModule(moduleFile.getAbsolutePath()); - } - catch (Exception e) { - LOG.error(e); - return null; - } - finally { - project.setOptimiseTestLoadSpeed(oldOptimiseTestLoadSpeed); - } - } - } - ); + ModuleManager moduleManager = ModuleManager.getInstance(myProject); + Module module; + AccessToken token = WriteAction.start(); + try { + module = moduleManager.loadModule(normalizedPath); + } + catch (Exception e) { + LOG.error(e); + return null; + } + finally { + token.finish(); + } myModulesToDispose.add(module); return module; } - protected Module loadModule(final String modulePath) { - return loadModule(new File(modulePath)); + @Nullable + protected Module loadAllModulesUnder(@NotNull VirtualFile rootDir) { + return loadAllModulesUnder(rootDir, null); } @Nullable - protected Module loadAllModulesUnder(@NotNull VirtualFile rootDir) throws Exception { + protected Module loadAllModulesUnder(@NotNull VirtualFile rootDir, @Nullable final Consumer moduleConsumer) { final Ref result = Ref.create(); VfsUtilCore.visitChildrenRecursively(rootDir, new VirtualFileVisitor() { @Override public boolean visitFile(@NotNull VirtualFile file) { if (!file.isDirectory() && file.getName().endsWith(ModuleFileType.DOT_DEFAULT_EXTENSION)) { - ModuleImpl module = (ModuleImpl)loadModule(new File(file.getPath())); - readJdomExternalizables(module); + ModuleImpl module = (ModuleImpl)loadModule(file.getPath()); + if (moduleConsumer != null) { + moduleConsumer.consume(module); + } result.setIfNull(module); } return true; @@ -153,21 +158,6 @@ public abstract class ModuleTestCase extends IdeaTestCase { return result.get(); } - protected void readJdomExternalizables(@NotNull Module module) { - loadModuleComponentState(module, ModuleRootManager.getInstance(module)); - } - - protected final void loadModuleComponentState(@NotNull Module module, @NotNull Object component) { - ProjectEx project = (ProjectEx)myProject; - project.setOptimiseTestLoadSpeed(false); - try { - ComponentsPackage.getStateStore(module).initComponent(component, false); - } - finally { - project.setOptimiseTestLoadSpeed(true); - } - } - protected Module createModuleFromTestData(final String dirInTestData, final String newModuleFileName, final ModuleType moduleType, final boolean addSourceRoot) throws IOException { diff --git a/platform/configuration-store-impl/src/ApplicationStoreImpl.kt b/platform/configuration-store-impl/src/ApplicationStoreImpl.kt index e36c1e4aba9c..1b3a19d0dda8 100644 --- a/platform/configuration-store-impl/src/ApplicationStoreImpl.kt +++ b/platform/configuration-store-impl/src/ApplicationStoreImpl.kt @@ -37,6 +37,9 @@ class ApplicationPathMacroManager : BasePathMacroManager(null) class ApplicationStoreImpl(private val application: Application, pathMacroManager: PathMacroManager) : ComponentStoreImpl() { override val storageManager = ApplicationStorageManager(application, pathMacroManager) + override val isLoadComponentState: Boolean + get() = !application.isUnitTestMode() + override fun setPath(path: String) { storageManager.addMacro(ROOT_CONFIG, path) storageManager.addMacro(StoragePathMacros.APP_CONFIG, "$path/${ApplicationStorageManager.FILE_STORAGE_DIR}") diff --git a/platform/configuration-store-impl/src/ComponentStoreImpl.kt b/platform/configuration-store-impl/src/ComponentStoreImpl.kt index 16ec1c2e56d6..624e872c29b3 100644 --- a/platform/configuration-store-impl/src/ComponentStoreImpl.kt +++ b/platform/configuration-store-impl/src/ComponentStoreImpl.kt @@ -61,6 +61,9 @@ abstract class ComponentStoreImpl : IComponentStore { protected open val project: Project? get() = null + open val isLoadComponentState: Boolean + get() = true + abstract val storageManager: StateStorageManager override final fun getStateStorageManager() = storageManager @@ -196,7 +199,7 @@ abstract class ComponentStoreImpl : IComponentStore { val componentName = ComponentManagerImpl.getComponentName(component) doAddComponent(componentName, component) - if (optimizeTestLoading()) { + if (!isLoadComponentState) { return null } @@ -226,11 +229,7 @@ abstract class ComponentStoreImpl : IComponentStore { } } - private fun initPersistentComponent(stateSpec: State, component: PersistentStateComponent, changedStorages: Set?, reloadData: Boolean): String? { - if (optimizeTestLoading()) { - return null - } - + private fun initPersistentComponent(stateSpec: State, component: PersistentStateComponent, changedStorages: Set?, reloadData: Boolean): String? { val name = stateSpec.name val stateClass = ComponentSerializationUtil.getStateClass(component.javaClass) if (!stateSpec.defaultStateAsResource && LOG.isDebugEnabled() && getDefaultState(component, name, stateClass) != null) { @@ -238,41 +237,44 @@ abstract class ComponentStoreImpl : IComponentStore { } val defaultState = if (stateSpec.defaultStateAsResource) getDefaultState(component, name, stateClass) else null - val storageSpecs = getStorageSpecs(component, stateSpec, StateStorageOperation.READ) - val storageChooser = component as? StateStorageChooserEx - for (storageSpec in storageSpecs) { - if (storageChooser?.getResolution(storageSpec, StateStorageOperation.READ) == Resolution.SKIP) { - continue - } - - val storage = storageManager.getStateStorage(storageSpec) - var stateGetter = if (isUseLoadedStateAsExisting(storage) && (ApplicationManager.getApplication().isUnitTestMode() || Registry.`is`("use.loaded.state.as.existing", false))) { - (storage as? StorageBaseEx<*>)?.createGetSession(component, name, stateClass) - } - else { - null - } - var state = if (stateGetter == null) storage.getState(component, name, stateClass, defaultState, reloadData) else stateGetter.getState(defaultState) - if (state == null) { - if (changedStorages != null && changedStorages.contains(storage)) { - // state will be null if file deleted - // we must create empty (initial) state to reinit component - state = DefaultStateSerializer.deserializeState(Element("state"), stateClass, null)!! - } - else { + if (isLoadComponentState) { + val storageSpecs = getStorageSpecs(component, stateSpec, StateStorageOperation.READ) + val storageChooser = component as? StateStorageChooserEx + for (storageSpec in storageSpecs) { + if (storageChooser?.getResolution(storageSpec, StateStorageOperation.READ) == Resolution.SKIP) { continue } - } - try { - component.loadState(state) + val storage = storageManager.getStateStorage(storageSpec) + var stateGetter = if (isUseLoadedStateAsExisting(storage) && (ApplicationManager.getApplication().isUnitTestMode() || Registry.`is`("use.loaded.state.as.existing", false))) { + (storage as? StorageBaseEx<*>)?.createGetSession(component, name, stateClass) + } + else { + null + } + var state = if (stateGetter == null) storage.getState(component, name, stateClass, defaultState, reloadData) else stateGetter.getState(defaultState) + if (state == null) { + if (changedStorages != null && changedStorages.contains(storage)) { + // state will be null if file deleted + // we must create empty (initial) state to reinit component + state = DefaultStateSerializer.deserializeState(Element("state"), stateClass, null)!! + } + else { + continue + } + } + + try { + component.loadState(state) + } + finally { + stateGetter?.close() + } + return name } - finally { - stateGetter?.close() - } - return name } + // we load default state even if isLoadComponentState false - required for app components (for example, at least one color scheme must exists) if (defaultState != null) { component.loadState(defaultState) } @@ -332,8 +334,6 @@ abstract class ComponentStoreImpl : IComponentStore { return sorted } - protected open fun optimizeTestLoading(): Boolean = false - override final fun isReloadPossible(componentNames: MutableSet) = !componentNames.any { isNotReloadable(it) } private fun isNotReloadable(component: Any?) = component != null && (component !is PersistentStateComponent<*> || !StoreUtil.getStateSpec(component).reloadable) diff --git a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt index 7a619fee2f95..f8cb55a1103c 100644 --- a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt @@ -30,6 +30,9 @@ class DefaultProjectStoreImpl(override val project: ProjectImpl, private val pat val FILE_SPEC = "${StoragePathMacros.APP_CONFIG}/project.default.xml" } + override val isLoadComponentState: Boolean + get() = !ApplicationManager.getApplication().isUnitTestMode() + init { service().project = project } diff --git a/platform/configuration-store-impl/src/ModuleStoreImpl.kt b/platform/configuration-store-impl/src/ModuleStoreImpl.kt index 40839c4d9831..6d7ac4bc1f55 100644 --- a/platform/configuration-store-impl/src/ModuleStoreImpl.kt +++ b/platform/configuration-store-impl/src/ModuleStoreImpl.kt @@ -17,11 +17,12 @@ package com.intellij.configurationStore import com.intellij.openapi.components.PathMacroManager import com.intellij.openapi.components.StoragePathMacros +import com.intellij.openapi.components.stateStore import com.intellij.openapi.module.Module -import com.intellij.openapi.project.ex.ProjectEx +import com.intellij.util.ThreeState import java.io.File -class ModuleStoreImpl(module: Module, private val pathMacroManager: PathMacroManager) : ComponentStoreImpl() { +open private class ModuleStoreImpl(module: Module, private val pathMacroManager: PathMacroManager) : ComponentStoreImpl() { override val project = module.getProject() override val storageManager = ModuleStateStorageManager(pathMacroManager.createTrackingSubstitutor(), module) @@ -32,7 +33,20 @@ class ModuleStoreImpl(module: Module, private val pathMacroManager: PathMacroMan } } - override fun optimizeTestLoading() = (project as ProjectEx).isOptimiseTestLoadSpeed() - override final fun getPathMacroManagerForDefaults() = pathMacroManager +} + +private class TestModuleStore(module: Module, pathMacroManager: PathMacroManager) : ModuleStoreImpl(module, pathMacroManager) { + private var isLoadModuleComponentState = ThreeState.UNSURE + + override fun setPath(path: String) { + super.setPath(path) + + if (File(path).exists()) { + isLoadModuleComponentState = ThreeState.YES + } + } + + override val isLoadComponentState: Boolean + get() = if (isLoadModuleComponentState == ThreeState.UNSURE) (project.stateStore as ProjectStoreImpl).isLoadComponentState else isLoadModuleComponentState.toBoolean() } \ No newline at end of file diff --git a/platform/configuration-store-impl/src/ProjectStoreImpl.kt b/platform/configuration-store-impl/src/ProjectStoreImpl.kt index 92d7d2b22143..4bbd82b22556 100644 --- a/platform/configuration-store-impl/src/ProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/ProjectStoreImpl.kt @@ -19,6 +19,7 @@ import com.intellij.ide.highlighter.ProjectFileType import com.intellij.ide.highlighter.WorkspaceFileType import com.intellij.notification.Notifications import com.intellij.notification.NotificationsManager +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ReadAction import com.intellij.openapi.application.invokeAndWaitIfNeed import com.intellij.openapi.components.* @@ -50,11 +51,17 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM private var presentableUrl: String? = null + override var isLoadComponentState = true + init { assert(!project.isDefault()) } - override fun optimizeTestLoading() = project.isOptimiseTestLoadSpeed() + override final fun isOptimiseTestLoadSpeed() = !isLoadComponentState + + override final fun setOptimiseTestLoadSpeed(value: Boolean) { + isLoadComponentState = !value + } override final fun getPathMacroManagerForDefaults() = pathMacroManager @@ -74,6 +81,11 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM invokeAndWaitIfNeed { VfsUtil.markDirtyAndRefresh(false, true, false, fs.refreshAndFindFileByPath(filePath), fs.refreshAndFindFileByPath(workspacePath)) } + + if (ApplicationManager.getApplication().isUnitTestMode()) { + // load state only if there are existing files + isLoadComponentState = File(filePath).exists() + } } else { scheme = StorageScheme.DIRECTORY_BASED @@ -91,6 +103,11 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM } invokeAndWaitIfNeed { VfsUtil.markDirtyAndRefresh(false, true, true, fs.refreshAndFindFileByPath(projectConfigDir)) } + + if (ApplicationManager.getApplication().isUnitTestMode()) { + // load state only if there are existing files + isLoadComponentState = dirStore.exists() + } } presentableUrl = null diff --git a/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt b/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt index d3b6269745ce..7d96ad1e6ba2 100644 --- a/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt @@ -5,28 +5,30 @@ import com.intellij.externalDependencies.ExternalDependenciesManager import com.intellij.externalDependencies.ProjectExternalDependency import com.intellij.openapi.application.ex.ApplicationManagerEx import com.intellij.openapi.components.StoragePathMacros +import com.intellij.openapi.components.impl.stores.IComponentStore +import com.intellij.openapi.components.impl.stores.StateStorageManager import com.intellij.openapi.components.service import com.intellij.openapi.components.stateStore import com.intellij.openapi.project.ProjectManager -import com.intellij.openapi.util.io.FileUtil import com.intellij.testFramework.ProjectRule import com.intellij.testFramework.RuleChain import com.intellij.testFramework.TemporaryDirectory +import com.intellij.testFramework.deleteRecursively import org.assertj.core.api.Assertions.assertThat import org.junit.ClassRule import org.junit.Rule import org.junit.Test import org.junit.rules.ExternalResource -import java.io.File +import java.nio.file.Paths class DefaultProjectStoreTest { companion object { - ClassRule val projectRule = ProjectRule() + @ClassRule val projectRule = ProjectRule() } private val tempDirManager = TemporaryDirectory() - private val requiredPlugins: List = listOf(DependencyOnPlugin("fake", "0", "1")) + private val requiredPlugins = listOf(DependencyOnPlugin("fake", "0", "1")) private val ruleChain = RuleChain( tempDirManager, @@ -45,7 +47,7 @@ class DefaultProjectStoreTest { app.doNotSave(isDoNotSave) } finally { - FileUtil.delete(File(app.stateStore.getStateStorageManager().expandMacros(StoragePathMacros.APP_CONFIG))) + Paths.get(app.stateStore.storageManager.expandMacros(StoragePathMacros.APP_CONFIG)).deleteRecursively() } } }, @@ -63,11 +65,14 @@ class DefaultProjectStoreTest { } ) - public Rule fun getChain(): RuleChain = ruleChain + @Rule fun getChain() = ruleChain - public Test fun `new project from default`() { - createProject(tempDirManager) { + @Test fun `new project from default`() { + createProjectAndUseInLoadComponentStateMode(tempDirManager) { assertThat(it.service().getAllDependencies()).isEqualTo(requiredPlugins) } } -} \ No newline at end of file +} + +val IComponentStore.storageManager: StateStorageManager + get() = getStateStorageManager() \ No newline at end of file diff --git a/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt b/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt index e3f4e94c1efe..935edfed2b4a 100644 --- a/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt @@ -32,11 +32,11 @@ import org.junit.Rule import org.junit.Test import java.io.File -fun createProject(tempDirManager: TemporaryDirectory, task: (Project) -> Unit) { +fun createProjectAndUseInLoadComponentStateMode(tempDirManager: TemporaryDirectory, task: (Project) -> Unit) { createOrLoadProject(tempDirManager, task) } -fun loadProject(tempDirManager: TemporaryDirectory, projectCreator: ((VirtualFile) -> String)? = null, task: (Project) -> Unit) { +fun loadAndUseProject(tempDirManager: TemporaryDirectory, projectCreator: ((VirtualFile) -> String)? = null, task: (Project) -> Unit) { createOrLoadProject(tempDirManager, task, projectCreator) } @@ -51,20 +51,22 @@ private fun createOrLoadProject(tempDirManager: TemporaryDirectory, task: (Proje } val projectManager = ProjectManagerEx.getInstanceEx() as ProjectManagerImpl - var project = if (projectCreator == null) projectManager.newProject(null, filePath, true, false, false)!! else projectManager.loadProject(filePath)!! - try { - projectManager.openTestProject(project) - task(project) - } - finally { - projectManager.closeProject(project, false, true, false) + var project = if (projectCreator == null) projectManager.newProject(null, filePath, true, false)!! else projectManager.loadProject(filePath)!! + project.runInLoadComponentStateMode { + try { + projectManager.openTestProject(project) + task(project) + } + finally { + projectManager.closeProject(project, false, true, false) + } } } } class ProjectStoreTest { companion object { - ClassRule val projectRule = ProjectRule() + @ClassRule val projectRule = ProjectRule() } val tempDirManager = TemporaryDirectory() @@ -72,7 +74,7 @@ class ProjectStoreTest { private val ruleChain = RuleChain(tempDirManager) @Rule fun getChain() = ruleChain - Language("XML") + @Language("XML") private val iprFileContent = "\n" + "\n" + @@ -81,7 +83,7 @@ class ProjectStoreTest { " \n" + "" - State(name = "AATestComponent", storages = arrayOf(Storage(file = StoragePathMacros.PROJECT_FILE))) + @State(name = "AATestComponent", storages = arrayOf(Storage(file = StoragePathMacros.PROJECT_FILE))) private class TestComponent : PersistentStateComponent { private var state: TestState? = null @@ -94,8 +96,8 @@ class ProjectStoreTest { data class TestState(var value: String = "default") - public Test fun directoryBasedStorage() { - loadProject(tempDirManager, { + @Test fun directoryBasedStorage() { + loadAndUseProject(tempDirManager, { it.writeChild("${Project.DIRECTORY_STORE_FOLDER}/misc.xml", iprFileContent) it.path }) { project -> @@ -112,8 +114,8 @@ class ProjectStoreTest { } } - public Test fun fileBasedStorage() { - loadProject(tempDirManager, { it.writeChild("test${ProjectFileType.DOT_DEFAULT_EXTENSION}", iprFileContent).path }) { project -> + @Test fun fileBasedStorage() { + loadAndUseProject(tempDirManager, { it.writeChild("test${ProjectFileType.DOT_DEFAULT_EXTENSION}", iprFileContent).path }) { project -> test(project) } } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IProjectStore.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IProjectStore.java index c711e37c40a2..8736913168a0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IProjectStore.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IProjectStore.java @@ -61,4 +61,8 @@ public interface IProjectStore extends IComponentStore { void loadProjectFromTemplate(@NotNull Project project); void clearStorages(); + + boolean isOptimiseTestLoadSpeed(); + + void setOptimiseTestLoadSpeed(boolean optimiseTestLoadSpeed); } diff --git a/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectEx.java b/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectEx.java index 90facde40980..a44339933569 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectEx.java @@ -27,9 +27,5 @@ public interface ProjectEx extends Project { void init(); - boolean isOptimiseTestLoadSpeed(); - - void setOptimiseTestLoadSpeed(boolean optimiseTestLoadSpeed); - void setProjectName(@NotNull String name); } diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/DefaultProject.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/DefaultProject.java index 0e60d4421212..5de4c4079c2e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/DefaultProject.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/DefaultProject.java @@ -24,8 +24,8 @@ import org.jetbrains.annotations.NotNull; class DefaultProject extends ProjectImpl { private static final String TEMPLATE_PROJECT_NAME = "Default (Template) Project"; - protected DefaultProject(@NotNull ProjectManager manager, @NotNull String filePath, boolean optimiseTestLoadSpeed) { - super(manager, filePath, optimiseTestLoadSpeed, TEMPLATE_PROJECT_NAME); + protected DefaultProject(@NotNull ProjectManager manager, @NotNull String filePath) { + super(manager, filePath, TEMPLATE_PROJECT_NAME); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java index 7158a5c424fd..ba37b449062f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java @@ -70,14 +70,12 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project private ProjectManager myProjectManager; private MyProjectManagerListener myProjectManagerListener; private final AtomicBoolean mySavingInProgress = new AtomicBoolean(false); - public boolean myOptimiseTestLoadSpeed; private String myName; private String myOldName; private final boolean myLight; protected ProjectImpl(@NotNull ProjectManager projectManager, @NotNull String filePath, - boolean optimiseTestLoadSpeed, @Nullable String projectName) { super(ApplicationManager.getApplication(), "Project " + (projectName == null ? filePath : projectName)); @@ -92,7 +90,6 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project getStateStore().setPath(FileUtilRt.toSystemIndependentName(filePath)); } - myOptimiseTestLoadSpeed = optimiseTestLoadSpeed; myProjectManager = projectManager; myName = projectName == null ? getStateStore().getProjectName() : projectName; @@ -271,16 +268,6 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project return isDefault() ? null : getStateStore().getWorkspaceFile(); } - @Override - public boolean isOptimiseTestLoadSpeed() { - return myOptimiseTestLoadSpeed; - } - - @Override - public void setOptimiseTestLoadSpeed(final boolean optimiseTestLoadSpeed) { - myOptimiseTestLoadSpeed = optimiseTestLoadSpeed; - } - @Override public void init() { long start = System.currentTimeMillis(); diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java index 30c25c643d8c..a854bedf87fe 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -142,15 +142,8 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable { private static final int MAX_LEAKY_PROJECTS = 42; @SuppressWarnings("FieldCanBeLocal") private final Map myProjects = new WeakHashMap(); - @Override @Nullable - public Project newProject(final String projectName, @NotNull String filePath, boolean useDefaultProjectSettings, boolean isDummy) { - return newProject(projectName, filePath, useDefaultProjectSettings, isDummy, ApplicationManager.getApplication().isUnitTestMode()); - } - - @Nullable - public Project newProject(@Nullable String projectName, @NotNull String filePath, boolean useDefaultProjectSettings, boolean isDummy, - boolean optimiseTestLoadSpeed) { + public Project newProject(@Nullable String projectName, @NotNull String filePath, boolean useDefaultProjectSettings, boolean isDummy) { filePath = toCanonicalName(filePath); //noinspection ConstantConditions @@ -184,7 +177,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable { } } } - ProjectImpl project = createProject(projectName, filePath, false, optimiseTestLoadSpeed); + ProjectImpl project = createProject(projectName, filePath, false); try { initProject(project, useDefaultProjectSettings ? getDefaultProject() : null); if (LOG_PROJECT_LEAKAGE_IN_TESTS) { @@ -243,10 +236,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable { private ProjectImpl createProject(@Nullable String projectName, @NotNull String filePath, - boolean isDefault, - boolean isOptimiseTestLoadSpeed) { - return isDefault ? new DefaultProject(this, "", isOptimiseTestLoadSpeed) - : new ProjectImpl(this, new File(filePath).getAbsolutePath(), isOptimiseTestLoadSpeed, projectName); + boolean isDefault) { + return isDefault ? new DefaultProject(this, "") + : new ProjectImpl(this, new File(filePath).getAbsolutePath(), projectName); } private static void scheduleDispose(@NotNull final ProjectImpl project) { @@ -273,7 +265,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable { @Nullable public Project loadProject(@NotNull String filePath) throws IOException { try { - ProjectImpl project = createProject(null, filePath, false, false); + ProjectImpl project = createProject(null, filePath, false); initProject(project, null); return project; } @@ -309,7 +301,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable { @Override public void run() { try { - myDefaultProject = createProject(null, "", true, ApplicationManager.getApplication().isUnitTestMode()); + myDefaultProject = createProject(null, "", true); initProject(myDefaultProject, null); } catch (Throwable t) { @@ -519,7 +511,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable { */ @Nullable private Project loadProjectWithProgress(@NotNull final String filePath) { - final ProjectImpl project = createProject(null, toCanonicalName(filePath), false, false); + final ProjectImpl project = createProject(null, toCanonicalName(filePath), false); try { myProgressManager.runProcessWithProgressSynchronously(new ThrowableComputable() { @Override diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 1276bf5631f4..4a19cf12e4ff 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -330,6 +330,9 @@ + Project.runInLoadComponentStateMode(task: () -> T): T { + val store = stateStore as IProjectStore + val isModeDisabled = store.isOptimiseTestLoadSpeed() + if (isModeDisabled) { + store.setOptimiseTestLoadSpeed(false) + } + try { + return task() + } + finally { + if (isModeDisabled) { + store.setOptimiseTestLoadSpeed(true) + } + } +} + public class DisposeModulesRule(private val projectRule: ProjectRule) : ExternalResource() { override fun after() { projectRule.projectIfOpened?.let { From 66d17dddf606d7884192f3e542f8afbc01d198ae Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 8 Sep 2015 16:46:08 +0200 Subject: [PATCH 089/138] convert to Kotlin --- .../build/PluginModuleCompilationTest.java | 266 ++++++++---------- 1 file changed, 124 insertions(+), 142 deletions(-) diff --git a/plugins/devkit/testSources/build/PluginModuleCompilationTest.java b/plugins/devkit/testSources/build/PluginModuleCompilationTest.java index 0d233e6ce346..349cf9cbe1ce 100644 --- a/plugins/devkit/testSources/build/PluginModuleCompilationTest.java +++ b/plugins/devkit/testSources/build/PluginModuleCompilationTest.java @@ -13,160 +13,142 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.idea.devkit.build; +package org.jetbrains.idea.devkit.build -import com.intellij.compiler.BaseCompilerTestCase; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.application.Result; -import com.intellij.openapi.application.WriteAction; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.projectRoots.ProjectJdkTable; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.SdkModificator; -import com.intellij.openapi.projectRoots.SdkType; -import com.intellij.openapi.roots.ModuleRootModificationUtil; -import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.io.FileUtilRt; -import com.intellij.openapi.vfs.LocalFileSystem; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.idea.devkit.projectRoots.IdeaJdk; -import org.jetbrains.idea.devkit.projectRoots.Sandbox; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static com.intellij.util.io.TestFileSystemBuilder.fs; +import com.intellij.compiler.BaseCompilerTestCase +import com.intellij.openapi.application.PathManager +import com.intellij.openapi.application.runWriteAction +import com.intellij.openapi.module.Module +import com.intellij.openapi.module.ModuleType +import com.intellij.openapi.project.ex.ProjectEx +import com.intellij.openapi.projectRoots.ProjectJdkTable +import com.intellij.openapi.projectRoots.Sdk +import com.intellij.openapi.projectRoots.SdkType +import com.intellij.openapi.roots.ModuleRootModificationUtil +import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.util.io.FileUtil +import com.intellij.openapi.util.io.FileUtilRt +import com.intellij.openapi.vfs.LocalFileSystem +import com.intellij.testFramework.runInLoadComponentStateMode +import com.intellij.util.SmartList +import com.intellij.util.io.TestFileSystemBuilder.fs +import junit.framework.TestCase +import org.assertj.core.api.Assertions.assertThat +import org.jetbrains.idea.devkit.module.PluginModuleType +import org.jetbrains.idea.devkit.projectRoots.IdeaJdk +import org.jetbrains.idea.devkit.projectRoots.Sandbox +import java.io.File +import java.util.ArrayList +import java.util.Arrays /** * @author nik */ -public class PluginModuleCompilationTest extends BaseCompilerTestCase { - private Sdk myPluginSdk; +public class PluginModuleCompilationTest : BaseCompilerTestCase() { + private var pluginSdk: Sdk? = null - @Override - protected void setUpJdk() { - super.setUpJdk(); - new WriteAction() { - @Override - protected void run(@NotNull final Result result) { - ProjectJdkTable table = ProjectJdkTable.getInstance(); - myPluginSdk = table.createSdk("IDEA plugin SDK", SdkType.findInstance(IdeaJdk.class)); - SdkModificator modificator = myPluginSdk.getSdkModificator(); - modificator.setSdkAdditionalData(new Sandbox(getSandboxPath(), getTestProjectJdk(), myPluginSdk)); - String rootPath = FileUtil.toSystemIndependentName(PathManager.getJarPathForClass(FileUtilRt.class)); - modificator.addRoot(LocalFileSystem.getInstance().refreshAndFindFileByPath(rootPath), OrderRootType.CLASSES); - modificator.commitChanges(); - table.addJdk(myPluginSdk); - } - }.execute(); - } - - private String getSandboxPath() { - return getProjectBasePath() + "/sandbox"; - } - - @Override - protected void tearDown() throws Exception { - new WriteAction() { - @Override - protected void run(@NotNull final Result result) { - ProjectJdkTable.getInstance().removeJdk(myPluginSdk); - } - }.execute(); - - super.tearDown(); - } - - public void testMakeSimpleModule() { - Module module = setupSimplePluginProject(); - make(module); - assertOutput(module, fs().dir("xxx").file("MyAction.class")); - - File sandbox = new File(FileUtilRt.toSystemDependentName(getSandboxPath())); - assertTrue(sandbox.exists()); - fs().dir("plugins") - .dir("pluginProject") - .dir("META-INF").file("plugin.xml").end() - .dir("classes") - .dir("xxx").file("MyAction.class") - .build().assertDirectoryEqual(sandbox); - } - - public void testRebuildSimpleProject() { - setupSimplePluginProject(); - CompilationLog log = rebuild(); - assertTrue("Rebuild finished with warnings: " + Arrays.toString(log.getWarnings()), log.getWarnings().length == 0); - } - - public void testPrepareSimpleProjectForDeployment() { - Module module = setupSimplePluginProject(); - rebuild(); - prepareForDeployment(module); - - File outputFile = new File(getProjectBasePath() + "/pluginProject.jar"); - assertTrue(outputFile + " not found", outputFile.exists()); - fs() - .archive("pluginProject.jar") - .dir("META-INF").file("plugin.xml").file("MANIFEST.MF").end() - .dir("xxx").file("MyAction.class") - .build().assertFileEqual(outputFile); - } - - public void testBuildProjectWithJpsModule() { - Module module = setupPluginProjectWithJpsModule(); - rebuild(); - prepareForDeployment(module); - - File outputFile = new File(getProjectBasePath() + "/pluginProject.zip"); - assertTrue(outputFile + " not found", outputFile.exists()); - fs() - .archive("pluginProject.zip") - .dir("pluginProject") - .dir("lib") - .archive("pluginProject.jar") - .dir("META-INF").file("plugin.xml").file("MANIFEST.MF").end() - .dir("xxx").file("MyAction.class").end() - .end() - .dir("jps") - .archive("jps-plugin.jar") - .file("Builder.class") - - .build().assertFileEqual(outputFile); - } - - @Override - protected void readJdomExternalizables(@NotNull Module module) { - super.readJdomExternalizables(module); - PluginBuildConfiguration buildConfiguration = PluginBuildConfiguration.getInstance(module); - if (buildConfiguration != null) { - loadModuleComponentState(module, buildConfiguration); + override fun setUpJdk() { + super.setUpJdk() + runWriteAction { + val table = ProjectJdkTable.getInstance() + pluginSdk = table.createSdk("IDEA plugin SDK", SdkType.findInstance(javaClass())) + val modificator = pluginSdk!!.getSdkModificator() + modificator.setSdkAdditionalData(Sandbox(getSandboxPath(), getTestProjectJdk(), pluginSdk)) + val rootPath = FileUtil.toSystemIndependentName(PathManager.getJarPathForClass(javaClass())) + modificator.addRoot(LocalFileSystem.getInstance().refreshAndFindFileByPath(rootPath), OrderRootType.CLASSES) + modificator.commitChanges() + table.addJdk(pluginSdk) } } - private static void prepareForDeployment(Module module) { - List errorMessages = new ArrayList(); - PrepareToDeployAction.doPrepare(module, errorMessages, new ArrayList()); - assertTrue("Building plugin zip finished with errors: " + errorMessages, errorMessages.isEmpty()); + private fun getSandboxPath() = "${getProjectBasePath()}/sandbox" + + override fun tearDown() { + try { + if (pluginSdk != null) { + runWriteAction { ProjectJdkTable.getInstance().removeJdk(pluginSdk) } + } + } + finally { + super.tearDown() + } } - private Module setupSimplePluginProject() { - copyToProject("plugins/devkit/testData/build/simple"); - Module module = loadModule(getProjectBasePath() + "/pluginProject.iml"); - readJdomExternalizables(module); - return module; + public fun testMakeSimpleModule() { + val module = setupSimplePluginProject() + make(module) + BaseCompilerTestCase.assertOutput(module, fs().dir("xxx").file("MyAction.class")) + + val sandbox = File(getSandboxPath()) + assertThat(sandbox).isDirectory() + fs() + .dir("plugins") + .dir("pluginProject") + .dir("META-INF").file("plugin.xml").end() + .dir("classes") + .dir("xxx").file("MyAction.class") + .build().assertDirectoryEqual(sandbox) } - private Module setupPluginProjectWithJpsModule() { - copyToProject("plugins/devkit/testData/build/withJpsModule"); - Module module = loadModule(getProjectBasePath() + "/pluginProject.iml"); - readJdomExternalizables(module); - loadModuleComponentState(module, PluginBuildConfiguration.getInstance(module)); - Module jpsModule = loadModule(getProjectBasePath() + "/jps-plugin/jps-plugin.iml"); - readJdomExternalizables(jpsModule); - ModuleRootModificationUtil.setModuleSdk(jpsModule, getTestProjectJdk()); - return module; + public fun testRebuildSimpleProject() { + setupSimplePluginProject() + val log = rebuild() + assertThat(log.getWarnings()).`as`("Rebuild finished with warnings: ${Arrays.toString(log.getWarnings())}").isEmpty() + } + + public fun testPrepareSimpleProjectForDeployment() { + val module = setupSimplePluginProject() + rebuild() + prepareForDeployment(module) + + val outputFile = File("${getProjectBasePath()}/pluginProject.jar") + assertThat(outputFile).isFile() + fs() + .archive("pluginProject.jar") + .dir("META-INF").file("plugin.xml").file("MANIFEST.MF").end() + .dir("xxx").file("MyAction.class") + .build().assertFileEqual(outputFile) + } + + public fun testBuildProjectWithJpsModule() { + val module = setupPluginProjectWithJpsModule() + rebuild() + prepareForDeployment(module) + + val outputFile = File("${getProjectBasePath()}/pluginProject.zip") + assertThat(outputFile).isFile() + fs() + .archive("pluginProject.zip") + .dir("pluginProject") + .dir("lib") + .archive("pluginProject.jar") + .dir("META-INF").file("plugin.xml").file("MANIFEST.MF").end() + .dir("xxx").file("MyAction.class").end() + .end() + .dir("jps") + .archive("jps-plugin.jar").file("Builder.class") + .build().assertFileEqual(outputFile) + } + + private fun prepareForDeployment(module: Module) { + val errorMessages = SmartList() + PrepareToDeployAction.doPrepare(module, errorMessages, SmartList()) + assertThat(errorMessages).`as`("Building plugin zip finished with errors: $errorMessages").isEmpty() + } + + private fun setupSimplePluginProject() = copyAndCreateModule("plugins/devkit/testData/build/simple") + + private fun copyAndCreateModule(relativePath: String): Module { + copyToProject(relativePath) + val module = loadModule("${getProjectBasePath()}/pluginProject.iml") + assertThat(ModuleType.get(module)).isEqualTo(PluginModuleType.getInstance()) + return module + } + + private fun setupPluginProjectWithJpsModule(): Module { + val module = copyAndCreateModule("plugins/devkit/testData/build/withJpsModule") + val jpsModule = loadModule("${getProjectBasePath()}/jps-plugin/jps-plugin.iml") + ModuleRootModificationUtil.setModuleSdk(jpsModule, getTestProjectJdk()) + return module } } From 2492f668cf81aae3f696d7958531724801e652af Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 8 Sep 2015 16:46:39 +0200 Subject: [PATCH 090/138] convert to Kotlin --- ...uleCompilationTest.java => PluginModuleCompilationTest.kt} | 4 ---- 1 file changed, 4 deletions(-) rename plugins/devkit/testSources/build/{PluginModuleCompilationTest.java => PluginModuleCompilationTest.kt} (97%) diff --git a/plugins/devkit/testSources/build/PluginModuleCompilationTest.java b/plugins/devkit/testSources/build/PluginModuleCompilationTest.kt similarity index 97% rename from plugins/devkit/testSources/build/PluginModuleCompilationTest.java rename to plugins/devkit/testSources/build/PluginModuleCompilationTest.kt index 349cf9cbe1ce..1a55a1a702b8 100644 --- a/plugins/devkit/testSources/build/PluginModuleCompilationTest.java +++ b/plugins/devkit/testSources/build/PluginModuleCompilationTest.kt @@ -20,7 +20,6 @@ import com.intellij.openapi.application.PathManager import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleType -import com.intellij.openapi.project.ex.ProjectEx import com.intellij.openapi.projectRoots.ProjectJdkTable import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.projectRoots.SdkType @@ -29,16 +28,13 @@ import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtilRt import com.intellij.openapi.vfs.LocalFileSystem -import com.intellij.testFramework.runInLoadComponentStateMode import com.intellij.util.SmartList import com.intellij.util.io.TestFileSystemBuilder.fs -import junit.framework.TestCase import org.assertj.core.api.Assertions.assertThat import org.jetbrains.idea.devkit.module.PluginModuleType import org.jetbrains.idea.devkit.projectRoots.IdeaJdk import org.jetbrains.idea.devkit.projectRoots.Sandbox import java.io.File -import java.util.ArrayList import java.util.Arrays /** From 370ae7a5ab126711f498db25405f2f01cd6aeee0 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 8 Sep 2015 21:04:59 +0200 Subject: [PATCH 091/138] =?UTF-8?q?fix=20compilation=20=E2=80=94=20don't?= =?UTF-8?q?=20use=20test-only=20code=20in=20production?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/testFramework/testFramework-java.iml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/testFramework/testFramework-java.iml b/java/testFramework/testFramework-java.iml index 06a46c65abad..a96cd3af8add 100644 --- a/java/testFramework/testFramework-java.iml +++ b/java/testFramework/testFramework-java.iml @@ -13,7 +13,7 @@ - + From 2c6b3869e51f5369496f706f2ee96795467e1a7a Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 8 Sep 2015 21:09:15 +0200 Subject: [PATCH 092/138] fix compilation --- plugins/devkit/devkit-tests.iml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/devkit/devkit-tests.iml b/plugins/devkit/devkit-tests.iml index 9387a1d87b6d..cf89675ebc14 100644 --- a/plugins/devkit/devkit-tests.iml +++ b/plugins/devkit/devkit-tests.iml @@ -5,7 +5,7 @@ - + From a7f5a45f225cdb56e0ee74a43cb94ee2e0d3108c Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 9 Sep 2015 10:22:00 +0200 Subject: [PATCH 093/138] =?UTF-8?q?simplify=20=E2=80=94=20it=20is=20not=20?= =?UTF-8?q?a=20persistent=20component,=20default=20state=20just=20loaded?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/impl/ApplicationInfoImpl.java | 43 ++++++++----------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java index d42d26f24198..b544bfef1dad 100644 --- a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java @@ -19,9 +19,9 @@ import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.ex.ApplicationInfoEx; -import com.intellij.openapi.components.NamedComponent; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.*; +import com.intellij.openapi.util.BuildNumber; +import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.JBColor; import com.intellij.util.ArrayUtil; @@ -45,7 +45,7 @@ import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; -public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExternalizable, NamedComponent { +public class ApplicationInfoImpl extends ApplicationInfoEx { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.application.impl.ApplicationInfoImpl"); private String myCodeName = null; @@ -187,6 +187,19 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern private static final String DEFAULT_PLUGINS_HOST = "http://plugins.jetbrains.com"; + ApplicationInfoImpl() { + try { + Document doc = JDOMUtil.loadDocument(ApplicationInfoImpl.class, IDEA_PATH + ApplicationNamesInfo.getComponentName() + XML_EXTENSION); + loadState(doc.getRootElement()); + } + catch (FileNotFoundException e) { + LOG.error("Resource is not in classpath or wrong platform prefix: " + System.getProperty(PlatformUtils.PLATFORM_PREFIX_KEY), e); + } + catch (Exception e) { + LOG.error(e); + } + } + @Override public Calendar getBuildDate() { return myBuildDate; @@ -536,22 +549,11 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern public static ApplicationInfoEx getShadowInstance() { if (ourShadowInstance == null) { ourShadowInstance = new ApplicationInfoImpl(); - try { - Document doc = JDOMUtil.loadDocument(ApplicationInfoImpl.class, IDEA_PATH + ApplicationNamesInfo.getComponentName() + XML_EXTENSION); - ourShadowInstance.readExternal(doc.getRootElement()); - } - catch (FileNotFoundException e) { - LOG.error("Resource is not in classpath or wrong platform prefix: " + System.getProperty(PlatformUtils.PLATFORM_PREFIX_KEY), e); - } - catch (Exception e) { - LOG.error(e); - } } return ourShadowInstance; } - @Override - public void readExternal(Element parentNode) throws InvalidDataException { + private void loadState(Element parentNode) { Element versionElement = parentNode.getChild(ELEMENT_VERSION); if (versionElement != null) { myMajorVersion = versionElement.getAttributeValue(ATTRIBUTE_MAJOR); @@ -845,11 +847,6 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern return new Color((int)rgb, rgb > 0xffffff); } - @Override - public void writeExternal(Element element) throws WriteExternalException { - throw new WriteExternalException(); - } - @Override public List getPluginChooserPages() { return myPluginChooserPages; @@ -860,12 +857,6 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern return PluginManagerCore.CORE_PLUGIN_ID.equals(pluginId) || ArrayUtil.contains(pluginId, myEssentialPluginsIds); } - @Override - @NotNull - public String getComponentName() { - return ApplicationNamesInfo.getComponentName(); - } - private static class UpdateUrlsImpl implements UpdateUrls { private String myCheckingUrl; private String myPatchesUrl; From 51cf96cfb11d1a8392834c984c68dd994cd81f04 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 9 Sep 2015 12:07:50 +0200 Subject: [PATCH 094/138] fix build (we should not use test source roots because we provide testframework in dist) --- java/testFramework/testFramework-java.iml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/testFramework/testFramework-java.iml b/java/testFramework/testFramework-java.iml index a96cd3af8add..90a2a5d0ce1f 100644 --- a/java/testFramework/testFramework-java.iml +++ b/java/testFramework/testFramework-java.iml @@ -3,7 +3,7 @@ - + From e5d366fb8f94582b739e73c46d88664500b2857f Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 9 Sep 2015 12:50:07 +0200 Subject: [PATCH 095/138] state storages could be specified as empty list if you need to load only default state ({@link #defaultStateAsResource()} must be true in this case) --- .../src/ComponentStoreImpl.kt | 9 ++++- .../usageView/UsageTreeColorsScheme.java | 33 ++++++++----------- .../intellij/openapi/components/State.java | 3 ++ 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/platform/configuration-store-impl/src/ComponentStoreImpl.kt b/platform/configuration-store-impl/src/ComponentStoreImpl.kt index 624e872c29b3..0184580eb18c 100644 --- a/platform/configuration-store-impl/src/ComponentStoreImpl.kt +++ b/platform/configuration-store-impl/src/ComponentStoreImpl.kt @@ -302,7 +302,14 @@ abstract class ComponentStoreImpl : IComponentStore { if (storages.size() == 1 || component is StateStorageChooserEx) { return storages } - assert(!storages.isEmpty()) + + if (storages.isEmpty()) { + if (stateSpec.defaultStateAsResource) { + return storages + } + + throw AssertionError("No storage specified") + } val defaultStorages = selectDefaultStorages(storages, operation) if (defaultStorages != null) { diff --git a/platform/lang-api/src/com/intellij/usageView/UsageTreeColorsScheme.java b/platform/lang-api/src/com/intellij/usageView/UsageTreeColorsScheme.java index 5eb526877ba6..cfe4274aea92 100644 --- a/platform/lang-api/src/com/intellij/usageView/UsageTreeColorsScheme.java +++ b/platform/lang-api/src/com/intellij/usageView/UsageTreeColorsScheme.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,18 +15,18 @@ */ package com.intellij.usageView; -import com.intellij.openapi.components.NamedComponent; +import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.components.State; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.colors.EditorColorsUtil; -import com.intellij.openapi.util.JDOMExternalizable; -import com.intellij.openapi.util.WriteExternalException; import com.intellij.util.ui.UIUtil; import org.jdom.Element; -import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public class UsageTreeColorsScheme implements NamedComponent, JDOMExternalizable { +@State(name = "FindViewColorsScheme", defaultStateAsResource = true, storages = {}) +public class UsageTreeColorsScheme implements PersistentStateComponent { private EditorColorsScheme myColorsScheme; /** @@ -39,26 +39,21 @@ public class UsageTreeColorsScheme implements NamedComponent, JDOMExternalizable return ServiceManager.getService(UsageTreeColorsScheme.class); } - @Override - @NotNull - public String getComponentName() { - return "FindViewColorsScheme"; - } - public EditorColorsScheme getScheme() { return myColorsScheme; } + @Nullable @Override - public void readExternal(Element element) { - if (myColorsScheme == null) { - myColorsScheme = (EditorColorsScheme)EditorColorsUtil.getColorSchemeForBackground(UIUtil.getTreeTextBackground()).clone(); - } - myColorsScheme.readExternal(element); + public Element getState() { + return null; } @Override - public void writeExternal(Element element) throws WriteExternalException { - throw new WriteExternalException(); + public void loadState(Element state) { + if (myColorsScheme == null) { + myColorsScheme = (EditorColorsScheme)EditorColorsUtil.getColorSchemeForBackground(UIUtil.getTreeTextBackground()).clone(); + } + myColorsScheme.readExternal(state); } } diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/State.java b/platform/projectModel-api/src/com/intellij/openapi/components/State.java index 05e21d4c3a5e..1f76209076bb 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/components/State.java +++ b/platform/projectModel-api/src/com/intellij/openapi/components/State.java @@ -24,6 +24,9 @@ import java.lang.annotation.RetentionPolicy; public @interface State { String name(); + /** + * Could be specified as empty list if you need to load only default state ({@link #defaultStateAsResource()} must be true in this case) + */ Storage[] storages(); boolean reloadable() default true; From 749ac3d8e270f5c86a1ee7e2ad0a2b03cb7bf149 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 9 Sep 2015 12:57:49 +0200 Subject: [PATCH 096/138] state storages could be specified as empty list if you need to load only default state ({@link #defaultStateAsResource()} must be true in this case) --- .../com/intellij/uiDesigner/Properties.java | 39 +++++++------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/Properties.java b/plugins/ui-designer/src/com/intellij/uiDesigner/Properties.java index 0c0c84dfd175..15e0064770b8 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/Properties.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/Properties.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,11 +15,10 @@ */ package com.intellij.uiDesigner; -import com.intellij.openapi.components.NamedComponent; +import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.components.State; import com.intellij.openapi.module.Module; -import com.intellij.openapi.util.JDOMExternalizable; -import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; @@ -27,7 +26,6 @@ import com.intellij.psi.util.PropertyUtil; import com.intellij.uiDesigner.lw.LwXmlReader; import com.intellij.uiDesigner.propertyInspector.editors.IntEnumEditor; import org.jdom.Element; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -37,7 +35,8 @@ import java.util.*; * @author Anton Katilin * @author Vladimir Kondratyev */ -public final class Properties implements NamedComponent, JDOMExternalizable{ +@State(name = "gui-designer-properties", defaultStateAsResource = true, storages = {}) +public final class Properties implements PersistentStateComponent { private final HashMap myClass2InplaceProperty; private final HashMap> myClass2ExpertProperties; private final Map> myClass2EnumProperties; @@ -113,22 +112,17 @@ public final class Properties implements NamedComponent, JDOMExternalizable{ return null; } - @SuppressWarnings({"HardCodedStringLiteral"}) - public void readExternal(final Element element) { - for (final Object classObject : element.getChildren("class")) { - final Element classElement = (Element)classObject; - + @Override + public void loadState(Element state) { + for (Element classElement : state.getChildren("class")) { final String className = LwXmlReader.getRequiredString(classElement, "name"); // Read "expert" properties final Element expertPropertiesElement = classElement.getChild("expert-properties"); if (expertPropertiesElement != null) { - final HashSet expertProperties = new HashSet(); - - for (final Object o : expertPropertiesElement.getChildren("property")) { - final Element e = (Element)o; - final String name = LwXmlReader.getRequiredString(e, "name"); - expertProperties.add(name); + HashSet expertProperties = new HashSet(); + for (Element e : expertPropertiesElement.getChildren("property")) { + expertProperties.add(LwXmlReader.getRequiredString(e, "name")); } myClass2ExpertProperties.put(className, expertProperties); @@ -171,12 +165,9 @@ public final class Properties implements NamedComponent, JDOMExternalizable{ } } - public void writeExternal(final Element element) throws WriteExternalException{ - throw new WriteExternalException(); - } - - @NonNls @NotNull - public String getComponentName() { - return "gui-designer-properties"; + @Nullable + @Override + public Element getState() { + return null; } } From 6ab12c76a3d52717c37f4ccde39bc3cc089ccca0 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 9 Sep 2015 14:21:11 +0200 Subject: [PATCH 097/138] cleanup --- .../intellij/codeInsight/daemon/impl/SeverityRegistrar.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java index 75caebfab82d..b0c423d7c3f9 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java @@ -21,7 +21,6 @@ import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.JDOMExternalizable; import com.intellij.openapi.util.JDOMExternalizableStringList; import com.intellij.profile.codeInspection.InspectionProfileManager; import com.intellij.profile.codeInspection.InspectionProjectProfileManager; @@ -47,7 +46,7 @@ import java.util.List; * User: anna * Date: 24-Feb-2006 */ -public class SeverityRegistrar implements JDOMExternalizable, Comparator { +public class SeverityRegistrar implements Comparator { @NonNls private static final String INFO_TAG = "info"; @NonNls private static final String COLOR_ATTRIBUTE = "color"; private final Map myMap = ContainerUtil.newConcurrentMap(); @@ -132,7 +131,6 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator list = getOrderAsList(getOrderMap()); for (HighlightSeverity severity : list) { From fc16a0efa245ba5aa3cf01d77b124aafe7b58182 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 9 Sep 2015 14:24:28 +0200 Subject: [PATCH 098/138] cleanup --- .../src/com/intellij/profile/DefaultProjectProfileManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java b/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java index 4bfee3617614..13f37ce525e5 100644 --- a/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java +++ b/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java @@ -59,7 +59,7 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager protected final Project myProject; private String myProjectProfile; - /** This field is used for serialization. Do not rename it or make access weaker */ + @OptionTag("USE_PROJECT_PROFILE") private boolean useProjectProfile = true; From 9653719e9345f41323932e1586255c5e97791f27 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 9 Sep 2015 15:31:27 +0200 Subject: [PATCH 099/138] cleanup --- .../src/SchemeManagerImpl.kt | 8 ++-- .../template/impl/LiveTemplateTree.java | 15 +++---- .../template/impl/TemplateContext.java | 20 +++------ .../template/impl/TemplateSettings.java | 44 ++++++++----------- 4 files changed, 36 insertions(+), 51 deletions(-) diff --git a/platform/configuration-store-impl/src/SchemeManagerImpl.kt b/platform/configuration-store-impl/src/SchemeManagerImpl.kt index 20846da1dbbe..eb72ce1b69fd 100644 --- a/platform/configuration-store-impl/src/SchemeManagerImpl.kt +++ b/platform/configuration-store-impl/src/SchemeManagerImpl.kt @@ -349,7 +349,7 @@ public class SchemeManagerImpl(private val val fileNameWithoutExtension = fileName.subSequence(0, fileName.length() - extension.length()).toString() if (duringLoad) { if (filesToDelete.isNotEmpty() && filesToDelete.contains(fileName.toString())) { - LOG.warn("Scheme file $fileName is not loaded because marked to delete") + LOG.warn("Scheme file \"$fileName\" is not loaded because marked to delete") return null } @@ -367,7 +367,7 @@ public class SchemeManagerImpl(private val else { // We don't load scheme with duplicated name - if we generate unique name for it, it will be saved then with new name. // It is not what all can expect. Such situation in most cases indicates error on previous level, so, we just warn about it. - LOG.warn("Scheme file $fileName is not loaded because defines duplicated name ${scheme.getName()}") + LOG.warn("Scheme file \"$fileName\" is not loaded because defines duplicated name \"${scheme.getName()}\"") } return null } @@ -428,13 +428,13 @@ public class SchemeManagerImpl(private val @suppress("UNCHECKED_CAST") if (scheme is ExternalizableScheme) { val state = getState(scheme as E) - if (state === BaseSchemeProcessor.State.NON_PERSISTENT) { + if (state == BaseSchemeProcessor.State.NON_PERSISTENT) { continue } hasSchemes = true - if (state !== BaseSchemeProcessor.State.UNCHANGED) { + if (state != BaseSchemeProcessor.State.UNCHANGED) { schemesToSave.add(scheme) } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateTree.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateTree.java index c54d9b837980..0b84a914e8dc 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateTree.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateTree.java @@ -22,7 +22,6 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.ide.CopyPasteManager; -import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.CheckboxTree; @@ -144,15 +143,13 @@ class LiveTemplateTree extends CheckboxTree implements DataProvider, CopyProvide assert buffer != null; try { - for (Element templateElement : JDOMUtil.load(new StringReader("" + buffer + "")).getChildren()) { - try { - TemplateImpl template = TemplateSettings.readTemplateFromElement(group.getName(), templateElement, getClass().getClassLoader()); - myConfigurable.addTemplate(template); - } - catch (InvalidDataException ignore) { } + for (Element templateElement : JDOMUtil.load(new StringReader("" + buffer + "")).getChildren(TemplateSettings.TEMPLATE)) { + myConfigurable.addTemplate(TemplateSettings.readTemplateFromElement(group.getName(), templateElement, getClass().getClassLoader())); } } - catch (JDOMException ignore) { } - catch (IOException ignore) { } + catch (JDOMException ignore) { + } + catch (IOException ignore) { + } } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateContext.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateContext.java index 24d085ea928c..98c20d4b69df 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateContext.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ package com.intellij.codeInsight.template.impl; import com.intellij.codeInsight.template.EverywhereContextType; import com.intellij.codeInsight.template.TemplateContextType; -import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; import com.intellij.util.containers.ContainerUtil; import org.jdom.Element; @@ -27,7 +26,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashMap; -import java.util.List; import java.util.Map; public class TemplateContext { @@ -103,16 +101,12 @@ public class TemplateContext { } // used during initialization => no sync - void readTemplateContext(Element element) throws InvalidDataException { - List options = element.getChildren("option"); - for (Object e : options) { - if (e instanceof Element) { - Element option = (Element)e; - String name = option.getAttributeValue("name"); - String value = option.getAttributeValue("value"); - if (name != null && value != null) { - myContextStates.put(name, Boolean.parseBoolean(value)); - } + void readTemplateContext(Element element) { + for (Element option : element.getChildren("option")) { + String name = option.getAttributeValue("name"); + String value = option.getAttributeValue("value"); + if (name != null && value != null) { + myContextStates.put(name, Boolean.parseBoolean(value)); } } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java index c1498426fe8c..397e3c309f90 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java @@ -55,7 +55,7 @@ public class TemplateSettings implements PersistentStateComponent myDefaultTemplates = new LinkedHashMap(); private int myMaxKeyLength = 0; - private final SchemesManager mySchemesManager; + private final SchemesManager mySchemeManager; private State myState = new State(); @@ -184,7 +184,7 @@ public class TemplateSettings implements PersistentStateComponent() { + mySchemeManager = schemesManagerFactory.create(TEMPLATES_DIR_PATH, new BaseSchemeProcessor() { @Nullable @Override public TemplateGroup readScheme(@NotNull Element element) throws InvalidDataException { @@ -241,7 +241,7 @@ public class TemplateSettings implements PersistentStateComponent getTemplateGroups() { - return mySchemesManager.getAllSchemes(); + return mySchemeManager.getAllSchemes(); } public List collectMatchingCandidates(String key, @Nullable Character shortcutChar, boolean hasArgument) { From 0615f020e7662415f2a426ff534cf67f484dcb94 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 9 Sep 2015 15:56:20 +0200 Subject: [PATCH 100/138] =?UTF-8?q?move=20from=20api=20to=20lang-impl=20?= =?UTF-8?q?=E2=80=94=20no=20external=20users,=20deprecated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/com/intellij/openapi/options/CompoundScheme.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename platform/{platform-api => lang-impl}/src/com/intellij/openapi/options/CompoundScheme.java (100%) diff --git a/platform/platform-api/src/com/intellij/openapi/options/CompoundScheme.java b/platform/lang-impl/src/com/intellij/openapi/options/CompoundScheme.java similarity index 100% rename from platform/platform-api/src/com/intellij/openapi/options/CompoundScheme.java rename to platform/lang-impl/src/com/intellij/openapi/options/CompoundScheme.java From a0d242391f228a5c595c70b99dccfe104531a8a8 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 9 Sep 2015 16:08:27 +0200 Subject: [PATCH 101/138] cleanup --- .../codeInsight/template/impl/TemplateGroup.java | 4 +--- .../com/intellij/openapi/options/CompoundScheme.java | 10 +++------- .../lang-impl/src/com/intellij/tools/ToolsGroup.java | 12 +++++++++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateGroup.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateGroup.java index e86ac895ea47..eb81b6ca6d6d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateGroup.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateGroup.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,14 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.codeInsight.template.impl; import com.intellij.openapi.options.CompoundScheme; import org.jetbrains.annotations.Nullable; public class TemplateGroup extends CompoundScheme { - private final String myReplace; public TemplateGroup(final String name) { diff --git a/platform/lang-impl/src/com/intellij/openapi/options/CompoundScheme.java b/platform/lang-impl/src/com/intellij/openapi/options/CompoundScheme.java index c6ea9f7de2b0..a2715ef61ca1 100644 --- a/platform/lang-impl/src/com/intellij/openapi/options/CompoundScheme.java +++ b/platform/lang-impl/src/com/intellij/openapi/options/CompoundScheme.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.options; +import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import java.lang.reflect.Constructor; @@ -24,7 +25,7 @@ import java.util.Iterator; import java.util.List; public class CompoundScheme extends ExternalizableSchemeAdapter { - private final List myElements = new ArrayList(); + protected final List myElements = new SmartList(); public CompoundScheme(final String name) { myName = name; @@ -36,12 +37,7 @@ public class CompoundScheme extends ExternalizableSchem } } - public void insertElement(T element, final int i) { - if (!contains(element)) { - myElements.add(i, element); - } - } - + @NotNull public List getElements() { return Collections.unmodifiableList(new ArrayList(myElements)); } diff --git a/platform/lang-impl/src/com/intellij/tools/ToolsGroup.java b/platform/lang-impl/src/com/intellij/tools/ToolsGroup.java index 0a4254ad1d5d..5b69cc05be97 100644 --- a/platform/lang-impl/src/com/intellij/tools/ToolsGroup.java +++ b/platform/lang-impl/src/com/intellij/tools/ToolsGroup.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,14 +24,20 @@ public class ToolsGroup extends CompoundScheme { } public void moveElementUp(final T tool) { - int index = getElements().indexOf(tool); + int index = myElements.indexOf(tool); removeElement(tool); insertElement(tool, index - 1); } public void moveElementDown(final T tool) { - int index = getElements().indexOf(tool); + int index = myElements.indexOf(tool); removeElement(tool); insertElement(tool, index + 1); } + + public void insertElement(T element, final int i) { + if (!contains(element)) { + myElements.add(i, element); + } + } } From de14af00a036e614704e1a9d28e64796440afa6d Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 9 Sep 2015 16:21:18 +0200 Subject: [PATCH 102/138] =?UTF-8?q?preserve=20scheme=20indentity=20?= =?UTF-8?q?=E2=80=94=20reuse=20old=20instance=20(required=20for=20scheme?= =?UTF-8?q?=20manager)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../template/impl/TemplateImpl.java | 3 +- .../template/impl/TemplateListPanel.java | 22 ++-- .../openapi/options/CompoundScheme.java | 105 ++++++++++++++---- .../com/intellij/tools/BaseToolsPanel.java | 27 ++--- .../src/com/intellij/tools/Tool.java | 3 +- .../openapi/options/SchemeElement.java | 5 +- 6 files changed, 113 insertions(+), 52 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImpl.java index 964cba3df726..8cafa29d13e8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -172,6 +172,7 @@ public class TemplateImpl extends Template implements SchemeElement { return myId; } + @NotNull @Override public TemplateImpl copy() { TemplateImpl template = new TemplateImpl(myKey, myString, myGroupName); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java index b5feef2ac32e..9dfe1501454d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.options.CompoundScheme; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.ui.*; @@ -88,6 +89,8 @@ public class TemplateListPanel extends JPanel implements Disposable { private LiveTemplateSettingsEditor myCurrentTemplateEditor; private final JLabel myEmptyCardLabel = new JLabel(); + private final CompoundScheme.MutatorHelper mutatorHelper = new CompoundScheme.MutatorHelper(); + public TemplateListPanel() { super(new BorderLayout()); @@ -173,10 +176,8 @@ public class TemplateListPanel extends JPanel implements Disposable { } } TemplateSettings templateSettings = TemplateSettings.getInstance(); - templateSettings.setTemplates(templateGroups); + templateSettings.setTemplates(mutatorHelper.apply(templateGroups)); templateSettings.setDefaultShortcutChar(myExpandByDefaultPanel.getSelectedChar()); - - reset(); } private final boolean isTest = ApplicationManager.getApplication().isUnitTestMode(); @@ -220,8 +221,8 @@ public class TemplateListPanel extends JPanel implements Disposable { return null; } - private static List collectTemplates(final List groups) { - ArrayList result = new ArrayList(); + private static List collectTemplates(@NotNull List groups) { + List result = new ArrayList(); for (TemplateGroup group : groups) { result.addAll(group.getElements()); } @@ -238,7 +239,7 @@ public class TemplateListPanel extends JPanel implements Disposable { return result; } - private String checkAreEqual(List originalGroup, List newGroup) { + private String checkAreEqual(@NotNull List originalGroup, @NotNull List newGroup) { if (originalGroup.size() != newGroup.size()) return "different sizes"; for (int i = 0; i < newGroup.size(); i++) { @@ -260,7 +261,7 @@ public class TemplateListPanel extends JPanel implements Disposable { return null; } - private boolean areOptionsEqual(final TemplateImpl newTemplate, final TemplateImpl originalTemplate) { + private boolean areOptionsEqual(@NotNull TemplateImpl newTemplate, @NotNull TemplateImpl originalTemplate) { Map templateOptions = getTemplateOptions(newTemplate); for (TemplateOptionalProcessor processor : templateOptions.keySet()) { if (processor.isEnabled(originalTemplate) != templateOptions.get(processor).booleanValue()) return false; @@ -272,7 +273,7 @@ public class TemplateListPanel extends JPanel implements Disposable { return myTemplateContext.get(newTemplate); } - private Map getTemplateOptions(final TemplateImpl newTemplate) { + private Map getTemplateOptions(@NotNull TemplateImpl newTemplate) { return myTemplateOptions.get(newTemplate); } @@ -922,8 +923,9 @@ public class TemplateListPanel extends JPanel implements Disposable { private void initTemplates(List groups, String lastSelectedGroup, String lastSelectedKey) { myTreeRoot.removeAllChildren(); myTemplateGroups.clear(); + mutatorHelper.clear(); for (TemplateGroup group : groups) { - myTemplateGroups.add((TemplateGroup)group.copy()); + myTemplateGroups.add(mutatorHelper.copy(group)); } for (TemplateGroup group : myTemplateGroups) { diff --git a/platform/lang-impl/src/com/intellij/openapi/options/CompoundScheme.java b/platform/lang-impl/src/com/intellij/openapi/options/CompoundScheme.java index a2715ef61ca1..dc07520f338f 100644 --- a/platform/lang-impl/src/com/intellij/openapi/options/CompoundScheme.java +++ b/platform/lang-impl/src/com/intellij/openapi/options/CompoundScheme.java @@ -15,7 +15,9 @@ */ package com.intellij.openapi.options; -import com.intellij.util.SmartList; +import com.intellij.util.containers.ContainerUtil; +import gnu.trove.THashMap; +import gnu.trove.TObjectObjectProcedure; import org.jetbrains.annotations.NotNull; import java.lang.reflect.Constructor; @@ -24,48 +26,55 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; -public class CompoundScheme extends ExternalizableSchemeAdapter { - protected final List myElements = new SmartList(); +public class CompoundScheme extends ExternalizableSchemeAdapter { + protected final ArrayList myElements = new ArrayList(); public CompoundScheme(final String name) { myName = name; } - public void addElement(T t) { + public final void addElement(E t) { if (!contains(t)) { myElements.add(t); } } @NotNull - public List getElements() { - return Collections.unmodifiableList(new ArrayList(myElements)); + public final List getElements() { + return Collections.unmodifiableList(new ArrayList(myElements)); } @Override - public void setName(@NotNull final String name) { + public final void setName(@NotNull final String name) { myName = name; - for (T template : myElements) { + for (E template : myElements) { template.setGroupName(name); } } - public void removeElement(final T template) { - for (Iterator templateIterator = myElements.iterator(); templateIterator.hasNext();) { - T t = templateIterator.next(); + public final void removeElement(final E template) { + for (Iterator templateIterator = myElements.iterator(); templateIterator.hasNext();) { + E t = templateIterator.next(); if (t.getKey() != null && t.getKey().equals(template.getKey())) { templateIterator.remove(); } } } - public boolean isEmpty() { + public final boolean isEmpty() { return myElements.isEmpty(); } - private CompoundScheme createNewInstance(final String name) { + @NotNull + private CompoundScheme createNewInstance(String name) { try { - Constructor constructor = getClass().getConstructor(String.class); + Constructor constructor = getClass().getConstructor(String.class); + try { + constructor.setAccessible(true); + } + catch (Exception ignored) { + } + //noinspection unchecked return constructor.newInstance(name); } catch (Exception e) { @@ -74,22 +83,70 @@ public class CompoundScheme extends ExternalizableSchem } @NotNull - public CompoundScheme copy() { - //noinspection unchecked - CompoundScheme result = createNewInstance(getName()); - for (T element : myElements) { - //noinspection unchecked - result.addElement((T)element.copy()); - } + CompoundScheme copy() { + CompoundScheme result = createNewInstance(getName()); + result.resetFrom(this); return result; } - public boolean contains(@NotNull T element) { - for (T t : myElements) { - if (t.getKey() != null && t.getKey().equals(element.getKey())) { + void resetFrom(@NotNull CompoundScheme template) { + myElements.clear(); + myElements.ensureCapacity(template.myElements.size()); + for (E element : template.myElements) { + //noinspection unchecked + myElements.add((E)element.copy()); + } + } + + public boolean contains(@NotNull E element) { + for (E t : myElements) { + String key = t.getKey(); + if (key != null && key.equals(element.getKey())) { return true; } } return false; } + + public static final class MutatorHelper, E extends SchemeElement> { + private final THashMap copiedToOriginal = new THashMap(ContainerUtil.identityStrategy()); + + @NotNull + public T copy(@NotNull T scheme) { + //noinspection unchecked + T copied = (T)scheme.copy(); + copiedToOriginal.put(copied, scheme); + return copied; + } + + @NotNull + public List apply(@NotNull final List copiedSchemes) { + copiedToOriginal.retainEntries(new TObjectObjectProcedure() { + @Override + public boolean execute(T copied, T original) { + return ContainerUtil.containsIdentity(copiedSchemes, copied); + } + }); + + List originals = new ArrayList(copiedSchemes.size()); + for (T copied : copiedSchemes) { + T original = copiedToOriginal.remove(copied); + if (original == null) { + //noinspection unchecked + original = (T)copied.copy(); + copiedToOriginal.put(copied, original); + } + else { + original.resetFrom(copied); + } + + originals.add(original); + } + return originals; + } + + public void clear() { + copiedToOriginal.clear(); + } + } } diff --git a/platform/lang-impl/src/com/intellij/tools/BaseToolsPanel.java b/platform/lang-impl/src/com/intellij/tools/BaseToolsPanel.java index 28a30c563162..2898f112e5a5 100644 --- a/platform/lang-impl/src/com/intellij/tools/BaseToolsPanel.java +++ b/platform/lang-impl/src/com/intellij/tools/BaseToolsPanel.java @@ -18,6 +18,7 @@ package com.intellij.tools; import com.intellij.CommonBundle; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.options.CompoundScheme; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; import com.intellij.ui.*; @@ -75,6 +76,8 @@ public abstract class BaseToolsPanel extends JPanel { private final AnActionButton myRemoveButton; private boolean myIsModified = false; + private final CompoundScheme.MutatorHelper, T> mutatorHelper = new CompoundScheme.MutatorHelper, T>(); + protected BaseToolsPanel() { myTree = new CheckboxTree( new CheckboxTree.CheckboxTreeCellRenderer() { @@ -198,8 +201,9 @@ public abstract class BaseToolsPanel extends JPanel { } public void reset() { - for (ToolsGroup group : getToolsGroups()) { - insertNewGroup((ToolsGroup)group.copy()); + mutatorHelper.clear(); + for (ToolsGroup group : getToolManager().getGroups()) { + insertNewGroup(mutatorHelper.copy(group)); } if ((getTreeRoot()).getChildCount() > 0) { @@ -219,20 +223,17 @@ public abstract class BaseToolsPanel extends JPanel { protected abstract BaseToolManager getToolManager(); - protected List> getToolsGroups() { - return getToolManager().getGroups(); - } - - private CheckedTreeNode insertNewGroup(@NotNull ToolsGroup groupCopy) { + @NotNull + private CheckedTreeNode insertNewGroup(@NotNull ToolsGroup groupCopy) { CheckedTreeNode groupNode = new CheckedTreeNode(groupCopy); getTreeRoot().add(groupNode); - for (Tool tool : groupCopy.getElements()) { + for (T tool : groupCopy.getElements()) { insertNewTool(groupNode, tool); } return groupNode; } - private CheckedTreeNode insertNewTool(final CheckedTreeNode groupNode, final Tool toolCopy) { + private CheckedTreeNode insertNewTool(@NotNull CheckedTreeNode groupNode, @NotNull Tool toolCopy) { CheckedTreeNode toolNode = new CheckedTreeNode(toolCopy); toolNode.setChecked(toolCopy.isEnabled()); ((ToolsGroup)groupNode.getUserObject()).addElement(toolCopy); @@ -246,14 +247,14 @@ public abstract class BaseToolsPanel extends JPanel { } public void apply() { - // unregister removed tools - getToolManager().setTools(getGroupList()); + getToolManager().setTools(mutatorHelper.apply(getGroupList())); myIsModified = false; } + @NotNull private List> getGroupList() { - List> result = new ArrayList>(); MutableTreeNode root = (MutableTreeNode)myTree.getModel().getRoot(); + List> result = new ArrayList>(root.getChildCount()); for (int i = 0; i < root.getChildCount(); i++) { final CheckedTreeNode node = (CheckedTreeNode)root.getChildAt(i); for (int j = 0; j < node.getChildCount(); j++) { @@ -313,7 +314,7 @@ public abstract class BaseToolsPanel extends JPanel { return dir.isAvailable(index, parent.getChildCount()); } - private void insertNewTool(final Tool newTool, boolean setSelection) { + private void insertNewTool(@NotNull Tool newTool, boolean setSelection) { CheckedTreeNode groupNode = findGroupNode(newTool.getGroup()); if (groupNode == null) { groupNode = insertNewGroup(new ToolsGroup(newTool.getGroup())); diff --git a/platform/lang-impl/src/com/intellij/tools/Tool.java b/platform/lang-impl/src/com/intellij/tools/Tool.java index 4e512989212f..fb85782906c6 100644 --- a/platform/lang-impl/src/com/intellij/tools/Tool.java +++ b/platform/lang-impl/src/com/intellij/tools/Tool.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -353,6 +353,7 @@ public class Tool implements SchemeElement { return getName(); } + @NotNull @Override public SchemeElement copy() { Tool copy = new Tool(); diff --git a/platform/platform-api/src/com/intellij/openapi/options/SchemeElement.java b/platform/platform-api/src/com/intellij/openapi/options/SchemeElement.java index 5720b7af38cd..3f390a34a88d 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/SchemeElement.java +++ b/platform/platform-api/src/com/intellij/openapi/options/SchemeElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,14 +15,13 @@ */ package com.intellij.openapi.options; - import org.jetbrains.annotations.NotNull; public interface SchemeElement { void setGroupName(@NotNull String name); - String getKey(); + @NotNull SchemeElement copy(); } From 804b1ead8bf8451aabecc31621116a3bba1ff560 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 10 Sep 2015 15:29:46 +0200 Subject: [PATCH 103/138] fix NPE in tests --- .../idea/maven/navigator/MavenProjectsNavigator.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigator.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigator.java index a66c6d841dcb..0e6c494a0296 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigator.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigator.java @@ -372,7 +372,9 @@ public class MavenProjectsNavigator extends MavenSimpleProjectComponent implemen private void scheduleStructureRequest(final Runnable r) { if (isUnitTestMode()) { - r.run(); + if (myStructure != null) { + r.run(); + } return; } From c247db8a510a50333504633bbf2ba8edc5a2eec4 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 10 Sep 2015 15:48:38 +0200 Subject: [PATCH 104/138] cleanup --- .../impl/HeavyIdeaTestFixtureImpl.java | 50 ++++++++----------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java index b728b74b0383..e83aa92d5170 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java @@ -45,13 +45,11 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.encoding.EncodingManager; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl; -import com.intellij.testFramework.EditorListenerTracker; -import com.intellij.testFramework.LightPlatformTestCase; -import com.intellij.testFramework.PlatformTestCase; -import com.intellij.testFramework.ThreadTracker; +import com.intellij.testFramework.*; import com.intellij.testFramework.builders.ModuleFixtureBuilder; import com.intellij.testFramework.fixtures.HeavyIdeaTestFixture; import com.intellij.util.PathUtil; +import com.intellij.util.ThrowableRunnable; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -71,9 +69,6 @@ import java.util.Set; * @author mike */ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixture { - - @NonNls private static final String PROJECT_FILE_SUFFIX = ProjectFileType.DOT_DEFAULT_EXTENSION; - private Project myProject; private final Set myFilesToDelete = new HashSet(); private IdeaTestApplication myApplication; @@ -140,38 +135,33 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu } - private void setUpProject() throws Exception { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { + private void setUpProject() { + EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { @Override - public void run() { - try { - File tempDirectory = FileUtil.createTempDirectory(myName, ""); - PlatformTestCase.synchronizeTempDirVfs(LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDirectory)); - myFilesToDelete.add(tempDirectory); + public void run() throws Throwable { + File tempDirectory = FileUtil.createTempDirectory(myName, ""); + PlatformTestCase.synchronizeTempDirVfs(LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDirectory)); + myFilesToDelete.add(tempDirectory); - File projectFile = new File(tempDirectory, myName + PROJECT_FILE_SUFFIX); + File projectFile = new File(tempDirectory, myName + ProjectFileType.DOT_DEFAULT_EXTENSION); - LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectFile); - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - new Throwable(projectFile.getPath()).printStackTrace(new PrintStream(buffer)); - myProject = PlatformTestCase.createProject(projectFile, buffer.toString()); - ProjectManagerEx.getInstanceEx().openTestProject(myProject); + LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectFile); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + new Throwable(projectFile.getPath()).printStackTrace(new PrintStream(buffer)); + myProject = PlatformTestCase.createProject(projectFile, buffer.toString()); + ProjectManagerEx.getInstanceEx().openTestProject(myProject); - for (ModuleFixtureBuilder moduleFixtureBuilder: myModuleFixtureBuilders) { - moduleFixtureBuilder.getFixture().setUp(); - } - - LightPlatformTestCase.clearUncommittedDocuments(myProject); - ((FileTypeManagerImpl)FileTypeManager.getInstance()).drainReDetectQueue(); - } - catch (Exception e) { - throw new RuntimeException(e); + for (ModuleFixtureBuilder moduleFixtureBuilder : myModuleFixtureBuilders) { + moduleFixtureBuilder.getFixture().setUp(); } + + LightPlatformTestCase.clearUncommittedDocuments(myProject); + ((FileTypeManagerImpl)FileTypeManager.getInstance()).drainReDetectQueue(); } }); } - private void initApplication() throws Exception { + private void initApplication() { myApplication = IdeaTestApplication.getInstance(); myApplication.setDataProvider(new MyDataProvider()); } From 26d9a040a6a2acb0d881d8ea631f9b641ab8e51b Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 10 Sep 2015 16:27:20 +0200 Subject: [PATCH 105/138] =?UTF-8?q?simplify=20=E2=80=94=20FIle=20is=20not?= =?UTF-8?q?=20requried,=20don't=20atttempt=20to=20get=20absolute=20path=20?= =?UTF-8?q?from=20passed=20path=20to=20newProject=20method,=20use=20it=20a?= =?UTF-8?q?s=20is=20(especially=20important=20for=20tests)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../openapi/project/impl/ProjectImpl.java | 8 ++++++-- .../openapi/project/impl/ProjectManagerImpl.java | 15 +++++++++------ .../psi/impl/PsiDocumentManagerImplTest.java | 4 ++-- .../intellij/testFramework/PlatformTestCase.java | 14 +++++++++++--- .../fixtures/impl/HeavyIdeaTestFixtureImpl.java | 8 +++----- .../com/intellij/testFramework/FixtureRule.kt | 11 ++++++----- 6 files changed, 37 insertions(+), 23 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java index ba37b449062f..c3684b90f236 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java @@ -42,7 +42,6 @@ import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.impl.FrameTitleBuilder; @@ -74,6 +73,11 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project private String myOldName; private final boolean myLight; + /** + * @param projectManager + * @param filePath System-independent path + * @param projectName + */ protected ProjectImpl(@NotNull ProjectManager projectManager, @NotNull String filePath, @Nullable String projectName) { @@ -87,7 +91,7 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project getPicoContainer().registerComponentInstance(Project.class, this); if (!isDefault()) { - getStateStore().setPath(FileUtilRt.toSystemIndependentName(filePath)); + getStateStore().setPath(filePath); } myProjectManager = projectManager; diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java index a854bedf87fe..e5ddd35354c1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -43,6 +43,7 @@ import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.impl.local.FileWatcher; @@ -234,11 +235,13 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable { } } - private ProjectImpl createProject(@Nullable String projectName, - @NotNull String filePath, - boolean isDefault) { - return isDefault ? new DefaultProject(this, "") - : new ProjectImpl(this, new File(filePath).getAbsolutePath(), projectName); + private ProjectImpl createProject(@Nullable String projectName, @NotNull String filePath, boolean isDefault) { + if (isDefault) { + return new DefaultProject(this, ""); + } + else { + return new ProjectImpl(this, FileUtilRt.toSystemIndependentName(filePath), projectName); + } } private static void scheduleDispose(@NotNull final ProjectImpl project) { @@ -265,7 +268,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable { @Nullable public Project loadProject(@NotNull String filePath) throws IOException { try { - ProjectImpl project = createProject(null, filePath, false); + ProjectImpl project = createProject(null, new File(filePath).getAbsolutePath(), false); initProject(project, null); return project; } diff --git a/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java b/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java index de66bb0dd321..c03cad6488f7 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java +++ b/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java @@ -226,7 +226,7 @@ public class PsiDocumentManagerImplTest extends PlatformTestCase { final Document document = getPsiDocumentManager().getDocument(file); File temp = createTempDirectory(); - final Project alienProject = createProject(new File(temp, "alien.ipr"), DebugUtil.currentStackTrace()); + final Project alienProject = createProject(temp + "/alien.ipr", DebugUtil.currentStackTrace()); boolean succ2 = ProjectManagerEx.getInstanceEx().openProject(alienProject); assertTrue(succ2); UIUtil.dispatchAllInvocationEvents(); // startup activities @@ -368,7 +368,7 @@ public class PsiDocumentManagerImplTest extends PlatformTestCase { final Document document = getPsiDocumentManager().getDocument(file); File temp = createTempDirectory(); - final Project alienProject = createProject(new File(temp, "alien.ipr"), DebugUtil.currentStackTrace()); + final Project alienProject = createProject(temp + "/alien.ipr", DebugUtil.currentStackTrace()); boolean succ2 = ProjectManagerEx.getInstanceEx().openProject(alienProject); assertTrue(succ2); UIUtil.dispatchAllInvocationEvents(); // startup activities diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 5ae21f15b5b6..3df5674b1894 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -66,6 +66,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.impl.DocumentCommitThread; import com.intellij.psi.impl.PsiManagerImpl; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl; +import com.intellij.util.PathUtilRt; import com.intellij.util.PlatformUtils; import com.intellij.util.indexing.IndexableSetContributor; import com.intellij.util.indexing.IndexedRootsProvider; @@ -252,17 +253,24 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } @NotNull - public static Project createProject(@NotNull File projectFile, @NotNull String creationPlace) { + public static Project createProject(File projectFile, String creationPlace) { + return createProject(projectFile.getPath(), creationPlace); + } + + @NotNull + public static Project createProject(@NotNull String path, String creationPlace) { VirtualFile projectBase = LocalFileSystem.getInstance().findFileByIoFile(projectFile.getName().endsWith( - ProjectFileType.DOT_DEFAULT_EXTENSION) ? projectFile.getParentFile() : projectFile); + ProjectFileType.DOT_DEFAULT_EXTENSION) ? projectFile.getParentFile() : projectFile); if (projectBase != null) { // must be leftovers from the previous test run for (VirtualFile file : ((NewVirtualFile)projectBase).iterInDbChildren()) { delete(file); } } + try { - Project project = ProjectManagerEx.getInstanceEx().newProject(FileUtil.getNameWithoutExtension(projectFile), projectFile.getPath(), false, false); + Project project = + ProjectManagerEx.getInstanceEx().newProject(FileUtilRt.getNameWithoutExtension(PathUtilRt.getFileName(path)), path, false, false); assert project != null; project.putUserData(CREATION_PLACE, creationPlace); diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java index e83aa92d5170..80ad5f8b8f5e 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java @@ -143,12 +143,10 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu PlatformTestCase.synchronizeTempDirVfs(LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDirectory)); myFilesToDelete.add(tempDirectory); - File projectFile = new File(tempDirectory, myName + ProjectFileType.DOT_DEFAULT_EXTENSION); - - LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectFile); + String projectPath = FileUtil.toSystemIndependentName(tempDirectory.getPath()) + "/" + myName + ProjectFileType.DOT_DEFAULT_EXTENSION; ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - new Throwable(projectFile.getPath()).printStackTrace(new PrintStream(buffer)); - myProject = PlatformTestCase.createProject(projectFile, buffer.toString()); + new Throwable(projectPath).printStackTrace(new PrintStream(buffer)); + myProject = PlatformTestCase.createProject(projectPath, buffer.toString()); ProjectManagerEx.getInstanceEx().openTestProject(myProject); for (ModuleFixtureBuilder moduleFixtureBuilder : myModuleFixtureBuilders) { diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt b/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt index e873d6f1e0dc..90a787fdbbcc 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt +++ b/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt @@ -30,7 +30,6 @@ import com.intellij.openapi.project.ex.ProjectEx import com.intellij.openapi.project.ex.ProjectManagerEx import com.intellij.openapi.project.impl.ProjectManagerImpl import com.intellij.openapi.util.Disposer -import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS @@ -48,6 +47,7 @@ import java.lang.annotation.ElementType import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy import java.lang.annotation.Target +import java.nio.file.Files import java.util.concurrent.atomic.AtomicBoolean /** @@ -66,18 +66,19 @@ public class ProjectRule() : ExternalResource() { private fun createLightProject(): ProjectEx { (PersistentFS.getInstance() as PersistentFSImpl).cleanPersistedContents() - val projectFile = generateTemporaryPath("light_temp_shared_project${ProjectFileType.DOT_DEFAULT_EXTENSION}").toFile() + val projectFile = generateTemporaryPath("light_temp_shared_project${ProjectFileType.DOT_DEFAULT_EXTENSION}") + val projectPath = projectFile.systemIndependentPath val buffer = ByteArrayOutputStream() - java.lang.Throwable(projectFile.path).printStackTrace(PrintStream(buffer)) + java.lang.Throwable(projectPath).printStackTrace(PrintStream(buffer)) - val project = PlatformTestCase.createProject(projectFile, "Light project: $buffer") as ProjectEx + val project = PlatformTestCase.createProject(projectPath, "Light project: $buffer") as ProjectEx Disposer.register(ApplicationManager.getApplication(), Disposable { try { disposeProject() } finally { - FileUtil.delete(projectFile) + Files.deleteIfExists(projectFile) } }) From 08fc9d2d3bb68b3b6e1c0e2ccbf6abf81d7388ce Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 11 Sep 2015 12:49:43 +0200 Subject: [PATCH 106/138] simplify, add logging to investigate "@NotNull method com/jetbrains/javascript/debugger/GlobalEvaluator$1.getEvaluateContext must not return null" --- .../backend/src/org/jetbrains/debugger/Vm.kt | 4 ++-- .../backend/src/org/jetbrains/debugger/VmBase.kt | 11 ++--------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/Vm.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/Vm.kt index cabd52952ea5..5476b51bcae9 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/Vm.kt +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/Vm.kt @@ -29,6 +29,8 @@ public interface Vm { public val attachStateManager: AttachStateManager + public val evaluateContext: EvaluateContext? + public fun getScriptManager(): ScriptManager public fun getBreakpointManager(): BreakpointManager @@ -39,6 +41,4 @@ public interface Vm { * Controls whether VM stops on exceptions */ public fun setBreakOnException(catchMode: ExceptionCatchMode): Promise<*> - - public fun getEvaluateContext(): EvaluateContext? } \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/VmBase.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/VmBase.kt index 8cba8e08bc33..ebfd940479b2 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/VmBase.kt +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/VmBase.kt @@ -15,20 +15,13 @@ */ package org.jetbrains.debugger -import org.jetbrains.util.concurrency.Promise +import kotlin.properties.Delegates public abstract class VmBase protected constructor(override val debugListener: DebugEventListener) : Vm, AttachStateManager { - private var evaluateContext: EvaluateContext? = null + override val evaluateContext: EvaluateContext? by Delegates.lazy { computeEvaluateContext() } override val attachStateManager: AttachStateManager get() = this - override synchronized fun getEvaluateContext(): EvaluateContext? { - if (evaluateContext == null) { - evaluateContext = computeEvaluateContext() - } - return evaluateContext - } - protected open fun computeEvaluateContext(): EvaluateContext? = null } \ No newline at end of file From 8e8731a3a4e92a882433899320ebcfc47b0d35b0 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 11 Sep 2015 12:58:59 +0200 Subject: [PATCH 107/138] fix "Must not start write action from within read action in the other thread - deadlock is coming" Write action is not required here --- .../xpath/xslt/quickfix/DownloadManager.java | 39 +++++++------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/quickfix/DownloadManager.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/quickfix/DownloadManager.java index d448c4f4562d..6ca2bdd84a6e 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/quickfix/DownloadManager.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/quickfix/DownloadManager.java @@ -18,8 +18,6 @@ package org.intellij.lang.xpath.xslt.quickfix; import com.intellij.javaee.ExternalResourceManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.application.Result; -import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; @@ -73,31 +71,24 @@ public abstract class DownloadManager { }); try { - final File _file = file; //noinspection unchecked final Set[] resourceDependencies = new Set[1]; - new WriteAction() { - @Override - protected void run(@NotNull Result result) throws Throwable { - final VirtualFile vf = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(_file); - if (vf != null) { - final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vf); - if (psiFile != null && isAccepted(psiFile)) { - resourceDependencies[0] = getResourceDependencies(psiFile); - resourceManager.addResource(location, _file.getAbsolutePath()); - } - else { - ApplicationManager.getApplication().invokeLater( - new Runnable() { - @Override - public void run() { - Messages.showErrorDialog(myProject, "Not a valid file: " + vf.getPresentableUrl(), "Download Problem"); - } - }, myProject.getDisposed()); - } - } + final VirtualFile vf = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file); + if (vf != null) { + PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vf); + if (psiFile != null && isAccepted(psiFile)) { + resourceDependencies[0] = getResourceDependencies(psiFile); + resourceManager.addResource(location, file.getAbsolutePath()); } - }.execute(); + else { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + Messages.showErrorDialog(myProject, "Not a valid file: " + vf.getPresentableUrl(), "Download Problem"); + } + }, myProject.getDisposed()); + } + } if (resourceDependencies[0] != null) { for (String s : resourceDependencies[0]) { From defa75cc6147e18a434c128ae8483569bb5251d9 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 11 Sep 2015 14:08:45 +0200 Subject: [PATCH 108/138] =?UTF-8?q?isRepositoryExists=20=E2=80=94=20don't?= =?UTF-8?q?=20create=20repository=20model=20automatically=20add=20shutdown?= =?UTF-8?q?=20hook=20"close=20repository"=20on=20repo=20creation,=20but=20?= =?UTF-8?q?not=20on=20repo=20manager=20init=20avoid=20repository=20model?= =?UTF-8?q?=20creation=20on=20sync=20action=20isEnabled=20call=20don't=20s?= =?UTF-8?q?how=20sync.done.message=20on=20error=20(typo)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/actions/SyncAction.kt | 6 +-- .../src/git/GitRepositoryManager.kt | 42 ++++++++++--------- plugins/settings-repository/src/git/commit.kt | 24 +++++++++-- plugins/settings-repository/src/git/pull.kt | 6 +-- 4 files changed, 48 insertions(+), 30 deletions(-) diff --git a/plugins/settings-repository/src/actions/SyncAction.kt b/plugins/settings-repository/src/actions/SyncAction.kt index e7f653ecfb05..0b6517b6f81a 100644 --- a/plugins/settings-repository/src/actions/SyncAction.kt +++ b/plugins/settings-repository/src/actions/SyncAction.kt @@ -26,7 +26,8 @@ val NOTIFICATION_GROUP = NotificationGroup.balloonGroup(PLUGIN_NAME) abstract class SyncAction(private val syncType: SyncType) : DumbAwareAction() { override fun update(e: AnActionEvent) { - e.getPresentation().setEnabledAndVisible(icsManager.repositoryManager.hasUpstream()) + val repositoryManager = icsManager.repositoryManager + e.getPresentation().setEnabledAndVisible(repositoryManager.isRepositoryExists() && repositoryManager.hasUpstream()) } override fun actionPerformed(event: AnActionEvent) { @@ -39,15 +40,14 @@ fun syncAndNotify(syncType: SyncType, project: Project?, notifyIfUpToDate: Boole if (icsManager.sync(syncType, project) == null && !notifyIfUpToDate) { return } + NOTIFICATION_GROUP.createNotification(IcsBundle.message("sync.done.message"), NotificationType.INFORMATION).notify(project) } catch (e: Exception) { LOG.warn(e) NOTIFICATION_GROUP.createNotification(IcsBundle.message("sync.rejected.title"), e.getMessage() ?: "Internal error", NotificationType.ERROR, null).notify(project) } - NOTIFICATION_GROUP.createNotification(IcsBundle.message("sync.done.message"), NotificationType.INFORMATION).notify(project) } -// we don't class MergeAction : SyncAction(SyncType.MERGE) class ResetToTheirsAction : SyncAction(SyncType.OVERWRITE_LOCAL) class ResetToMyAction : SyncAction(SyncType.OVERWRITE_REMOTE) diff --git a/plugins/settings-repository/src/git/GitRepositoryManager.kt b/plugins/settings-repository/src/git/GitRepositoryManager.kt index e63ca32c2e9a..58892c28c709 100644 --- a/plugins/settings-repository/src/git/GitRepositoryManager.kt +++ b/plugins/settings-repository/src/git/GitRepositoryManager.kt @@ -52,6 +52,9 @@ class GitRepositoryManager(private val credentialsStore: NotNullLazyValue): Boolean { - val addCommand = AddCommand(repository) + var addCommand: AddCommand? = null val toDelete = SmartList() - var added = false for ((oldPath, newPath) in pairs) { val old = File(dir, oldPath) if (!old.exists()) { @@ -252,8 +252,10 @@ class GitRepositoryManager(private val credentialsStore: NotNullLazyValue Date: Fri, 11 Sep 2015 14:16:22 +0200 Subject: [PATCH 109/138] wrap jgit NoRemoteRepositoryException to avoid log as error --- plugins/settings-repository/src/git/GitEx.kt | 31 +++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/plugins/settings-repository/src/git/GitEx.kt b/plugins/settings-repository/src/git/GitEx.kt index 5997a40eab20..1428ad659c17 100644 --- a/plugins/settings-repository/src/git/GitEx.kt +++ b/plugins/settings-repository/src/git/GitEx.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ package org.jetbrains.settingsRepository.git import com.intellij.openapi.progress.ProcessCanceledException @@ -29,7 +44,7 @@ import java.io.File import java.io.InputStream fun wrapIfNeedAndReThrow(e: TransportException) { - if (e.getStatus() == TransportException.Status.CANNOT_RESOLVE_REPO) { + if (e is org.eclipse.jgit.errors.NoRemoteRepositoryException || e.getStatus() == TransportException.Status.CANNOT_RESOLVE_REPO) { throw org.jetbrains.settingsRepository.NoRemoteRepositoryException(e) } @@ -47,10 +62,15 @@ fun wrapIfNeedAndReThrow(e: TransportException) { } fun Repository.fetch(remoteConfig: RemoteConfig, credentialsProvider: CredentialsProvider? = null, progressMonitor: ProgressMonitor? = null): FetchResult? { - val transport = Transport.open(this, remoteConfig) try { - transport.setCredentialsProvider(credentialsProvider) - return transport.fetch(progressMonitor ?: NullProgressMonitor.INSTANCE, null) + val transport = Transport.open(this, remoteConfig) + try { + transport.setCredentialsProvider(credentialsProvider) + return transport.fetch(progressMonitor ?: NullProgressMonitor.INSTANCE, null) + } + finally { + transport.close() + } } catch (e: TransportException) { val message = e.getMessage()!! @@ -63,9 +83,6 @@ fun Repository.fetch(remoteConfig: RemoteConfig, credentialsProvider: Credential wrapIfNeedAndReThrow(e) return null } - finally { - transport.close() - } } fun Repository.disableAutoCrLf(): Repository { From e847a251b21f8dbf0f632a15c1b3cc3775cf422c Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 11 Sep 2015 14:23:17 +0200 Subject: [PATCH 110/138] don't fix repository state on auto commit --- plugins/settings-repository/src/IcsManager.kt | 2 +- plugins/settings-repository/src/RepositoryManager.kt | 4 +++- plugins/settings-repository/src/git/GitRepositoryManager.kt | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/settings-repository/src/IcsManager.kt b/plugins/settings-repository/src/IcsManager.kt index a0d1aa62b99d..24f14902bb32 100644 --- a/plugins/settings-repository/src/IcsManager.kt +++ b/plugins/settings-repository/src/IcsManager.kt @@ -91,7 +91,7 @@ class IcsManager(dir: File) { ProgressManager.getInstance().run(object : Task.Backgroundable(null, IcsBundle.message("task.commit.title")) { override fun run(indicator: ProgressIndicator) { try { - repositoryManager.commit(indicator) + repositoryManager.commit(indicator, fixStateIfCannotCommit = false) } catch (e: Throwable) { LOG.error(e) diff --git a/plugins/settings-repository/src/RepositoryManager.kt b/plugins/settings-repository/src/RepositoryManager.kt index 6fa3f4410f10..16dcdab057d7 100644 --- a/plugins/settings-repository/src/RepositoryManager.kt +++ b/plugins/settings-repository/src/RepositoryManager.kt @@ -54,8 +54,10 @@ public interface RepositoryManager { * Not all implementations support progress indicator (will not be updated on progress). * * syncType will be passed if called before sync. + * + * If fixStateIfCannotCommit, repository state will be fixed before commit. */ - public fun commit(indicator: ProgressIndicator? = null, syncType: SyncType? = null): Boolean + public fun commit(indicator: ProgressIndicator? = null, syncType: SyncType? = null, fixStateIfCannotCommit: Boolean = true): Boolean public fun getAheadCommitsCount(): Int diff --git a/plugins/settings-repository/src/git/GitRepositoryManager.kt b/plugins/settings-repository/src/git/GitRepositoryManager.kt index 58892c28c709..363798b65246 100644 --- a/plugins/settings-repository/src/git/GitRepositoryManager.kt +++ b/plugins/settings-repository/src/git/GitRepositoryManager.kt @@ -120,11 +120,11 @@ class GitRepositoryManager(private val credentialsStore: NotNullLazyValue Date: Fri, 11 Sep 2015 19:50:07 +0200 Subject: [PATCH 111/138] =?UTF-8?q?call=20tearDown=20if=20setUp=20failed?= =?UTF-8?q?=20=E2=80=94=20avoid=20situation=20when=20one=20failed=20test?= =?UTF-8?q?=20breaks=20the=20whole=20run=20don't=20save=20project=20on=20c?= =?UTF-8?q?lose=20in=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../testSrc/ApplicationStoreTest.kt | 40 ++++-- .../openapi/project/ex/ProjectManagerEx.java | 5 +- .../project/impl/ProjectManagerImpl.java | 5 +- .../LightPlatformCodeInsightTestCase.java | 22 +-- .../testFramework/LightPlatformTestCase.java | 129 +++++++++--------- .../testFramework/PlatformTestCase.java | 72 ++++++---- .../testFramework/UsefulTestCase.java | 19 +-- .../fixtures/impl/BaseFixture.java | 4 +- .../impl/CodeInsightTestFixtureImpl.java | 53 +++---- .../impl/HeavyIdeaTestFixtureImpl.java | 66 ++++----- 10 files changed, 240 insertions(+), 175 deletions(-) diff --git a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt index 3b125e60db94..1c7682d53073 100644 --- a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt @@ -67,7 +67,7 @@ class ApplicationStoreTest { component.foo = "newValue" componentStore.save(SmartList()) - assertThat(streamProvider.data.get(RoamingType.DEFAULT)!!.get("proxy.xml")).isEqualTo("\n" + " \n" + " \n" + "") + assertThat(streamProvider.data.get(RoamingType.DEFAULT)!!.get("new.xml")).isEqualTo("\n" + " \n" + "") } @Test fun `load from stream provider`() { @@ -75,8 +75,8 @@ class ApplicationStoreTest { val streamProvider = MyStreamProvider() val map = THashMap() - val fileSpec = "proxy.xml" - map.put(fileSpec, "\n \n \n") + val fileSpec = "new.xml" + map.put(fileSpec, "\n \n") streamProvider.data.put(RoamingType.DEFAULT, map) componentStore.storageManager.streamProvider = streamProvider @@ -95,8 +95,8 @@ class ApplicationStoreTest { } private fun doRemoveDeprecatedStorageOnWrite(component: Foo) { - val oldFile = writeConfig("other.xml", "") - writeConfig("proxy.xml", "") + val oldFile = writeConfig("old.xml", "${createComponentData("old")}") + writeConfig("new.xml", "${createComponentData("new")}") testAppConfig.refreshVfs() @@ -109,6 +109,29 @@ class ApplicationStoreTest { assertThat(oldFile).doesNotExist() } + private fun createComponentData(foo: String) = """""" + + @Test fun `remove data from deprecated storage if another component data exists`() { + val data = createComponentData("new") + val oldFile = writeConfig("old.xml", """ + + ${createComponentData("old")} + """) + writeConfig("new.xml", "$data") + + testAppConfig.refreshVfs() + + val component = SeveralStoragesConfigured() + componentStore.initComponent(component, false) + assertThat(component.foo).isEqualTo("new") + + saveStore() + + assertThat(oldFile).hasContent(""" + +""") + } + @State(name = "A", storages = arrayOf(Storage(file = "a.xml"))) private open class A : PersistentStateComponent { data class State(@Attribute var foo: String = "", @Attribute var bar: String = "") @@ -209,10 +232,11 @@ class ApplicationStoreTest { } abstract class Foo { - public var foo: String = "defaultValue" + @Attribute + var foo = "defaultValue" } - @State(name = "HttpConfigurable", storages = arrayOf(Storage(file = "proxy.xml"), Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml", deprecated = true))) + @State(name = "A", storages = arrayOf(Storage(file = "new.xml"), Storage(file = StoragePathMacros.APP_CONFIG + "/old.xml", deprecated = true))) class SeveralStoragesConfigured : Foo(), PersistentStateComponent { override fun getState(): SeveralStoragesConfigured? { return this @@ -223,7 +247,7 @@ class ApplicationStoreTest { } } - @State(name = "HttpConfigurable", storages = arrayOf(Storage(file = "other.xml", deprecated = true), Storage(file = "${StoragePathMacros.APP_CONFIG}/proxy.xml"))) + @State(name = "A", storages = arrayOf(Storage(file = "old.xml", deprecated = true), Storage(file = "${StoragePathMacros.APP_CONFIG}/new.xml"))) class ActualStorageLast : Foo(), PersistentStateComponent { override fun getState() = this diff --git a/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectManagerEx.java b/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectManagerEx.java index 8abeb689ba4a..ed44bae8514c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectManagerEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectManagerEx.java @@ -56,7 +56,10 @@ public abstract class ProjectManagerEx extends ProjectManager { @TestOnly @NotNull - // returns remaining open test projects + /** + * Without save and "check can close". + * Returns remaining open test projects. + */ public abstract Collection closeTestProject(@NotNull Project project); // returns true on success diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java index e5ddd35354c1..e15b6450558b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -550,8 +550,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable { @TestOnly public Collection closeTestProject(@NotNull final Project project) { assert ApplicationManager.getApplication().isUnitTestMode(); - closeProject(project); - return Arrays.asList(getOpenProjects()); + closeProject(project, false, false, false); + Project[] projects = getOpenProjects(); + return projects.length == 0 ? Collections.emptyList() : Arrays.asList(projects); } @Override diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java index 7fafca562698..80d55e2251f8 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java @@ -268,16 +268,20 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest @Override protected void tearDown() throws Exception { - FileEditorManager editorManager = FileEditorManager.getInstance(getProject()); - VirtualFile[] openFiles = editorManager.getOpenFiles(); - for (VirtualFile openFile : openFiles) { - editorManager.closeFile(openFile); + try { + FileEditorManager editorManager = FileEditorManager.getInstance(getProject()); + VirtualFile[] openFiles = editorManager.getOpenFiles(); + for (VirtualFile openFile : openFiles) { + editorManager.closeFile(openFile); + } + deleteVFile(); + myEditor = null; + myFile = null; + myVFile = null; + } + finally { + super.tearDown(); } - deleteVFile(); - myEditor = null; - myFile = null; - myVFile = null; - super.tearDown(); } /** diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java index beed5a3a3145..97dc8dfb07b8 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java @@ -447,86 +447,93 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da Project project = getProject(); CodeStyleSettingsManager.getInstance(project).dropTemporarySettings(); List errors = checkForSettingsDamage(); - VirtualFilePointerManagerImpl filePointerManager = (VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance(); - doTearDown(project, ourApplication, true); - try { - super.tearDown(); + doTearDown(project, ourApplication, true); } finally { - myThreadTracker.checkLeak(); - InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project); - filePointerManager.assertPointersAreDisposed(); + try { + super.tearDown(); + } + finally { + myThreadTracker.checkLeak(); + InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project); + ((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).assertPointersAreDisposed(); + CompoundRuntimeException.doThrow(errors); + } } - CompoundRuntimeException.doThrow(errors); } public static void doTearDown(@NotNull final Project project, @NotNull IdeaTestApplication application, boolean checkForEditors) throws Exception { - ((FileTypeManagerImpl)FileTypeManager.getInstance()).drainReDetectQueue(); - DocumentCommitThread.getInstance().clearQueue(); - CodeStyleSettingsManager.getInstance(project).dropTemporarySettings(); - checkAllTimersAreDisposed(); - UsefulTestCase.doPostponedFormatting(project); + PsiDocumentManagerImpl documentManager; + try { + ((FileTypeManagerImpl)FileTypeManager.getInstance()).drainReDetectQueue(); + DocumentCommitThread.getInstance().clearQueue(); + CodeStyleSettingsManager.getInstance(project).dropTemporarySettings(); + checkAllTimersAreDisposed(); + UsefulTestCase.doPostponedFormatting(project); - LookupManager lookupManager = LookupManager.getInstance(project); - if (lookupManager != null) { - lookupManager.hideActiveLookup(); - } - ((StartupManagerImpl)StartupManager.getInstance(project)).prepareForNextTest(); - InspectionProfileManager.getInstance().deleteProfile(PROFILE); - assertNotNull("Application components damaged", ProjectManager.getInstance()); + LookupManager lookupManager = LookupManager.getInstance(project); + if (lookupManager != null) { + lookupManager.hideActiveLookup(); + } + ((StartupManagerImpl)StartupManager.getInstance(project)).prepareForNextTest(); + InspectionProfileManager.getInstance().deleteProfile(PROFILE); + assertNotNull("Application components damaged", ProjectManager.getInstance()); - new WriteCommandAction.Simple(project) { - @Override - protected void run() throws Throwable { - if (ourSourceRoot != null) { - try { - final VirtualFile[] children = ourSourceRoot.getChildren(); - for (VirtualFile child : children) { - child.delete(this); + new WriteCommandAction.Simple(project) { + @Override + protected void run() throws Throwable { + if (ourSourceRoot != null) { + try { + final VirtualFile[] children = ourSourceRoot.getChildren(); + for (VirtualFile child : children) { + child.delete(this); + } + } + catch (IOException e) { + //noinspection CallToPrintStackTrace + e.printStackTrace(); } } - catch (IOException e) { - //noinspection CallToPrintStackTrace - e.printStackTrace(); + EncodingManager encodingManager = EncodingManager.getInstance(); + if (encodingManager instanceof EncodingManagerImpl) ((EncodingManagerImpl)encodingManager).clearDocumentQueue(); + + FileDocumentManager manager = FileDocumentManager.getInstance(); + + ApplicationManager.getApplication().runWriteAction(EmptyRunnable.getInstance()); // Flush postponed formatting if any. + manager.saveAllDocuments(); + if (manager instanceof FileDocumentManagerImpl) { + ((FileDocumentManagerImpl)manager).dropAllUnsavedDocuments(); } } - EncodingManager encodingManager = EncodingManager.getInstance(); - if (encodingManager instanceof EncodingManagerImpl) ((EncodingManagerImpl)encodingManager).clearDocumentQueue(); + }.execute().throwException(); - FileDocumentManager manager = FileDocumentManager.getInstance(); - - ApplicationManager.getApplication().runWriteAction(EmptyRunnable.getInstance()); // Flush postponed formatting if any. - manager.saveAllDocuments(); - if (manager instanceof FileDocumentManagerImpl) { - ((FileDocumentManagerImpl)manager).dropAllUnsavedDocuments(); + assertFalse(PsiManager.getInstance(project).isDisposed()); + if (!ourAssertionsInTestDetected) { + if (IdeaLogger.ourErrorsOccurred != null) { + throw IdeaLogger.ourErrorsOccurred; } } - }.execute().throwException(); + documentManager = clearUncommittedDocuments(project); + ((HintManagerImpl)HintManager.getInstance()).cleanup(); + DocumentCommitThread.getInstance().clearQueue(); - assertFalse(PsiManager.getInstance(project).isDisposed()); - if (!ourAssertionsInTestDetected) { - if (IdeaLogger.ourErrorsOccurred != null) { - throw IdeaLogger.ourErrorsOccurred; - } + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + ((UndoManagerImpl)UndoManager.getGlobalInstance()).dropHistoryInTests(); + ((UndoManagerImpl)UndoManager.getInstance(project)).dropHistoryInTests(); + + UIUtil.dispatchAllInvocationEvents(); + } + }); + + TemplateDataLanguageMappings.getInstance(project).cleanupForNextTest(); + } + finally { + ProjectManagerEx.getInstanceEx().closeTestProject(project); } - PsiDocumentManagerImpl documentManager = clearUncommittedDocuments(project); - ((HintManagerImpl)HintManager.getInstance()).cleanup(); - DocumentCommitThread.getInstance().clearQueue(); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - ((UndoManagerImpl)UndoManager.getGlobalInstance()).dropHistoryInTests(); - ((UndoManagerImpl)UndoManager.getInstance(project)).dropHistoryInTests(); - - UIUtil.dispatchAllInvocationEvents(); - } - }); - - TemplateDataLanguageMappings.getInstance(project).cleanupForNextTest(); - - ProjectManagerEx.getInstanceEx().closeTestProject(project); application.setDataProvider(null); ourTestCase = null; ((PsiManagerImpl)PsiManager.getInstance(project)).cleanupForNextTest(); diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 3df5674b1894..099f8bcaad86 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -22,6 +22,7 @@ import com.intellij.idea.IdeaLogger; import com.intellij.idea.IdeaTestApplication; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; @@ -216,7 +217,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro UIUtil.dispatchAllInvocationEvents(); } - public Project getProject() { + public final Project getProject() { return myProject; } @@ -427,9 +428,11 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro @Override protected void tearDown() throws Exception { CompositeException result = new CompositeException(); - if (myProject != null) { + Project project = myProject; + if (project != null) { try { LightPlatformTestCase.doTearDown(getProject(), ourApplication, false); + disposeProject(result); } catch (Throwable e) { result.add(e); @@ -443,9 +446,6 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro result.add(e); } try { - Project project = getProject(); - disposeProject(result); - if (project != null) { try { InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project); @@ -520,39 +520,53 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro UIUtil.dispatchAllInvocationEvents(); } } - catch (Exception e) { + catch (Throwable e) { result.add(e); } + + Project project = myProject; + if (project == null) { + return; + } + + myProject = null; + closeAndDisposeProjectAndCheckThatNoOpenProjects(project, result); + } + + public static void closeAndDisposeProjectAndCheckThatNoOpenProjects(@NotNull Project projectToClose) throws CompositeException { + CompositeException compositeException = new CompositeException(); + closeAndDisposeProjectAndCheckThatNoOpenProjects(projectToClose, compositeException); + if (!compositeException.isEmpty()) { + throw compositeException; + } + } + + public static void closeAndDisposeProjectAndCheckThatNoOpenProjects(@NotNull Project projectToClose, @NotNull CompositeException result) { try { - if (myProject != null) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - ProjectManagerEx projectManager = ProjectManagerEx.getInstanceEx(); - if (projectManager instanceof ProjectManagerImpl) { - Collection projectsStillOpen = projectManager.closeTestProject(myProject); - if (!projectsStillOpen.isEmpty()) { - Project project = projectsStillOpen.iterator().next(); - String message = "Test project is not disposed: " + project + ";\n created in: " + getCreationPlace(project); - try { - projectManager.closeAndDispose(project); - } - catch (Exception e) { - // ignore, we already have something to throw - } - throw new AssertionError(message); - } - } - Disposer.dispose(myProject); + ProjectManagerEx projectManager = ProjectManagerEx.getInstanceEx(); + if (projectManager instanceof ProjectManagerImpl) { + for (Project project : projectManager.closeTestProject(projectToClose)) { + result.add(new IllegalStateException("Test project is not disposed: " + project + ";\n created in: " + getCreationPlace(project))); + try { + ((ProjectManagerImpl)projectManager).closeProject(project, false, true, false); } - }); + catch (Throwable e) { + result.add(e); + } + } } } - catch (Exception e) { + catch (Throwable e) { result.add(e); } finally { - myProject = null; + AccessToken token = WriteAction.start(); + try { + Disposer.dispose(projectToClose); + } + finally { + token.finish(); + } } } diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java index 923c32e39daf..adfba7e6ec13 100644 --- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java @@ -359,22 +359,25 @@ public abstract class UsefulTestCase extends TestCase { protected void defaultRunBare() throws Throwable { Throwable exception = null; - long setupStart = System.nanoTime(); - setUp(); - long setupCost = (System.nanoTime() - setupStart) / 1000000; - logPerClassCost(setupCost, TOTAL_SETUP_COST_MILLIS); - try { + long setupStart = System.nanoTime(); + setUp(); + long setupCost = (System.nanoTime() - setupStart) / 1000000; + logPerClassCost(setupCost, TOTAL_SETUP_COST_MILLIS); + runTest(); - } catch (Throwable running) { + } + catch (Throwable running) { exception = running; - } finally { + } + finally { try { long teardownStart = System.nanoTime(); tearDown(); long teardownCost = (System.nanoTime() - teardownStart) / 1000000; logPerClassCost(teardownCost, TOTAL_TEARDOWN_COST_MILLIS); - } catch (Throwable tearingDown) { + } + catch (Throwable tearingDown) { if (exception == null) exception = tearingDown; } } diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/BaseFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/BaseFixture.java index 2b6236a27a09..b8506d06e19d 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/BaseFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/BaseFixture.java @@ -17,9 +17,9 @@ package com.intellij.testFramework.fixtures.impl; import com.intellij.openapi.Disposable; import com.intellij.openapi.util.Disposer; +import com.intellij.testFramework.EdtTestUtil; import com.intellij.testFramework.UsefulTestCase; import com.intellij.testFramework.fixtures.IdeaTestFixture; -import com.intellij.util.ui.UIUtil; import org.junit.Assert; /** @@ -41,7 +41,7 @@ public class BaseFixture implements IdeaTestFixture { public void tearDown() throws Exception { Assert.assertTrue("setUp() has not been called", myInitialized); Assert.assertFalse("tearDown() already has been called", myDisposed); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { + EdtTestUtil.runInEdtAndWait(new Runnable() { @Override public void run() { Disposer.dispose(myTestRootDisposable); diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 02ffd6732a85..57006b629b31 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -1399,32 +1399,37 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig @Override public void tearDown() throws Exception { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(true); // return default value to avoid unnecessary save - FileEditorManager editorManager = FileEditorManager.getInstance(getProject()); - PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); - VirtualFile[] openFiles = editorManager.getOpenFiles(); - for (VirtualFile openFile : openFiles) { - editorManager.closeFile(openFile); - } + try { + EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { + @Override + public void run() throws Throwable { + try { + DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(true); // return default value to avoid unnecessary save + FileEditorManager editorManager = FileEditorManager.getInstance(getProject()); + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); + VirtualFile[] openFiles = editorManager.getOpenFiles(); + for (VirtualFile openFile : openFiles) { + editorManager.closeFile(openFile); + } + } + finally { + myEditor = null; + myFile = null; + myPsiManager = null; - myEditor = null; - myFile = null; - myPsiManager = null; - - try { - myProjectFixture.tearDown(); - myTempDirFixture.tearDown(); + try { + myProjectFixture.tearDown(); + } + finally { + myTempDirFixture.tearDown(); + } + } } - catch (Exception e) { - throw new RuntimeException(e); - } - } - }); - - super.tearDown(); + }); + } + finally { + super.tearDown(); + } } @NotNull diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java index 80ad5f8b8f5e..15712e9240fe 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java @@ -36,7 +36,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -50,7 +49,6 @@ import com.intellij.testFramework.builders.ModuleFixtureBuilder; import com.intellij.testFramework.fixtures.HeavyIdeaTestFixture; import com.intellij.util.PathUtil; import com.intellij.util.ThrowableRunnable; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -100,41 +98,47 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu @Override public void tearDown() throws Exception { - Project project = getProject(); - LightPlatformTestCase.doTearDown(project, myApplication, false); + final Project project = getProject(); + try { + LightPlatformTestCase.doTearDown(project, myApplication, false); - for (ModuleFixtureBuilder moduleFixtureBuilder : myModuleFixtureBuilders) { - moduleFixtureBuilder.getFixture().tearDown(); - } - - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - Disposer.dispose(myProject); - myProject = null; - } - }); + for (ModuleFixtureBuilder moduleFixtureBuilder : myModuleFixtureBuilders) { + moduleFixtureBuilder.getFixture().tearDown(); } - }); - for (final File fileToDelete : myFilesToDelete) { - boolean deleted = FileUtil.delete(fileToDelete); - Assert.assertTrue("Can't delete " + fileToDelete, deleted); + final CompositeException compositeException = new CompositeException(); + EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { + @Override + public void run() throws Throwable { + PlatformTestCase.closeAndDisposeProjectAndCheckThatNoOpenProjects(project, compositeException); + } + }); + myProject = null; + + for (File fileToDelete : myFilesToDelete) { + if (!FileUtil.delete(fileToDelete)) { + compositeException.add(new IOException("Can't delete " + fileToDelete)); + } + } + + if (!compositeException.isEmpty()) { + throw compositeException; + } + } + finally { + try { + super.tearDown(); + } + finally { + myEditorListenerTracker.checkListenersLeak(); + myThreadTracker.checkLeak(); + LightPlatformTestCase.checkEditorsReleased(); + PlatformTestCase.cleanupApplicationCaches(project); + InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project); + } } - - super.tearDown(); - - myEditorListenerTracker.checkListenersLeak(); - myThreadTracker.checkLeak(); - LightPlatformTestCase.checkEditorsReleased(); - PlatformTestCase.cleanupApplicationCaches(project); - InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project); } - private void setUpProject() { EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { @Override From 0286eee84336ff0785a11b7bedba670e945a4223 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Sat, 12 Sep 2015 11:50:41 +0200 Subject: [PATCH 112/138] =?UTF-8?q?project=20store=20=E2=80=94=20we=20don'?= =?UTF-8?q?t=20load=20default=20state=20in=20tests=20as=20app=20store=20do?= =?UTF-8?q?es=20because=201)=20we=20should=20not=20do=20it=20=202)=20it=20?= =?UTF-8?q?was=20so=20before,=20so,=20we=20preserve=20old=20behavior=20(ot?= =?UTF-8?q?herwise=20RunManager=20will=20load=20template=20run=20configura?= =?UTF-8?q?tions)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../intellij/execution/ConfigurationsTest.java | 17 ++++++++++++++++- .../src/ApplicationStoreImpl.kt | 5 +++-- .../src/ComponentStoreImpl.kt | 16 ++++++++++++---- .../src/DefaultProjectStoreImpl.kt | 5 +++-- .../src/ModuleStoreImpl.kt | 9 ++++----- .../src/ProjectStoreImpl.kt | 14 ++++++++------ 6 files changed, 46 insertions(+), 20 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/execution/ConfigurationsTest.java b/java/java-tests/testSrc/com/intellij/execution/ConfigurationsTest.java index 1aecb65638f9..39d4f6380f0f 100644 --- a/java/java-tests/testSrc/com/intellij/execution/ConfigurationsTest.java +++ b/java/java-tests/testSrc/com/intellij/execution/ConfigurationsTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ package com.intellij.execution; import com.intellij.execution.application.ApplicationConfigurable; @@ -135,7 +150,7 @@ public class ConfigurationsTest extends BaseConfigurationTestCase { PsiClass testA = findTestA(getModule1()); JUnitConfiguration configuration = createConfiguration(testA); JavaParameters parameters = checkCanRun(configuration); - CHECK.empty(parameters.getVMParametersList().getList()); + assertEmpty(parameters.getVMParametersList().getList()); final SegmentedOutputStream notifications = new SegmentedOutputStream(System.out); assertTrue(JUnitStarter.checkVersion(parameters.getProgramParametersList().getArray(), new PrintStream(notifications))); diff --git a/platform/configuration-store-impl/src/ApplicationStoreImpl.kt b/platform/configuration-store-impl/src/ApplicationStoreImpl.kt index 1b3a19d0dda8..e3f7c89d51a1 100644 --- a/platform/configuration-store-impl/src/ApplicationStoreImpl.kt +++ b/platform/configuration-store-impl/src/ApplicationStoreImpl.kt @@ -37,8 +37,9 @@ class ApplicationPathMacroManager : BasePathMacroManager(null) class ApplicationStoreImpl(private val application: Application, pathMacroManager: PathMacroManager) : ComponentStoreImpl() { override val storageManager = ApplicationStorageManager(application, pathMacroManager) - override val isLoadComponentState: Boolean - get() = !application.isUnitTestMode() + // number of app components require some state, so, we load default state in test mode + override val loadPolicy: StateLoadPolicy + get() = if (application.isUnitTestMode()) StateLoadPolicy.LOAD_ONLY_DEFAULT else StateLoadPolicy.LOAD override fun setPath(path: String) { storageManager.addMacro(ROOT_CONFIG, path) diff --git a/platform/configuration-store-impl/src/ComponentStoreImpl.kt b/platform/configuration-store-impl/src/ComponentStoreImpl.kt index 0184580eb18c..1ed883a1dd28 100644 --- a/platform/configuration-store-impl/src/ComponentStoreImpl.kt +++ b/platform/configuration-store-impl/src/ComponentStoreImpl.kt @@ -61,8 +61,8 @@ abstract class ComponentStoreImpl : IComponentStore { protected open val project: Project? get() = null - open val isLoadComponentState: Boolean - get() = true + open val loadPolicy: StateLoadPolicy + get() = StateLoadPolicy.LOAD abstract val storageManager: StateStorageManager @@ -199,7 +199,7 @@ abstract class ComponentStoreImpl : IComponentStore { val componentName = ComponentManagerImpl.getComponentName(component) doAddComponent(componentName, component) - if (!isLoadComponentState) { + if (loadPolicy != StateLoadPolicy.LOAD) { return null } @@ -230,6 +230,10 @@ abstract class ComponentStoreImpl : IComponentStore { } private fun initPersistentComponent(stateSpec: State, component: PersistentStateComponent, changedStorages: Set?, reloadData: Boolean): String? { + if (loadPolicy == StateLoadPolicy.NOT_LOAD) { + return null + } + val name = stateSpec.name val stateClass = ComponentSerializationUtil.getStateClass(component.javaClass) if (!stateSpec.defaultStateAsResource && LOG.isDebugEnabled() && getDefaultState(component, name, stateClass) != null) { @@ -237,7 +241,7 @@ abstract class ComponentStoreImpl : IComponentStore { } val defaultState = if (stateSpec.defaultStateAsResource) getDefaultState(component, name, stateClass) else null - if (isLoadComponentState) { + if (loadPolicy == StateLoadPolicy.LOAD) { val storageSpecs = getStorageSpecs(component, stateSpec, StateStorageOperation.READ) val storageChooser = component as? StateStorageChooserEx for (storageSpec in storageSpecs) { @@ -456,4 +460,8 @@ abstract class ComponentStoreImpl : IComponentStore { return errors } } +} + +enum class StateLoadPolicy { + LOAD, LOAD_ONLY_DEFAULT, NOT_LOAD } \ No newline at end of file diff --git a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt index f8cb55a1103c..11f74ad2a33f 100644 --- a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt @@ -30,8 +30,9 @@ class DefaultProjectStoreImpl(override val project: ProjectImpl, private val pat val FILE_SPEC = "${StoragePathMacros.APP_CONFIG}/project.default.xml" } - override val isLoadComponentState: Boolean - get() = !ApplicationManager.getApplication().isUnitTestMode() + // see note about default state in project store + override val loadPolicy: StateLoadPolicy + get() = if (ApplicationManager.getApplication().isUnitTestMode()) StateLoadPolicy.NOT_LOAD else StateLoadPolicy.LOAD init { service().project = project diff --git a/platform/configuration-store-impl/src/ModuleStoreImpl.kt b/platform/configuration-store-impl/src/ModuleStoreImpl.kt index 6d7ac4bc1f55..6d3258086673 100644 --- a/platform/configuration-store-impl/src/ModuleStoreImpl.kt +++ b/platform/configuration-store-impl/src/ModuleStoreImpl.kt @@ -19,7 +19,6 @@ import com.intellij.openapi.components.PathMacroManager import com.intellij.openapi.components.StoragePathMacros import com.intellij.openapi.components.stateStore import com.intellij.openapi.module.Module -import com.intellij.util.ThreeState import java.io.File open private class ModuleStoreImpl(module: Module, private val pathMacroManager: PathMacroManager) : ComponentStoreImpl() { @@ -37,16 +36,16 @@ open private class ModuleStoreImpl(module: Module, private val pathMacroManager: } private class TestModuleStore(module: Module, pathMacroManager: PathMacroManager) : ModuleStoreImpl(module, pathMacroManager) { - private var isLoadModuleComponentState = ThreeState.UNSURE + private var moduleComponentLoadPolicy: StateLoadPolicy? = null override fun setPath(path: String) { super.setPath(path) if (File(path).exists()) { - isLoadModuleComponentState = ThreeState.YES + moduleComponentLoadPolicy = StateLoadPolicy.LOAD } } - override val isLoadComponentState: Boolean - get() = if (isLoadModuleComponentState == ThreeState.UNSURE) (project.stateStore as ProjectStoreImpl).isLoadComponentState else isLoadModuleComponentState.toBoolean() + override val loadPolicy: StateLoadPolicy + get() = moduleComponentLoadPolicy ?: (project.stateStore as ProjectStoreImpl).loadPolicy } \ No newline at end of file diff --git a/platform/configuration-store-impl/src/ProjectStoreImpl.kt b/platform/configuration-store-impl/src/ProjectStoreImpl.kt index 4bbd82b22556..e1451172af55 100644 --- a/platform/configuration-store-impl/src/ProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/ProjectStoreImpl.kt @@ -51,16 +51,19 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM private var presentableUrl: String? = null - override var isLoadComponentState = true + override var loadPolicy = StateLoadPolicy.LOAD init { assert(!project.isDefault()) } - override final fun isOptimiseTestLoadSpeed() = !isLoadComponentState + override final fun isOptimiseTestLoadSpeed() = loadPolicy != StateLoadPolicy.LOAD override final fun setOptimiseTestLoadSpeed(value: Boolean) { - isLoadComponentState = !value + // we don't load default state in tests as app store does because + // 1) we should not do it + // 2) it was so before, so, we preserve old behavior (otherwise RunManager will load template run configurations) + loadPolicy = if (value) StateLoadPolicy.NOT_LOAD else StateLoadPolicy.LOAD } override final fun getPathMacroManagerForDefaults() = pathMacroManager @@ -84,7 +87,7 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM if (ApplicationManager.getApplication().isUnitTestMode()) { // load state only if there are existing files - isLoadComponentState = File(filePath).exists() + setOptimiseTestLoadSpeed(!File(filePath).exists()) } } else { @@ -106,7 +109,7 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM if (ApplicationManager.getApplication().isUnitTestMode()) { // load state only if there are existing files - isLoadComponentState = dirStore.exists() + setOptimiseTestLoadSpeed(!dirStore.exists()) } } @@ -147,7 +150,6 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM } catch (ignored: IOException) { } - } } From 21358d6331a1d592183a6f1a93494745fcb52564 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Sat, 12 Sep 2015 12:11:48 +0200 Subject: [PATCH 113/138] fix MultipleJdksMoveClassTest an FileTemplatesTest --- .../MultipleJdksMoveClassTest.java | 23 ++++--------------- .../intellij/testFramework/PsiTestCase.java | 14 +++++++---- .../testFramework/PlatformTestCase.java | 5 +++- 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MultipleJdksMoveClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MultipleJdksMoveClassTest.java index e88d816cd7b2..b2e9b9e190a8 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/MultipleJdksMoveClassTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/MultipleJdksMoveClassTest.java @@ -16,36 +16,23 @@ package com.intellij.refactoring; -import com.intellij.JavaTestUtil; import com.intellij.openapi.application.ex.PathManagerEx; -import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtil; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootModificationUtil; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtilCore; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.pom.java.LanguageLevel; -import com.intellij.psi.*; -import com.intellij.psi.impl.source.PostprocessReformattingAspect; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor; -import com.intellij.refactoring.move.moveClassesOrPackages.SingleSourceRootMoveDestination; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.refactoring.util.RefactoringConflictsUtil; -import com.intellij.testFramework.*; +import com.intellij.testFramework.IdeaTestUtil; +import com.intellij.testFramework.UsefulTestCase; import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; import com.intellij.testFramework.fixtures.*; import com.intellij.usageView.UsageInfo; -import com.intellij.util.Consumer; import com.intellij.util.containers.MultiMap; -import org.jetbrains.annotations.NonNls; -import java.io.File; import java.util.Collections; -public class MultipleJdksMoveClassTest extends RefactoringTestCase { - +public class MultipleJdksMoveClassTest extends UsefulTestCase { private CodeInsightTestFixture myFixture; private Module myJava7Module; private Module myJava8Module; diff --git a/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java b/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java index d78c00776528..26153fac55c5 100644 --- a/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java +++ b/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java @@ -62,11 +62,15 @@ public abstract class PsiTestCase extends ModuleTestCase { @Override protected void tearDown() throws Exception { - myPsiManager = null; - myFile = null; - myTestDataBefore = null; - myTestDataAfter = null; - super.tearDown(); + try { + myPsiManager = null; + myFile = null; + myTestDataBefore = null; + myTestDataAfter = null; + } + finally { + super.tearDown(); + } } @NotNull diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 099f8bcaad86..09ae67610659 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -529,8 +529,8 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro return; } - myProject = null; closeAndDisposeProjectAndCheckThatNoOpenProjects(project, result); + myProject = null; } public static void closeAndDisposeProjectAndCheckThatNoOpenProjects(@NotNull Project projectToClose) throws CompositeException { @@ -564,6 +564,9 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro try { Disposer.dispose(projectToClose); } + catch (Throwable e) { + result.add(e); + } finally { token.finish(); } From cdccaf4ddf2fe3b73790a0a91bb4619f356bf519 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 18 Sep 2015 13:49:52 +0200 Subject: [PATCH 114/138] cleanup --- .../src/ComponentStoreImpl.kt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/platform/configuration-store-impl/src/ComponentStoreImpl.kt b/platform/configuration-store-impl/src/ComponentStoreImpl.kt index 1ed883a1dd28..27d6e4abaf6b 100644 --- a/platform/configuration-store-impl/src/ComponentStoreImpl.kt +++ b/platform/configuration-store-impl/src/ComponentStoreImpl.kt @@ -31,7 +31,10 @@ import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.project.Project import com.intellij.openapi.util -import com.intellij.openapi.util.* +import com.intellij.openapi.util.InvalidDataException +import com.intellij.openapi.util.JDOMExternalizable +import com.intellij.openapi.util.JDOMUtil +import com.intellij.openapi.util.NamedJDOMExternalizable import com.intellij.openapi.util.registry.Registry import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess @@ -46,7 +49,10 @@ import org.jdom.Element import org.jetbrains.annotations.TestOnly import java.io.File import java.io.IOException -import java.util.* +import java.util.Arrays +import java.util.Collections +import java.util.Comparator +import java.util.LinkedHashSet import java.util.concurrent.CopyOnWriteArrayList private val LOG = Logger.getInstance(javaClass()) @@ -85,6 +91,7 @@ abstract class ComponentStoreImpl : IComponentStore { componentNameIfStateExists = if (component is PersistentStateComponent<*>) { val stateSpec = StoreUtil.getStateSpec(component) doAddComponent(stateSpec.name, component) + @suppress("UNCHECKED_CAST") initPersistentComponent(stateSpec, component as PersistentStateComponent, null, false) } else { @@ -229,7 +236,7 @@ abstract class ComponentStoreImpl : IComponentStore { } } - private fun initPersistentComponent(stateSpec: State, component: PersistentStateComponent, changedStorages: Set?, reloadData: Boolean): String? { + private fun initPersistentComponent(stateSpec: State, component: PersistentStateComponent, changedStorages: Set?, reloadData: Boolean): String? { if (loadPolicy == StateLoadPolicy.NOT_LOAD) { return null } @@ -370,6 +377,7 @@ abstract class ComponentStoreImpl : IComponentStore { override final fun reloadState(componentClass: Class>) { val stateSpec = StoreUtil.getStateSpecOrError(componentClass) + @suppress("UNCHECKED_CAST") val component = components.get(stateSpec.name) as PersistentStateComponent? if (component != null) { initPersistentComponent(stateSpec, component, emptySet(), true) @@ -377,6 +385,7 @@ abstract class ComponentStoreImpl : IComponentStore { } private fun reloadState(componentName: String, changedStorages: Set): Boolean { + @suppress("UNCHECKED_CAST") val component = components.get(componentName) as PersistentStateComponent? if (component == null) { return false From 5491480d8762ba27c2765f43fec7b96d6857601f Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 09:49:55 +0200 Subject: [PATCH 115/138] fix after merge --- .../platform-resources/src/META-INF/LangExtensions.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 4a19cf12e4ff..ed5ba6128b51 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -330,15 +330,15 @@ - - + + From 306253c21fb51573169861e895de33eb0ca73e80 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 10:10:13 +0200 Subject: [PATCH 116/138] cleanup --- .../src/com/intellij/testFramework/PlatformTestCase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 09ae67610659..faf43850bc4e 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -431,7 +431,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro Project project = myProject; if (project != null) { try { - LightPlatformTestCase.doTearDown(getProject(), ourApplication, false); + LightPlatformTestCase.doTearDown(project, ourApplication, false); disposeProject(result); } catch (Throwable e) { From cd662b5dbde83125331e34617d026d3bc90ce648 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 10:36:55 +0200 Subject: [PATCH 117/138] =?UTF-8?q?cleanup=20(javaClass<>=20is=20deprecate?= =?UTF-8?q?d,=20JvmStatic)=20kotlin=20m13=20=E2=80=94=20not-null=20upper?= =?UTF-8?q?=20bound=20now=20could=20be=20specified=20even=20if=20override?= =?UTF-8?q?=20method=20defined=20in=20java?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtInWebServer/BuiltInWebServer.kt | 2 +- .../jetbrains/builtInWebServer/NetService.kt | 2 +- .../jetbrains/io/fastCgi/FastCgiService.kt | 2 +- .../built-in-server/testSrc/TestManager.kt | 2 +- .../src/ComponentStoreImpl.kt | 11 ++++----- .../src/PlatformProjectStoreClassProvider.kt | 2 +- .../src/ProjectStoreImpl.kt | 6 ++--- .../src/ProjectWithModulesStoreImpl.kt | 2 +- .../src/StateStorageManagerImpl.kt | 11 ++++----- .../testSrc/ApplicationStoreTest.kt | 2 +- .../testSrc/SchemeManagerTest.kt | 5 ++-- .../testSrc/XmlElementStorageTest.kt | 4 ++-- .../impl/stores/StateStorageBase.kt | 10 ++++---- .../intellij/openapi/components/service.kt | 6 ++--- .../util/concurrency/AsyncPromise.kt | 2 +- .../debugger/BreakpointManagerBase.kt | 2 +- .../debugger/ProcessHandlerWrapper.kt | 4 +--- .../debugger/connection/VmConnection.kt | 4 ++-- .../com/intellij/testFramework/EdtTestUtil.kt | 7 +++--- .../com/intellij/testFramework/FixtureRule.kt | 6 ++--- .../intellij/util/xmlb/XmlSerializerTest.kt | 22 ++++++++--------- .../actions/ChangeListRemoveConfirmation.kt | 3 +-- .../build/PluginModuleCompilationTest.kt | 24 +++++++++---------- .../tests/git4idea/test/GitPlatformTest.java | 5 ++-- plugins/settings-repository/src/IcsBundle.kt | 20 +++++++++++++--- plugins/settings-repository/src/IcsManager.kt | 4 ++-- .../src/actions/CommitToIcsAction.kt | 19 +++++++++++++-- .../src/copyAppSettingsToRepository.kt | 2 +- .../src/keychain/CredentialsStore.kt | 17 ++++++++++++- .../src/keychain/OSXKeychainLibrary.kt | 17 ++++++++++++- .../src/settings/IcsSettings.kt | 2 +- .../src/settings/readOnlySourcesEditor.kt | 4 ++-- 32 files changed, 140 insertions(+), 91 deletions(-) diff --git a/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt b/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt index f032106892ea..4a93364c15d1 100644 --- a/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt +++ b/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt @@ -46,7 +46,7 @@ import java.net.UnknownHostException public class BuiltInWebServer : HttpRequestHandler() { companion object { - val LOG = Logger.getInstance(javaClass()) + val LOG = Logger.getInstance(BuiltInWebServer::class.java) private fun doProcess(request: FullHttpRequest, context: ChannelHandlerContext, projectNameAsHost: String?): Boolean { val decodedPath = URLUtil.unescapePercentSequences(UriUtil.trimParameters(request.uri())) diff --git a/platform/built-in-server/src/org/jetbrains/builtInWebServer/NetService.kt b/platform/built-in-server/src/org/jetbrains/builtInWebServer/NetService.kt index 70f69ff5660e..3cd342a7f496 100644 --- a/platform/built-in-server/src/org/jetbrains/builtInWebServer/NetService.kt +++ b/platform/built-in-server/src/org/jetbrains/builtInWebServer/NetService.kt @@ -22,7 +22,7 @@ import org.jetbrains.util.concurrency import org.jetbrains.util.concurrency.toPromise import javax.swing.Icon -val LOG: Logger = Logger.getInstance(javaClass()) +val LOG: Logger = Logger.getInstance(NetService::class.java) public abstract class NetService @jvmOverloads protected constructor(protected val project: Project, private val consoleManager: ConsoleManager = ConsoleManager()) : Disposable { protected val processHandler: AsyncValueLoader = object : AsyncValueLoader() { diff --git a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt index d43952c3f582..b1597d17abc0 100644 --- a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt +++ b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt @@ -30,7 +30,7 @@ import org.jetbrains.concurrency.Promise import org.jetbrains.io.* import java.util.concurrent.atomic.AtomicInteger -val LOG: Logger = Logger.getInstance(javaClass()) +val LOG: Logger = Logger.getInstance(FastCgiService::class.java) // todo send FCGI_ABORT_REQUEST if client channel disconnected public abstract class FastCgiService(project: Project) : SingleConnectionNetService(project) { diff --git a/platform/built-in-server/testSrc/TestManager.kt b/platform/built-in-server/testSrc/TestManager.kt index 03181ce3ce18..f990a1c751d7 100644 --- a/platform/built-in-server/testSrc/TestManager.kt +++ b/platform/built-in-server/testSrc/TestManager.kt @@ -38,7 +38,7 @@ class TestManager(val projectRule: ProjectRule, private val tempDirManager: Temp public val status: Int = 200) override fun starting(description: Description) { - annotation = description.getAnnotation(javaClass()) + annotation = description.getAnnotation(TestDescriptor::class.java) if (annotation == null) { return } diff --git a/platform/configuration-store-impl/src/ComponentStoreImpl.kt b/platform/configuration-store-impl/src/ComponentStoreImpl.kt index 27d6e4abaf6b..e8db5edecc70 100644 --- a/platform/configuration-store-impl/src/ComponentStoreImpl.kt +++ b/platform/configuration-store-impl/src/ComponentStoreImpl.kt @@ -49,13 +49,10 @@ import org.jdom.Element import org.jetbrains.annotations.TestOnly import java.io.File import java.io.IOException -import java.util.Arrays -import java.util.Collections -import java.util.Comparator -import java.util.LinkedHashSet +import java.util.* import java.util.concurrent.CopyOnWriteArrayList -private val LOG = Logger.getInstance(javaClass()) +private val LOG = Logger.getInstance(ComponentStoreImpl::class.java) /** * Note: this class is used in upsource, please notify upsource team in case you change its API. @@ -211,13 +208,13 @@ abstract class ComponentStoreImpl : IComponentStore { } try { - getDefaultState(component, componentName, javaClass())?.let { component.readExternal(it) } + getDefaultState(component, componentName, Element::class.java)?.let { component.readExternal(it) } } catch (e: Throwable) { LOG.error(e) } - val element = storageManager.getOldStorage(component, componentName, StateStorageOperation.READ)?.getState(component, componentName, javaClass(), null, false) ?: return null + val element = storageManager.getOldStorage(component, componentName, StateStorageOperation.READ)?.getState(component, componentName, Element::class.java, null, false) ?: return null try { component.readExternal(element) } diff --git a/platform/configuration-store-impl/src/PlatformProjectStoreClassProvider.kt b/platform/configuration-store-impl/src/PlatformProjectStoreClassProvider.kt index b1a94c0ab065..3b3662c3d735 100644 --- a/platform/configuration-store-impl/src/PlatformProjectStoreClassProvider.kt +++ b/platform/configuration-store-impl/src/PlatformProjectStoreClassProvider.kt @@ -20,6 +20,6 @@ import com.intellij.openapi.project.impl.ProjectStoreClassProvider class PlatformProjectStoreClassProvider : ProjectStoreClassProvider { override fun getProjectStoreClass(isDefaultProject: Boolean): Class { - return if (isDefaultProject) javaClass() else javaClass() + return if (isDefaultProject) DefaultProjectStoreImpl::class.java else ProjectStoreImpl::class.java } } \ No newline at end of file diff --git a/platform/configuration-store-impl/src/ProjectStoreImpl.kt b/platform/configuration-store-impl/src/ProjectStoreImpl.kt index e1451172af55..8f3e8a8efce7 100644 --- a/platform/configuration-store-impl/src/ProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/ProjectStoreImpl.kt @@ -42,7 +42,7 @@ import java.io.BufferedReader import java.io.File import java.io.IOException import java.io.InputStreamReader -import java.util.ArrayList +import java.util.* open class ProjectStoreImpl(override val project: ProjectImpl, private val pathMacroManager: PathMacroManager) : ComponentStoreImpl(), IProjectStore { // protected setter used in upsource @@ -203,7 +203,7 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM super.doSave(saveSessions, readonlyFiles, errors) - val notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(javaClass(), project) + val notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(UnableToSaveProjectNotification::class.java, project) if (readonlyFiles.isEmpty()) { for (notification in notifications) { notification.expire() @@ -286,7 +286,7 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM } private fun dropUnableToSaveProjectNotification(project: Project, readOnlyFiles: Array) { - val notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(javaClass(), project) + val notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(UnableToSaveProjectNotification::class.java, project) if (notifications.isEmpty()) { Notifications.Bus.notify(UnableToSaveProjectNotification(project, readOnlyFiles), project) } diff --git a/platform/configuration-store-impl/src/ProjectWithModulesStoreImpl.kt b/platform/configuration-store-impl/src/ProjectWithModulesStoreImpl.kt index ee88d24f9a4a..da1e7c58b262 100644 --- a/platform/configuration-store-impl/src/ProjectWithModulesStoreImpl.kt +++ b/platform/configuration-store-impl/src/ProjectWithModulesStoreImpl.kt @@ -28,7 +28,7 @@ import com.intellij.openapi.vfs.VirtualFile class PlatformLangProjectStoreClassProvider : ProjectStoreClassProvider { override fun getProjectStoreClass(isDefaultProject: Boolean): Class { - return if (isDefaultProject) javaClass() else javaClass() + return if (isDefaultProject) DefaultProjectStoreImpl::class.java else ProjectWithModulesStoreImpl::class.java } } diff --git a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt index ebd0de554a1c..12f8975480c9 100644 --- a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt +++ b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt @@ -36,11 +36,10 @@ import org.jdom.Element import org.jetbrains.annotations.TestOnly import java.io.File import java.io.IOException -import java.util.LinkedHashMap +import java.util.* import java.util.concurrent.locks.ReentrantLock import java.util.regex.Pattern import kotlin.concurrent.withLock -import kotlin.reflect.jvm.java /** * If componentManager not specified, storage will not add file tracker (see VirtualFileTracker) @@ -147,9 +146,9 @@ open class StateStorageManagerImpl(private val rootTagName: String, */ open fun expandNormalizedPath(path: String): String = expandMacros(path) - fun getOrCreateStorage(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT, storageClass: Class = javaClass(), @SuppressWarnings("deprecation") stateSplitter: Class = javaClass()): StateStorage { + fun getOrCreateStorage(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT, storageClass: Class = StateStorage::class.java, @SuppressWarnings("deprecation") stateSplitter: Class = StateSplitterEx::class.java): StateStorage { val collapsedPath = normalizeFileSpec(fileSpec) - val key = if (storageClass == javaClass()) collapsedPath else storageClass.getName() + val key = if (storageClass == StateStorage::class.java) collapsedPath else storageClass.getName() storageLock.withLock { var storage = storages.get(key) if (storage == null) { @@ -184,7 +183,7 @@ open class StateStorageManagerImpl(private val rootTagName: String, // overridden in upsource protected open fun createStateStorage(storageClass: Class, collapsedPath: String, roamingType: RoamingType, @SuppressWarnings("deprecation") stateSplitter: Class): StateStorage { - if (storageClass != javaClass()) { + if (storageClass != StateStorage::class.java) { val constructor = storageClass.getConstructors()[0]!! constructor.setAccessible(true) return constructor.newInstance(componentManager!!, this) as StateStorage @@ -195,7 +194,7 @@ open class StateStorageManagerImpl(private val rootTagName: String, } val filePath = expandNormalizedPath(collapsedPath) - if (stateSplitter != javaClass() && stateSplitter != javaClass()) { + if (stateSplitter != StateSplitter::class.java && stateSplitter != StateSplitterEx::class.java) { val storage = MyDirectoryStorage(this, File(filePath), ReflectionUtil.newInstance(stateSplitter)) virtualFileTracker?.put(filePath, storage) return storage diff --git a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt index 1c7682d53073..7278059c44cd 100644 --- a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt @@ -141,7 +141,7 @@ class ApplicationStoreTest { override fun getState() = state.serialize() override fun loadState(state: Element) { - this.state = XmlSerializer.deserialize(state, javaClass())!! + this.state = XmlSerializer.deserialize(state, State::class.java)!! } } diff --git a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt index 91c25b201d02..542e021375bd 100644 --- a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt +++ b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt @@ -29,7 +29,6 @@ import com.intellij.util.lang.CompoundRuntimeException import com.intellij.util.xmlb.SerializationFilter import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters import com.intellij.util.xmlb.XmlSerializer -import com.intellij.util.xmlb.annotations.Attribute import com.intellij.util.xmlb.annotations.Tag import com.intellij.util.xmlb.annotations.Transient import com.intellij.util.xmlb.toByteArray @@ -200,7 +199,7 @@ class SchemeManagerTest { public Test fun `save only if scheme differs from bundled`() { val dir = tempDirManager.newDirectory() var schemeManager = createSchemeManager(dir) - val converter: (Element) -> TestScheme = { XmlSerializer.deserialize(it, javaClass())!! } + val converter: (Element) -> TestScheme = { XmlSerializer.deserialize(it, TestScheme::class.java)!! } val bundledPath = "/bundledSchemes/default" schemeManager.loadBundledScheme(bundledPath, this, converter) var schemes = schemeManager.getAllSchemes() @@ -382,7 +381,7 @@ public data class TestScheme(@Attribute private var name: String = "", @Attribut } public open class TestSchemesProcessor : BaseSchemeProcessor() { - override fun readScheme(element: Element) = XmlSerializer.deserialize(element, javaClass()) + override fun readScheme(element: Element) = XmlSerializer.deserialize(element, TestScheme::class.java) override fun writeScheme(scheme: TestScheme) = scheme._serialize() } diff --git a/platform/configuration-store-impl/testSrc/XmlElementStorageTest.kt b/platform/configuration-store-impl/testSrc/XmlElementStorageTest.kt index f94298331401..7a80a34c7c3d 100644 --- a/platform/configuration-store-impl/testSrc/XmlElementStorageTest.kt +++ b/platform/configuration-store-impl/testSrc/XmlElementStorageTest.kt @@ -24,7 +24,7 @@ import org.junit.Test class XmlElementStorageTest { @Test fun testGetStateSucceeded() { val storage = MyXmlElementStorage(tag("root", tag("component", attr("name", "test"), tag("foo")))) - val state = storage.getState(this, "test", javaClass()) + val state = storage.getState(this, "test", Element::class.java) assertThat(state).isNotNull() assertThat(state!!.getName()).isEqualTo("component") assertThat(state.getChild("foo")).isNotNull() @@ -32,7 +32,7 @@ class XmlElementStorageTest { @Test fun `get state not succeeded`() { val storage = MyXmlElementStorage(tag("root")) - val state = storage.getState(this, "test", javaClass()) + val state = storage.getState(this, "test", Element::class.java) assertThat(state).isNull() } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageBase.kt b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageBase.kt index 7bcfe136c750..03f9840274fb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageBase.kt +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageBase.kt @@ -20,24 +20,24 @@ import com.intellij.openapi.diagnostic.Logger import org.jdom.Element import java.util.concurrent.atomic.AtomicReference -public abstract class StateStorageBase : StateStorage { +abstract class StateStorageBase : StateStorage { companion object { - private val LOG: Logger = Logger.getInstance(javaClass>()) + private val LOG: Logger = Logger.getInstance(StateStorageBase::class.java) } private var mySavingDisabled = false protected val storageDataRef: AtomicReference = AtomicReference() - override final fun getState(component: Any?, componentName: String, stateClass: Class, mergeInto: S?, reload: Boolean): S? { + override final fun getState(component: Any?, componentName: String, stateClass: Class, mergeInto: S?, reload: Boolean): S? { return getState(component, componentName, stateClass, true, reload, mergeInto) } - fun getState(component: Any?, componentName: String, stateClass: Class, archive: Boolean = true, reload: Boolean = false, mergeInto: S? = null): S? { + fun getState(component: Any?, componentName: String, stateClass: Class, archive: Boolean = true, reload: Boolean = false, mergeInto: S? = null): S? { return deserializeState(getSerializedState(getStorageData(reload), component, componentName, archive), stateClass, mergeInto) } - open fun deserializeState(serializedState: Element?, stateClass: Class, mergeInto: S?): S? { + open fun deserializeState(serializedState: Element?, stateClass: Class, mergeInto: S?): S? { return DefaultStateSerializer.deserializeState(serializedState, stateClass, mergeInto) } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/service.kt b/platform/platform-impl/src/com/intellij/openapi/components/service.kt index f5818f0f37be..f8046adffeaf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/service.kt +++ b/platform/platform-impl/src/com/intellij/openapi/components/service.kt @@ -19,11 +19,11 @@ import com.intellij.openapi.components.ex.ComponentManagerEx import com.intellij.openapi.components.impl.stores.IComponentStore import com.intellij.openapi.project.Project -public inline fun service(): T = ServiceManager.getService(javaClass()) +public inline fun service(): T = ServiceManager.getService(T::class.java) -public inline fun Project.service(): T = ServiceManager.getService(this, javaClass()) +public inline fun Project.service(): T = ServiceManager.getService(this, T::class.java) public val ComponentManager.stateStore: IComponentStore - get() = if (this is Project) getPicoContainer().getComponentInstance(javaClass()) as IComponentStore else getPicoContainer().getComponentInstance(javaClass().getName()) as IComponentStore + get() = if (this is Project) getPicoContainer().getComponentInstance(IComponentStore::class.java) as IComponentStore else getPicoContainer().getComponentInstance(IComponentStore::class.java.getName()) as IComponentStore public fun ComponentManager.getComponents(baseClass: Class): List = (this as ComponentManagerEx).getComponentInstancesOfType(baseClass) \ No newline at end of file diff --git a/platform/platform-impl/src/org/jetbrains/util/concurrency/AsyncPromise.kt b/platform/platform-impl/src/org/jetbrains/util/concurrency/AsyncPromise.kt index f6cff5324b3c..6b228c630efe 100644 --- a/platform/platform-impl/src/org/jetbrains/util/concurrency/AsyncPromise.kt +++ b/platform/platform-impl/src/org/jetbrains/util/concurrency/AsyncPromise.kt @@ -21,7 +21,7 @@ import java.util.* public class AsyncPromise : Promise { companion object { - private val LOG = Logger.getInstance(javaClass>()) + private val LOG = Logger.getInstance(AsyncPromise::class.java) public val OBSOLETE_ERROR: RuntimeException = MessageError("Obsolete") diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManagerBase.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManagerBase.kt index df6064c96767..d7f7845dfcef 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManagerBase.kt +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManagerBase.kt @@ -42,7 +42,7 @@ public abstract class BreakpointManagerBase> : BreakpointM override fun equals(b1: T, b2: T) = b1.target.javaClass == b2.target.javaClass && b1.target == b2.target && b1.line == b2.line && b1.column == b2.column && StringUtil.equals(b1.condition, b2.condition) }) - protected val dispatcher: EventDispatcher = EventDispatcher.create(javaClass()) + protected val dispatcher: EventDispatcher = EventDispatcher.create(BreakpointManager.BreakpointListener::class.java) protected abstract fun createBreakpoint(target: BreakpointTarget, line: Int, column: Int, condition: String?, ignoreCount: Int, enabled: Boolean): T diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ProcessHandlerWrapper.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ProcessHandlerWrapper.kt index cd4ee74d8a07..775e59c6ac49 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ProcessHandlerWrapper.kt +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ProcessHandlerWrapper.kt @@ -20,9 +20,7 @@ import com.intellij.execution.process.ProcessAdapter import com.intellij.execution.process.ProcessEvent import com.intellij.execution.process.ProcessHandler import com.intellij.openapi.diagnostic.Logger -import com.intellij.util.Consumer import com.intellij.xdebugger.XDebugProcess -import org.jetbrains.debugger.connection.VmConnection public class ProcessHandlerWrapper(private val debugProcess: XDebugProcess, private val handler: ProcessHandler) : ProcessHandler(), KillableProcess { init { @@ -42,7 +40,7 @@ public class ProcessHandlerWrapper(private val debugProcess: XDebugProcess, priv } companion object { - private val LOG: Logger = Logger.getInstance(javaClass()) + private val LOG: Logger = Logger.getInstance(ProcessHandlerWrapper::class.java) } override fun isSilentlyDestroyOnClose() = handler.isSilentlyDestroyOnClose() diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/connection/VmConnection.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/connection/VmConnection.kt index b8da252bb115..582c27ac279d 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/connection/VmConnection.kt +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/connection/VmConnection.kt @@ -34,8 +34,8 @@ import javax.swing.event.HyperlinkListener public abstract class VmConnection : Disposable, BrowserConnection { private val state = AtomicReference(ConnectionState(ConnectionStatus.NOT_CONNECTED)) - private val dispatcher = EventDispatcher.create(javaClass()) - private val connectionDispatcher = EventDispatcher.create(javaClass()) + private val dispatcher = EventDispatcher.create(DebugEventListener::class.java) + private val connectionDispatcher = EventDispatcher.create(SocketConnectionListener::class.java) public volatile var vm: T? = null protected set diff --git a/platform/testFramework/src/com/intellij/testFramework/EdtTestUtil.kt b/platform/testFramework/src/com/intellij/testFramework/EdtTestUtil.kt index 70b4c93274dc..1fe4187e62c8 100644 --- a/platform/testFramework/src/com/intellij/testFramework/EdtTestUtil.kt +++ b/platform/testFramework/src/com/intellij/testFramework/EdtTestUtil.kt @@ -18,22 +18,21 @@ package com.intellij.testFramework import com.intellij.util.ThrowableRunnable import java.lang.reflect.InvocationTargetException import javax.swing.SwingUtilities -import kotlin.platform.platformStatic class EdtTestUtil { companion object { - public platformStatic fun runInEdtAndWait(runnable: ThrowableRunnable) { + @JvmStatic fun runInEdtAndWait(runnable: ThrowableRunnable) { runInEdtAndWait({ runnable.run() }) } - public platformStatic fun runInEdtAndWait(runnable: Runnable) { + @JvmStatic fun runInEdtAndWait(runnable: Runnable) { runInEdtAndWait({ runnable.run() }) } // Test only because in production you must use Application.invokeAndWait(Runnable, ModalityState). // The problem is - Application logs errors, but not throws. But in tests must be thrown. // In any case name "runInEdtAndWait" is better than "invokeAndWait". - public platformStatic fun runInEdtAndWait(runnable: () -> Unit) { + @JvmStatic fun runInEdtAndWait(runnable: () -> Unit) { if (SwingUtilities.isEventDispatchThread()) { runnable() } diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt b/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt index 90a787fdbbcc..af14d1b043f8 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt +++ b/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt @@ -56,7 +56,7 @@ import java.util.concurrent.atomic.AtomicBoolean public class ProjectRule() : ExternalResource() { companion object { init { - Logger.setFactory(javaClass()) + Logger.setFactory(TestLoggerFactory::class.java) } private var sharedProject: ProjectEx? = null @@ -181,7 +181,7 @@ annotation public class RunsInEdt public class EdtRule : TestRule { override fun apply(base: Statement, description: Description): Statement { - return if (description.getOwnOrClassAnnotation(javaClass()) == null) { + return if (description.getOwnOrClassAnnotation(RunsInEdt::class.java) == null) { base } else { @@ -204,7 +204,7 @@ annotation public class RunsInActiveStoreMode public class ActiveStoreRule(private val projectRule: ProjectRule) : TestRule { override fun apply(base: Statement, description: Description): Statement { - return if (description.getOwnOrClassAnnotation(javaClass()) == null) { + return if (description.getOwnOrClassAnnotation(RunsInActiveStoreMode::class.java) == null) { base } else { diff --git a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt index 20d4c9574ebd..f3c8027f6cba 100644 --- a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt +++ b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt @@ -22,6 +22,7 @@ import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream import com.intellij.openapi.util.text.StringUtil import com.intellij.util.SmartList import com.intellij.util.xmlb.annotations.* +import com.intellij.util.xmlb.annotations.AbstractCollection import gnu.trove.THashMap import junit.framework.AssertionFailedError import junit.framework.TestCase @@ -31,10 +32,7 @@ import org.jdom.Element import org.jdom.JDOMException import org.junit.Test import java.io.IOException -import java.util.ArrayList -import java.util.Arrays -import java.util.LinkedHashMap -import java.util.LinkedHashSet +import java.util.* import java.util.concurrent.atomic.AtomicReference public class XmlSerializerTest { @@ -290,7 +288,7 @@ public class XmlSerializerTest { @Test fun ParallelDeserialization() { val e = Element("root").addContent(Element("name").setText("x")) - XmlSerializer.deserialize(e, javaClass())//to initialize XmlSerializerImpl.ourBindings + XmlSerializer.deserialize(e, BeanWithArray::class.java)//to initialize XmlSerializerImpl.ourBindings val exc = AtomicReference() val threads = Array(5) { Thread(Runnable { @@ -664,7 +662,7 @@ public class XmlSerializerTest { @Test fun DeserializeJDOMElementField() { - val bean = XmlSerializer.deserialize(JDOMUtil.loadDocument("").getRootElement(), javaClass())!! + val bean = XmlSerializer.deserialize(JDOMUtil.loadDocument("").getRootElement(), BeanWithJDOMElement::class.java)!! TestCase.assertEquals("bye", bean.STRING_V) @@ -680,7 +678,7 @@ public class XmlSerializerTest { @Test fun JDOMElementArrayField() { val text = "\n" + " " - val bean = XmlSerializer.deserialize(JDOMUtil.loadDocument(text).getRootElement(), javaClass())!! + val bean = XmlSerializer.deserialize(JDOMUtil.loadDocument(text).getRootElement(), BeanWithJDOMElementArray::class.java)!! TestCase.assertEquals("bye", bean.STRING_V) @@ -757,7 +755,7 @@ public class XmlSerializerTest { val bb = doSerializerTest("\n" + " \n" + "", bean) for (collection in bb.myMap.keySet()) { - assertThat(collection).isInstanceOf(javaClass>()) + assertThat(collection).isInstanceOf(Set::class.java) } } @@ -951,7 +949,7 @@ public class XmlSerializerTest { val value = Element("value") list.writeExternal(value) - val o = XmlSerializer.deserialize(Element("state").addContent(Element("option").setAttribute("name", "myList").addContent(value)), javaClass())!! + val o = XmlSerializer.deserialize(Element("state").addContent(Element("option").setAttribute("name", "myList").addContent(value)), Bean4::class.java)!! assertSerializer(o, "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "", SkipDefaultsSerializationFilter()) } @@ -980,10 +978,10 @@ public class XmlSerializerTest {

Node.js integration

]]> -""".reader), javaClass())!! +""".reader), Bean::class.java)!! assertThat(bean.description).isEqualToIgnoringWhitespace("

Node.js integration

") - bean = XmlSerializer.deserialize(JDOMUtil.load("""Node.js integration]]>""".reader), javaClass())!! + bean = XmlSerializer.deserialize(JDOMUtil.load("""Node.js integration]]>""".reader), Bean::class.java)!! assertThat(bean.description).isEqualTo("

Node.js integration

") } @@ -1022,7 +1020,7 @@ public class XmlSerializerTest { public fun T.serialize(filter: SerializationFilter? = SkipDefaultValuesSerializationFilters()): Element = XmlSerializer.serialize(this, filter) -public inline fun Element.deserialize(): T = XmlSerializer.deserialize(this, javaClass())!! +public inline fun Element.deserialize(): T = XmlSerializer.deserialize(this, T::class.java)!! public fun Element.toByteArray(): ByteArray { val out = BufferExposingByteArrayOutputStream(512) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeListRemoveConfirmation.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeListRemoveConfirmation.kt index 8d15b4af8fe4..a3a2ad105945 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeListRemoveConfirmation.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeListRemoveConfirmation.kt @@ -21,14 +21,13 @@ import com.intellij.openapi.vcs.changes.ChangeListManager import com.intellij.openapi.vcs.changes.LocalChangeList import com.intellij.util.ThreeState import com.intellij.util.containers.ContainerUtil -import kotlin.platform.platformStatic abstract class ChangeListRemoveConfirmation() { abstract fun askIfShouldRemoveChangeLists(ask: List): Boolean companion object { - platformStatic + JvmStatic fun processLists(project: Project, explicitly: Boolean, allLists: Collection, ask: ChangeListRemoveConfirmation) { val confirmationAsked = ContainerUtil.newIdentityTroveSet() val doNotRemove = ContainerUtil.newIdentityTroveSet() diff --git a/plugins/devkit/testSources/build/PluginModuleCompilationTest.kt b/plugins/devkit/testSources/build/PluginModuleCompilationTest.kt index 1a55a1a702b8..b8d060d4822b 100644 --- a/plugins/devkit/testSources/build/PluginModuleCompilationTest.kt +++ b/plugins/devkit/testSources/build/PluginModuleCompilationTest.kt @@ -35,7 +35,7 @@ import org.jetbrains.idea.devkit.module.PluginModuleType import org.jetbrains.idea.devkit.projectRoots.IdeaJdk import org.jetbrains.idea.devkit.projectRoots.Sandbox import java.io.File -import java.util.Arrays +import java.util.* /** * @author nik @@ -47,17 +47,17 @@ public class PluginModuleCompilationTest : BaseCompilerTestCase() { super.setUpJdk() runWriteAction { val table = ProjectJdkTable.getInstance() - pluginSdk = table.createSdk("IDEA plugin SDK", SdkType.findInstance(javaClass())) - val modificator = pluginSdk!!.getSdkModificator() - modificator.setSdkAdditionalData(Sandbox(getSandboxPath(), getTestProjectJdk(), pluginSdk)) - val rootPath = FileUtil.toSystemIndependentName(PathManager.getJarPathForClass(javaClass())) + pluginSdk = table.createSdk("IDEA plugin SDK", SdkType.findInstance(IdeaJdk::class.java)) + val modificator = pluginSdk!!.sdkModificator + modificator.sdkAdditionalData = Sandbox(getSandboxPath(), testProjectJdk, pluginSdk) + val rootPath = FileUtil.toSystemIndependentName(PathManager.getJarPathForClass(FileUtilRt::class.java)!!) modificator.addRoot(LocalFileSystem.getInstance().refreshAndFindFileByPath(rootPath), OrderRootType.CLASSES) modificator.commitChanges() table.addJdk(pluginSdk) } } - private fun getSandboxPath() = "${getProjectBasePath()}/sandbox" + private fun getSandboxPath() = "$projectBasePath/sandbox" override fun tearDown() { try { @@ -89,7 +89,7 @@ public class PluginModuleCompilationTest : BaseCompilerTestCase() { public fun testRebuildSimpleProject() { setupSimplePluginProject() val log = rebuild() - assertThat(log.getWarnings()).`as`("Rebuild finished with warnings: ${Arrays.toString(log.getWarnings())}").isEmpty() + assertThat(log.warnings).`as`("Rebuild finished with warnings: ${Arrays.toString(log.warnings)}").isEmpty() } public fun testPrepareSimpleProjectForDeployment() { @@ -97,7 +97,7 @@ public class PluginModuleCompilationTest : BaseCompilerTestCase() { rebuild() prepareForDeployment(module) - val outputFile = File("${getProjectBasePath()}/pluginProject.jar") + val outputFile = File("$projectBasePath/pluginProject.jar") assertThat(outputFile).isFile() fs() .archive("pluginProject.jar") @@ -111,7 +111,7 @@ public class PluginModuleCompilationTest : BaseCompilerTestCase() { rebuild() prepareForDeployment(module) - val outputFile = File("${getProjectBasePath()}/pluginProject.zip") + val outputFile = File("$projectBasePath/pluginProject.zip") assertThat(outputFile).isFile() fs() .archive("pluginProject.zip") @@ -136,15 +136,15 @@ public class PluginModuleCompilationTest : BaseCompilerTestCase() { private fun copyAndCreateModule(relativePath: String): Module { copyToProject(relativePath) - val module = loadModule("${getProjectBasePath()}/pluginProject.iml") + val module = loadModule("$projectBasePath/pluginProject.iml") assertThat(ModuleType.get(module)).isEqualTo(PluginModuleType.getInstance()) return module } private fun setupPluginProjectWithJpsModule(): Module { val module = copyAndCreateModule("plugins/devkit/testData/build/withJpsModule") - val jpsModule = loadModule("${getProjectBasePath()}/jps-plugin/jps-plugin.iml") - ModuleRootModificationUtil.setModuleSdk(jpsModule, getTestProjectJdk()) + val jpsModule = loadModule("$projectBasePath/jps-plugin/jps-plugin.iml") + ModuleRootModificationUtil.setModuleSdk(jpsModule, testProjectJdk) return module } } diff --git a/plugins/git4idea/tests/git4idea/test/GitPlatformTest.java b/plugins/git4idea/tests/git4idea/test/GitPlatformTest.java index 83b448032a94..422220375c7d 100644 --- a/plugins/git4idea/tests/git4idea/test/GitPlatformTest.java +++ b/plugins/git4idea/tests/git4idea/test/GitPlatformTest.java @@ -25,6 +25,7 @@ import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.testFramework.EdtTestUtil; import com.intellij.testFramework.PlatformTestCase; import com.intellij.testFramework.TestLoggerFactory; import com.intellij.testFramework.vcs.AbstractVcsTestCase; @@ -72,7 +73,7 @@ public abstract class GitPlatformTest extends PlatformTestCase { checkTestRootIsEmpty(myTestRoot); - edt(new ThrowableRunnable() { + EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { @Override public void run() throws Exception { GitPlatformTest.super.setUp(); @@ -151,7 +152,7 @@ public abstract class GitPlatformTest extends PlatformTestCase { } finally { try { - edt(new ThrowableRunnable() { + EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { @Override public void run() throws Exception { GitPlatformTest.super.tearDown(); diff --git a/plugins/settings-repository/src/IcsBundle.kt b/plugins/settings-repository/src/IcsBundle.kt index 045afff450cf..1793542b3646 100644 --- a/plugins/settings-repository/src/IcsBundle.kt +++ b/plugins/settings-repository/src/IcsBundle.kt @@ -1,11 +1,25 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ package org.jetbrains.settingsRepository import com.intellij.CommonBundle import org.jetbrains.annotations.PropertyKey import java.lang.ref.Reference import java.lang.ref.SoftReference -import java.util.ResourceBundle -import kotlin.platform.platformStatic +import java.util.* class IcsBundle { companion object { @@ -13,7 +27,7 @@ class IcsBundle { val BUNDLE: String = "messages.IcsBundle" - platformStatic + JvmStatic fun message(PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any?): String { return CommonBundle.message(getBundle(), key, *params) } diff --git a/plugins/settings-repository/src/IcsManager.kt b/plugins/settings-repository/src/IcsManager.kt index 24f14902bb32..f68ef032730e 100644 --- a/plugins/settings-repository/src/IcsManager.kt +++ b/plugins/settings-repository/src/IcsManager.kt @@ -46,10 +46,10 @@ import kotlin.properties.Delegates val PLUGIN_NAME: String = "Settings Repository" -val LOG: Logger = Logger.getInstance(javaClass()) +val LOG: Logger = Logger.getInstance(IcsManager::class.java) val icsManager by Delegates.lazy { - ApplicationLoadListener.EP_NAME.findExtension(javaClass()).icsManager + ApplicationLoadListener.EP_NAME.findExtension(IcsApplicationLoadListener::class.java).icsManager } class IcsManager(dir: File) { diff --git a/plugins/settings-repository/src/actions/CommitToIcsAction.kt b/plugins/settings-repository/src/actions/CommitToIcsAction.kt index 304251949164..4d7542d4b0a8 100644 --- a/plugins/settings-repository/src/actions/CommitToIcsAction.kt +++ b/plugins/settings-repository/src/actions/CommitToIcsAction.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ package org.jetbrains.settingsRepository.actions import com.intellij.openapi.components.ServiceManager @@ -28,7 +43,7 @@ import org.jetbrains.settingsRepository.CommitToIcsDialog import org.jetbrains.settingsRepository.IcsBundle import org.jetbrains.settingsRepository.ProjectId import org.jetbrains.settingsRepository.icsManager -import java.util.UUID +import java.util.* class CommitToIcsAction : CommonCheckinFilesAction() { class IcsBeforeCommitDialogHandler : CheckinHandlerFactory() { @@ -103,7 +118,7 @@ private class ProjectChangeCollectConsumer(private val project: Project) { } private fun getProjectId(project: Project): String? { - val projectId = ServiceManager.getService(project, javaClass())!! + val projectId = ServiceManager.getService(project, ProjectId::class.java)!! if (projectId.uid == null) { if (MessageDialogBuilder.yesNo("Settings Server Project Mapping", "Project is not mapped on Settings Server. Would you like to map?").project(project).doNotAsk(object : DialogWrapper.PropertyDoNotAskOption("") { override fun setToBeShown(value: Boolean, exitCode: Int) { diff --git a/plugins/settings-repository/src/copyAppSettingsToRepository.kt b/plugins/settings-repository/src/copyAppSettingsToRepository.kt index e42c1e8ab607..be631497f57f 100644 --- a/plugins/settings-repository/src/copyAppSettingsToRepository.kt +++ b/plugins/settings-repository/src/copyAppSettingsToRepository.kt @@ -72,7 +72,7 @@ private fun getRoamingType(components: Collection): Roaming return component.getRoamingType() } else if (component is PersistentStateComponent<*>) { - val stateAnnotation = component.javaClass.getAnnotation(javaClass()) + val stateAnnotation = component.javaClass.getAnnotation(State::class.java) if (stateAnnotation != null) { val storages = stateAnnotation.storages if (!storages.isEmpty()) { diff --git a/plugins/settings-repository/src/keychain/CredentialsStore.kt b/plugins/settings-repository/src/keychain/CredentialsStore.kt index 082eba376a98..3929da6f07c5 100644 --- a/plugins/settings-repository/src/keychain/CredentialsStore.kt +++ b/plugins/settings-repository/src/keychain/CredentialsStore.kt @@ -1,8 +1,23 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ package org.jetbrains.keychain import com.intellij.openapi.diagnostic.Logger -val LOG: Logger = Logger.getInstance(javaClass()) +val LOG: Logger = Logger.getInstance(CredentialsStore::class.java) public data class Credentials(id: String?, token: String?) { public val id: String? = if (id.isNullOrEmpty()) null else id diff --git a/plugins/settings-repository/src/keychain/OSXKeychainLibrary.kt b/plugins/settings-repository/src/keychain/OSXKeychainLibrary.kt index 4367ab7ba5f8..650174e0658e 100644 --- a/plugins/settings-repository/src/keychain/OSXKeychainLibrary.kt +++ b/plugins/settings-repository/src/keychain/OSXKeychainLibrary.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ package org.jetbrains.keychain import com.intellij.openapi.util.SystemInfo @@ -12,7 +27,7 @@ val isOSXCredentialsStoreSupported: Boolean // It is very, very important to use CFRelease/SecKeychainItemFreeContent You must do it, otherwise you can get "An invalid record was encountered." public interface OSXKeychainLibrary : com.sun.jna.Library { companion object { - private val LIBRARY = com.sun.jna.Native.loadLibrary("Security", javaClass()) as OSXKeychainLibrary + private val LIBRARY = com.sun.jna.Native.loadLibrary("Security", OSXKeychainLibrary::class.java) as OSXKeychainLibrary fun saveGenericPassword(serviceName: ByteArray, accountName: String, password: CharArray) { saveGenericPassword(serviceName, accountName, Charsets.UTF_8.encode(CharBuffer.wrap(password))) diff --git a/plugins/settings-repository/src/settings/IcsSettings.kt b/plugins/settings-repository/src/settings/IcsSettings.kt index 0b2886649858..c1e944221d70 100644 --- a/plugins/settings-repository/src/settings/IcsSettings.kt +++ b/plugins/settings-repository/src/settings/IcsSettings.kt @@ -74,7 +74,7 @@ fun loadSettings(settingsFile: File): IcsSettings { return IcsSettings() } - val settings = ObjectMapper().readValue(settingsFile, javaClass()) + val settings = ObjectMapper().readValue(settingsFile, IcsSettings::class.java) if (settings.commitDelay <= 0) { settings.commitDelay = DEFAULT_COMMIT_DELAY } diff --git a/plugins/settings-repository/src/settings/readOnlySourcesEditor.kt b/plugins/settings-repository/src/settings/readOnlySourcesEditor.kt index b2f15ea01e71..adeebbe95ea2 100644 --- a/plugins/settings-repository/src/settings/readOnlySourcesEditor.kt +++ b/plugins/settings-repository/src/settings/readOnlySourcesEditor.kt @@ -38,7 +38,7 @@ import javax.swing.JTextField import javax.swing.event.DocumentEvent private val COLUMNS = arrayOf(object : TableModelEditor.EditableColumnInfo() { - override fun getColumnClass() = javaClass() + override fun getColumnClass() = Boolean::class.java override fun valueOf(item: ReadonlySource) = item.active @@ -58,7 +58,7 @@ private fun createReadOnlySourcesEditor(): ConfigurableUi { val itemEditor = object : TableModelEditor.DialogItemEditor() { override fun clone(item: ReadonlySource, forInPlaceEditing: Boolean) = ReadonlySource(item.url, item.active) - override fun getItemClass() = javaClass() + override fun getItemClass() = ReadonlySource::class.java override fun edit(item: ReadonlySource, mutator: Function, isAdd: Boolean) { val dialogBuilder = DialogBuilder() From 5f67f434b04c646ab228124ce06dbf2c72da3c3d Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 10:43:01 +0200 Subject: [PATCH 118/138] cleanup --- .../testSrc/SchemeManagerTest.kt | 61 ++++++++++--------- .../intellij/util/xmlb/XmlSerializerTest.kt | 43 ++++++------- 2 files changed, 49 insertions(+), 55 deletions(-) diff --git a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt index 542e021375bd..6e0de04c85f7 100644 --- a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt +++ b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt @@ -40,6 +40,7 @@ import org.junit.ClassRule import org.junit.Rule import org.junit.Test import java.io.File +import com.intellij.util.xmlb.annotations.Attribute val FILE_SPEC = "REMOTE" @@ -48,26 +49,26 @@ val FILE_SPEC = "REMOTE" */ class SchemeManagerTest { companion object { - ClassRule val projectRule = ProjectRule() + @ClassRule val projectRule = ProjectRule() } private val tempDirManager = TemporaryDirectory() - public Rule fun getTemporaryFolder(): TemporaryDirectory = tempDirManager + @Rule fun getTemporaryFolder() = tempDirManager private var localBaseDir: File? = null private var remoteBaseDir: File? = null private fun getTestDataPath() = PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + "/platform/platform-tests/testData/options" - public Test fun testLoadSchemes() { + @Test fun testLoadSchemes() { doLoadSaveTest("options1", "1->first;2->second") } - public Test fun testLoadSimpleSchemes() { + @Test fun testLoadSimpleSchemes() { doLoadSaveTest("options", "1->1") } - public Test fun testDeleteScheme() { + @Test fun testDeleteScheme() { val manager = createAndLoad("options1") manager.removeScheme(TestScheme("first")) manager.save() @@ -75,7 +76,7 @@ class SchemeManagerTest { checkSchemes("2->second") } - public Test fun testRenameScheme() { + @Test fun testRenameScheme() { val manager = createAndLoad("options1") val scheme = manager.findSchemeByName("first") @@ -86,7 +87,7 @@ class SchemeManagerTest { checkSchemes("2->second;renamed->renamed") } - public Test fun testRenameScheme2() { + @Test fun testRenameScheme2() { val manager = createAndLoad("options1") val first = manager.findSchemeByName("first") @@ -102,7 +103,7 @@ class SchemeManagerTest { checkSchemes("1->1;2->2") } - public Test fun testDeleteRenamedScheme() { + @Test fun testDeleteRenamedScheme() { val manager = createAndLoad("options1") val firstScheme = manager.findSchemeByName("first") @@ -122,7 +123,7 @@ class SchemeManagerTest { checkSchemes(localBaseDir!!, "", false) } - public Test fun testDeleteAndCreateSchemeWithTheSameName() { + @Test fun testDeleteAndCreateSchemeWithTheSameName() { val manager = createAndLoad("options1") val firstScheme = manager.findSchemeByName("first") assertThat(firstScheme).isNotNull() @@ -133,7 +134,7 @@ class SchemeManagerTest { checkSchemes("2->second;first->first") } - public Test fun testGenerateUniqueSchemeName() { + @Test fun testGenerateUniqueSchemeName() { val manager = createAndLoad("options1") val scheme = TestScheme("first") manager.addNewScheme(scheme, false) @@ -145,7 +146,7 @@ class SchemeManagerTest { FileUtil.writeToFile(file, _serialize().toByteArray()) } - public Test fun `different extensions`() { + @Test fun `different extensions`() { val dir = tempDirManager.newDirectory() val scheme = TestScheme("local", "true") @@ -158,7 +159,7 @@ class SchemeManagerTest { override fun getSchemeExtension() = ".icls" }, null, dir) schemesManager.loadSchemes() - assertThat(schemesManager.getAllSchemes()).containsOnly(scheme) + assertThat(schemesManager.allSchemes).containsOnly(scheme) assertThat(File(dir, "1.icls")).isFile() assertThat(File(dir, "1.xml")).isFile() @@ -170,16 +171,16 @@ class SchemeManagerTest { assertThat(File(dir, "1.xml")).doesNotExist() } - public Test fun setSchemes() { + @Test fun setSchemes() { val dir = tempDirManager.newDirectory() val schemeManager = createSchemeManager(dir) schemeManager.loadSchemes() - assertThat(schemeManager.getAllSchemes()).isEmpty() + assertThat(schemeManager.allSchemes).isEmpty() val scheme = TestScheme("s1") schemeManager.setSchemes(listOf(scheme)) - val schemes = schemeManager.getAllSchemes() + val schemes = schemeManager.allSchemes assertThat(schemes).containsOnly(scheme) assertThat(File(dir, "s1.xml")).doesNotExist() @@ -196,13 +197,13 @@ class SchemeManagerTest { assertThat(dir).doesNotExist() } - public Test fun `save only if scheme differs from bundled`() { + @Test fun `save only if scheme differs from bundled`() { val dir = tempDirManager.newDirectory() var schemeManager = createSchemeManager(dir) val converter: (Element) -> TestScheme = { XmlSerializer.deserialize(it, TestScheme::class.java)!! } val bundledPath = "/bundledSchemes/default" schemeManager.loadBundledScheme(bundledPath, this, converter) - var schemes = schemeManager.getAllSchemes() + var schemes = schemeManager.allSchemes val customScheme = TestScheme("default") assertThat(schemes).containsOnly(customScheme) @@ -213,7 +214,7 @@ class SchemeManagerTest { schemeManager.setSchemes(listOf(customScheme)) assertThat(dir).doesNotExist() - schemes = schemeManager.getAllSchemes() + schemes = schemeManager.allSchemes assertThat(schemes).containsOnly(customScheme) customScheme.data = "foo" @@ -224,11 +225,11 @@ class SchemeManagerTest { schemeManager.loadBundledScheme(bundledPath, this, converter) schemeManager.loadSchemes() - schemes = schemeManager.getAllSchemes() + schemes = schemeManager.allSchemes assertThat(schemes).containsOnly(customScheme) } - public Test fun `don't remove dir if no schemes but at least one non-hidden file exists`() { + @Test fun `don't remove dir if no schemes but at least one non-hidden file exists`() { val dir = tempDirManager.newDirectory() val schemeManager = createSchemeManager(dir) @@ -250,7 +251,7 @@ class SchemeManagerTest { assertThat(dir).isDirectory() } - public Test fun `remove empty directory only if some file was deleted`() { + @Test fun `remove empty directory only if some file was deleted`() { val dir = tempDirManager.newDirectory() val schemeManager = createSchemeManager(dir) schemeManager.loadSchemes() @@ -268,16 +269,16 @@ class SchemeManagerTest { assertThat(dir).doesNotExist() } - public Test fun rename() { + @Test fun rename() { val dir = tempDirManager.newDirectory() val schemeManager = createSchemeManager(dir) schemeManager.loadSchemes() - assertThat(schemeManager.getAllSchemes()).isEmpty() + assertThat(schemeManager.allSchemes).isEmpty() val scheme = TestScheme("s1") schemeManager.setSchemes(listOf(scheme)) - val schemes = schemeManager.getAllSchemes() + val schemes = schemeManager.allSchemes assertThat(schemes).containsOnly(scheme) assertThat(File(dir, "s1.xml")).doesNotExist() @@ -295,11 +296,11 @@ class SchemeManagerTest { assertThat(File(dir, "s2.xml")).isFile() } - public Test fun `path must not contains ROOT_CONFIG macro`() { + @Test fun `path must not contains ROOT_CONFIG macro`() { assertThatThrownBy({ SchemesManagerFactory.getInstance().create("\$ROOT_CONFIG$/foo", TestSchemesProcessor()) }).hasMessage("Path must not contains ROOT_CONFIG macro, corrected: foo") } - public Test fun `path must be system-independent`() { + @Test fun `path must be system-independent`() { assertThatThrownBy({SchemesManagerFactory.getInstance().create("foo\\bar", TestSchemesProcessor())}).hasMessage("Path must be system-independent, use forward slash instead of backslash") } @@ -368,15 +369,15 @@ private fun checkSchemes(baseDir: File, expected: String, ignoreDeleted: Boolean } } -Tag("scheme") -public data class TestScheme(@Attribute private var name: String = "", @Attribute public var data: String? = null) : ExternalizableScheme { +@Tag("scheme") +data class TestScheme(@field:Attribute private var name: String = "", @field:Attribute var data: String? = null) : ExternalizableScheme { override fun getName() = name - override Transient fun setName(newName: String) { + override @Transient fun setName(newName: String) { name = newName } - @suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") + @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") override fun getExternalInfo() = null } diff --git a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt index f3c8027f6cba..e27f9ce8e8e6 100644 --- a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt +++ b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt @@ -29,9 +29,7 @@ import junit.framework.TestCase import org.assertj.core.api.Assertions.assertThat import org.intellij.lang.annotations.Language import org.jdom.Element -import org.jdom.JDOMException import org.junit.Test -import java.io.IOException import java.util.* import java.util.concurrent.atomic.AtomicReference @@ -196,8 +194,8 @@ public class XmlSerializerTest { public class BeanWithMapWithAnnotations { - Property(surroundWithTag = false) - MapAnnotation(surroundWithTag = false, entryTagName = "option", keyAttributeName = "name", valueAttributeName = "value") + @Property(surroundWithTag = false) + @MapAnnotation(surroundWithTag = false, entryTagName = "option", keyAttributeName = "name", valueAttributeName = "value") public var VALUES: MutableMap = LinkedHashMap() init { @@ -235,7 +233,7 @@ public class XmlSerializerTest { public class BeanWithMapWithBeanValue2 { - MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false) + @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false) public var values: Map = THashMap() } @@ -282,7 +280,7 @@ public class XmlSerializerTest { } class BeanWithFieldWithTagAnnotation { - Tag("name") + @Tag("name") public var STRING_V: String = "hello" } @@ -381,7 +379,7 @@ public class XmlSerializerTest { } public class BeanWithArrayWithoutTagName { - AbstractCollection(surroundWithTag = false) + @AbstractCollection(surroundWithTag = false) public var V: Array = arrayOf("a") } @@ -618,7 +616,7 @@ public class XmlSerializerTest { class BeanWithPropertyFilter { - Property(filter = PropertyFilterTest::class) + @Property(filter = PropertyFilterTest::class) public var STRING_V: String = "hello" } @@ -644,7 +642,7 @@ public class XmlSerializerTest { class BeanWithJDOMElement { public var STRING_V: String = "hello" - Tag("actions") + @Tag("actions") public var actions: org.jdom.Element? = null } @@ -658,13 +656,9 @@ public class XmlSerializerTest { assertSerializer(element, "\n" + " ", null) } - throws(Exception::class) @Test fun DeserializeJDOMElementField() { - - val bean = XmlSerializer.deserialize(JDOMUtil.loadDocument("").getRootElement(), BeanWithJDOMElement::class.java)!! - TestCase.assertEquals("bye", bean.STRING_V) TestCase.assertNotNull(bean.actions) TestCase.assertEquals(2, bean.actions!!.getChildren("action").size()) @@ -672,7 +666,7 @@ public class XmlSerializerTest { class BeanWithJDOMElementArray { public var STRING_V: String = "hello" - Tag("actions") + @Tag("actions") public var actions: Array? = null } @@ -699,7 +693,7 @@ public class XmlSerializerTest { class BeanWithTextAnnotation { public var INT_V: Int = 1 - Text + @Text public var STRING_V: String = "hello" public constructor(INT_V: Int, STRING_V: String) { @@ -873,7 +867,7 @@ public class XmlSerializerTest { } private class BeanWithDefaultAttributeName { - Attribute + @Attribute public fun getFoo(): String { return "foo" } @@ -888,17 +882,16 @@ public class XmlSerializerTest { } class Bean2 { - Attribute + @Attribute var ab: String? = null - Attribute + @Attribute var module: String? = null - Attribute + @Attribute var ac: String? = null } - throws(IOException::class, JDOMException::class) @Test fun Ordered() { val bean = Bean2() bean.module = "module" @@ -914,11 +907,11 @@ public class XmlSerializerTest { @Tag("b") class Bean3 { - @suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") + @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") public var list: JDOMExternalizableStringList = JDOMExternalizableStringList() } - Tag("b") + @Tag("b") class Bean4 { @CollectionBean val list = SmartList() @@ -941,7 +934,7 @@ public class XmlSerializerTest { } @Test fun CollectionBeanReadJDOMExternalizableStringList() { - @suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") + @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") val list = JDOMExternalizableStringList() list.add("one") list.add("two") @@ -970,7 +963,7 @@ public class XmlSerializerTest { @Test fun cdataAfterNewLine() { @Tag("bean") - @data class Bean(@Tag var description: String? = null) + data class Bean(@Tag var description: String? = null) var bean = XmlSerializer.deserialize(JDOMUtil.load(""" @@ -996,7 +989,7 @@ public class XmlSerializerTest { TestCase.assertEquals(serialized, JDOMUtil.writeElement(serializedState)) } - private fun doSerializerTest(Language("XML") expectedText: String, bean: T, filter: SerializationFilter? = null): T { + private fun doSerializerTest(@Language("XML") expectedText: String, bean: T, filter: SerializationFilter? = null): T { val element = assertSerializer(bean, expectedText, filter) //test deserializer From b86e73e643bf7aa401215b41474a52959ee5c36b Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 11:33:05 +0200 Subject: [PATCH 119/138] cleanup --- .../jetbrains/io/fastCgi/FastCgiRequest.kt | 20 +++++++++---------- .../jetbrains/io/fastCgi/FastCgiService.kt | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiRequest.kt b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiRequest.kt index 495ef9b6e74f..7b1c62c74fa1 100644 --- a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiRequest.kt +++ b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiRequest.kt @@ -12,7 +12,7 @@ import io.netty.handler.codec.http.HttpHeaderNames import org.jetbrains.builtInWebServer.WebServerPathToFileManager import org.jetbrains.io.Responses import java.net.InetSocketAddress -import java.util.Locale +import java.util.* class FastCgiRequest(val requestId: Int, allocator: ByteBufAllocator) { companion object { @@ -37,8 +37,8 @@ class FastCgiRequest(val requestId: Int, allocator: ByteBufAllocator) { public fun writeFileHeaders(file: VirtualFile, project: Project, canonicalRequestPath: CharSequence) { val root = WebServerPathToFileManager.getInstance(project).getRoot(file) LOG.assertTrue(root != null) - addHeader("DOCUMENT_ROOT", root!!.getRoot().getPath()) - addHeader("SCRIPT_FILENAME", file.getPath()) + addHeader("DOCUMENT_ROOT", root!!.root.path) + addHeader("SCRIPT_FILENAME", file.path) addHeader("SCRIPT_NAME", canonicalRequestPath) } @@ -80,19 +80,19 @@ class FastCgiRequest(val requestId: Int, allocator: ByteBufAllocator) { addHeader("REQUEST_METHOD", request.method().name()) val remote = clientChannel.remoteAddress() as InetSocketAddress - addHeader("REMOTE_ADDR", remote.getAddress().getHostAddress()) - addHeader("REMOTE_PORT", Integer.toString(remote.getPort())) + addHeader("REMOTE_ADDR", remote.address.hostAddress) + addHeader("REMOTE_PORT", Integer.toString(remote.port)) val local = clientChannel.localAddress() as InetSocketAddress addHeader("SERVER_SOFTWARE", Responses.getServerHeaderValue()) addHeader("SERVER_NAME", Responses.getServerHeaderValue()) - addHeader("SERVER_ADDR", local.getAddress().getHostAddress()) - addHeader("SERVER_PORT", Integer.toString(local.getPort())) + addHeader("SERVER_ADDR", local.address.hostAddress) + addHeader("SERVER_PORT", Integer.toString(local.port)) addHeader("GATEWAY_INTERFACE", "CGI/1.1") addHeader("SERVER_PROTOCOL", request.protocolVersion().text()) - addHeader("CONTENT_TYPE", request.headers().get(HttpHeaderNames.CONTENT_TYPE)) + addHeader("CONTENT_TYPE", request.headers().getAsString(HttpHeaderNames.CONTENT_TYPE)) // PHP only, required if PHP was built with --enable-force-cgi-redirect addHeader("REDIRECT_STATUS", "200") @@ -106,8 +106,8 @@ class FastCgiRequest(val requestId: Int, allocator: ByteBufAllocator) { addHeader("CONTENT_LENGTH", request.content().readableBytes().toString()) - for (entry in request.headers()) { - addHeader("HTTP_${entry.getKey().replace('-', '_').toUpperCase(Locale.ENGLISH)}", entry.getValue()) + for ((key, value) in request.headers().iteratorAsString()) { + addHeader("HTTP_${key.replace('-', '_').toUpperCase(Locale.ENGLISH)}", value) } } diff --git a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt index b1597d17abc0..7be4a5ba1468 100644 --- a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt +++ b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt @@ -149,10 +149,10 @@ public abstract class FastCgiService(project: Project) : SingleConnectionNetServ fastCgiRequest.writeToServerChannel(notEmptyContent, processChannel!!) } }) - .rejected(Consumer { + .rejected { Promise.logError(LOG, it) handleError(fastCgiRequest, notEmptyContent) - }) + } } } catch (e: Throwable) { From af536bad89273b3b04d2701475ee5df0f0e843a5 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 11:52:58 +0200 Subject: [PATCH 120/138] cleanup --- .../impl/HeavyIdeaTestFixtureImpl.java | 20 ++++++++++--------- .../fixtures/impl/ModuleFixtureImpl.java | 17 +++++----------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java index 15712e9240fe..0e6a97e16583 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java @@ -139,18 +139,20 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu } } - private void setUpProject() { + private void setUpProject() throws IOException { + File tempDirectory = FileUtil.createTempDirectory(myName, ""); + PlatformTestCase.synchronizeTempDirVfs(LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDirectory)); + myFilesToDelete.add(tempDirectory); + + String projectPath = FileUtil.toSystemIndependentName(tempDirectory.getPath()) + "/" + myName + ProjectFileType.DOT_DEFAULT_EXTENSION; + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + new Throwable(projectPath).printStackTrace(new PrintStream(buffer)); + myProject = PlatformTestCase.createProject(projectPath, buffer.toString()); + EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { + @SuppressWarnings("TestOnlyProblems") @Override public void run() throws Throwable { - File tempDirectory = FileUtil.createTempDirectory(myName, ""); - PlatformTestCase.synchronizeTempDirVfs(LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDirectory)); - myFilesToDelete.add(tempDirectory); - - String projectPath = FileUtil.toSystemIndependentName(tempDirectory.getPath()) + "/" + myName + ProjectFileType.DOT_DEFAULT_EXTENSION; - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - new Throwable(projectPath).printStackTrace(new PrintStream(buffer)); - myProject = PlatformTestCase.createProject(projectPath, buffer.toString()); ProjectManagerEx.getInstanceEx().openTestProject(myProject); for (ModuleFixtureBuilder moduleFixtureBuilder : myModuleFixtureBuilders) { diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/ModuleFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/ModuleFixtureImpl.java index 2bba6b208517..4b1e15ac780d 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/ModuleFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/ModuleFixtureImpl.java @@ -13,35 +13,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.testFramework.fixtures.impl; -import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.module.Module; import com.intellij.testFramework.fixtures.ModuleFixture; +import org.jetbrains.annotations.NotNull; /** * @author mike */ public class ModuleFixtureImpl extends BaseFixture implements ModuleFixture { - private Module myModule; protected final ModuleFixtureBuilderImpl myBuilder; - public ModuleFixtureImpl(final ModuleFixtureBuilderImpl builder) { + public ModuleFixtureImpl(@NotNull ModuleFixtureBuilderImpl builder) { myBuilder = builder; } @Override public Module getModule() { - if (myModule != null) return myModule; - new WriteCommandAction.Simple(null) { - @Override - protected void run() throws Throwable { - myModule = myBuilder.buildModule(); - } - }.execute().throwException(); - + if (myModule == null) { + myModule = myBuilder.buildModule(); + } return myModule; } From 4b375b4f284b9e96bbb77a456174e5a76070188d Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 12:04:19 +0200 Subject: [PATCH 121/138] ensure that module model and library model are disposed on error --- .../impl/JavaModuleFixtureBuilderImpl.java | 92 ++++++++++--------- 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java index f527677f23e6..9ee51cf765af 100644 --- a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java +++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java @@ -27,6 +27,7 @@ import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.LocalFileSystem; @@ -39,6 +40,7 @@ import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.ModuleFixture; import com.intellij.testFramework.fixtures.TestFixtureBuilder; import com.intellij.util.ArrayUtil; +import com.intellij.util.Consumer; import org.jetbrains.annotations.NonNls; import java.io.File; @@ -116,51 +118,59 @@ abstract class JavaModuleFixtureBuilderImpl extends Mod protected void initModule(final Module module) { super.initModule(module); - final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); - final LibraryTable libraryTable = model.getModuleLibraryTable(); - - for (Lib lib : myLibraries) { - String libraryName = lib.getName(); - - final Library library = libraryTable.createLibrary(libraryName); - - final Library.ModifiableModel libraryModel = library.getModifiableModel(); - - for (OrderRootType rootType : OrderRootType.getAllTypes()) { - final String[] roots = lib.getRoots(rootType); - for (String root : roots) { - VirtualFile vRoot = LocalFileSystem.getInstance().refreshAndFindFileByPath(root); - if (vRoot != null && OrderRootType.CLASSES.equals(rootType) && !vRoot.isDirectory()) { - final VirtualFile jar = JarFileSystem.getInstance().refreshAndFindFileByPath(root + "!/"); - if (jar != null) vRoot = jar; + ModuleRootModificationUtil.updateModel(module, new Consumer() { + @Override + public void consume(ModifiableRootModel model) { + LibraryTable libraryTable = model.getModuleLibraryTable(); + for (Lib lib : myLibraries) { + Library library = libraryTable.createLibrary(lib.getName()); + Library.ModifiableModel libraryModel = library.getModifiableModel(); + boolean success = false; + try { + for (OrderRootType rootType : OrderRootType.getAllTypes()) { + for (String root : lib.getRoots(rootType)) { + VirtualFile vRoot = LocalFileSystem.getInstance().refreshAndFindFileByPath(root); + if (vRoot != null && OrderRootType.CLASSES.equals(rootType) && !vRoot.isDirectory()) { + VirtualFile jar = JarFileSystem.getInstance().refreshAndFindFileByPath(root + "!/"); + if (jar != null) { + vRoot = jar; + } + } + if (vRoot != null) { + libraryModel.addRoot(vRoot, rootType); + } + } + } + success = true; } - if (vRoot != null) { - libraryModel.addRoot(vRoot, rootType); + finally { + if (!success) { + Disposer.dispose(libraryModel); + } } + + libraryModel.commit(); + } + + final Sdk jdk; + if (myJdk != null) { + VfsRootAccess.allowRootAccessTemporarily(module, myJdk); + jdk = JavaSdk.getInstance().createJdk(module.getName() + "_jdk", myJdk, false); + ((ProjectJdkImpl)jdk).setVersionString(StringUtil.notNullize(IdeaTestUtil.getMockJdkVersion(myJdk), "java 1.5")); + } + else { + jdk = IdeaTestUtil.getMockJdk17(); + } + model.setSdk(new MockJdkWrapper(CompilerConfigurationImpl.getTestsExternalCompilerHome(), jdk)); + + if (myLanguageLevel != null) { + model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(myLanguageLevel); + } + else if (myMockJdkLevel == MockJdkLevel.jdk15) { + model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_5); } } - libraryModel.commit(); - } - - final Sdk jdk; - if (myJdk != null) { - VfsRootAccess.allowRootAccessTemporarily(module, myJdk); - jdk = JavaSdk.getInstance().createJdk(module.getName() + "_jdk", myJdk, false); - ((ProjectJdkImpl)jdk).setVersionString(StringUtil.notNullize(IdeaTestUtil.getMockJdkVersion(myJdk), "java 1.5")); - } - else { - jdk = IdeaTestUtil.getMockJdk17(); - } - model.setSdk(new MockJdkWrapper(CompilerConfigurationImpl.getTestsExternalCompilerHome(), jdk)); - - if (myLanguageLevel != null) { - model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(myLanguageLevel); - } - else if (myMockJdkLevel == MockJdkLevel.jdk15) { - model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_5); - } - - model.commit(); + }); for (OrderEntry entry : ModuleRootManager.getInstance(module).getOrderEntries()) { if (entry instanceof LibraryOrderEntry) { From 1485fab1b193fc8b79cd65fab2a932d7854cde67 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 12:57:29 +0200 Subject: [PATCH 122/138] cleanup --- .../src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt | 4 ++-- .../src/org/jetbrains/io/fastCgi/FastCgiService.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt index ddd0bb4c309a..4aac0e327d02 100644 --- a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt +++ b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt @@ -76,7 +76,7 @@ class FastCgiDecoder(private val errorOutputConsumer: Consumer, private override fun channelInactive(context: ChannelHandlerContext) { try { - if (!dataBuffers.isEmpty()) { + if (!dataBuffers.isEmpty) { dataBuffers.forEachEntry(object : TIntObjectProcedure { override fun execute(a: Int, buffer: ByteBuf): Boolean { try { @@ -92,7 +92,7 @@ class FastCgiDecoder(private val errorOutputConsumer: Consumer, private } } finally { - super.channelInactive(context) + super.channelInactive(context) } } diff --git a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt index 7be4a5ba1468..e7d54e0210f7 100644 --- a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt +++ b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt @@ -51,7 +51,7 @@ public abstract class FastCgiService(project: Project) : SingleConnectionNetServ private fun parseHeaders(response: HttpResponse, buffer: ByteBuf) { val builder = StringBuilder() - while (buffer.isReadable()) { + while (buffer.isReadable) { builder.setLength(0) var key: String? = null @@ -187,7 +187,7 @@ public abstract class FastCgiService(project: Project) : SingleConnectionNetServ fun responseReceived(id: Int, buffer: ByteBuf?) { val channel = requests.remove(id) - if (channel == null || !channel.isActive()) { + if (channel == null || !channel.isActive) { buffer?.release() return } From 49fb7587e8b40a44cbe604d1588f8438c3c0da02 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 13:11:12 +0200 Subject: [PATCH 123/138] WEB-17803 Built-in webserver truncates output on large php files --- .../src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt index 4aac0e327d02..b5c418747977 100644 --- a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt +++ b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt @@ -136,8 +136,10 @@ class FastCgiDecoder(private val errorOutputConsumer: Consumer, private data.writerIndex(data.writerIndex() + data.readableBytes()) } else { + // must be computed here before we set data to new composite buffer + val newLength = data.readableBytes() + sliced.readableBytes() data = context.alloc().compositeBuffer(Decoder.DEFAULT_MAX_COMPOSITE_BUFFER_COMPONENTS).addComponents(data, sliced) - data.writerIndex(data.writerIndex() + data.readableBytes() + sliced.readableBytes()) + data.writerIndex(data.writerIndex() + newLength) } dataBuffers.put(id, data) } @@ -153,7 +155,7 @@ class FastCgiDecoder(private val errorOutputConsumer: Consumer, private } } - else -> LOG.error("Unknown type " + type) + else -> LOG.error("Unknown type $type") } return null } From 5e6c94a9310994504118663c9bff379e93e24b9a Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 13:13:49 +0200 Subject: [PATCH 124/138] avoid NPE in tests --- .../platform-impl/src/com/intellij/ide/util/TipUIUtil.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java index f98ce8b1d826..ffd9cff6ec70 100644 --- a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java +++ b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -124,7 +124,8 @@ public class TipUIUtil { private static final String TIP_HTML_TEXT_TAGS = "h1, p, pre, ul"; private static void adjustFontSize(StyleSheet styleSheet) { - float scale = (float)UISettings.getInstance().FONT_SIZE / UIUtil.getSystemFontData().getSecond(); + Pair systemFontData = UIUtil.getSystemFontData(); + float scale = systemFontData == null ? 0 : (float)UISettings.getInstance().FONT_SIZE / systemFontData.getSecond(); if (scale <= 1) return; // don't bother about decreasing // When the primary font is increased we should take care of the visibility of the tips font From a7b0ad8471329c1725e306366bd441755f477f47 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 15:48:53 +0200 Subject: [PATCH 125/138] =?UTF-8?q?robust=20tearDown=20=E2=80=94=20one=20f?= =?UTF-8?q?ailed=20test=20must=20not=20cause=20the=20whole=20run=20fail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ExecutionWithDebuggerToolsTestCase.java | 17 +- .../intellij/execution/ExecutionTestCase.java | 34 +- .../testFramework/ModuleTestCase.java | 2 +- .../src/ComponentStoreImpl.kt | 4 +- .../src/ProjectStoreImpl.kt | 2 +- .../src/SchemeManagerFactoryImpl.kt | 2 +- .../testSrc/SchemeManagerTest.kt | 3 +- .../intellij/pom/core/impl/PomModelImpl.java | 2 +- .../ExternalChangesAndRefreshingTest.java | 67 +- .../application/impl/LaterInvocatorTest.java | 473 +++++------ .../testFramework/CompositeException.java | 153 ---- .../testFramework/LightPlatformTestCase.java | 106 +-- .../testFramework/PlatformTestCase.java | 102 +-- .../testFramework/UsefulTestCase.java | 37 +- .../impl/HeavyIdeaTestFixtureImpl.java | 43 +- .../impl/LightIdeaTestFixtureImpl.java | 21 +- .../com/intellij/testFramework/FixtureRule.kt | 4 +- .../util/lang/CompoundRuntimeException.java | 113 ++- .../idea/svn/SvnAuthenticationTest.java | 21 +- .../idea/svn16/SvnAuthenticationTest.java | 734 ++++++++---------- 20 files changed, 872 insertions(+), 1068 deletions(-) delete mode 100644 platform/testFramework/src/com/intellij/testFramework/CompositeException.java diff --git a/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java b/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java index ade8358e30dd..68426748e81a 100644 --- a/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java +++ b/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java @@ -39,10 +39,11 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; -import com.intellij.testFramework.CompositeException; import com.intellij.ui.classFilter.ClassFilter; import com.intellij.util.IJSwingUtilities; +import com.intellij.util.SmartList; import com.intellij.util.TimeoutUtil; +import com.intellij.util.lang.CompoundRuntimeException; import com.intellij.util.ui.UIUtil; import com.sun.jdi.Method; import com.sun.jdi.ThreadReference; @@ -58,7 +59,7 @@ public abstract class ExecutionWithDebuggerToolsTestCase extends ExecutionTestCa private final SynchronizationBasedSemaphore myScriptRunnablesSema = new SynchronizationBasedSemaphore(); protected static final int RATHER_LATER_INVOKES_N = 10; public DebugProcessImpl myDebugProcess = null; - private final CompositeException myException = new CompositeException(); + private final List myException = new SmartList(); private static class InvokeRatherLaterRequest { private final DebuggerCommandImpl myDebuggerCommand; @@ -112,13 +113,17 @@ public abstract class ExecutionWithDebuggerToolsTestCase extends ExecutionTestCa @Override protected void tearDown() throws Exception { - super.tearDown(); - throwExceptionsIfAny(); + try { + super.tearDown(); + } + finally { + throwExceptionsIfAny(); + } } - protected void throwExceptionsIfAny() throws CompositeException { + protected void throwExceptionsIfAny() { synchronized (myException) { - myException.throwIfNotEmpty(); + CompoundRuntimeException.throwIfNotEmpty(myException); } } diff --git a/java/testFramework/src/com/intellij/execution/ExecutionTestCase.java b/java/testFramework/src/com/intellij/execution/ExecutionTestCase.java index 81a5ffe6fb3e..339e490c7a86 100644 --- a/java/testFramework/src/com/intellij/execution/ExecutionTestCase.java +++ b/java/testFramework/src/com/intellij/execution/ExecutionTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,13 +31,10 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; -import com.intellij.testFramework.CompilerTester; -import com.intellij.testFramework.IdeaTestCase; -import com.intellij.testFramework.IdeaTestUtil; -import com.intellij.testFramework.PsiTestUtil; +import com.intellij.testFramework.*; import com.intellij.util.Alarm; import com.intellij.util.PathUtil; -import com.intellij.util.ui.UIUtil; +import com.intellij.util.ThrowableRunnable; import org.jetbrains.annotations.NonNls; import java.io.File; @@ -70,16 +67,10 @@ public abstract class ExecutionTestCase extends IdeaTestCase { } myModuleOutputDir = new File(ourOutputRoot, PathUtil.getFileName(getTestAppPath())); myChecker = initOutputChecker(); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { + EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { @Override - public void run() { - try { - ExecutionTestCase.super.setUp(); - } - catch (Throwable e) { - e.printStackTrace(); - assertTrue(false); - } + public void run() throws Throwable { + ExecutionTestCase.super.setUp(); } }); if (!myModuleOutputDir.exists()) { @@ -129,7 +120,7 @@ public abstract class ExecutionTestCase extends IdeaTestCase { } @Override - protected void runBareRunnable(Runnable runnable) throws Throwable { + protected void runBareRunnable(ThrowableRunnable runnable) throws Throwable { runnable.run(); } @@ -144,15 +135,10 @@ public abstract class ExecutionTestCase extends IdeaTestCase { if (myCompilerTester != null) { myCompilerTester.tearDown(); } - UIUtil.invokeAndWaitIfNeeded(new Runnable() { + EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { @Override - public void run() { - try { - ExecutionTestCase.super.tearDown(); - } - catch (Exception e) { - LOG.error(e); - } + public void run() throws Throwable { + ExecutionTestCase.super.tearDown(); } }); //myChecker.checkValid(getTestProjectJdk()); diff --git a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java index 589b04c0aa79..a2139b376f95 100644 --- a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java +++ b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java @@ -79,7 +79,7 @@ public abstract class ModuleTestCase extends IdeaTestCase { token.finish(); } - CompoundRuntimeException.doThrow(errors); + CompoundRuntimeException.throwIfNotEmpty(errors); } finally { myModulesToDispose.clear(); diff --git a/platform/configuration-store-impl/src/ComponentStoreImpl.kt b/platform/configuration-store-impl/src/ComponentStoreImpl.kt index e8db5edecc70..2218288cd495 100644 --- a/platform/configuration-store-impl/src/ComponentStoreImpl.kt +++ b/platform/configuration-store-impl/src/ComponentStoreImpl.kt @@ -139,7 +139,7 @@ abstract class ComponentStoreImpl : IComponentStore { if (externalizationSession != null) { errors = doSave(externalizationSession.createSaveSessions(), readonlyFiles, errors) } - CompoundRuntimeException.doThrow(errors) + CompoundRuntimeException.throwIfNotEmpty(errors) } override TestOnly fun saveApplicationComponent(component: Any) { @@ -166,7 +166,7 @@ abstract class ComponentStoreImpl : IComponentStore { val token = WriteAction.start() try { VfsRootAccess.allowRootAccess(file.getAbsolutePath()) - CompoundRuntimeException.doThrow(doSave(sessions)) + CompoundRuntimeException.throwIfNotEmpty(doSave(sessions)) } finally { try { diff --git a/platform/configuration-store-impl/src/ProjectStoreImpl.kt b/platform/configuration-store-impl/src/ProjectStoreImpl.kt index 8f3e8a8efce7..ae6900ab4570 100644 --- a/platform/configuration-store-impl/src/ProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/ProjectStoreImpl.kt @@ -235,7 +235,7 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM } if (errors != null) { - CompoundRuntimeException.doThrow(errors) + CompoundRuntimeException.throwIfNotEmpty(errors) } if (!readonlyFiles.isEmpty()) { diff --git a/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt b/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt index de4019a335ff..09117da34363 100644 --- a/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt +++ b/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt @@ -83,7 +83,7 @@ public abstract class SchemeManagerFactoryBase : SchemesManagerFactory(), Settin } } - CompoundRuntimeException.doThrow(errors) + CompoundRuntimeException.throwIfNotEmpty(errors) } } diff --git a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt index 6e0de04c85f7..3b89d712980b 100644 --- a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt +++ b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt @@ -40,7 +40,6 @@ import org.junit.ClassRule import org.junit.Rule import org.junit.Test import java.io.File -import com.intellij.util.xmlb.annotations.Attribute val FILE_SPEC = "REMOTE" @@ -390,7 +389,7 @@ public open class TestSchemesProcessor : BaseSchemeProcessor() { fun SchemeManagerImpl<*, *>.save() { val errors = SmartList() save(errors) - CompoundRuntimeException.doThrow(errors) + CompoundRuntimeException.throwIfNotEmpty(errors) } public fun T._serialize(filter: SerializationFilter? = SkipDefaultValuesSerializationFilters()): Element = XmlSerializer.serialize(this, filter) \ No newline at end of file diff --git a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java index a37613c76fb0..9761e4882cc5 100644 --- a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java +++ b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java @@ -210,7 +210,7 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel { finally { DebugUtil.finishPsiModification(); } - if (!throwables.isEmpty()) CompoundRuntimeException.doThrow(throwables); + if (!throwables.isEmpty()) CompoundRuntimeException.throwIfNotEmpty(throwables); } } } diff --git a/platform/platform-tests/testSrc/com/intellij/history/integration/ExternalChangesAndRefreshingTest.java b/platform/platform-tests/testSrc/com/intellij/history/integration/ExternalChangesAndRefreshingTest.java index 74cfc98bde23..0ec801c52a9c 100644 --- a/platform/platform-tests/testSrc/com/intellij/history/integration/ExternalChangesAndRefreshingTest.java +++ b/platform/platform-tests/testSrc/com/intellij/history/integration/ExternalChangesAndRefreshingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,8 @@ import com.intellij.history.core.revisions.Revision; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.*; -import com.intellij.util.ui.UIUtil; +import com.intellij.testFramework.EdtTestUtil; +import com.intellij.util.ThrowableRunnable; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -43,17 +44,7 @@ public class ExternalChangesAndRefreshingTest extends IntegrationTestCase { // this methods waits for another thread to finish, that leads // to deadlock in swing-thread. Therefore we have to run this test // outside of swing-thread - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - try { - ExternalChangesAndRefreshingTest.super.setUp(); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - }); + EdtTestUtil.runInEdtAndWait((ThrowableRunnable)ExternalChangesAndRefreshingTest.super::setUp); } else { super.setUp(); @@ -66,25 +57,16 @@ public class ExternalChangesAndRefreshingTest extends IntegrationTestCase { // this methods waits for another thread to finish, that leads // to deadlock in swing-thread. Therefore we have to run this test // outside of swing-thread - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - try { - ExternalChangesAndRefreshingTest.super.tearDown(); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - }); + EdtTestUtil.runInEdtAndWait((ThrowableRunnable)ExternalChangesAndRefreshingTest.super::tearDown); } else { + //noinspection SuperTearDownInFinally super.tearDown(); } } @Override - protected void runBareRunnable(Runnable r) throws Throwable { + protected void runBareRunnable(ThrowableRunnable r) throws Throwable { if (getName().equals("testRefreshingAsynchronously")) { // this method waits for another thread to finish, that leads // to deadlock in swing-thread. Therefore we have to run this test @@ -118,12 +100,7 @@ public class ExternalChangesAndRefreshingTest extends IntegrationTestCase { public void testRefreshDuringCommand() { // shouldn't throw - CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { - @Override - public void run() { - refreshVFS(); - } - }, "", null); + CommandProcessor.getInstance().executeCommand(myProject, ExternalChangesAndRefreshingTest::refreshVFS, "", null); } public void testCommandDuringRefresh() throws Exception { @@ -137,19 +114,11 @@ public class ExternalChangesAndRefreshingTest extends IntegrationTestCase { }; // shouldn't throw - addFileListenerDuring(l, new Runnable() { - @Override - public void run() { - refreshVFS(); - } - }); + addFileListenerDuring(l, ExternalChangesAndRefreshingTest::refreshVFS); } private void executeSomeCommand() { - CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { - @Override - public void run() { - } + CommandProcessor.getInstance().executeCommand(myProject, () -> { }, "", null); } @@ -163,7 +132,7 @@ public class ExternalChangesAndRefreshingTest extends IntegrationTestCase { public void fileCreated(@NotNull VirtualFileEvent e) { try { if (!e.getFile().getPath().equals(path)) return; - content[0] = new String(e.getFile().contentsToByteArray()); + content[0] = new String(e.getFile().contentsToByteArray(), CharsetToolkit.UTF8_CHARSET); } catch (IOException ex) { throw new RuntimeException(ex); @@ -171,12 +140,7 @@ public class ExternalChangesAndRefreshingTest extends IntegrationTestCase { } }; - addFileListenerDuring(l, new Runnable() { - @Override - public void run() { - refreshVFS(); - } - }); + addFileListenerDuring(l, ExternalChangesAndRefreshingTest::refreshVFS); assertEquals("content", content[0]); } @@ -232,12 +196,7 @@ public class ExternalChangesAndRefreshingTest extends IntegrationTestCase { VirtualFileManager fm = VirtualFileManager.getInstance(); if (async) { - fm.asyncRefresh(new Runnable() { - @Override - public void run() { - s.release(); - } - }); + fm.asyncRefresh(s::release); } else { try { diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/LaterInvocatorTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/LaterInvocatorTest.java index 0a785f1ecd38..500b5844ffaf 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/LaterInvocatorTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/LaterInvocatorTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 + * + * http://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. + */ package com.intellij.openapi.application.impl; import com.intellij.openapi.application.ApplicationManager; @@ -7,6 +22,7 @@ import com.intellij.openapi.util.Conditions; import com.intellij.testFramework.PlatformTestCase; import com.intellij.testFramework.SkipInHeadlessEnvironment; import com.intellij.testFramework.UsefulTestCase; +import com.intellij.util.ThrowableRunnable; import com.intellij.util.ui.UIUtil; import junit.framework.TestCase; @@ -20,7 +36,7 @@ import java.util.ArrayList; public class LaterInvocatorTest extends PlatformTestCase { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.application.impl.LaterInvokatorTest"); - private final ArrayList myOrder = new ArrayList(); + private final ArrayList myOrder = new ArrayList<>(); @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized") private Window myWindow1; private Window myWindow2; @@ -59,35 +75,27 @@ public class LaterInvocatorTest extends PlatformTestCase { } }; final Exception[] exception = {null}; - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - try { - LaterInvocatorTest.super.setUp(); - final Object[] modalEntities = LaterInvocator.getCurrentModalEntities(); - if (modalEntities.length > 0) { - LOG.error( - "Expect no modal entries. Probably some of the previous tests didn't left their entries. Top entry is: " + modalEntities[0]); - } - } - catch (Exception e) { - exception[0] = e; + UIUtil.invokeAndWaitIfNeeded((Runnable)() -> { + try { + LaterInvocatorTest.super.setUp(); + final Object[] modalEntities = LaterInvocator.getCurrentModalEntities(); + if (modalEntities.length > 0) { + LOG.error( + "Expect no modal entries. Probably some of the previous tests didn't left their entries. Top entry is: " + modalEntities[0]); } } + catch (Exception e) { + exception[0] = e; + } }); if (exception[0] != null) throw exception[0]; - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - TestCase.assertFalse("Can't run test", LaterInvocator.isInModalContext()); - } - }); + UIUtil.invokeAndWaitIfNeeded((Runnable)() -> TestCase.assertFalse("Can't run test", LaterInvocator.isInModalContext())); flushSwingQueue(); } @Override - protected void runBareRunnable(Runnable runnable) throws Throwable { + protected void runBareRunnable(ThrowableRunnable runnable) throws Throwable { runnable.run(); } @@ -95,27 +103,21 @@ public class LaterInvocatorTest extends PlatformTestCase { protected void tearDown() throws Exception { myOrder.clear(); final boolean[] inModalState = {true}; - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - synchronized (inModalState) { - inModalState[0] = false; - } + ApplicationManager.getApplication().invokeLater(() -> { + synchronized (inModalState) { + inModalState[0] = false; } }, ModalityState.NON_MODAL); flushSwingQueue(); flushSwingQueue(); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - while (true) { - synchronized (inModalState) { - if (!inModalState[0]) break; - } - flushSwingQueue(); - synchronized (inModalState) { - if (inModalState[0] && LaterInvocator.isInModalContext()) LaterInvocator.leaveAllModals(); - } + UIUtil.invokeAndWaitIfNeeded((Runnable)() -> { + while (true) { + synchronized (inModalState) { + if (!inModalState[0]) break; + } + flushSwingQueue(); + synchronized (inModalState) { + if (inModalState[0] && LaterInvocator.isInModalContext()) LaterInvocator.leaveAllModals(); } } }); @@ -140,35 +142,29 @@ public class LaterInvocatorTest extends PlatformTestCase { } public void testReorder() throws InterruptedException, InvocationTargetException { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - LaterInvocator.enterModal(myWindow1); - synchronized (LaterInvocatorTest.this) { - blockSwingThread(); - ApplicationManager.getApplication().invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); - SwingUtilities.invokeLater(ENTER_MODAL); - LaterInvocator.leaveModal(myWindow1); - SwingUtilities.invokeLater(LEAVE_MODAL); - ApplicationManager.getApplication().invokeLater(new MyRunnable("2"), ModalityState.NON_MODAL); - } - flushSwingQueue(); - checkOrder(2); - } - }); - } - - public void testTrueReorder() throws InvocationTargetException, InterruptedException { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - LaterInvocator.enterModal(myWindow1); + UIUtil.invokeAndWaitIfNeeded((Runnable)() -> { + LaterInvocator.enterModal(myWindow1); + synchronized (this) { + blockSwingThread(); ApplicationManager.getApplication().invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); SwingUtilities.invokeLater(ENTER_MODAL); LaterInvocator.leaveModal(myWindow1); SwingUtilities.invokeLater(LEAVE_MODAL); ApplicationManager.getApplication().invokeLater(new MyRunnable("2"), ModalityState.NON_MODAL); } + flushSwingQueue(); + checkOrder(2); + }); + } + + public void testTrueReorder() throws InvocationTargetException, InterruptedException { + SwingUtilities.invokeLater(() -> { + LaterInvocator.enterModal(myWindow1); + ApplicationManager.getApplication().invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); + SwingUtilities.invokeLater(ENTER_MODAL); + LaterInvocator.leaveModal(myWindow1); + SwingUtilities.invokeLater(LEAVE_MODAL); + ApplicationManager.getApplication().invokeLater(new MyRunnable("2"), ModalityState.NON_MODAL); }); flushSwingQueue(); flushSwingQueue(); @@ -176,39 +172,33 @@ public class LaterInvocatorTest extends PlatformTestCase { } public void testEverInvoked() throws InvocationTargetException, InterruptedException { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - LaterInvocator.enterModal(myWindow1); - ApplicationManager.getApplication().invokeLater(ENTER_MODAL, ModalityState.NON_MODAL); - ApplicationManager.getApplication().invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); - LaterInvocator.leaveModal(myWindow1); - flushSwingQueue(); - flushSwingQueue(); - checkOrder(0); - SwingUtilities.invokeLater(LEAVE_MODAL); - flushSwingQueue(); - flushSwingQueue(); - checkOrder(1); - } + UIUtil.invokeAndWaitIfNeeded((Runnable)() -> { + LaterInvocator.enterModal(myWindow1); + ApplicationManager.getApplication().invokeLater(ENTER_MODAL, ModalityState.NON_MODAL); + ApplicationManager.getApplication().invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); + LaterInvocator.leaveModal(myWindow1); + flushSwingQueue(); + flushSwingQueue(); + checkOrder(0); + SwingUtilities.invokeLater(LEAVE_MODAL); + flushSwingQueue(); + flushSwingQueue(); + checkOrder(1); }); } public void testDoesNotInvokeWhenModal() throws InvocationTargetException, InterruptedException { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - LaterInvocator.enterModal(myWindow1); + UIUtil.invokeAndWaitIfNeeded((Runnable)() -> { + LaterInvocator.enterModal(myWindow1); - ApplicationManager.getApplication().invokeLater(ENTER_MODAL, ModalityState.NON_MODAL); - ApplicationManager.getApplication().invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); - LaterInvocator.leaveModal(myWindow1); - flushSwingQueue(); - checkOrder(0); - LaterInvocator.leaveModal(myWindow1); - flushSwingQueue(); - checkOrder(1); - } + ApplicationManager.getApplication().invokeLater(ENTER_MODAL, ModalityState.NON_MODAL); + ApplicationManager.getApplication().invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); + LaterInvocator.leaveModal(myWindow1); + flushSwingQueue(); + checkOrder(0); + LaterInvocator.leaveModal(myWindow1); + flushSwingQueue(); + checkOrder(1); }); } @@ -242,111 +232,99 @@ public class LaterInvocatorTest extends PlatformTestCase { } public void testStress() throws Exception { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - int N = 1000; - //long start = System.currentTimeMillis(); - for (int i = 0; i < N; i++) { - /* - if (i % 10 == 0) { - long elapsed = System.currentTimeMillis() - start; - System.out.println("i = " + i+"; elapsed="+elapsed); - start = System.currentTimeMillis(); - } - */ - - //assertEquals(null, Toolkit.getDefaultToolkit().getSystemEventQueue().peekEvent()); - //assertEquals(null, LaterInvocator.dumpQueue()); - - UsefulTestCase.assertEmpty(LaterInvocator.getCurrentModalEntities()); - LaterInvocator.enterModal(myWindow2); - //some weird things like MyFireIdleRequest may still sneak in - //assertEquals(null, LaterInvocator.dumpQueue()); - TestCase.assertTrue(LaterInvocator.isInModalContext()); - TestCase.assertEquals(1, LaterInvocator.getCurrentModalEntities().length); - - LaterInvocator.invokeLater(new Runnable() { - @Override - public void run() { - TestCase.assertTrue(!LaterInvocator.isInModalContext()); - } - - public String toString() { - return "ass2"; - } - }, ModalityState.NON_MODAL); - LaterInvocator.invokeLater(ENTER_MODAL, ModalityState.NON_MODAL); - - LaterInvocator.invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); - - //some weird things like MyFireIdleRequest may still sneak in - //java.util.List dump = LaterInvocator.dumpQueue(); - //assertEquals(dump.toString(), 3, dump.size()); - - LaterInvocator.leaveModal(myWindow2); - flushSwingQueue(); - if (!LaterInvocator.isInModalContext()) { - //System.out.println("inv queue" + LaterInvocator.dumpQueue()); - TestCase.fail(); - } - - checkOrder(0); - - SwingUtilities.invokeLater(LEAVE_MODAL); - flushSwingQueue(); - TestCase.assertTrue(!LaterInvocator.isInModalContext()); - - checkOrder(1); - - - LaterInvocator.leaveAllModals(); - myOrder.clear(); - flushSwingQueue(); + UIUtil.invokeAndWaitIfNeeded((Runnable)() -> { + int N = 1000; + //long start = System.currentTimeMillis(); + for (int i = 0; i < N; i++) { + /* + if (i % 10 == 0) { + long elapsed = System.currentTimeMillis() - start; + System.out.println("i = " + i+"; elapsed="+elapsed); + start = System.currentTimeMillis(); } + */ + + //assertEquals(null, Toolkit.getDefaultToolkit().getSystemEventQueue().peekEvent()); + //assertEquals(null, LaterInvocator.dumpQueue()); + + UsefulTestCase.assertEmpty(LaterInvocator.getCurrentModalEntities()); + LaterInvocator.enterModal(myWindow2); + //some weird things like MyFireIdleRequest may still sneak in + //assertEquals(null, LaterInvocator.dumpQueue()); + TestCase.assertTrue(LaterInvocator.isInModalContext()); + TestCase.assertEquals(1, LaterInvocator.getCurrentModalEntities().length); + + LaterInvocator.invokeLater(new Runnable() { + @Override + public void run() { + TestCase.assertTrue(!LaterInvocator.isInModalContext()); + } + + public String toString() { + return "ass2"; + } + }, ModalityState.NON_MODAL); + LaterInvocator.invokeLater(ENTER_MODAL, ModalityState.NON_MODAL); + + LaterInvocator.invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); + + //some weird things like MyFireIdleRequest may still sneak in + //java.util.List dump = LaterInvocator.dumpQueue(); + //assertEquals(dump.toString(), 3, dump.size()); + + LaterInvocator.leaveModal(myWindow2); + flushSwingQueue(); + if (!LaterInvocator.isInModalContext()) { + //System.out.println("inv queue" + LaterInvocator.dumpQueue()); + TestCase.fail(); + } + + checkOrder(0); + + SwingUtilities.invokeLater(LEAVE_MODAL); + flushSwingQueue(); + TestCase.assertTrue(!LaterInvocator.isInModalContext()); + + checkOrder(1); + + + LaterInvocator.leaveAllModals(); + myOrder.clear(); + flushSwingQueue(); } }); } public void testOrderWithSwingInvokeLater2() throws InterruptedException, InvocationTargetException { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - LaterInvocator.enterModal(myWindow1); - synchronized (LaterInvocatorTest.this) { - blockSwingThread(); - ApplicationManager.getApplication().invokeLater(new MyRunnable("2"), ModalityState.NON_MODAL); - SwingUtilities.invokeLater(LEAVE_MODAL); - SwingUtilities.invokeLater(new MyRunnable("1")); - ApplicationManager.getApplication().invokeLater(new MyRunnable("3"), ModalityState.NON_MODAL); - } - flushSwingQueue(); - checkOrder(3); + UIUtil.invokeAndWaitIfNeeded((Runnable)() -> { + LaterInvocator.enterModal(myWindow1); + synchronized (this) { + blockSwingThread(); + ApplicationManager.getApplication().invokeLater(new MyRunnable("2"), ModalityState.NON_MODAL); + SwingUtilities.invokeLater(LEAVE_MODAL); + SwingUtilities.invokeLater(new MyRunnable("1")); + ApplicationManager.getApplication().invokeLater(new MyRunnable("3"), ModalityState.NON_MODAL); } + flushSwingQueue(); + checkOrder(3); }); } public void testOrderWithSwingInvokeLater3() throws InterruptedException, InvocationTargetException { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - LaterInvocator.enterModal(myWindow1); - synchronized (LaterInvocatorTest.this) { - blockSwingThread(); - SwingUtilities.invokeLater(new MyRunnable("1")); - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().invokeLater(new MyRunnable("3"), ModalityState.NON_MODAL); - } - }, ModalityState.NON_MODAL); - SwingUtilities.invokeLater(LEAVE_MODAL); - ApplicationManager.getApplication().invokeLater(new MyRunnable("2"), ModalityState.NON_MODAL); - } - flushSwingQueue(); - checkOrder(3); + UIUtil.invokeAndWaitIfNeeded((Runnable)() -> { + LaterInvocator.enterModal(myWindow1); + synchronized (this) { + blockSwingThread(); + SwingUtilities.invokeLater(new MyRunnable("1")); + ApplicationManager.getApplication().invokeLater(() -> { + ApplicationManager.getApplication().invokeLater(new MyRunnable("3"), ModalityState.NON_MODAL); + }, ModalityState.NON_MODAL); + SwingUtilities.invokeLater(LEAVE_MODAL); + ApplicationManager.getApplication().invokeLater(new MyRunnable("2"), ModalityState.NON_MODAL); } + flushSwingQueue(); + checkOrder(3); }); } @@ -354,7 +332,7 @@ public class LaterInvocatorTest extends PlatformTestCase { UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { - final ArrayList consumed = new ArrayList(); + final ArrayList consumed = new ArrayList<>(); synchronized (LaterInvocatorTest.this) { blockSwingThread(); ApplicationManager.getApplication().getInvokator().invokeLater(new Runnable() { @@ -368,19 +346,9 @@ public class LaterInvocatorTest extends PlatformTestCase { } }, Conditions.alwaysTrue()); } - }, ModalityState.NON_MODAL).doWhenDone(new Runnable() { - @Override - public void run() { - consumed.add("1"); - } - }); + }, ModalityState.NON_MODAL).doWhenDone(() -> consumed.add("1")); ApplicationManager.getApplication().getInvokator().invokeLater(new MyRunnable("2"), ModalityState.NON_MODAL) - .doWhenDone(new Runnable() { - @Override - public void run() { - consumed.add("2"); - } - }); + .doWhenDone(() -> consumed.add("2")); } flushSwingQueue(); @@ -390,31 +358,25 @@ public class LaterInvocatorTest extends PlatformTestCase { } public void testOrderWithSwingInvokeLater4() throws InterruptedException, InvocationTargetException { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - SwingUtilities.invokeLater(ENTER_MODAL); - flushSwingQueue(); - synchronized (LaterInvocatorTest.this) { - blockSwingThread(); - SwingUtilities.invokeLater(new MyRunnable("1")); - ApplicationManager.getApplication().invokeLater(new MyRunnable("3"), ModalityState.NON_MODAL); - SwingUtilities.invokeLater(LEAVE_MODAL); - SwingUtilities.invokeLater(ENTER_MODAL); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - SwingUtilities.invokeLater(new MyRunnable("2")); - ApplicationManager.getApplication().invokeLater(new MyRunnable("5"), ModalityState.NON_MODAL); - } - }); - ApplicationManager.getApplication().invokeLater(new MyRunnable("4"), ModalityState.NON_MODAL); - } - flushSwingQueue(); + UIUtil.invokeAndWaitIfNeeded((Runnable)() -> { + SwingUtilities.invokeLater(ENTER_MODAL); + flushSwingQueue(); + synchronized (this) { + blockSwingThread(); + SwingUtilities.invokeLater(new MyRunnable("1")); + ApplicationManager.getApplication().invokeLater(new MyRunnable("3"), ModalityState.NON_MODAL); SwingUtilities.invokeLater(LEAVE_MODAL); - flushSwingQueue(); - checkOrder(5); + SwingUtilities.invokeLater(ENTER_MODAL); + SwingUtilities.invokeLater(() -> { + SwingUtilities.invokeLater(new MyRunnable("2")); + ApplicationManager.getApplication().invokeLater(new MyRunnable("5"), ModalityState.NON_MODAL); + }); + ApplicationManager.getApplication().invokeLater(new MyRunnable("4"), ModalityState.NON_MODAL); } + flushSwingQueue(); + SwingUtilities.invokeLater(LEAVE_MODAL); + flushSwingQueue(); + checkOrder(5); }); } @@ -432,34 +394,28 @@ public class LaterInvocatorTest extends PlatformTestCase { } }; - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - synchronized (LaterInvocatorTest.this) { - blockSwingThread(); - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - thread.start(); - while (!started[0]) { - try { - //noinspection BusyWait - Thread.sleep(5); - } - catch (InterruptedException e) { - TestCase.fail(e.getMessage()); - } - } - synchronized (lock) { - checkOrder(0); - } + UIUtil.invokeAndWaitIfNeeded((Runnable)() -> { + synchronized (this) { + blockSwingThread(); + ApplicationManager.getApplication().invokeLater(() -> { + thread.start(); + while (!started[0]) { + try { + //noinspection BusyWait + Thread.sleep(5); } - }, ModalityState.NON_MODAL); - } - flushSwingQueue(); - flushSwingQueue(); - checkOrder(1); + catch (InterruptedException e) { + TestCase.fail(e.getMessage()); + } + } + synchronized (lock) { + checkOrder(0); + } + }, ModalityState.NON_MODAL); } + flushSwingQueue(); + flushSwingQueue(); + checkOrder(1); }); } @@ -558,26 +514,23 @@ public class LaterInvocatorTest extends PlatformTestCase { } public void testInvokeLaterWithNonexistentModalityStateIsInvokedInLowerModalityState() throws Exception { - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { - LaterInvocator.enterModal(myWindow2); - ModalityState window2State = ModalityState.current(); - LaterInvocator.leaveModal(myWindow2); - LaterInvocator.invokeLater(new MyRunnable("1"), window2State); + SwingUtilities.invokeAndWait(() -> { + LaterInvocator.enterModal(myWindow2); + ModalityState window2State = ModalityState.current(); + LaterInvocator.leaveModal(myWindow2); + LaterInvocator.invokeLater(new MyRunnable("1"), window2State); - LaterInvocator.enterModal(myWindow1); - flushSwingQueue(); - checkOrder(0); + LaterInvocator.enterModal(myWindow1); + flushSwingQueue(); + checkOrder(0); - LaterInvocator.leaveModal(myWindow1); - flushSwingQueue(); - checkOrder(1); + LaterInvocator.leaveModal(myWindow1); + flushSwingQueue(); + checkOrder(1); - LaterInvocator.invokeLater(new MyRunnable("2"), window2State); - flushSwingQueue(); - checkOrder(2); - } + LaterInvocator.invokeLater(new MyRunnable("2"), window2State); + flushSwingQueue(); + checkOrder(2); }); } } diff --git a/platform/testFramework/src/com/intellij/testFramework/CompositeException.java b/platform/testFramework/src/com/intellij/testFramework/CompositeException.java deleted file mode 100644 index 4e1e38301e70..000000000000 --- a/platform/testFramework/src/com/intellij/testFramework/CompositeException.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2000-2015 JetBrains s.r.o. - * - * 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 - * - * http://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. - */ -package com.intellij.testFramework; - -import com.intellij.util.CommonProcessors; -import com.intellij.util.Function; -import com.intellij.util.Processor; -import org.jetbrains.annotations.NotNull; - -import java.io.PrintStream; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class CompositeException extends Exception { - private final List myExceptions = new ArrayList(); - public CompositeException(@NotNull Throwable... e) { - myExceptions.addAll(Arrays.asList(e)); - } - - public void add(@NotNull Throwable e) { - if (e instanceof CompositeException) { - myExceptions.addAll(((CompositeException)e).myExceptions); - } - else { - myExceptions.add(e); - } - } - - public void addAll(@NotNull List errors) { - myExceptions.addAll(errors); - } - - public boolean isEmpty() { - return myExceptions.isEmpty(); - } - - @Override - public String getMessage() { - return processAll(new Function() { - @Override - public String fun(Throwable throwable) { - return throwable.getMessage(); - } - }, CommonProcessors.alwaysTrue()); - } - - @Override - public String getLocalizedMessage() { - return processAll(new Function() { - @Override - public String fun(Throwable throwable) { - return throwable.getLocalizedMessage(); - } - }, CommonProcessors.alwaysTrue()); - } - - @Override - public String toString() { - return processAll(new Function() { - @Override - public String fun(Throwable throwable) { - return throwable.toString(); - } - }, CommonProcessors.alwaysTrue()); - } - - @Override - public void printStackTrace(final PrintStream s) { - processAll(new Function() { - @Override - public String fun(Throwable throwable) { - throwable.printStackTrace(s); - return ""; - } - }, new Processor() { - @Override - public boolean process(String str) { - s.print(str); - return false; - } - }); - } - - @Override - public void printStackTrace(final PrintWriter s) { - processAll(new Function() { - @Override - public String fun(Throwable throwable) { - throwable.printStackTrace(s); - return ""; - } - }, new Processor() { - @Override - public boolean process(String str) { - s.print(str); - return false; - } - }); - } - - private String processAll(Function exceptionProcessor, Processor stringProcessor) { - if (myExceptions.size() == 1) { - Throwable throwable = myExceptions.get(0); - String s = exceptionProcessor.fun(throwable); - stringProcessor.process(s); - return s; - } - - StringBuilder sb = new StringBuilder(); - String line = "CompositeException ("+myExceptions.size() +" nested):\n------------------------------\n"; - stringProcessor.process(line); - sb.append(line); - - for (int i = 0; i < myExceptions.size(); i++) { - Throwable exception = myExceptions.get(i); - - line = "[" + i + "]: "; - stringProcessor.process(line); - sb.append(line); - - line = exceptionProcessor.fun(exception); - if (line == null) line = "null\n"; - else if (!line.endsWith("\n")) line += '\n'; - stringProcessor.process(line); - sb.append(line); - } - - line = "------------------------------\n"; - stringProcessor.process(line); - sb.append(line); - - return sb.toString(); - } - - public void throwIfNotEmpty() throws CompositeException { - if (!isEmpty()) throw this; - } -} diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java index 97dc8dfb07b8..b3a5892ce05d 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java @@ -95,10 +95,7 @@ import com.intellij.psi.impl.PsiManagerImpl; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl; import com.intellij.psi.templateLanguages.TemplateDataLanguageMappings; import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl; -import com.intellij.util.GCUtil; -import com.intellij.util.IncorrectOperationException; -import com.intellij.util.LocalTimeCounter; -import com.intellij.util.ThrowableRunnable; +import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.indexing.UnindexedFilesUpdater; import com.intellij.util.lang.CompoundRuntimeException; @@ -446,30 +443,45 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da protected void tearDown() throws Exception { Project project = getProject(); CodeStyleSettingsManager.getInstance(project).dropTemporarySettings(); - List errors = checkForSettingsDamage(); + List errors = new SmartList(); try { - doTearDown(project, ourApplication, true); + checkForSettingsDamage(errors); + doTearDown(project, ourApplication, true, errors); + } + catch (Throwable e) { + errors.add(e); + } + + try { + //noinspection SuperTearDownInFinally + super.tearDown(); + } + catch (Throwable e) { + errors.add(e); + } + + try { + myThreadTracker.checkLeak(); + InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project); + ((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).assertPointersAreDisposed(); + } + catch (Throwable e) { + errors.add(e); } finally { - try { - super.tearDown(); - } - finally { - myThreadTracker.checkLeak(); - InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project); - ((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).assertPointersAreDisposed(); - CompoundRuntimeException.doThrow(errors); - } + CompoundRuntimeException.throwIfNotEmpty(errors); } } - public static void doTearDown(@NotNull final Project project, @NotNull IdeaTestApplication application, boolean checkForEditors) throws Exception { + public static void doTearDown(@NotNull final Project project, @NotNull IdeaTestApplication application, boolean checkForEditors, @NotNull List exceptions) throws Exception { PsiDocumentManagerImpl documentManager; try { ((FileTypeManagerImpl)FileTypeManager.getInstance()).drainReDetectQueue(); DocumentCommitThread.getInstance().clearQueue(); CodeStyleSettingsManager.getInstance(project).dropTemporarySettings(); - checkAllTimersAreDisposed(); + + checkAllTimersAreDisposed(exceptions); + UsefulTestCase.doPostponedFormatting(project); LookupManager lookupManager = LookupManager.getInstance(project); @@ -478,9 +490,11 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da } ((StartupManagerImpl)StartupManager.getInstance(project)).prepareForNextTest(); InspectionProfileManager.getInstance().deleteProfile(PROFILE); - assertNotNull("Application components damaged", ProjectManager.getInstance()); + if (ProjectManager.getInstance() == null) { + exceptions.add(new AssertionError("Application components damaged")); + } - new WriteCommandAction.Simple(project) { + ContainerUtil.addIfNotNull(exceptions, new WriteCommandAction.Simple(project) { @Override protected void run() throws Throwable { if (ourSourceRoot != null) { @@ -506,7 +520,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da ((FileDocumentManagerImpl)manager).dropAllUnsavedDocuments(); } } - }.execute().throwException(); + }.execute().getThrowable()); assertFalse(PsiManager.getInstance(project).isDisposed()); if (!ourAssertionsInTestDetected) { @@ -518,7 +532,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da ((HintManagerImpl)HintManager.getInstance()).cleanup(); DocumentCommitThread.getInstance().clearQueue(); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { + EdtTestUtil.runInEdtAndWait(new Runnable() { @Override public void run() { ((UndoManagerImpl)UndoManager.getGlobalInstance()).dropHistoryInTests(); @@ -532,16 +546,14 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da } finally { ProjectManagerEx.getInstanceEx().closeTestProject(project); + application.setDataProvider(null); + ourTestCase = null; + ((PsiManagerImpl)PsiManager.getInstance(project)).cleanupForNextTest(); + CompletionProgressIndicator.cleanupForNextTest(); } - application.setDataProvider(null); - ourTestCase = null; - ((PsiManagerImpl)PsiManager.getInstance(project)).cleanupForNextTest(); - - CompletionProgressIndicator.cleanupForNextTest(); - if (checkForEditors) { - checkEditorsReleased(); + checkEditorsReleased(exceptions); } documentManager.clearUncommittedDocuments(); @@ -566,30 +578,30 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da return documentManager; } - public static void checkEditorsReleased() throws Exception { - CompositeException result = new CompositeException(); - final Editor[] allEditors = EditorFactory.getInstance().getAllEditors(); - if (allEditors.length > 0) { - for (Editor editor : allEditors) { - try { - EditorFactoryImpl.throwNotReleasedError(editor); - } - catch (Throwable e) { - result.add(e); - } - finally { - EditorFactory.getInstance().releaseEditor(editor); - } - } + public static void checkEditorsReleased(@NotNull List exceptions) { + Editor[] allEditors = EditorFactory.getInstance().getAllEditors(); + if (allEditors.length == 0) { + return; + } + + for (Editor editor : allEditors) { try { - ((EditorImpl)allEditors[0]).throwDisposalError("Unreleased editors: " + allEditors.length); + EditorFactoryImpl.throwNotReleasedError(editor); } catch (Throwable e) { - e.printStackTrace(); - result.add(e); + exceptions.add(e); + } + finally { + EditorFactory.getInstance().releaseEditor(editor); } } - if (!result.isEmpty()) throw result; + + try { + ((EditorImpl)allEditors[0]).throwDisposalError("Unreleased editors: " + allEditors.length); + } + catch (Throwable e) { + exceptions.add(e); + } } @Override diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index faf43850bc4e..882ac14bde7a 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -69,8 +69,11 @@ import com.intellij.psi.impl.PsiManagerImpl; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl; import com.intellij.util.PathUtilRt; import com.intellij.util.PlatformUtils; +import com.intellij.util.SmartList; +import com.intellij.util.ThrowableRunnable; import com.intellij.util.indexing.IndexableSetContributor; import com.intellij.util.indexing.IndexedRootsProvider; +import com.intellij.util.lang.CompoundRuntimeException; import com.intellij.util.ui.UIUtil; import junit.framework.TestCase; import org.jetbrains.annotations.NonNls; @@ -91,6 +94,7 @@ import java.net.URL; import java.nio.charset.Charset; import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -427,23 +431,24 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro @Override protected void tearDown() throws Exception { - CompositeException result = new CompositeException(); + List exceptions = new SmartList(); Project project = myProject; if (project != null) { try { - LightPlatformTestCase.doTearDown(project, ourApplication, false); - disposeProject(result); + LightPlatformTestCase.doTearDown(project, ourApplication, false, exceptions); } catch (Throwable e) { - result.add(e); + exceptions.add(e); } + + disposeProject(exceptions); } try { - result.addAll(checkForSettingsDamage()); + checkForSettingsDamage(exceptions); } catch (Throwable e) { - result.add(e); + exceptions.add(e); } try { if (project != null) { @@ -451,7 +456,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project); } catch (AssertionError e) { - result.add(e); + exceptions.add(e); } } try { @@ -461,12 +466,12 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro LocalFileSystem.getInstance().refreshIoFiles(myFilesToDelete); } catch (Throwable e) { - result.add(e); + exceptions.add(e); } if (!myAssertionsInTestDetected) { if (IdeaLogger.ourErrorsOccurred != null) { - result.add(IdeaLogger.ourErrorsOccurred); + exceptions.add(IdeaLogger.ourErrorsOccurred); } } @@ -474,7 +479,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro super.tearDown(); } catch (Throwable e) { - result.add(e); + exceptions.add(e); } try { @@ -483,7 +488,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } } catch (AssertionError error) { - result.add(error); + exceptions.add(error); } try { if (myThreadTracker != null) { @@ -491,13 +496,13 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } } catch (AssertionError error) { - result.add(error); + exceptions.add(error); } try { - LightPlatformTestCase.checkEditorsReleased(); + LightPlatformTestCase.checkEditorsReleased(exceptions); } catch (Throwable error) { - result.add(error); + exceptions.add(error); } } finally { @@ -509,10 +514,10 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro myThreadTracker = null; ourTestCase = null; } - if (!result.isEmpty()) throw result; + CompoundRuntimeException.throwIfNotEmpty(exceptions); } - private void disposeProject(@NotNull CompositeException result) /* throws nothing */ { + private void disposeProject(@NotNull List exceptions) { try { DocumentCommitThread.getInstance().clearQueue(); // sometimes SwingUtilities maybe confused about EDT at this point @@ -521,7 +526,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } } catch (Throwable e) { - result.add(e); + exceptions.add(e); } Project project = myProject; @@ -529,35 +534,33 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro return; } - closeAndDisposeProjectAndCheckThatNoOpenProjects(project, result); + closeAndDisposeProjectAndCheckThatNoOpenProjects(project, exceptions); myProject = null; } - public static void closeAndDisposeProjectAndCheckThatNoOpenProjects(@NotNull Project projectToClose) throws CompositeException { - CompositeException compositeException = new CompositeException(); - closeAndDisposeProjectAndCheckThatNoOpenProjects(projectToClose, compositeException); - if (!compositeException.isEmpty()) { - throw compositeException; - } + public static void closeAndDisposeProjectAndCheckThatNoOpenProjects(@NotNull Project projectToClose) { + List exceptions = new SmartList(); + closeAndDisposeProjectAndCheckThatNoOpenProjects(projectToClose, exceptions); + CompoundRuntimeException.throwIfNotEmpty(exceptions); } - public static void closeAndDisposeProjectAndCheckThatNoOpenProjects(@NotNull Project projectToClose, @NotNull CompositeException result) { + public static void closeAndDisposeProjectAndCheckThatNoOpenProjects(@NotNull Project projectToClose, @NotNull List exceptions) { try { ProjectManagerEx projectManager = ProjectManagerEx.getInstanceEx(); if (projectManager instanceof ProjectManagerImpl) { for (Project project : projectManager.closeTestProject(projectToClose)) { - result.add(new IllegalStateException("Test project is not disposed: " + project + ";\n created in: " + getCreationPlace(project))); + exceptions.add(new IllegalStateException("Test project is not disposed: " + project + ";\n created in: " + getCreationPlace(project))); try { ((ProjectManagerImpl)projectManager).closeProject(project, false, true, false); } catch (Throwable e) { - result.add(e); + exceptions.add(e); } } } } catch (Throwable e) { - result.add(e); + exceptions.add(e); } finally { AccessToken token = WriteAction.start(); @@ -565,7 +568,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro Disposer.dispose(projectToClose); } catch (Throwable e) { - result.add(e); + exceptions.add(e); } finally { token.finish(); @@ -646,10 +649,9 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } private void runBareImpl() throws Throwable { - final Throwable[] throwables = new Throwable[1]; - Runnable runnable = new Runnable() { + ThrowableRunnable runnable = new ThrowableRunnable() { @Override - public void run() { + public void run() throws Throwable { ourTestThread = Thread.currentThread(); ourTestTime = getTimeRequired(); try { @@ -657,31 +659,37 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro setUp(); } catch (Throwable e) { - CompositeException result = new CompositeException(e); try { tearDown(); } - catch (Throwable th) { - result.add(th); + catch (Throwable ignored) { } - throw result; + + throw e; } + + Throwable exception = null; try { myAssertionsInTestDetected = true; runTest(); myAssertionsInTestDetected = false; } catch (Throwable e) { - throwables[0] = e; - throw e; + exception = e; } finally { - tearDown(); + try { + tearDown(); + } + catch (Throwable e) { + if (exception == null) { + exception = e; + } + } } - } - catch (Throwable throwable) { - if (throwables[0] == null) { // report tearDown() problems if only no exceptions thrown from runTest() - throwables[0] = throwable; + + if (exception != null) { + throw exception; } } finally { @@ -696,10 +704,6 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro throw IdeaLogger.ourErrorsOccurred; } - if (throwables[0] != null) { - throw throwables[0]; - } - // just to make sure all deferred Runnable's to finish waitForAllLaters(); if (IdeaLogger.ourErrorsOccurred != null) { @@ -730,9 +734,9 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro return true; } - protected void runBareRunnable(Runnable runnable) throws Throwable { + protected void runBareRunnable(ThrowableRunnable runnable) throws Throwable { if (isRunInEdt()) { - SwingUtilities.invokeAndWait(runnable); + EdtTestUtil.runInEdtAndWait(runnable); } else { runnable.run(); diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java index adfba7e6ec13..193eae27b047 100644 --- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java @@ -233,26 +233,23 @@ public abstract class UsefulTestCase extends TestCase { containerMap.clear(); } - @NotNull - protected List checkForSettingsDamage() throws Exception { + protected void checkForSettingsDamage(@NotNull List exceptions) { Application app = ApplicationManager.getApplication(); if (isPerformanceTest() || app == null || app instanceof MockApplication) { - return Collections.emptyList(); + return; } CodeStyleSettings oldCodeStyleSettings = myOldCodeStyleSettings; if (oldCodeStyleSettings == null) { - return Collections.emptyList(); + return; } myOldCodeStyleSettings = null; - return doCheckForSettingsDamage(oldCodeStyleSettings, getCurrentCodeStyleSettings()); + doCheckForSettingsDamage(oldCodeStyleSettings, getCurrentCodeStyleSettings(), exceptions); } - @NotNull - public static List doCheckForSettingsDamage(@NotNull CodeStyleSettings oldCodeStyleSettings, @NotNull CodeStyleSettings currentCodeStyleSettings) throws Exception { - List result = new SmartList(); + public static void doCheckForSettingsDamage(@NotNull CodeStyleSettings oldCodeStyleSettings, @NotNull CodeStyleSettings currentCodeStyleSettings, @NotNull List exceptions) { final CodeInsightSettings settings = CodeInsightSettings.getInstance(); try { Element newS = new Element("temp"); @@ -268,15 +265,15 @@ public abstract class UsefulTestCase extends TestCase { catch (Exception ignored) { } } - result.add(error); + exceptions.add(error); } currentCodeStyleSettings.getIndentOptions(StdFileTypes.JAVA); try { checkSettingsEqual(oldCodeStyleSettings, currentCodeStyleSettings, "Code style settings damaged"); } - catch (AssertionError e) { - result.add(e); + catch (Throwable e) { + exceptions.add(e); } finally { currentCodeStyleSettings.clearCodeStyleSettings(); @@ -286,16 +283,14 @@ public abstract class UsefulTestCase extends TestCase { InplaceRefactoring.checkCleared(); } catch (AssertionError e) { - result.add(e); + exceptions.add(e); } try { StartMarkAction.checkCleared(); } catch (AssertionError e) { - result.add(e); + exceptions.add(e); } - - return result; } protected void storeSettings() { @@ -858,7 +853,7 @@ public abstract class UsefulTestCase extends TestCase { }); } - protected static void checkAllTimersAreDisposed() { + protected static void checkAllTimersAreDisposed(@NotNull List exceptions) { Field firstTimerF; Object timerQueue; Object timer; @@ -881,8 +876,10 @@ public abstract class UsefulTestCase extends TestCase { } } catch (Throwable e) { - throw new RuntimeException(e); + exceptions.add(e); + return; } + if (timer != null) { if (firstTimerF != null) { ReflectionUtil.resetField(timerQueue, firstTimerF); @@ -897,13 +894,13 @@ public abstract class UsefulTestCase extends TestCase { timer = getTimer.invoke(timer); } catch (Exception e) { - throw new RuntimeException(e); + exceptions.add(e); + return; } } Timer t = (Timer)timer; text = "Timer (listeners: "+Arrays.asList(t.getActionListeners()) + ") "+text; - - fail("Not disposed Timer: " + text + "; queue:" + timerQueue); + exceptions.add(new AssertionFailedError("Not disposed Timer: " + text + "; queue:" + timerQueue)); } } diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java index 0e6a97e16583..cfd56708a0d3 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java @@ -48,7 +48,9 @@ import com.intellij.testFramework.*; import com.intellij.testFramework.builders.ModuleFixtureBuilder; import com.intellij.testFramework.fixtures.HeavyIdeaTestFixture; import com.intellij.util.PathUtil; +import com.intellij.util.SmartList; import com.intellij.util.ThrowableRunnable; +import com.intellij.util.lang.CompoundRuntimeException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -60,12 +62,14 @@ import java.io.IOException; import java.io.PrintStream; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.List; import java.util.Set; /** * Creates new project for each test. * @author mike */ +@SuppressWarnings("TestOnlyProblems") class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixture { private Project myProject; private final Set myFilesToDelete = new HashSet(); @@ -99,43 +103,48 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu @Override public void tearDown() throws Exception { final Project project = getProject(); + final List exceptions = new SmartList(); try { - LightPlatformTestCase.doTearDown(project, myApplication, false); + LightPlatformTestCase.doTearDown(project, myApplication, false, exceptions); for (ModuleFixtureBuilder moduleFixtureBuilder : myModuleFixtureBuilders) { moduleFixtureBuilder.getFixture().tearDown(); } - final CompositeException compositeException = new CompositeException(); EdtTestUtil.runInEdtAndWait(new ThrowableRunnable() { @Override public void run() throws Throwable { - PlatformTestCase.closeAndDisposeProjectAndCheckThatNoOpenProjects(project, compositeException); + PlatformTestCase.closeAndDisposeProjectAndCheckThatNoOpenProjects(project, exceptions); } }); myProject = null; for (File fileToDelete : myFilesToDelete) { if (!FileUtil.delete(fileToDelete)) { - compositeException.add(new IOException("Can't delete " + fileToDelete)); + exceptions.add(new IOException("Can't delete " + fileToDelete)); } } + } + catch (Throwable e) { + exceptions.add(e); + } - if (!compositeException.isEmpty()) { - throw compositeException; - } + try { + super.tearDown(); + } + catch (Throwable e) { + exceptions.add(e); + } + + try { + myEditorListenerTracker.checkListenersLeak(); + myThreadTracker.checkLeak(); + LightPlatformTestCase.checkEditorsReleased(exceptions); + PlatformTestCase.cleanupApplicationCaches(project); + InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project); } finally { - try { - super.tearDown(); - } - finally { - myEditorListenerTracker.checkListenersLeak(); - myThreadTracker.checkLeak(); - LightPlatformTestCase.checkEditorsReleased(); - PlatformTestCase.cleanupApplicationCaches(project); - InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project); - } + CompoundRuntimeException.throwIfNotEmpty(exceptions); } } diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java index 97c9c590d488..99ff8d2cb5b8 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java @@ -28,6 +28,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl; import com.intellij.testFramework.*; import com.intellij.testFramework.fixtures.LightIdeaTestFixture; +import com.intellij.util.SmartList; import com.intellij.util.lang.CompoundRuntimeException; import java.util.List; @@ -64,15 +65,19 @@ public class LightIdeaTestFixtureImpl extends BaseFixture implements LightIdeaTe CodeStyleSettingsManager.getInstance(project).dropTemporarySettings(); CodeStyleSettings oldCodeStyleSettings = myOldCodeStyleSettings; myOldCodeStyleSettings = null; - @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - List errors = UsefulTestCase.doCheckForSettingsDamage(oldCodeStyleSettings, getCurrentCodeStyleSettings()); + List exceptions = new SmartList(); + try { + UsefulTestCase.doCheckForSettingsDamage(oldCodeStyleSettings, getCurrentCodeStyleSettings(), exceptions); - LightPlatformTestCase.doTearDown(project, LightPlatformTestCase.getApplication(), true); - super.tearDown(); - InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project); - PersistentFS.getInstance().clearIdCache(); - PlatformTestCase.cleanupApplicationCaches(project); - CompoundRuntimeException.doThrow(errors); + LightPlatformTestCase.doTearDown(project, LightPlatformTestCase.getApplication(), true, exceptions); + super.tearDown(); + InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project); + PersistentFS.getInstance().clearIdCache(); + PlatformTestCase.cleanupApplicationCaches(project); + } + finally { + CompoundRuntimeException.throwIfNotEmpty(exceptions); + } } @Override diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt b/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt index af14d1b043f8..bb8ddc710b74 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt +++ b/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt @@ -168,7 +168,7 @@ public class RuleChain(vararg val rules: TestRule) : TestRule { } } - CompoundRuntimeException.doThrow(errors) + CompoundRuntimeException.throwIfNotEmpty(errors) return statement } } @@ -259,7 +259,7 @@ public class DisposeModulesRule(private val projectRule: ProjectRule) : External } } } - CompoundRuntimeException.doThrow(errors) + CompoundRuntimeException.throwIfNotEmpty(errors) } } } \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/lang/CompoundRuntimeException.java b/platform/util/src/com/intellij/util/lang/CompoundRuntimeException.java index 28ccf8d25eea..c7ee6325fa41 100644 --- a/platform/util/src/com/intellij/util/lang/CompoundRuntimeException.java +++ b/platform/util/src/com/intellij/util/lang/CompoundRuntimeException.java @@ -15,6 +15,9 @@ */ package com.intellij.util.lang; +import com.intellij.util.Consumer; +import com.intellij.util.EmptyConsumer; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,31 +30,111 @@ import java.util.List; * @author mike */ public class CompoundRuntimeException extends RuntimeException { - private final List myThrowables; + private final List myExceptions; public CompoundRuntimeException(@NotNull List throwables) { - //noinspection HardCodedStringLiteral - super("Several Exceptions occurred", throwables.get(0)); - - myThrowables = throwables; + myExceptions = throwables; } @Override - public void printStackTrace(PrintStream s) { - for (Throwable throwable : myThrowables) { - throwable.printStackTrace(s); - } + public String getMessage() { + return processAll(new Function() { + @Override + public String fun(Throwable throwable) { + return throwable.getMessage(); + } + }, EmptyConsumer.getInstance()); } - @Override - public void printStackTrace(PrintWriter s) { - for (Throwable throwable : myThrowables) { - throwable.printStackTrace(s); - } + public String getLocalizedMessage() { + return processAll(new Function() { + @Override + public String fun(Throwable throwable) { + return throwable.getLocalizedMessage(); + } + }, EmptyConsumer.getInstance()); } - public static void doThrow(@Nullable List throwables) { + @Override + public String toString() { + return processAll(new Function() { + @Override + public String fun(Throwable throwable) { + return throwable.toString(); + } + }, EmptyConsumer.getInstance()); + } + + @Override + public void printStackTrace(final PrintStream s) { + processAll(new Function() { + @Override + public String fun(Throwable throwable) { + throwable.printStackTrace(s); + return ""; + } + }, new Consumer() { + @Override + public void consume(String str) { + s.print(str); + } + }); + } + + @Override + public void printStackTrace(final PrintWriter s) { + processAll(new Function() { + @Override + public String fun(Throwable throwable) { + throwable.printStackTrace(s); + return ""; + } + }, new Consumer() { + @Override + public void consume(String str) { + s.print(str); + } + }); + } + + private String processAll(@NotNull Function exceptionProcessor, @NotNull Consumer stringProcessor) { + if (myExceptions.size() == 1) { + Throwable throwable = myExceptions.get(0); + String s = exceptionProcessor.fun(throwable); + stringProcessor.consume(s); + return s; + } + + StringBuilder sb = new StringBuilder(); + String line = "CompositeException (" + myExceptions.size() + " nested):\n------------------------------\n"; + stringProcessor.consume(line); + sb.append(line); + + for (int i = 0; i < myExceptions.size(); i++) { + Throwable exception = myExceptions.get(i); + + line = "[" + i + "]: "; + stringProcessor.consume(line); + sb.append(line); + + line = exceptionProcessor.fun(exception); + if (line == null) { + line = "null\n"; + } + else if (!line.endsWith("\n")) line += '\n'; + stringProcessor.consume(line); + sb.append(line); + } + + line = "------------------------------\n"; + stringProcessor.consume(line); + sb.append(line); + + return sb.toString(); + } + + public static void throwIfNotEmpty(@Nullable List throwables) { if (ContainerUtil.isEmpty(throwables)) { return; } diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java index bf0c9eebb1bb..24aea3a633fa 100644 --- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java +++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,9 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.Trinity; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.testFramework.EdtTestUtil; import com.intellij.testFramework.PlatformTestCase; +import com.intellij.util.ThrowableRunnable; import com.intellij.util.concurrency.Semaphore; import com.intellij.util.ui.UIUtil; import junit.framework.Assert; @@ -46,21 +48,18 @@ public class SvnAuthenticationTest extends PlatformTestCase { private SvnConfiguration myConfiguration; @Override - protected void runBareRunnable(Runnable runnable) throws Throwable { + protected void runBareRunnable(ThrowableRunnable runnable) throws Throwable { runnable.run(); } @Override protected void setUp() throws Exception { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - try { - SvnAuthenticationTest.super.setUp(); - } - catch (Exception e) { - throw new RuntimeException(e); - } + EdtTestUtil.runInEdtAndWait((Runnable)() -> { + try { + SvnAuthenticationTest.super.setUp(); + } + catch (Exception e) { + throw new RuntimeException(e); } }); diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnAuthenticationTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnAuthenticationTest.java index e8068989374b..3842e0ae125e 100644 --- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnAuthenticationTest.java +++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnAuthenticationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,18 +20,15 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.Trinity; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.testFramework.EdtTestUtil; import com.intellij.testFramework.PlatformTestCase; +import com.intellij.util.ThrowableRunnable; import com.intellij.util.concurrency.Semaphore; import com.intellij.util.ui.UIUtil; import junit.framework.Assert; -import org.jetbrains.idea.svn.auth.SvnAuthenticationManager; -import org.jetbrains.idea.svn.auth.SvnAuthenticationNotifier; import org.jetbrains.idea.svn.SvnConfiguration; import org.jetbrains.idea.svn.SvnVcs; -import org.jetbrains.idea.svn.auth.ProviderType; -import org.jetbrains.idea.svn.auth.SvnAuthenticationInteraction; -import org.jetbrains.idea.svn.auth.SvnAuthenticationListener; -import org.jetbrains.idea.svn.auth.SvnAuthenticationProvider; +import org.jetbrains.idea.svn.auth.*; import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; @@ -53,21 +50,18 @@ public class SvnAuthenticationTest extends PlatformTestCase { private SvnConfiguration myConfiguration; @Override - protected void runBareRunnable(Runnable runnable) throws Throwable { + protected void runBareRunnable(ThrowableRunnable runnable) throws Throwable { runnable.run(); } @Override protected void setUp() throws Exception { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - try { - SvnAuthenticationTest.super.setUp(); - } - catch (Exception e) { - throw new RuntimeException(e); - } + EdtTestUtil.runInEdtAndWait((Runnable)() -> { + try { + SvnAuthenticationTest.super.setUp(); + } + catch (Exception e) { + throw new RuntimeException(e); } }); @@ -95,15 +89,12 @@ public class SvnAuthenticationTest extends PlatformTestCase { @Override protected void tearDown() throws Exception { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - try { - SvnAuthenticationTest.super.tearDown(); - } - catch (Exception e) { - throw new RuntimeException(e); - } + EdtTestUtil.runInEdtAndWait((Runnable)() -> { + try { + SvnAuthenticationTest.super.tearDown(); + } + catch (Exception e) { + throw new RuntimeException(e); } }); @@ -120,42 +111,39 @@ public class SvnAuthenticationTest extends PlatformTestCase { final SVNException[] exception = new SVNException[1]; final boolean[] result = {false}; - synchronousBackground(new Runnable() { - @Override - public void run() { - try { + synchronousBackground(() -> { + try { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - if (SystemInfo.isWindows) { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.save)); - } else { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); - } - - commonScheme(url, false, null); - Assert.assertEquals(3, listener.getCnt()); - //long start = System.currentTimeMillis(); - //waitListenerStep(start, listener, 3); - - listener.reset(); - if (!SystemInfo.isWindows) savedOnceListener.reset(); - SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - if (! SystemInfo.isWindows) { - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); - } - commonScheme(url, false, null); - //start = System.currentTimeMillis(); - //waitListenerStep(start, listener, 4); - Assert.assertEquals(SystemInfo.isWindows ? 1 : 3, listener.getCnt()); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + if (SystemInfo.isWindows) { + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.save)); + } else { + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); } - catch (SVNException e) { - exception[0] = e; + + commonScheme(url, false, null); + Assert.assertEquals(3, listener.getCnt()); + //long start = System.currentTimeMillis(); + //waitListenerStep(start, listener, 3); + + listener.reset(); + if (!SystemInfo.isWindows) savedOnceListener.reset(); + SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + if (! SystemInfo.isWindows) { + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); } - result[0] = true; + commonScheme(url, false, null); + //start = System.currentTimeMillis(); + //waitListenerStep(start, listener, 4); + Assert.assertEquals(SystemInfo.isWindows ? 1 : 3, listener.getCnt()); } + catch (SVNException e) { + exception[0] = e; + } + result[0] = true; }); Assert.assertTrue(result[0]); @@ -194,31 +182,28 @@ public class SvnAuthenticationTest extends PlatformTestCase { try { FileUtil.appendToFile(servers, "\nstore-plaintext-passwords=yes\n"); - synchronousBackground(new Runnable() { - @Override - public void run() { - try { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.save)); + synchronousBackground(() -> { + try { + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.save)); - commonScheme(url, false, null); - Assert.assertEquals(3, listener.getCnt()); - //long start = System.currentTimeMillis(); - //waitListenerStep(start, listener, 3); + commonScheme(url, false, null); + Assert.assertEquals(3, listener.getCnt()); + //long start = System.currentTimeMillis(); + //waitListenerStep(start, listener, 3); - SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - commonScheme(url, false, null); - //start = System.currentTimeMillis(); - //waitListenerStep(start, listener, 4); - Assert.assertEquals(4, listener.getCnt()); - } - catch (SVNException e) { - exception[0] = e; - } - result[0] = true; + SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + commonScheme(url, false, null); + //start = System.currentTimeMillis(); + //waitListenerStep(start, listener, 4); + Assert.assertEquals(4, listener.getCnt()); } + catch (SVNException e) { + exception[0] = e; + } + result[0] = true; }); } finally { FileUtil.delete(servers); @@ -264,35 +249,32 @@ public class SvnAuthenticationTest extends PlatformTestCase { final SVNException[] exception = new SVNException[1]; final Boolean[] result = new Boolean[1]; - synchronousBackground(new Runnable() { - @Override - public void run() { - try { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); + synchronousBackground(() -> { + try { + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); - commonScheme(url, false, null); - //long start = System.currentTimeMillis(); - //waitListenerStep(start, listener, 2); - Assert.assertEquals(2, listener.getCnt()); + commonScheme(url, false, null); + //long start = System.currentTimeMillis(); + //waitListenerStep(start, listener, 2); + Assert.assertEquals(2, listener.getCnt()); - savedOnceListener.assertNotSaved(url, ISVNAuthenticationManager.PASSWORD); - // cause is not cleared though - savedOnceListener.reset(); + savedOnceListener.assertNotSaved(url, ISVNAuthenticationManager.PASSWORD); + // cause is not cleared though + savedOnceListener.reset(); - SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - commonScheme(url, false, null); - Assert.assertEquals(4, listener.getCnt()); - //start = System.currentTimeMillis(); - //waitListenerStep(start, listener, 4); - } - catch (SVNException e) { - exception[0] = e; - } - result[0] = true; + SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + commonScheme(url, false, null); + Assert.assertEquals(4, listener.getCnt()); + //start = System.currentTimeMillis(); + //waitListenerStep(start, listener, 4); } + catch (SVNException e) { + exception[0] = e; + } + result[0] = true; }); Assert.assertTrue(result[0]); @@ -330,32 +312,29 @@ public class SvnAuthenticationTest extends PlatformTestCase { final SVNException[] exception = new SVNException[1]; final Boolean[] result = new Boolean[1]; - synchronousBackground(new Runnable() { - @Override - public void run() { - try { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); + synchronousBackground(() -> { + try { + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); - commonScheme(url, false, null); - Assert.assertEquals(2, listener.getCnt()); - Assert.assertEquals(1, myTestInteraction.getNumAuthWarn()); - myTestInteraction.reset(); - savedOnceListener.assertForAwt(); - savedOnceListener.reset(); + commonScheme(url, false, null); + Assert.assertEquals(2, listener.getCnt()); + Assert.assertEquals(1, myTestInteraction.getNumAuthWarn()); + myTestInteraction.reset(); + savedOnceListener.assertForAwt(); + savedOnceListener.reset(); - SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - commonScheme(url, false, null); - Assert.assertEquals(4, listener.getCnt()); - Assert.assertEquals(1, myTestInteraction.getNumAuthWarn()); - } - catch (SVNException e) { - exception[0] = e; - } - result[0] = true; + SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + commonScheme(url, false, null); + Assert.assertEquals(4, listener.getCnt()); + Assert.assertEquals(1, myTestInteraction.getNumAuthWarn()); } + catch (SVNException e) { + exception[0] = e; + } + result[0] = true; }); Assert.assertTrue(result[0]); @@ -391,32 +370,29 @@ public class SvnAuthenticationTest extends PlatformTestCase { final SVNException[] exception = new SVNException[1]; final Boolean[] result = new Boolean[1]; - synchronousBackground(new Runnable() { - @Override - public void run() { - try { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); + synchronousBackground(() -> { + try { + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); - commonScheme(url, false, null); - Assert.assertEquals(2, listener.getCnt()); - Assert.assertEquals(1, myTestInteraction.getNumAuthWarn()); - myTestInteraction.reset(); - savedOnceListener.assertForAwt(); - savedOnceListener.reset(); + commonScheme(url, false, null); + Assert.assertEquals(2, listener.getCnt()); + Assert.assertEquals(1, myTestInteraction.getNumAuthWarn()); + myTestInteraction.reset(); + savedOnceListener.assertForAwt(); + savedOnceListener.reset(); - SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - commonScheme(url, false, null); - Assert.assertEquals(4, listener.getCnt()); - Assert.assertEquals(1, myTestInteraction.getNumAuthWarn()); - } - catch (SVNException e) { - exception[0] = e; - } - result[0] = true; + SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + commonScheme(url, false, null); + Assert.assertEquals(4, listener.getCnt()); + Assert.assertEquals(1, myTestInteraction.getNumAuthWarn()); } + catch (SVNException e) { + exception[0] = e; + } + result[0] = true; }); Assert.assertTrue(result[0]); @@ -458,34 +434,31 @@ public class SvnAuthenticationTest extends PlatformTestCase { final SVNException[] exception = new SVNException[1]; final Boolean[] result = new Boolean[1]; - synchronousBackground(new Runnable() { - @Override - public void run() { - try { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); + synchronousBackground(() -> { + try { + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); - commonScheme(url, false, null); - Assert.assertEquals(3, listener.getCnt()); - Assert.assertEquals(1, myTestInteraction.getNumPasswordsWarn()); - myTestInteraction.reset(); - savedOnceListener.assertForAwt(); - savedOnceListener.reset(); + commonScheme(url, false, null); + Assert.assertEquals(3, listener.getCnt()); + Assert.assertEquals(1, myTestInteraction.getNumPasswordsWarn()); + myTestInteraction.reset(); + savedOnceListener.assertForAwt(); + savedOnceListener.reset(); - SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); - commonScheme(url, false, null); - Assert.assertEquals(6, listener.getCnt()); - Assert.assertEquals(1, myTestInteraction.getNumPasswordsWarn()); - } - catch (SVNException e) { - exception[0] = e; - } - result[0] = true; + SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); + commonScheme(url, false, null); + Assert.assertEquals(6, listener.getCnt()); + Assert.assertEquals(1, myTestInteraction.getNumPasswordsWarn()); } + catch (SVNException e) { + exception[0] = e; + } + result[0] = true; }); Assert.assertTrue(result[0]); @@ -521,34 +494,31 @@ public class SvnAuthenticationTest extends PlatformTestCase { final SVNException[] exception = new SVNException[1]; final Boolean[] result = new Boolean[1]; - synchronousBackground(new Runnable() { - @Override - public void run() { - try { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); + synchronousBackground(() -> { + try { + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); - commonScheme(url, false, null); - Assert.assertEquals(3, listener.getCnt()); - Assert.assertEquals(1, myTestInteraction.getNumPasswordsWarn()); - myTestInteraction.reset(); - savedOnceListener.assertForAwt(); - savedOnceListener.reset(); + commonScheme(url, false, null); + Assert.assertEquals(3, listener.getCnt()); + Assert.assertEquals(1, myTestInteraction.getNumPasswordsWarn()); + myTestInteraction.reset(); + savedOnceListener.assertForAwt(); + savedOnceListener.reset(); - SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); - commonScheme(url, false, null); - Assert.assertEquals(6, listener.getCnt()); - Assert.assertEquals(1, myTestInteraction.getNumPasswordsWarn()); - } - catch (SVNException e) { - exception[0] = e; - } - result[0] = true; + SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); + commonScheme(url, false, null); + Assert.assertEquals(6, listener.getCnt()); + Assert.assertEquals(1, myTestInteraction.getNumPasswordsWarn()); } + catch (SVNException e) { + exception[0] = e; + } + result[0] = true; }); Assert.assertTrue(result[0]); @@ -591,34 +561,31 @@ public class SvnAuthenticationTest extends PlatformTestCase { final SVNException[] exception = new SVNException[1]; final Boolean[] result = new Boolean[1]; - synchronousBackground(new Runnable() { - @Override - public void run() { - try { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); + synchronousBackground(() -> { + try { + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); - commonScheme(url, false, null); - Assert.assertEquals(3, listener.getCnt()); - Assert.assertEquals(1, myTestInteraction.getNumPasswordsWarn()); - myTestInteraction.reset(); - savedOnceListener.assertForAwt(); - savedOnceListener.reset(); + commonScheme(url, false, null); + Assert.assertEquals(3, listener.getCnt()); + Assert.assertEquals(1, myTestInteraction.getNumPasswordsWarn()); + myTestInteraction.reset(); + savedOnceListener.assertForAwt(); + savedOnceListener.reset(); - SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); - commonScheme(url, false, null); - Assert.assertEquals(6, listener.getCnt()); - Assert.assertEquals(1, myTestInteraction.getNumPasswordsWarn()); - } - catch (SVNException e) { - exception[0] = e; - } - result[0] = true; + SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); + commonScheme(url, false, null); + Assert.assertEquals(6, listener.getCnt()); + Assert.assertEquals(1, myTestInteraction.getNumPasswordsWarn()); } + catch (SVNException e) { + exception[0] = e; + } + result[0] = true; }); Assert.assertTrue(result[0]); @@ -654,34 +621,31 @@ public class SvnAuthenticationTest extends PlatformTestCase { final SVNException[] exception = new SVNException[1]; final Boolean[] result = new Boolean[1]; - synchronousBackground(new Runnable() { - @Override - public void run() { - try { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); + synchronousBackground(() -> { + try { + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); - commonScheme(url, false, null); - Assert.assertEquals(3, listener.getCnt()); - Assert.assertEquals(1, myTestInteraction.getNumSSLWarn()); - myTestInteraction.reset(); - savedOnceListener.assertForAwt(); - savedOnceListener.reset(); + commonScheme(url, false, null); + Assert.assertEquals(3, listener.getCnt()); + Assert.assertEquals(1, myTestInteraction.getNumSSLWarn()); + myTestInteraction.reset(); + savedOnceListener.assertForAwt(); + savedOnceListener.reset(); - SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); - commonScheme(url, false, null); - Assert.assertEquals(6, listener.getCnt()); - Assert.assertEquals(1, myTestInteraction.getNumSSLWarn()); - } - catch (SVNException e) { - exception[0] = e; - } - result[0] = true; + SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); + commonScheme(url, false, null); + Assert.assertEquals(6, listener.getCnt()); + Assert.assertEquals(1, myTestInteraction.getNumSSLWarn()); } + catch (SVNException e) { + exception[0] = e; + } + result[0] = true; }); Assert.assertTrue(result[0]); @@ -714,61 +678,55 @@ public class SvnAuthenticationTest extends PlatformTestCase { final SVNException[] exception = new SVNException[1]; final Boolean[] result = new Boolean[1]; - synchronousBackground(new Runnable() { - @Override - public void run() { - try { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.save)); + synchronousBackground(() -> { + try { + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.save)); - commonScheme(url, false, null); - long start = System.currentTimeMillis(); - waitListenerStep(start, listener, 3); - Assert.assertEquals(1, myTestInteraction.getNumPlaintextPrompt()); - savedOnceListener.assertSaved(url, ISVNAuthenticationManager.PASSWORD); - savedOnceListener.reset(); - myTestInteraction.reset(); + commonScheme(url, false, null); + long start = System.currentTimeMillis(); + waitListenerStep(start, listener, 3); + Assert.assertEquals(1, myTestInteraction.getNumPlaintextPrompt()); + savedOnceListener.assertSaved(url, ISVNAuthenticationManager.PASSWORD); + savedOnceListener.reset(); + myTestInteraction.reset(); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - try { - clearAuthCache(); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - }); + UIUtil.invokeAndWaitIfNeeded((Runnable)() -> { + try { + clearAuthCache(); + } + catch (Exception e) { + throw new RuntimeException(e); + } + }); - myTestInteraction.setPlaintextAnswer(false); - SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); + myTestInteraction.setPlaintextAnswer(false); + SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); - commonScheme(url, false, null); - start = System.currentTimeMillis(); - waitListenerStep(start, listener, 6); - Assert.assertEquals(1, myTestInteraction.getNumPlaintextPrompt()); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); + commonScheme(url, false, null); + start = System.currentTimeMillis(); + waitListenerStep(start, listener, 6); + Assert.assertEquals(1, myTestInteraction.getNumPlaintextPrompt()); - savedOnceListener.reset(); - myTestInteraction.reset(); - SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); - commonScheme(url, false, null); - start = System.currentTimeMillis(); - waitListenerStep(start, listener, 9); - Assert.assertEquals(1, myTestInteraction.getNumPlaintextPrompt()); - } - catch (SVNException e) { - exception[0] = e; - } - result[0] = true; + savedOnceListener.reset(); + myTestInteraction.reset(); + SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); + commonScheme(url, false, null); + start = System.currentTimeMillis(); + waitListenerStep(start, listener, 9); + Assert.assertEquals(1, myTestInteraction.getNumPlaintextPrompt()); } + catch (SVNException e) { + exception[0] = e; + } + result[0] = true; }); Assert.assertTrue(result[0]); @@ -803,36 +761,33 @@ public class SvnAuthenticationTest extends PlatformTestCase { final SVNException[] exception = new SVNException[1]; final Boolean[] result = new Boolean[1]; - synchronousBackground(new Runnable() { - @Override - public void run() { - try { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); + synchronousBackground(() -> { + try { + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); - commonScheme(url, false, null); - long start = System.currentTimeMillis(); - waitListenerStep(start, listener, 3); - Assert.assertEquals(1, myTestInteraction.getNumPlaintextPrompt()); - // actually password not saved, but save was called - savedOnceListener.assertSaved(url, ISVNAuthenticationManager.PASSWORD); - savedOnceListener.reset(); - myTestInteraction.reset(); + commonScheme(url, false, null); + long start = System.currentTimeMillis(); + waitListenerStep(start, listener, 3); + Assert.assertEquals(1, myTestInteraction.getNumPlaintextPrompt()); + // actually password not saved, but save was called + savedOnceListener.assertSaved(url, ISVNAuthenticationManager.PASSWORD); + savedOnceListener.reset(); + myTestInteraction.reset(); - listener.addStep(new Trinity(ProviderType.persistent, url2, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url2, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url2, Type.without_pasword_save)); - commonScheme(url2, false, "anotherRealm"); - start = System.currentTimeMillis(); - waitListenerStep(start, listener, 6); - Assert.assertEquals(1, myTestInteraction.getNumPlaintextPrompt()); - } - catch (SVNException e) { - exception[0] = e; - } - result[0] = true; + listener.addStep(new Trinity<>(ProviderType.persistent, url2, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url2, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url2, Type.without_pasword_save)); + commonScheme(url2, false, "anotherRealm"); + start = System.currentTimeMillis(); + waitListenerStep(start, listener, 6); + Assert.assertEquals(1, myTestInteraction.getNumPlaintextPrompt()); } + catch (SVNException e) { + exception[0] = e; + } + result[0] = true; }); Assert.assertTrue(result[0]); @@ -863,62 +818,56 @@ public class SvnAuthenticationTest extends PlatformTestCase { final SVNException[] exception = new SVNException[1]; final Boolean[] result = new Boolean[1]; - synchronousBackground(new Runnable() { - @Override - public void run() { - try { - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.save)); + synchronousBackground(() -> { + try { + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.save)); - commonScheme(url, false, null); - long start = System.currentTimeMillis(); - waitListenerStep(start, listener, 3); - Assert.assertEquals(1, myTestInteraction.getNumSSLPlaintextPrompt()); - savedOnceListener.assertSaved(url, ISVNAuthenticationManager.SSL); - savedOnceListener.reset(); - myTestInteraction.reset(); + commonScheme(url, false, null); + long start = System.currentTimeMillis(); + waitListenerStep(start, listener, 3); + Assert.assertEquals(1, myTestInteraction.getNumSSLPlaintextPrompt()); + savedOnceListener.assertSaved(url, ISVNAuthenticationManager.SSL); + savedOnceListener.reset(); + myTestInteraction.reset(); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - try { - clearAuthCache(); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - }); + UIUtil.invokeAndWaitIfNeeded((Runnable)() -> { + try { + clearAuthCache(); + } + catch (Exception e) { + throw new RuntimeException(e); + } + }); - myTestInteraction.setSSLPlaintextAnswer(false); - SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); + myTestInteraction.setSSLPlaintextAnswer(false); + SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); - commonScheme(url, false, null); - start = System.currentTimeMillis(); - waitListenerStep(start, listener, 6); - Assert.assertEquals(1, myTestInteraction.getNumSSLPlaintextPrompt()); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); + commonScheme(url, false, null); + start = System.currentTimeMillis(); + waitListenerStep(start, listener, 6); + Assert.assertEquals(1, myTestInteraction.getNumSSLPlaintextPrompt()); - SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); - myTestInteraction.reset(); - savedOnceListener.reset(); + SvnConfiguration.RUNTIME_AUTH_CACHE.clear(); + myTestInteraction.reset(); + savedOnceListener.reset(); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.request)); - listener.addStep(new Trinity(ProviderType.interactive, url, Type.request)); - listener.addStep(new Trinity(ProviderType.persistent, url, Type.without_pasword_save)); - commonScheme(url, false, null); - start = System.currentTimeMillis(); - waitListenerStep(start, listener, 9); - Assert.assertEquals(1, myTestInteraction.getNumSSLPlaintextPrompt()); - } - catch (SVNException e) { - exception[0] = e; - } - result[0] = true; + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.interactive, url, Type.request)); + listener.addStep(new Trinity<>(ProviderType.persistent, url, Type.without_pasword_save)); + commonScheme(url, false, null); + start = System.currentTimeMillis(); + waitListenerStep(start, listener, 9); + Assert.assertEquals(1, myTestInteraction.getNumSSLPlaintextPrompt()); } + catch (SVNException e) { + exception[0] = e; + } + result[0] = true; }); Assert.assertTrue(result[0]); @@ -937,14 +886,11 @@ public class SvnAuthenticationTest extends PlatformTestCase { private static void synchronousBackground(final Runnable runnable) throws InterruptedException { final Semaphore semaphore = new Semaphore(); semaphore.down(); - ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { - @Override - public void run() { - try { - runnable.run(); - } finally { - semaphore.up(); - } + ApplicationManager.getApplication().executeOnPooledThread((Runnable)() -> { + try { + runnable.run(); + } finally { + semaphore.up(); } }); semaphore.waitFor(); @@ -1049,7 +995,7 @@ public class SvnAuthenticationTest extends PlatformTestCase { private TestListener(final Object synchObject) { mySynchObject = synchObject; - myExpectedSequence = new ArrayList>(); + myExpectedSequence = new ArrayList<>(); myCnt = 0; mySuccess = true; } @@ -1087,7 +1033,7 @@ public class SvnAuthenticationTest extends PlatformTestCase { } private void saveRegistration(ProviderType type, SVNURL url, boolean withCredentials) { - mySuccess = myExpectedSequence.get(myCnt).equals(new Trinity(type, url, withCredentials ? Type.save : Type.without_pasword_save)); + mySuccess = myExpectedSequence.get(myCnt).equals(new Trinity<>(type, url, withCredentials ? Type.save : Type.without_pasword_save)); if (mySuccess) { ++ myCnt; } @@ -1106,7 +1052,7 @@ public class SvnAuthenticationTest extends PlatformTestCase { public void requested(ProviderType type, SVNURL url, String realm, String kind, boolean canceled) { if (! mySuccess) return; - mySuccess = myExpectedSequence.get(myCnt).equals(new Trinity(type, url, Type.request)); + mySuccess = myExpectedSequence.get(myCnt).equals(new Trinity<>(type, url, Type.request)); if (mySuccess) { ++ myCnt; } @@ -1127,8 +1073,8 @@ public class SvnAuthenticationTest extends PlatformTestCase { private boolean mySaveCalled; private SavedOnceListener() { - myClientRequested = new HashSet>(); - mySaved = new HashSet>(); + myClientRequested = new HashSet<>(); + mySaved = new HashSet<>(); } @Override @@ -1159,7 +1105,7 @@ public class SvnAuthenticationTest extends PlatformTestCase { } private void saveRegistration(SVNURL url, String kind) { - final Pair pair = new Pair(url, kind); + final Pair pair = new Pair<>(url, kind); if (mySaved.contains(pair)) { myCause = "saved twice"; } @@ -1167,13 +1113,13 @@ public class SvnAuthenticationTest extends PlatformTestCase { } public boolean isSaved(final SVNURL url, final String kind) { - return mySaved.contains(new Pair(url, kind)); + return mySaved.contains(new Pair<>(url, kind)); } @Override public void requested(ProviderType type, SVNURL url, String realm, String kind, boolean canceled) { if (ProviderType.interactive.equals(type)) { - final Pair pair = new Pair(url, kind); + final Pair pair = new Pair<>(url, kind); if (myClientRequested.contains(pair)) { myCause = "client requested twice"; } @@ -1186,11 +1132,11 @@ public class SvnAuthenticationTest extends PlatformTestCase { } public void assertSaved(final SVNURL url, final String kind) { - Assert.assertTrue("not saved", mySaved.contains(new Pair(url, kind))); + Assert.assertTrue("not saved", mySaved.contains(new Pair<>(url, kind))); } public void assertNotSaved(final SVNURL url, final String kind) { - Assert.assertTrue("saved", ! mySaved.contains(new Pair(url, kind))); + Assert.assertTrue("saved", ! mySaved.contains(new Pair<>(url, kind))); } } From e5ac944c7a4d90481084d4e21ad5f5d366c3b2ea Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 16:16:05 +0200 Subject: [PATCH 126/138] fix after merge --- .../src/com/intellij/testFramework/PlatformTestCase.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 882ac14bde7a..0084621f5409 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -264,8 +264,10 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro @NotNull public static Project createProject(@NotNull String path, String creationPlace) { - VirtualFile projectBase = LocalFileSystem.getInstance().findFileByIoFile(projectFile.getName().endsWith( - ProjectFileType.DOT_DEFAULT_EXTENSION) ? projectFile.getParentFile() : projectFile); + String fileName = PathUtilRt.getFileName(path); + String projectName = FileUtilRt.getNameWithoutExtension(fileName); + VirtualFile projectBase = LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(fileName.endsWith( + ProjectFileType.DOT_DEFAULT_EXTENSION) ? PathUtilRt.getParentPath(path) : path)); if (projectBase != null) { // must be leftovers from the previous test run for (VirtualFile file : ((NewVirtualFile)projectBase).iterInDbChildren()) { @@ -274,8 +276,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } try { - Project project = - ProjectManagerEx.getInstanceEx().newProject(FileUtilRt.getNameWithoutExtension(PathUtilRt.getFileName(path)), path, false, false); + Project project = ProjectManagerEx.getInstanceEx().newProject(projectName, path, false, false); assert project != null; project.putUserData(CREATION_PLACE, creationPlace); From 044759ef47bbc0fc24823f8e819183b9dd236f8d Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 16:36:39 +0200 Subject: [PATCH 127/138] cleanup --- .../intellij/openapi/components/service.kt | 9 ++-- .../src/org/jetbrains/io/netty.kt | 2 +- .../util/concurrency/AsyncPromise.kt | 39 +++++++------- .../jetbrains/util/concurrency/DonePromise.kt | 2 +- .../org/jetbrains/util/concurrency/Promise.kt | 53 +++++++++---------- .../util/concurrency/RejectedPromise.kt | 4 +- .../testSrc/com/intellij/util/Assertion.java | 2 +- .../containers/FilteringIteratorTest.java | 37 +++++++------ .../intellij/util/xmlb/XmlSerializerTest.kt | 8 +-- 9 files changed, 78 insertions(+), 78 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/components/service.kt b/platform/platform-impl/src/com/intellij/openapi/components/service.kt index f8046adffeaf..a8e27387c272 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/service.kt +++ b/platform/platform-impl/src/com/intellij/openapi/components/service.kt @@ -19,11 +19,12 @@ import com.intellij.openapi.components.ex.ComponentManagerEx import com.intellij.openapi.components.impl.stores.IComponentStore import com.intellij.openapi.project.Project -public inline fun service(): T = ServiceManager.getService(T::class.java) +inline fun service(): T = ServiceManager.getService(T::class.java) -public inline fun Project.service(): T = ServiceManager.getService(this, T::class.java) +inline fun Project.service(): T = ServiceManager.getService(this, T::class.java) -public val ComponentManager.stateStore: IComponentStore +val ComponentManager.stateStore: IComponentStore get() = if (this is Project) getPicoContainer().getComponentInstance(IComponentStore::class.java) as IComponentStore else getPicoContainer().getComponentInstance(IComponentStore::class.java.getName()) as IComponentStore -public fun ComponentManager.getComponents(baseClass: Class): List = (this as ComponentManagerEx).getComponentInstancesOfType(baseClass) \ No newline at end of file +@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") +fun ComponentManager.getComponents(baseClass: Class): List = (this as ComponentManagerEx).getComponentInstancesOfType(baseClass) \ No newline at end of file diff --git a/platform/platform-impl/src/org/jetbrains/io/netty.kt b/platform/platform-impl/src/org/jetbrains/io/netty.kt index 17377e63e398..46236aacfea0 100644 --- a/platform/platform-impl/src/org/jetbrains/io/netty.kt +++ b/platform/platform-impl/src/org/jetbrains/io/netty.kt @@ -19,7 +19,7 @@ import io.netty.bootstrap.Bootstrap import io.netty.channel.Channel import io.netty.channel.ChannelInitializer -public inline fun Bootstrap.handler(@inlineOptions(InlineOption.ONLY_LOCAL_RETURN) task: (Channel) -> Unit): Bootstrap { +public inline fun Bootstrap.handler(crossinline task: (Channel) -> Unit): Bootstrap { handler(object : ChannelInitializer() { override fun initChannel(channel: Channel) { task(channel) diff --git a/platform/platform-impl/src/org/jetbrains/util/concurrency/AsyncPromise.kt b/platform/platform-impl/src/org/jetbrains/util/concurrency/AsyncPromise.kt index 6b228c630efe..8a68d09acc77 100644 --- a/platform/platform-impl/src/org/jetbrains/util/concurrency/AsyncPromise.kt +++ b/platform/platform-impl/src/org/jetbrains/util/concurrency/AsyncPromise.kt @@ -19,11 +19,11 @@ import com.intellij.openapi.diagnostic.Logger import org.jetbrains.concurrency.Obsolescent import java.util.* -public class AsyncPromise : Promise { +class AsyncPromise : Promise { companion object { private val LOG = Logger.getInstance(AsyncPromise::class.java) - public val OBSOLETE_ERROR: RuntimeException = MessageError("Obsolete") + val OBSOLETE_ERROR = MessageError("Obsolete") private fun setHandler(oldConsumer: ((T) -> Unit)?, newConsumer: (T) -> Unit): (T) -> Unit { return when (oldConsumer) { @@ -68,14 +68,14 @@ public class AsyncPromise : Promise { } } - private volatile var done: ((T) -> Unit)? = null - private volatile var rejected: ((Throwable) -> Unit)? = null + private @Volatile var done: ((T) -> Unit)? = null + private @Volatile var rejected: ((Throwable) -> Unit)? = null - override volatile var state = Promise.State.PENDING + override @Volatile var state = Promise.State.PENDING private set // result object or error message - private volatile var result: Any? = null + private @Volatile var result: Any? = null override fun done(done: (T) -> Unit): Promise { if (done.isObsolete()) { @@ -86,7 +86,7 @@ public class AsyncPromise : Promise { Promise.State.PENDING -> { } Promise.State.FULFILLED -> { - @suppress("UNCHECKED_CAST") + @Suppress("UNCHECKED_CAST") done(result as T) return this } @@ -116,8 +116,9 @@ public class AsyncPromise : Promise { return this } + @Suppress("BASE_WITH_NULLABLE_UPPER_BOUND") public fun get(): T? { - @suppress("UNCHECKED_CAST") + @Suppress("UNCHECKED_CAST") return when (state) { Promise.State.FULFILLED -> result as T else -> null @@ -133,7 +134,7 @@ public class AsyncPromise : Promise { Promise.State.PENDING -> { } Promise.State.FULFILLED -> { - @suppress("UNCHECKED_CAST") + @Suppress("UNCHECKED_CAST") return if (asyncResult) done(result as T) as Promise else DonePromise(done(result as T) as SUB_RESULT) } Promise.State.REJECTED -> return RejectedPromise(result as Throwable) @@ -142,7 +143,7 @@ public class AsyncPromise : Promise { val promise = AsyncPromise() addHandlers({ promise.catchError { - if (done is Obsolescent && done.isObsolete()) { + if (done is Obsolescent && done.isObsolete) { promise.setError(OBSOLETE_ERROR) } else { @@ -151,12 +152,12 @@ public class AsyncPromise : Promise { (subResult as Promise<*>).notify(promise) if (subResult is AsyncPromise<*> && subResult.state == Promise.State.PENDING) { // if promise fulfilled separately from sub result - @suppress("UNCHECKED_CAST") + @Suppress("UNCHECKED_CAST") promise.notify(subResult as AsyncPromise) } } else { - @suppress("UNCHECKED_CAST") + @Suppress("UNCHECKED_CAST") promise.setResult(subResult as SUB_RESULT) } } @@ -176,7 +177,7 @@ public class AsyncPromise : Promise { Promise.State.PENDING -> { } Promise.State.FULFILLED -> { - @suppress("UNCHECKED_CAST") + @Suppress("UNCHECKED_CAST") child.setResult(result as T) return this } @@ -195,7 +196,7 @@ public class AsyncPromise : Promise { this.rejected = setHandler(this.rejected, rejected) } - public fun setResult(result: T) { + fun setResult(result: T) { if (state != Promise.State.PENDING) { return } @@ -210,9 +211,9 @@ public class AsyncPromise : Promise { } } - public fun setError(error: String): Boolean = setError(MessageError(error)) + fun setError(error: String): Boolean = setError(MessageError(error)) - public fun setError(error: Throwable): Boolean { + fun setError(error: Throwable): Boolean { if (state != Promise.State.PENDING) { return false } @@ -238,16 +239,16 @@ public class AsyncPromise : Promise { rejected = null } - override fun processed(processed: (T?) -> Unit): Promise { + override fun processed(@Suppress("BASE_WITH_NULLABLE_UPPER_BOUND") processed: (T?) -> Unit): Promise { done(processed) rejected { processed(null) } return this } } -fun ((T) -> Unit).isObsolete() = this is Obsolescent && this.isObsolete() +internal fun ((T) -> Unit).isObsolete() = this is Obsolescent && this.isObsolete -public inline fun AsyncPromise.catchError(task: () -> Unit) { +inline fun AsyncPromise.catchError(task: () -> Unit) { try { task() } diff --git a/platform/platform-impl/src/org/jetbrains/util/concurrency/DonePromise.kt b/platform/platform-impl/src/org/jetbrains/util/concurrency/DonePromise.kt index 7671d7595c2b..8cbaa5b18081 100644 --- a/platform/platform-impl/src/org/jetbrains/util/concurrency/DonePromise.kt +++ b/platform/platform-impl/src/org/jetbrains/util/concurrency/DonePromise.kt @@ -17,7 +17,7 @@ package org.jetbrains.util.concurrency import org.jetbrains.concurrency.Obsolescent -private class DonePromise(private val result: T) : Promise { +internal class DonePromise(private val result: T) : Promise { override val state: Promise.State get() = Promise.State.FULFILLED diff --git a/platform/platform-impl/src/org/jetbrains/util/concurrency/Promise.kt b/platform/platform-impl/src/org/jetbrains/util/concurrency/Promise.kt index cdd2ff18bcc1..253fc5cf360f 100644 --- a/platform/platform-impl/src/org/jetbrains/util/concurrency/Promise.kt +++ b/platform/platform-impl/src/org/jetbrains/util/concurrency/Promise.kt @@ -17,45 +17,44 @@ package org.jetbrains.util.concurrency import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.diagnostic.Logger -import com.intellij.util.Consumer import org.jetbrains.concurrency -public interface Promise { - public enum class State { +interface Promise { + enum class State { PENDING, FULFILLED, REJECTED } - public val state: State + val state: State - public fun done(done: (T) -> Unit): Promise + fun done(done: (T) -> Unit): Promise - public fun rejected(rejected: (Throwable) -> Unit): Promise + fun rejected(rejected: (Throwable) -> Unit): Promise - public fun processed(processed: (T?) -> Unit): Promise + fun processed(processed: (T?) -> Unit): Promise - public fun then(done: (T) -> SUB_RESULT): Promise + fun then(done: (T) -> SUB_RESULT): Promise - public fun thenAsync(done: (T) -> Promise): Promise + fun thenAsync(done: (T) -> Promise): Promise - public fun notify(child: AsyncPromise): Promise + fun notify(child: AsyncPromise): Promise companion object { /** * Log error if not message error */ - public fun logError(logger: Logger, e: Throwable) { - if (e !is MessageError || ApplicationManager.getApplication().isUnitTestMode()) { + fun logError(logger: Logger, e: Throwable) { + if (e !is MessageError || ApplicationManager.getApplication().isUnitTestMode) { logger.error(e) } } - public fun all(promises: Collection>): Promise<*> = all(promises, null) + fun all(promises: Collection>): Promise<*> = all(promises, null) - public fun all(promises: Collection>, totalResult: T): Promise { + fun all(promises: Collection>, totalResult: T): Promise { if (promises.isEmpty()) { - @suppress("UNCHECKED_CAST") + @Suppress("UNCHECKED_CAST") return DONE as Promise } @@ -80,21 +79,21 @@ public interface Promise { private val DONE: Promise<*> = DonePromise(null) private val REJECTED: Promise<*> = RejectedPromise(MessageError("rejected")) -private class MessageError(error: String) : RuntimeException(error) { - public synchronized fun fillInStackTrace(): Throwable? = this +internal class MessageError(error: String) : RuntimeException(error) { + @Synchronized fun fillInStackTrace(): Throwable? = this } -public fun RejectedPromise(error: String): Promise = RejectedPromise(MessageError(error)) +fun RejectedPromise(error: String): Promise = RejectedPromise(MessageError(error)) -public fun ResolvedPromise(): Promise<*> = DONE +fun ResolvedPromise(): Promise<*> = DONE -public fun ResolvedPromise(result: T): Promise = DonePromise(result) +fun ResolvedPromise(result: T): Promise = DonePromise(result) -public fun concurrency.Promise.toPromise(): AsyncPromise { +fun concurrency.Promise.toPromise(): AsyncPromise { val promise = AsyncPromise() val oldPromise = this - done(Consumer { promise.setResult(it) }) - .rejected(Consumer { promise.setError(it) }) + done({ promise.setResult(it) }) + .rejected({ promise.setError(it) }) if (oldPromise is concurrency.AsyncPromise) { promise @@ -104,14 +103,14 @@ public fun concurrency.Promise.toPromise(): AsyncPromise { return promise } -public fun Promise.toPromise(): concurrency.AsyncPromise { +fun Promise.toPromise(): concurrency.AsyncPromise { val promise = concurrency.AsyncPromise() done { promise.setResult(it) } .rejected { promise.setError(it) } return promise } -private class CountDownConsumer(private volatile var countDown: Int, private val promise: AsyncPromise, private val totalResult: T) : (T) -> Unit { +private class CountDownConsumer(private @field:Volatile var countDown: Int, private val promise: AsyncPromise, private val totalResult: T) : (T) -> Unit { override fun invoke(p1: T) { if (--countDown == 0) { promise.setResult(totalResult) @@ -119,8 +118,8 @@ private class CountDownConsumer(private volatile var countDown: Int, private } } -public val Promise<*>.isPending: Boolean +val Promise<*>.isPending: Boolean get() = state == Promise.State.PENDING -public val Promise<*>.isRejected: Boolean +val Promise<*>.isRejected: Boolean get() = state == Promise.State.REJECTED \ No newline at end of file diff --git a/platform/platform-impl/src/org/jetbrains/util/concurrency/RejectedPromise.kt b/platform/platform-impl/src/org/jetbrains/util/concurrency/RejectedPromise.kt index 9976543ba903..08b523a31adf 100644 --- a/platform/platform-impl/src/org/jetbrains/util/concurrency/RejectedPromise.kt +++ b/platform/platform-impl/src/org/jetbrains/util/concurrency/RejectedPromise.kt @@ -34,12 +34,12 @@ class RejectedPromise(private val error: Throwable) : Promise { } override fun then(done: (T) -> SUB_RESULT): Promise { - @suppress("UNCHECKED_CAST") + @Suppress("UNCHECKED_CAST") return this as Promise } override fun thenAsync(done: (T) -> Promise): Promise { - @suppress("UNCHECKED_CAST") + @Suppress("UNCHECKED_CAST") return this as Promise } diff --git a/platform/util/testSrc/com/intellij/util/Assertion.java b/platform/util/testSrc/com/intellij/util/Assertion.java index c1ea62275d73..92769218229c 100644 --- a/platform/util/testSrc/com/intellij/util/Assertion.java +++ b/platform/util/testSrc/com/intellij/util/Assertion.java @@ -18,8 +18,8 @@ package com.intellij.util; import com.intellij.openapi.util.Comparing; import gnu.trove.Equality; -import junit.framework.Assert; import junit.framework.AssertionFailedError; +import org.junit.Assert; import java.io.BufferedReader; import java.io.IOException; diff --git a/platform/util/testSrc/com/intellij/util/containers/FilteringIteratorTest.java b/platform/util/testSrc/com/intellij/util/containers/FilteringIteratorTest.java index 792274d493ee..3e77ceb7ac08 100644 --- a/platform/util/testSrc/com/intellij/util/containers/FilteringIteratorTest.java +++ b/platform/util/testSrc/com/intellij/util/containers/FilteringIteratorTest.java @@ -18,7 +18,6 @@ package com.intellij.util.containers; import com.intellij.openapi.util.Condition; import com.intellij.util.Assertion; -import junit.framework.Assert; import junit.framework.TestCase; import java.util.ArrayList; @@ -65,28 +64,28 @@ public class FilteringIteratorTest extends TestCase { MockIterator mockIterator = new MockIterator(list.iterator()); MockCondition mockCondition = new MockCondition(STRINGS_ONLY); Iterator iterator = FilteringIterator.create(mockIterator, mockCondition); - Assert.assertTrue(iterator.hasNext()); - Assert.assertTrue(iterator.hasNext()); - Assert.assertEquals(2, mockIterator.myHasNextCalls); - Assert.assertEquals(2, mockCondition.myValueCalls); - Assert.assertEquals("a", iterator.next()); - Assert.assertEquals(2, mockIterator.myHasNextCalls); - Assert.assertEquals(2, mockCondition.myValueCalls); + assertTrue(iterator.hasNext()); + assertTrue(iterator.hasNext()); + assertEquals(2, mockIterator.myHasNextCalls); + assertEquals(2, mockCondition.myValueCalls); + assertEquals("a", iterator.next()); + assertEquals(2, mockIterator.myHasNextCalls); + assertEquals(2, mockCondition.myValueCalls); iterator.remove(); - Assert.assertEquals(2, mockIterator.myHasNextCalls); - Assert.assertEquals(2, mockCondition.myValueCalls); - Assert.assertTrue(iterator.hasNext()); - Assert.assertTrue(iterator.hasNext()); - Assert.assertEquals(4, mockIterator.myHasNextCalls); - Assert.assertEquals(4, mockCondition.myValueCalls); - Assert.assertEquals("b", iterator.next()); - Assert.assertEquals(4, mockIterator.myHasNextCalls); - Assert.assertEquals(4, mockCondition.myValueCalls); + assertEquals(2, mockIterator.myHasNextCalls); + assertEquals(2, mockCondition.myValueCalls); + assertTrue(iterator.hasNext()); + assertTrue(iterator.hasNext()); + assertEquals(4, mockIterator.myHasNextCalls); + assertEquals(4, mockCondition.myValueCalls); + assertEquals("b", iterator.next()); + assertEquals(4, mockIterator.myHasNextCalls); + assertEquals(4, mockCondition.myValueCalls); - Assert.assertEquals(3, list.size()); + assertEquals(3, list.size()); } - private void checkRemove(Object[] expected, ArrayList collection) { + private static void checkRemove(Object[] expected, ArrayList collection) { Iterator iterator = FilteringIterator.create(collection.iterator(), STRINGS_ONLY); while (iterator.hasNext()) { if (iterator.next().equals("x")) iterator.remove(); diff --git a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt index e27f9ce8e8e6..d199f7778e95 100644 --- a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt +++ b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt @@ -872,7 +872,7 @@ public class XmlSerializerTest { return "foo" } - public fun setFoo(value: String) { + public fun setFoo(@Suppress("UNUSED_PARAMETER") value: String) { } } @@ -1011,11 +1011,11 @@ public class XmlSerializerTest { } } -public fun T.serialize(filter: SerializationFilter? = SkipDefaultValuesSerializationFilters()): Element = XmlSerializer.serialize(this, filter) +fun T.serialize(filter: SerializationFilter? = SkipDefaultValuesSerializationFilters()): Element = XmlSerializer.serialize(this, filter) -public inline fun Element.deserialize(): T = XmlSerializer.deserialize(this, T::class.java)!! +inline fun Element.deserialize(): T = XmlSerializer.deserialize(this, T::class.java)!! -public fun Element.toByteArray(): ByteArray { +fun Element.toByteArray(): ByteArray { val out = BufferExposingByteArrayOutputStream(512) JDOMUtil.writeParent(this, out, "\n") return out.toByteArray() From bc5e4c3022aac15ffba12c05b68dc3c91e239f42 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 17:00:15 +0200 Subject: [PATCH 128/138] fix compilation --- platform/configuration-store-impl/testSrc/SchemeManagerTest.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt index 3b89d712980b..da842436ca58 100644 --- a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt +++ b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt @@ -29,6 +29,7 @@ import com.intellij.util.lang.CompoundRuntimeException import com.intellij.util.xmlb.SerializationFilter import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters import com.intellij.util.xmlb.XmlSerializer +import com.intellij.util.xmlb.annotations.Attribute import com.intellij.util.xmlb.annotations.Tag import com.intellij.util.xmlb.annotations.Transient import com.intellij.util.xmlb.toByteArray From 16666f1ce5b6e44a895ac133170760082b75c617 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 21 Sep 2015 17:11:39 +0200 Subject: [PATCH 129/138] cleanup --- .../builtInWebServer/BuiltInWebServer.kt | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt b/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt index 4a93364c15d1..e9797d72be3f 100644 --- a/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt +++ b/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt @@ -44,7 +44,7 @@ import java.io.File import java.net.InetAddress import java.net.UnknownHostException -public class BuiltInWebServer : HttpRequestHandler() { +class BuiltInWebServer : HttpRequestHandler() { companion object { val LOG = Logger.getInstance(BuiltInWebServer::class.java) @@ -67,15 +67,15 @@ public class BuiltInWebServer : HttpRequestHandler() { } var candidateByDirectoryName: Project? = null - val project = ProjectManager.getInstance().getOpenProjects().firstOrNull(fun(project: Project): Boolean { - if (project.isDisposed()) { + val project = ProjectManager.getInstance().openProjects.firstOrNull(fun(project: Project): Boolean { + if (project.isDisposed) { return false } - val name = project.getName() + val name = project.name if (isCustomHost) { // domain name is case-insensitive - if (projectName.equals(project.getName(), ignoreCase = true)) { + if (projectName.equals(project.name, ignoreCase = true)) { return true } } @@ -101,7 +101,7 @@ public class BuiltInWebServer : HttpRequestHandler() { if (emptyPath) { if (!SystemInfoRt.isFileSystemCaseSensitive) { // may be passed path is not correct - projectName = project.getName() + projectName = project.name } // we must redirect "jsdebug" to "jsdebug/" as nginx does, otherwise browser will treat it as file instead of directory, so, relative path will not work @@ -110,7 +110,7 @@ public class BuiltInWebServer : HttpRequestHandler() { } val path = FileUtil.toCanonicalPath(decodedPath.substring(offset + 1), '/') - for (pathHandler in WebServerPathHandler.EP_NAME.getExtensions()) { + for (pathHandler in WebServerPathHandler.EP_NAME.extensions) { try { if (pathHandler.process(path, project, request, context, projectName, decodedPath, isCustomHost)) { return true @@ -157,12 +157,12 @@ public class BuiltInWebServer : HttpRequestHandler() { } public fun compareNameAndProjectBasePath(projectName: String, project: Project): Boolean { - val basePath = project.getBasePath() + val basePath = project.basePath return basePath != null && basePath.length() > projectName.length() && basePath.endsWith(projectName) && basePath.charAt(basePath.length() - projectName.length() - 1) == '/' } public fun findIndexFile(basedir: VirtualFile): VirtualFile? { - val children = basedir.getChildren() + val children = basedir.children if (children == null || children.isEmpty()) { return null } @@ -171,8 +171,8 @@ public fun findIndexFile(basedir: VirtualFile): VirtualFile? { var index: VirtualFile? = null val preferredName = indexNamePrefix + "html" for (child in children) { - if (!child.isDirectory()) { - val name = child.getName() + if (!child.isDirectory) { + val name = child.name //noinspection IfStatementWithIdenticalBranches if (name == preferredName) { return child @@ -196,11 +196,11 @@ public fun isOwnHostName(host: String): Boolean { try { val address = InetAddress.getByName(host) - if (host == address.getHostAddress() || host.equals(address.getCanonicalHostName(), ignoreCase = true)) { + if (host == address.hostAddress || host.equals(address.canonicalHostName, ignoreCase = true)) { return true } - val localHostName = InetAddress.getLocalHost().getHostName() + val localHostName = InetAddress.getLocalHost().hostName // WEB-8889 // develar.local is own host name: develar. equals to "develar.labs.intellij.net" (canonical host name) return localHostName.equals(host, ignoreCase = true) || (host.endsWith(".local") && localHostName.regionMatches(0, host, 0, host.length() - ".local".length(), true)) @@ -214,8 +214,8 @@ private class StaticFileHandler : WebServerFileHandler() { private var ssiProcessor: SsiProcessor? = null override fun process(file: VirtualFile, canonicalRequestPath: CharSequence, project: Project, request: FullHttpRequest, channel: Channel, isCustomHost: Boolean): Boolean { - if (file.isInLocalFileSystem()) { - val nameSequence = file.getNameSequence() + if (file.isInLocalFileSystem) { + val nameSequence = file.nameSequence //noinspection SpellCheckingInspection if (StringUtilRt.endsWithIgnoreCase(nameSequence, ".shtml") || StringUtilRt.endsWithIgnoreCase(nameSequence, ".stm") || StringUtilRt.endsWithIgnoreCase(nameSequence, ".shtm")) { processSsi(file, canonicalRequestPath, project, request, channel, isCustomHost) @@ -231,17 +231,17 @@ private class StaticFileHandler : WebServerFileHandler() { } } else { - val response = FileResponses.prepareSend(request, channel, file.getTimeStamp(), file.getPath()) ?: return true + val response = FileResponses.prepareSend(request, channel, file.timeStamp, file.path) ?: return true val keepAlive = addKeepAliveIfNeed(response, request) if (request.method() !== HttpMethod.HEAD) { - HttpUtil.setContentLength(response, file.getLength()) + HttpUtil.setContentLength(response, file.length) } channel.write(response) if (request.method() != HttpMethod.HEAD) { - channel.write(ChunkedStream(file.getInputStream())) + channel.write(ChunkedStream(file.inputStream)) } val future = channel.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT) @@ -267,9 +267,9 @@ private class StaticFileHandler : WebServerFileHandler() { val keepAlive: Boolean var releaseBuffer = true try { - val lastModified = ssiProcessor!!.process(SsiExternalResolver(project, request, path, file.getParent()), VfsUtilCore.loadText(file), file.getTimeStamp(), ByteBufUtf8Writer(buffer)) + val lastModified = ssiProcessor!!.process(SsiExternalResolver(project, request, path, file.parent), VfsUtilCore.loadText(file), file.timeStamp, ByteBufUtf8Writer(buffer)) - val response = FileResponses.prepareSend(request, channel, lastModified, file.getPath()) ?: return + val response = FileResponses.prepareSend(request, channel, lastModified, file.path) ?: return keepAlive = addKeepAliveIfNeed(response, request) if (request.method() !== HttpMethod.HEAD) { @@ -296,5 +296,5 @@ private class StaticFileHandler : WebServerFileHandler() { } // deny access to .htaccess files - private fun hasAccess(result: File) = !result.isDirectory() && result.canRead() && !(result.isHidden() || result.getName().startsWith(".ht")) + private fun hasAccess(result: File) = !result.isDirectory && result.canRead() && !(result.isHidden || result.name.startsWith(".ht")) } \ No newline at end of file From e4669d1b8d8b8067b7fbf4630f544a1f507eb7fc Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 21 Sep 2015 18:39:03 +0300 Subject: [PATCH 130/138] early return: evaluate finally block if needed --- .../actions/ForceEarlyReturnAction.java | 74 +++++-- .../debugger/actions/PopFrameAction.java | 202 ++++++++++-------- .../src/messages/DebuggerBundle.properties | 4 +- 3 files changed, 166 insertions(+), 114 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java index 4bf18a9e45a8..8c37fda39f52 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java @@ -21,6 +21,7 @@ import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.JavaStackFrame; import com.intellij.debugger.engine.JavaValue; import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.jdi.StackFrameProxyImpl; @@ -77,7 +78,7 @@ public class ForceEarlyReturnAction extends DebuggerAction { } if ("void".equals(method.returnTypeName())) { - forceEarlyReturn(thread.getVirtualMachine().mirrorOfVoid(), thread, debugProcess, null); + forceEarlyReturnWithFinally(thread.getVirtualMachine().mirrorOfVoid(), stackFrame, debugProcess, null); } else { //noinspection SSBasedInspection @@ -92,25 +93,60 @@ public class ForceEarlyReturnAction extends DebuggerAction { }); } - private static void forceEarlyReturn(Value value, - ThreadReferenceProxyImpl thread, - final DebugProcessImpl debugProcess, - @Nullable final DialogWrapper dialog) { - try { - thread.forceEarlyReturn(value); - } - catch (Exception e) { - showError(debugProcess.getProject(), DebuggerBundle.message("error.early.return", e.getLocalizedMessage())); - return; - } + private static void forceEarlyReturnWithFinally(final Value value, + final JavaStackFrame frame, + final DebugProcessImpl debugProcess, + @Nullable final DialogWrapper dialog) { //noinspection SSBasedInspection SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - if (dialog != null) { - dialog.close(DialogWrapper.OK_EXIT_CODE); + if (PopFrameAction.evaluateFinallyBlocks(debugProcess.getProject(), + UIUtil.removeMnemonic(ActionsBundle.actionText("Debugger.ForceEarlyReturn")), + frame, + new XDebuggerEvaluator.XEvaluationCallback() { + @Override + public void evaluated(@NotNull XValue result) { + forceEarlyReturn(value, frame.getDescriptor().getFrameProxy().threadProxy(), debugProcess, dialog); + } + + @Override + public void errorOccurred(@NotNull String errorMessage) { + showError(debugProcess.getProject(), + DebuggerBundle.message("error.executing.finally", errorMessage)); + } + })) { + return; } - debugProcess.getSession().stepInto(true, null); + forceEarlyReturn(value, frame.getDescriptor().getFrameProxy().threadProxy(), debugProcess, dialog); + } + }); + } + + private static void forceEarlyReturn(final Value value, + final ThreadReferenceProxyImpl thread, + final DebugProcessImpl debugProcess, + @Nullable final DialogWrapper dialog) { + debugProcess.getManagerThread().schedule(new DebuggerCommandImpl() { + @Override + protected void action() throws Exception { + try { + thread.forceEarlyReturn(value); + } + catch (Exception e) { + showError(debugProcess.getProject(), DebuggerBundle.message("error.early.return", e.getLocalizedMessage())); + return; + } + //noinspection SSBasedInspection + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (dialog != null) { + dialog.close(DialogWrapper.OK_EXIT_CODE); + } + debugProcess.getSession().stepInto(true, null); + } + }); } }); } @@ -127,10 +163,10 @@ public class ForceEarlyReturnAction extends DebuggerAction { @Override public void evaluated(@NotNull XValue result) { if (result instanceof JavaValue) { - forceEarlyReturn(((JavaValue)result).getDescriptor().getValue(), - stackFrame.getDescriptor().getFrameProxy().threadProxy(), - debugProcess, - dialog); + forceEarlyReturnWithFinally(((JavaValue)result).getDescriptor().getValue(), + stackFrame, + debugProcess, + dialog); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java index f18200161a4d..8e1dc5075727 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java @@ -81,76 +81,29 @@ public class PopFrameAction extends DebuggerAction { } debugProcess.getSession().setSteppingThrough(stackFrame.getStackFrameProxy().threadProxy()); - if (!DebuggerSettings.EVALUATE_FINALLY_NEVER.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME)) { - List statements = getFinallyStatements(debuggerContext.getSourcePosition()); - if (!statements.isEmpty()) { - StringBuilder sb = new StringBuilder(); - for (PsiStatement statement : statements) { - sb.append("\n").append(statement.getText()); - } - if (DebuggerSettings.EVALUATE_FINALLY_ALWAYS.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME)) { - evaluateAndPop(project, stackFrame, debuggerContext, debugProcess, sb); - return; - } - else { - int res = MessageDialogBuilder - .yesNoCancel(UIUtil.removeMnemonic(ActionsBundle.actionText(DebuggerActions.POP_FRAME)), - DebuggerBundle.message("warning.finally.block.detected") + sb) - .project(project) - .icon(Messages.getWarningIcon()) - .yesText(DebuggerBundle.message("button.execute.finally")) - .noText(DebuggerBundle.message("button.drop.anyway")) - .cancelText(CommonBundle.message("button.cancel")) - .doNotAsk( - new DialogWrapper.DoNotAskOption() { - @Override - public boolean isToBeShown() { - return !DebuggerSettings.EVALUATE_FINALLY_ALWAYS.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME) && - !DebuggerSettings.EVALUATE_FINALLY_NEVER.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME); - } + if (evaluateFinallyBlocks(project, + UIUtil.removeMnemonic(ActionsBundle.actionText(DebuggerActions.POP_FRAME)), + stackFrame, + new XDebuggerEvaluator.XEvaluationCallback() { + @Override + public void evaluated(@NotNull XValue result) { + popFrame(debugProcess, debuggerContext, stackFrame); + } - @Override - public void setToBeShown(boolean value, int exitCode) { - if (!value) { - DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME = - exitCode == Messages.YES ? DebuggerSettings.EVALUATE_FINALLY_ALWAYS : DebuggerSettings.EVALUATE_FINALLY_NEVER; - } - else { - DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME = DebuggerSettings.EVALUATE_FINALLY_ASK; - } - } - - @Override - public boolean canBeHidden() { - return true; - } - - @Override - public boolean shouldSaveOptionsOnCancel() { - return false; - } - - @NotNull - @Override - public String getDoNotShowMessage() { - return CommonBundle.message("dialog.options.do.not.show"); - } - }) - .show(); - - switch (res) { - case Messages.CANCEL: - return; - case Messages.NO: - break; - case Messages.YES: // evaluate finally - evaluateAndPop(project, stackFrame, debuggerContext, debugProcess, sb); - return; - } - } - } - } - debugProcess.getManagerThread().schedule(debugProcess.createPopFrameCommand(debuggerContext, stackFrame.getStackFrameProxy())); + @Override + public void errorOccurred(@NotNull final String errorMessage) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + Messages + .showMessageDialog(project, DebuggerBundle.message("error.executing.finally", errorMessage), + UIUtil.removeMnemonic(ActionsBundle.actionText(DebuggerActions.POP_FRAME)), + Messages.getErrorIcon()); + } + }); + } + })) return; + popFrame(debugProcess, debuggerContext, stackFrame); } catch (NativeMethodException e2){ Messages.showMessageDialog(project, DebuggerBundle.message("error.native.method.exception"), @@ -162,33 +115,96 @@ public class PopFrameAction extends DebuggerAction { } } - private static void evaluateAndPop(final Project project, - final JavaStackFrame stackFrame, - final DebuggerContextImpl debuggerContext, - final DebugProcessImpl debugProcess, StringBuilder sb) { + static boolean evaluateFinallyBlocks(Project project, + String title, + JavaStackFrame stackFrame, + XDebuggerEvaluator.XEvaluationCallback callback) { + if (!DebuggerSettings.EVALUATE_FINALLY_NEVER.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME)) { + List statements = getFinallyStatements(stackFrame.getDescriptor().getSourcePosition()); + if (!statements.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (PsiStatement statement : statements) { + sb.append("\n").append(statement.getText()); + } + if (DebuggerSettings.EVALUATE_FINALLY_ALWAYS.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME)) { + evaluateAndAct(project, stackFrame, sb, callback); + return true; + } + else { + int res = MessageDialogBuilder + .yesNoCancel(title, + DebuggerBundle.message("warning.finally.block.detected") + sb) + .project(project) + .icon(Messages.getWarningIcon()) + .yesText(DebuggerBundle.message("button.execute.finally")) + .noText(DebuggerBundle.message("button.drop.anyway")) + .cancelText(CommonBundle.message("button.cancel")) + .doNotAsk( + new DialogWrapper.DoNotAskOption() { + @Override + public boolean isToBeShown() { + return !DebuggerSettings.EVALUATE_FINALLY_ALWAYS.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME) && + !DebuggerSettings.EVALUATE_FINALLY_NEVER.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME); + } + + @Override + public void setToBeShown(boolean value, int exitCode) { + if (!value) { + DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME = + exitCode == Messages.YES ? DebuggerSettings.EVALUATE_FINALLY_ALWAYS : DebuggerSettings.EVALUATE_FINALLY_NEVER; + } + else { + DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME = DebuggerSettings.EVALUATE_FINALLY_ASK; + } + } + + @Override + public boolean canBeHidden() { + return true; + } + + @Override + public boolean shouldSaveOptionsOnCancel() { + return false; + } + + @NotNull + @Override + public String getDoNotShowMessage() { + return CommonBundle.message("dialog.options.do.not.show"); + } + }) + .show(); + + switch (res) { + case Messages.CANCEL: + return true; + case Messages.NO: + break; + case Messages.YES: // evaluate finally + evaluateAndAct(project, stackFrame, sb, callback); + return true; + } + } + } + } + return false; + } + + private static void popFrame(DebugProcessImpl debugProcess, DebuggerContextImpl debuggerContext, JavaStackFrame stackFrame) { + debugProcess.getManagerThread() + .schedule(debugProcess.createPopFrameCommand(debuggerContext, stackFrame.getStackFrameProxy())); + } + + private static void evaluateAndAct(Project project, + JavaStackFrame stackFrame, + StringBuilder sb, + XDebuggerEvaluator.XEvaluationCallback callback) { XDebuggerEvaluator evaluator = stackFrame.getEvaluator(); if (evaluator != null) { evaluator.evaluate(XExpressionImpl.fromText(sb.toString(), EvaluationMode.CODE_FRAGMENT), - new XDebuggerEvaluator.XEvaluationCallback() { - @Override - public void evaluated(@NotNull XValue result) { - debugProcess.getManagerThread() - .schedule(debugProcess.createPopFrameCommand(debuggerContext, stackFrame.getStackFrameProxy())); - } - - @Override - public void errorOccurred(@NotNull final String errorMessage) { - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - Messages - .showMessageDialog(project, DebuggerBundle.message("error.executing.finally", errorMessage), - UIUtil.removeMnemonic(ActionsBundle.actionText(DebuggerActions.POP_FRAME)), - Messages.getErrorIcon()); - } - }); - } - }, stackFrame.getSourcePosition()); + callback, + stackFrame.getSourcePosition()); } else { Messages.showMessageDialog(project, XDebuggerBundle.message("xdebugger.evaluate.stack.frame.has.not.evaluator"), diff --git a/resources-en/src/messages/DebuggerBundle.properties b/resources-en/src/messages/DebuggerBundle.properties index d0c2d8834f89..cd6e64bcdd62 100644 --- a/resources-en/src/messages/DebuggerBundle.properties +++ b/resources-en/src/messages/DebuggerBundle.properties @@ -30,8 +30,8 @@ error.native.method.exception=None of the frames through and including frame may error.executing.finally=Error while executing finally blocks: {0} error.early.return=Error while doing early return: {0} warning.finally.block.detected=Non-empty finally blocks detected: -button.drop.anyway=Drop frame anyway -button.execute.finally=Execute finally blocks and drop frame +button.drop.anyway=Do not execute +button.execute.finally=Execute finally blocks drop.frame.error.no.information=Information about the frame is not available action.remove.watch.text={0,choice, 1#Remove Watch|2#Remove Watches} progress.evaluating=Evaluating {0} From 38844e7d50c8695700f092f2c2e2d8e60a94f2b9 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 21 Sep 2015 18:43:05 +0300 Subject: [PATCH 131/138] [platform] fixes UOE on shell environment loading (IDEA-CR-5094) --- platform/util/src/com/intellij/util/EnvironmentUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/util/src/com/intellij/util/EnvironmentUtil.java b/platform/util/src/com/intellij/util/EnvironmentUtil.java index 2f5b853e07a3..09de8487165b 100644 --- a/platform/util/src/com/intellij/util/EnvironmentUtil.java +++ b/platform/util/src/com/intellij/util/EnvironmentUtil.java @@ -56,7 +56,7 @@ public class EnvironmentUtil { ourEnvGetter = executor.submit(new Callable>() { @Override public Map call() throws Exception { - return setCharsetVar(getShellEnv()); + return Collections.unmodifiableMap(setCharsetVar(getShellEnv())); } }); executor.shutdown(); @@ -203,7 +203,7 @@ public class EnvironmentUtil { } LOG.info("shell environment loaded (" + newEnv.size() + " vars)"); - return Collections.unmodifiableMap(newEnv); + return newEnv; } private static int waitAndTerminateAfter(@NotNull Process process, int timeoutMillis) { From e87132e422b544482fcf3fb9c7f8fa8f81dd5e87 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Fri, 7 Aug 2015 15:22:18 +0300 Subject: [PATCH 132/138] merge: allow to specify custom captions --- .../com/intellij/diff/merge/MergeUtil.java | 22 +++++++++++++++---- .../diff/util/DiffUserDataKeysEx.java | 12 ++++++++++ .../src/com/intellij/diff/util/DiffUtil.java | 22 +++++-------------- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/merge/MergeUtil.java b/platform/diff-impl/src/com/intellij/diff/merge/MergeUtil.java index 004915250a35..bc196709a352 100644 --- a/platform/diff-impl/src/com/intellij/diff/merge/MergeUtil.java +++ b/platform/diff-impl/src/com/intellij/diff/merge/MergeUtil.java @@ -16,12 +16,16 @@ package com.intellij.diff.merge; import com.intellij.diff.DiffContext; +import com.intellij.diff.util.DiffUserDataKeysEx; +import com.intellij.diff.util.DiffUtil; import com.intellij.diff.util.ThreeSide; import com.intellij.openapi.diff.DiffBundle; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Couple; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -32,6 +36,10 @@ import java.util.List; public class MergeUtil { @NotNull public static String getResolveActionTitle(@NotNull MergeResult result, @NotNull MergeRequest request, @NotNull MergeContext context) { + Function getter = DiffUtil.getUserData(request, context, DiffUserDataKeysEx.MERGE_ACTION_CAPTIONS); + String message = getter != null ? getter.fun(result) : null; + if (message != null) return message; + switch (result) { case CANCEL: return "Abort"; @@ -95,9 +103,15 @@ public class MergeUtil { } public static boolean showExitWithoutApplyingChangesDialog(@NotNull JComponent component, @NotNull MergeRequest request, @NotNull MergeContext context) { - return Messages.showYesNoDialog(component.getRootPane(), - DiffBundle.message("merge.dialog.exit.without.applying.changes.confirmation.message"), - DiffBundle.message("cancel.visual.merge.dialog.title"), Messages.getQuestionIcon()) == - Messages.YES; + String message = DiffBundle.message("merge.dialog.exit.without.applying.changes.confirmation.message"); + String title = DiffBundle.message("cancel.visual.merge.dialog.title"); + + Couple customMessage = DiffUtil.getUserData(request, context, DiffUserDataKeysEx.MERGE_CANCEL_MESSAGE); + if (customMessage != null) { + title = customMessage.first; + message = customMessage.second; + } + + return Messages.showYesNoDialog(component.getRootPane(), message, title, Messages.getQuestionIcon()) == Messages.YES; } } diff --git a/platform/diff-impl/src/com/intellij/diff/util/DiffUserDataKeysEx.java b/platform/diff-impl/src/com/intellij/diff/util/DiffUserDataKeysEx.java index a2c90ce8e5b2..9b914d7f3f24 100644 --- a/platform/diff-impl/src/com/intellij/diff/util/DiffUserDataKeysEx.java +++ b/platform/diff-impl/src/com/intellij/diff/util/DiffUserDataKeysEx.java @@ -15,9 +15,12 @@ */ package com.intellij.diff.util; +import com.intellij.diff.merge.MergeResult; import com.intellij.openapi.diff.DiffNavigationContext; import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.util.Couple; import com.intellij.openapi.util.Key; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -53,4 +56,13 @@ public interface DiffUserDataKeysEx extends DiffUserDataKeys { Key BOTTOM_PANEL = Key.create("Diff.BottomPanel"); // Could implement Disposable Key SHOW_READ_ONLY_LOCK = Key.create("Diff.ShowReadOnlyLock"); + + // + // MergeContext / MergeRequest + // + + // (title, message) + Key> MERGE_CANCEL_MESSAGE = Key.create("Diff.MergeCancelMessage"); + // null -> default + Key> MERGE_ACTION_CAPTIONS = Key.create("Diff.MergeActionCaptions"); } diff --git a/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java b/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java index f420755e73b0..b9dfda2faf40 100644 --- a/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java +++ b/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java @@ -931,25 +931,13 @@ public class DiffUtil { return false; } - public static T getUserData(@Nullable DiffRequest request, @Nullable DiffContext context, @NotNull Key key) { - if (request != null) { - T data = request.getUserData(key); + public static T getUserData(@Nullable UserDataHolder first, @Nullable UserDataHolder second, @NotNull Key key) { + if (first != null) { + T data = first.getUserData(key); if (data != null) return data; } - if (context != null) { - T data = context.getUserData(key); - if (data != null) return data; - } - return null; - } - - public static T getUserData(@Nullable DiffContext context, @Nullable DiffRequest request, @NotNull Key key) { - if (context != null) { - T data = context.getUserData(key); - if (data != null) return data; - } - if (request != null) { - T data = request.getUserData(key); + if (second != null) { + T data = second.getUserData(key); if (data != null) return data; } return null; From adc88f75c217e4ca600af0950b36adba047aa5ca Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 21 Sep 2015 17:48:22 +0200 Subject: [PATCH 133/138] CheckBox on Mac: indeterminate state for graphite --- .../graphite/checkBoxIndeterminateSelected.png | Bin 0 -> 236 bytes .../graphite/checkBoxIndeterminateSelected@2x.png | Bin 0 -> 445 bytes .../checkBoxIndeterminateSelectedDisabled.png | Bin 0 -> 254 bytes .../checkBoxIndeterminateSelectedDisabled@2x.png | Bin 0 -> 537 bytes .../checkBoxIndeterminateSelectedFocused.png | Bin 0 -> 444 bytes .../checkBoxIndeterminateSelectedFocused@2x.png | Bin 0 -> 906 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxIndeterminateSelected.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxIndeterminateSelected@2x.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxIndeterminateSelectedDisabled.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxIndeterminateSelectedDisabled@2x.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxIndeterminateSelectedFocused.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxIndeterminateSelectedFocused@2x.png diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxIndeterminateSelected.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxIndeterminateSelected.png new file mode 100644 index 0000000000000000000000000000000000000000..0a2c752250965d2515854515b36f05e9c74845ce GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqERR!CwBB``WRP4d2+JH9MTATkl&C?3`b4T>MCj!as!@+hn&aT+G(}NHk|wyVMe( zbe6&Ca~3lGaW7cd?H@jOG*`6vx8d`hJNkdVFeR7lG?wz2bhnMk|7oa*%w3ba`L*_Q jS_QaIJ3LBEcl*q8P%yLph`(1p(D@9Wu6{1-oD!MS6oo5=Dxy!|%4aD^7rsU}LIpv(@TcImly-vosnxnE_y`KVfVz;XZxWM0ySm;} zQcyu5nL8oq44mzEzRV<$xfLR+lsOeE_^$-ZvP1UPR#pqfjV1WrXI&ul7J2&EsIIDRCTX;%Sa?7MU*~%=a zl>aDstiK&My7KJc+_c;>+%?N1NCgU#6|{m@(6r#~-905qLb?kKu*3x=LV2-jT6tJo+ nYks;_`te(#f_4P_7X?26xs_K07)~P=00000NkvXXu0mjf_9?`F literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxIndeterminateSelectedDisabled.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxIndeterminateSelectedDisabled.png new file mode 100644 index 0000000000000000000000000000000000000000..04f47991b6b8a4310a858f1961cc19bfaeec318b GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE z3J>6zC{V4Wyv{h~p6`wa>vC@|dcEtm0gouV%+ioXUhzFWk0YY8wRc56IB>L$d!BRB z{lJ_Z4>V1_9n7zj$(i*`b7_f8K~r;S?EYs>K)Uw+{a!+KBd>_Y((4x6Xz z&D~Y1Klc~^uk-sZ{hQ*&Zhn+qYlj9O7hjjcJ^@h{QIoHKbI!RgjP@*IuD$cnnWN&| z&S$GU*Ia&?^7qL`p9P#IjdIM@d*@xvFsaz9C)Uk>G9~EH!woG?it)_MVm>$0+n*n} z9isJh%GtD~F?!ycZ%)bE{yID1Koh5Q`}G6a4ClO34J1w!SWNj?p)>j9k?RK?o4eKW^wUfcIWFeSz_d#=1L-IyD_?e1$OgK*X_S9S1x(O!iM!&l3}FY^hWka zAjK0sR`AM}DDcIoU0|sbzmc`|-kfCliy2>@q$eD>B)3BOUG|gz+-t68z5iGdb6j&< zVkZBbvuXP0H2}>y8%2(|`D89f+5IaYy^ZSza3fcD?J3KWpNC{oS|A zg#T5S6xdslLq8|W9vqw&1(m!Z^Hr8N)K2nSel?jJBAVV_xhs{)_rZMLKP(KQZEHeS S9E$=*IfJLGpUXO@geCw$r|eJw literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxIndeterminateSelectedFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/checkBoxIndeterminateSelectedFocused.png new file mode 100644 index 0000000000000000000000000000000000000000..ed3e0ed31fb42391391af19cabfa47871bb1d7cf GIT binary patch literal 444 zcmV;t0Ym>%8gL`VcETBHr9caSCcz$}04y1N$ zA^AcA|M{3X!;GVpa+ns;Aufn6ab=;)S=6+&)(#Na8F5)F7!X6kCjuhmyU))DMi#Z_ z4lW*9T{dDtL`?P&@%vFt+H!cv<-w4dRd$xER6rKZ*D!>DUYuSw%$Kw$WqOlu~W*e=gMAA zlJphmFM|&nxd2eL?gPVBWFz0aV}HOWT>npXj4L*Qy;+@=-kaX^C&)aPJL@@bN< zEM86oOoybkPAS3_=xzZO2HPdS7WvE4o#p|HAt^O&+xv2M=6)ZK-6hE1QA_j!&udy$ zU6Jx4157E7kGktlUxV4qb}oF^``}M6KE@*SLQnAi2{GPskm7Na(&#LbrPV|@XYxKa zFj43YG43esGRTZZ2c}pMEl9y<{FeKIW5O7e?hfrqzHkZ}o$CC)!|F0{pTwEguykWA z+K&dsXZx{)fG0v~@d)U`W`5i^9MdY+zY6bCe3t4Lnq>9xoa$r69T3pxjv$j?MNQay zIvu8iga8K=UuS!f2W-$Duo4Djd$GX-R;hwI>`9RzV4th#swPWs!hmaO)`aS{o(Q1D zs+k8g!T_&tZvDk#;qUr`9_Y0Jpuq#O0_m#&XZNb{(fh;`Fy_e+5m8E1p|9f1ngNu-|Sei2)!Zz1A8z~#UkKn?8E|z z9_Y0J;93<2&Os4ypOOFu&cVQwBtbywlO*sgP7qM~EDoeOLBPOm=0tWMgbzI)5OAru z50=F%KYyeCai}Xl#!}peAI2Ks{)x1-Qw2A;RJZNGsST}9Jgj2a%X*^CY;=piT=p2i{YdIg>XVdbh} z!y{Dg2~D?h+YT@fIUmgb?+AF`6V}xTSc9Kkhv;$7sJ9-X^Ev`O1092&D++1bDSw5$ gj>-Ed?B5W70Yt&}J9&LE^Z)<=07*qoM6N<$g6Th{xBvhE literal 0 HcmV?d00001 From 18aecfe5968e9eab6be2c05123efad34124a86a1 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 21 Sep 2015 17:49:18 +0200 Subject: [PATCH 134/138] CheckBox on Mac: indeterminate state for blue theme --- .../laf/icons/checkBoxIndeterminateSelected.png | Bin 0 -> 242 bytes .../icons/checkBoxIndeterminateSelected@2x.png | Bin 0 -> 405 bytes .../checkBoxIndeterminateSelectedDisabled.png | Bin 0 -> 254 bytes .../checkBoxIndeterminateSelectedDisabled@2x.png | Bin 0 -> 537 bytes .../checkBoxIndeterminateSelectedFocused.png | Bin 0 -> 466 bytes .../checkBoxIndeterminateSelectedFocused@2x.png | Bin 0 -> 565 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelected.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelected@2x.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelectedDisabled.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelectedDisabled@2x.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelectedFocused.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelectedFocused@2x.png diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelected.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelected.png new file mode 100644 index 0000000000000000000000000000000000000000..38f74ff4026f08ad9d8ea5a591b964fc0896708f GIT binary patch literal 242 zcmV&g1kZie+Q{m sDLx^AufSmhVpbsLAQH1e^$Z~Z0My25AOjXPy#N3J07*qoM6N<$f)jXOa{vGU literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelected@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelected@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1c9f162db0b35a43a77ce2c2922bca6b87dd4cec GIT binary patch literal 405 zcmV;G0c!qS6ovB`eTN3kLW;G|A_#8Xxhwb%E%?){1;H2S(yn!3S6vpmm0HB&57sGHzTzSc zqM6A|oWcYSS>>EBnVZXdPfao zL-8ygc;SincZM-wa(MmLO-_|GE|fHTN?K_-;ei*Pc#~lYSi@lFOvzqa9xN|B@g{>T zZ9tZQw{!uQg(QP4Z9wXTrD&yYMFv^gfE2Thn)~s~^*+~Xk}PdN{y1k#n*l^*X#>U; z0>%L_09Fi`mleR{{!$)arSyddUe*C^z-1w=15RI-76Bc6!K2HuOy`Tza1YNPD=+JS z$;nW*+jqZet9@HYcv%PB?acm!ECzSK^7@xHLw_qGCvC?2KIk1_y+S~vam(evn%_hj z4Xoae{N8Vxyx(?i!p7b2qmOX96#xU^h5&v6r7BKPj$4y}00000NkvXXu0mjfuR^i) literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelectedDisabled.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelectedDisabled.png new file mode 100644 index 0000000000000000000000000000000000000000..04f47991b6b8a4310a858f1961cc19bfaeec318b GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE z3J>6zC{V4Wyv{h~p6`wa>vC@|dcEtm0gouV%+ioXUhzFWk0YY8wRc56IB>L$d!BRB z{lJ_Z4>V1_9n7zj$(i*`b7_f8K~r;S?EYs>K)Uw+{a!+KBd>_Y((4x6Xz z&D~Y1Klc~^uk-sZ{hQ*&Zhn+qYlj9O7hjjcJ^@h{QIoHKbI!RgjP@*IuD$cnnWN&| z&S$GU*Ia&?^7qL`p9P#IjdIM@d*@xvFsaz9C)Uk>G9~EH!woG?it)_MVm>$0+n*n} z9isJh%GtD~F?!ycZ%)bE{yID1Koh5Q`}G6a4ClO34J1w!SWNj?p)>j9k?RK?o4eKW^wUfcIWFeSz_d#=1L-IyD_?e1$OgK*X_S9S1x(O!iM!&l3}FY^hWka zAjK0sR`AM}DDcIoU0|sbzmc`|-kfCliy2>@q$eD>B)3BOUG|gz+-t68z5iGdb6j&< zVkZBbvuXP0H2}>y8%2(|`D89f+5IaYy^ZSza3fcD?J3KWpNC{oS|A zg#T5S6xdslLq8|W9vqw&1(m!Z^Hr8N)K2nSel?jJBAVV_xhs{)_rZMLKP(KQZEHeS S9E$=*IfJLGpUXO@geCw$r|eJw literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelectedFocused.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelectedFocused.png new file mode 100644 index 0000000000000000000000000000000000000000..848f60ee0af61232473aee7c9fbc5a2ecdf723c6 GIT binary patch literal 466 zcmV;@0WJQCP)&~zz$FW>M>L(i#3LnQXq?~D>s0mR?q-U zzyfTbNq38$H(0i$93(SBWLV$;Ex-+-MgNSO|nD%a1&{JND&X44A@{rKx!uzMWjJq%sBD4cxb0zfT?c-Oh@D4JV)r3v0 zLtlk*7Y}l~a}x<>7D7L?LyHU7K@(cqDJK#xPq`YrhuOjULabr$VU2%!X8CG1$&dao z#VpiJ*_TrIGaS;rkJIw?Y?2-NYAI1*2C~z1@AI5}%W62JX!O)Y$KMz2H%FX39|A|Q zwBHY)#-=SRDHj{Cr3CYk4Op?9+9_IofgM!T#I8{`v+7KUU#UusbuRN#ivR!s07*qo IM6N<$g0%F_(f|Me literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelectedFocused@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkBoxIndeterminateSelectedFocused@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..e4ebd3e7c2330be910e36ed785d24d206e49ff64 GIT binary patch literal 565 zcmV-50?Pe~P) z>o{AFr!tMSa;u(O5j@}pPk18(SsVi-3;=yvqws0IzH^vqQ2fRj!5bOKLZ(^3*|S0| z<`k5XkcsS3fUdxCkQ|_^aKn(pfIb=E1|h+u18SoPBQ|Vw^6qtmHcq~2E!Cuu(xSO| zn*w7BZQ%hgc*5H#7ffK&O9@62cT((1rS)`^=9M-rCb|?%bSRYU(8@t~ETJtt-~~^3 zBZJEZ6W9c55m!oZbud^^tU>(+3vXm_cM?os6DXM672pxzDxH8EghU3iI0mo@RCVqk z`UxI|Q*eDD16dpc*aW5??jSld`is+mdcW4PI0mo@%#YkbeZ(c52Sf(4I0mp80-`K9 z4cAv-0yqKu4}ja3J*s?>OMdBJ znxud2l>WtC`mGP?H;=rs{pN`cOiye9dtwt^s?QKV^^o?MHzNP900000NkvXXu0mjf D>~s7+ literal 0 HcmV?d00001 From 2467a15f7f36d763f790c75ad90fb6909b9b6477 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 21 Sep 2015 17:50:47 +0200 Subject: [PATCH 135/138] Intellij laf support indeterminate state for Mac OS X --- .../ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java index 3604d1b96b12..96f9114781ed 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java @@ -41,9 +41,13 @@ public class MacIntelliJCheckBoxUI extends IntelliJCheckBoxUI { @Override protected void drawCheckIcon(JComponent c, Graphics2D g, JCheckBox b, Rectangle iconRect, boolean selected, boolean enabled) { - MacIntelliJIconCache - .getIcon("checkBox", selected, c.hasFocus(), b.isEnabled()) - .paintIcon(c, g, iconRect.x, iconRect.y); + String iconName = isIndeterminate(b) ? "checkBoxIndeterminate" : "checkBox"; + Icon icon = MacIntelliJIconCache.getIcon(iconName, selected || isIndeterminate(b), c.hasFocus(), b.isEnabled()); + icon.paintIcon(c, g, iconRect.x, iconRect.y); + } + + private static boolean isIndeterminate(JCheckBox checkBox) { + return "indeterminate".equals(checkBox.getClientProperty("JButton.selectedState")); } @Override From 8ae761de0f2177d89b2460524e4aa696250f2ae1 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 21 Sep 2015 17:51:48 +0200 Subject: [PATCH 136/138] Three state checkbox: don't paint indeterminate sign on Mac with IntelliJ LaF --- .../util/src/com/intellij/util/ui/ThreeStateCheckBox.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/util/ui/ThreeStateCheckBox.java b/platform/util/src/com/intellij/util/ui/ThreeStateCheckBox.java index 123021663a4e..0d9e6b58bf2e 100644 --- a/platform/util/src/com/intellij/util/ui/ThreeStateCheckBox.java +++ b/platform/util/src/com/intellij/util/ui/ThreeStateCheckBox.java @@ -15,6 +15,8 @@ */ package com.intellij.util.ui; +import com.intellij.openapi.util.SystemInfo; + import javax.swing.*; import java.awt.*; import java.awt.event.ItemEvent; @@ -116,7 +118,7 @@ public class ThreeStateCheckBox extends JCheckBox { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); - if (UIUtil.isUnderAquaLookAndFeel()) { + if (UIUtil.isUnderAquaLookAndFeel() || (SystemInfo.isMac && UIUtil.isUnderIntelliJLaF())) { return; } From 5a09e2d951033977bc8e017f54a07c46aca4e1f8 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 21 Sep 2015 18:55:56 +0300 Subject: [PATCH 137/138] fixed compatibility with kotlin --- .../intellij/debugger/jdi/VirtualMachineProxyImpl.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java index 68ef3cd6aeb5..57fadf168a81 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java @@ -22,6 +22,7 @@ package com.intellij.debugger.jdi; import com.intellij.debugger.engine.DebugProcess; import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.jdi.VirtualMachineProxy; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; @@ -278,6 +279,14 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy { return myVirtualMachine.eventRequestManager(); } + /** + * @deprecated use {@link #mirrorOfVoid()} instead + */ + @Deprecated + public VoidValue mirrorOf() throws EvaluateException { + return mirrorOfVoid(); + } + public VoidValue mirrorOfVoid() { return myVirtualMachine.mirrorOfVoid(); } From 18e6c3ac8e4611ab34febac05800a7b8abf8f837 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 21 Sep 2015 19:06:12 +0300 Subject: [PATCH 138/138] fixed wording in settings for early return --- resources-en/src/messages/DebuggerBundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources-en/src/messages/DebuggerBundle.properties b/resources-en/src/messages/DebuggerBundle.properties index cd6e64bcdd62..1107191084fe 100644 --- a/resources-en/src/messages/DebuggerBundle.properties +++ b/resources-en/src/messages/DebuggerBundle.properties @@ -234,7 +234,7 @@ label.debugger.general.configurable.skip.constructors=Skip &constructors label.debugger.general.configurable.skip.classLoaders=Skip class l&oaders label.debugger.general.configurable.skip.simple.getters=Skip simple &getters label.debugger.general.configurable.step.filters.list.header=Do not step &into the classes -label.debugger.general.configurable.evaluate.finally.on.pop=Evaluate finally blocks on pop frame: +label.debugger.general.configurable.evaluate.finally.on.pop=Evaluate finally blocks on pop frame and early return: label.debugger.general.configurable.evaluate.finally.always=&Always label.debugger.general.configurable.evaluate.finally.never=N&ever label.debugger.general.configurable.evaluate.finally.ask=As&k