@@ -771,6 +771,34 @@ public void nullsafeFieldPropertyDereferencing_SPR16489() throws Exception {
771
771
assertThat (expression .getValue (context )).isNull ();
772
772
}
773
773
774
+ @ Test // gh-27421
775
+ public void nullSafeMethodChainingWithNonStaticVoidMethod () throws Exception {
776
+ FooObjectHolder foh = new FooObjectHolder ();
777
+ StandardEvaluationContext context = new StandardEvaluationContext (foh );
778
+ SpelExpression expression = (SpelExpression ) parser .parseExpression ("getFoo()?.doFoo()" );
779
+
780
+ FooObject .doFooInvoked = false ;
781
+ assertThat (expression .getValue (context )).isNull ();
782
+ assertThat (FooObject .doFooInvoked ).isTrue ();
783
+
784
+ FooObject .doFooInvoked = false ;
785
+ foh .foo = null ;
786
+ assertThat (expression .getValue (context )).isNull ();
787
+ assertThat (FooObject .doFooInvoked ).isFalse ();
788
+
789
+ assertCanCompile (expression );
790
+
791
+ FooObject .doFooInvoked = false ;
792
+ foh .foo = new FooObject ();
793
+ assertThat (expression .getValue (context )).isNull ();
794
+ assertThat (FooObject .doFooInvoked ).isTrue ();
795
+
796
+ FooObject .doFooInvoked = false ;
797
+ foh .foo = null ;
798
+ assertThat (expression .getValue (context )).isNull ();
799
+ assertThat (FooObject .doFooInvoked ).isFalse ();
800
+ }
801
+
774
802
@ Test
775
803
public void nullsafeMethodChaining_SPR16489 () throws Exception {
776
804
FooObjectHolder foh = new FooObjectHolder ();
@@ -3898,37 +3926,71 @@ void methodReferenceVarargs() {
3898
3926
tc .reset ();
3899
3927
}
3900
3928
3901
- @ Test
3902
- void nullSafeInvocationOfNonStaticVoidWrapperMethod () {
3929
+ @ Test // gh-27421
3930
+ public void nullSafeInvocationOfNonStaticVoidMethod () {
3931
+ // non-static method, no args, void return
3932
+ expression = parser .parseExpression ("new %s()?.one()" .formatted (TestClass5 .class .getName ()));
3933
+
3934
+ assertCantCompile (expression );
3935
+
3936
+ TestClass5 ._i = 0 ;
3937
+ assertThat (expression .getValue ()).isNull ();
3938
+ assertThat (TestClass5 ._i ).isEqualTo (1 );
3939
+
3940
+ TestClass5 ._i = 0 ;
3941
+ assertCanCompile (expression );
3942
+ assertThat (expression .getValue ()).isNull ();
3943
+ assertThat (TestClass5 ._i ).isEqualTo (1 );
3944
+ }
3945
+
3946
+ @ Test // gh-27421
3947
+ public void nullSafeInvocationOfStaticVoidMethod () {
3948
+ // static method, no args, void return
3949
+ expression = parser .parseExpression ("T(%s)?.two()" .formatted (TestClass5 .class .getName ()));
3950
+
3951
+ assertCantCompile (expression );
3952
+
3953
+ TestClass5 ._i = 0 ;
3954
+ assertThat (expression .getValue ()).isNull ();
3955
+ assertThat (TestClass5 ._i ).isEqualTo (1 );
3956
+
3957
+ TestClass5 ._i = 0 ;
3958
+ assertCanCompile (expression );
3959
+ assertThat (expression .getValue ()).isNull ();
3960
+ assertThat (TestClass5 ._i ).isEqualTo (1 );
3961
+ }
3962
+
3963
+ @ Test // gh-27421
3964
+ public void nullSafeInvocationOfNonStaticVoidWrapperMethod () {
3903
3965
// non-static method, no args, Void return
3904
3966
expression = parser .parseExpression ("new %s()?.oneVoidWrapper()" .formatted (TestClass5 .class .getName ()));
3905
3967
3906
3968
assertCantCompile (expression );
3907
3969
3908
3970
TestClass5 ._i = 0 ;
3909
- expression .getValue ();
3971
+ assertThat ( expression .getValue ()). isNull ();
3910
3972
assertThat (TestClass5 ._i ).isEqualTo (1 );
3911
3973
3912
3974
TestClass5 ._i = 0 ;
3913
3975
assertCanCompile (expression );
3914
- expression .getValue ();
3976
+ assertThat ( expression .getValue ()). isNull ();
3915
3977
assertThat (TestClass5 ._i ).isEqualTo (1 );
3916
3978
}
3917
3979
3918
- @ Test
3919
- void nullSafeInvocationOfStaticVoidWrapperMethod () {
3980
+ @ Test // gh-27421
3981
+ public void nullSafeInvocationOfStaticVoidWrapperMethod () {
3920
3982
// static method, no args, Void return
3921
3983
expression = parser .parseExpression ("T(%s)?.twoVoidWrapper()" .formatted (TestClass5 .class .getName ()));
3922
3984
3923
3985
assertCantCompile (expression );
3924
3986
3925
3987
TestClass5 ._i = 0 ;
3926
- expression .getValue ();
3988
+ assertThat ( expression .getValue ()). isNull ();
3927
3989
assertThat (TestClass5 ._i ).isEqualTo (1 );
3928
3990
3929
3991
TestClass5 ._i = 0 ;
3930
3992
assertCanCompile (expression );
3931
- expression .getValue ();
3993
+ assertThat ( expression .getValue ()). isNull ();
3932
3994
assertThat (TestClass5 ._i ).isEqualTo (1 );
3933
3995
}
3934
3996
@@ -5496,7 +5558,10 @@ public FooObject getFoo() {
5496
5558
5497
5559
public static class FooObject {
5498
5560
5561
+ static boolean doFooInvoked = false ;
5562
+
5499
5563
public Object getObject () { return "hello" ; }
5564
+ public void doFoo () { doFooInvoked = true ; }
5500
5565
}
5501
5566
5502
5567
@@ -5744,7 +5809,10 @@ public void reset() {
5744
5809
field = null ;
5745
5810
}
5746
5811
5747
- public void one () { i = 1 ; }
5812
+ public void one () {
5813
+ _i = 1 ;
5814
+ this .i = 1 ;
5815
+ }
5748
5816
5749
5817
public Void oneVoidWrapper () {
5750
5818
_i = 1 ;
0 commit comments