1313import java .lang .reflect .Array ;
1414import java .util .*;
1515import java .util .concurrent .ThreadLocalRandom ;
16+ import java .util .function .Function ;
1617import java .util .function .Predicate ;
1718
1819/**
@@ -184,20 +185,50 @@ public void invertAnd() {
184185
185186 @ Override
186187 public Class <?> @ Nullable [] acceptChange (ChangeMode mode ) {
187- Class <?>[] exprClasses = expressions [0 ].acceptChange (mode );
188- if (exprClasses == null )
189- return null ;
190- ArrayList <Class <?>> acceptedClasses = new ArrayList <>(Arrays .asList (exprClasses ));
191- for (int i = 1 ; i < expressions .length ; i ++) {
192- exprClasses = expressions [i ].acceptChange (mode );
193- if (exprClasses == null )
194- return null ;
195188
196- acceptedClasses .retainAll (Arrays .asList (exprClasses ));
197- if (acceptedClasses .isEmpty ())
189+ // given X: Object.class, Y: Vector.class, Number.class, Z: Integer.class
190+ // output should be Integer.class.
191+
192+ // get all accepted type arrays.
193+ List <Class <?>[]> expressionTypes = new ArrayList <>();
194+ for (Expression <?> expr : expressions ) {
195+ Class <?>[] exprTypes = expr .acceptChange (mode );
196+ if (exprTypes == null )
198197 return null ;
198+ expressionTypes .add (exprTypes );
199+ }
200+
201+ // shortcut
202+ if (expressionTypes .size () == 1 )
203+ return expressionTypes .get (0 );
204+
205+ // iterate over types and keep what works
206+ Set <Class <?>> acceptable = new LinkedHashSet <>(Arrays .asList (expressionTypes .get (0 )));
207+ for (int i = 1 ; i < expressionTypes .size (); i ++) {
208+ Set <Class <?>> newAcceptable = new LinkedHashSet <>();
209+
210+ // Check if each existing acceptable types can be matched to this expr's accepted types
211+ for (Class <?> candidate : acceptable ) {
212+ for (Class <?> accepted : expressionTypes .get (i )) {
213+ // keep the more specific version
214+ if (accepted .isAssignableFrom (candidate )) {
215+ newAcceptable .add (candidate );
216+ break ;
217+ } else if (candidate .isAssignableFrom (accepted )) {
218+ newAcceptable .add (accepted );
219+ break ;
220+ }
221+ }
222+ }
223+
224+ acceptable = newAcceptable ;
225+
226+ if (acceptable .isEmpty ()) {
227+ return new Class <?>[0 ]; // Early exit if no common types
228+ }
199229 }
200- return acceptedClasses .toArray (new Class [0 ]);
230+
231+ return acceptable .toArray (new Class <?>[0 ]);
201232 }
202233
203234 @ Override
@@ -212,6 +243,20 @@ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) thro
212243 }
213244 }
214245
246+ @ Override
247+ public <R > void changeInPlace (Event event , Function <T , R > changeFunction , boolean getAll ) {
248+ if (and || getAll ) {
249+ for (Expression <?> expr : expressions ) {
250+ //noinspection unchecked,rawtypes
251+ expr .changeInPlace (event , (Function ) changeFunction , getAll );
252+ }
253+ } else {
254+ int i = ThreadLocalRandom .current ().nextInt (expressions .length );
255+ //noinspection unchecked,rawtypes
256+ expressions [i ].changeInPlace (event , (Function ) changeFunction , false );
257+ }
258+ }
259+
215260 private int time = 0 ;
216261
217262 @ Override
0 commit comments