@@ -6656,6 +6656,18 @@ private void putNotInstanceOfTypeInfo(final Object key, final Collection<ClassNo
66566656 tti .addAll (types ); // stash negative type(s)
66576657 }
66586658
6659+ private boolean optInstanceOfTypeInfo (final Expression expression , final ClassNode type ) {
6660+ var tti = typeCheckingContext .temporaryIfBranchTypeInformation .peek ().get (extractTemporaryTypeInfoKey (expression ));
6661+ if (tti != null ) { assert !tti .isEmpty ();
6662+ tti .add (type );
6663+ ClassNode ut = newUnionTypeClassNode (tti );
6664+ tti .clear ();
6665+ tti .add (ut );
6666+ return true ;
6667+ }
6668+ return false ;
6669+ }
6670+
66596671 /**
66606672 * GROOVY-11983: Whether the temporary type info captured while visiting {@code expr}
66616673 * may be soundly inverted for the else branch of {@code if (expr) ... else ...} (or
@@ -6679,38 +6691,33 @@ private void putNotInstanceOfTypeInfo(final Object key, final Collection<ClassNo
66796691 private static boolean canInvertNarrowingForElseBranch (final Expression expr ) {
66806692 // NotExpression extends BooleanExpression — must check before the BooleanExpression branch
66816693 if (expr instanceof NotExpression ) return true ;
6682- if (expr instanceof BooleanExpression be ) return canInvertNarrowingForElseBranch (be .getExpression ());
6694+ if (expr instanceof BooleanExpression be ) {
6695+ return canInvertNarrowingForElseBranch (be .getExpression ());
6696+ }
66836697 if (expr instanceof BinaryExpression be ) {
6684- int op = be .getOperation ().getType ();
6685- // AND-like / XOR: !(L op R) doesn't pin down each operand's truth value
6686- if (op == LOGICAL_AND || op == BITWISE_AND || op == BITWISE_XOR ) return false ;
6687- // OR-like: !(L op R) <=> !L && !R, so recurse into both operands
6688- if (op == LOGICAL_OR || op == BITWISE_OR ) {
6698+ switch (be .getOperation ().getType ()) {
6699+ case LOGICAL_AND :
6700+ case BITWISE_AND :
6701+ case BITWISE_XOR :
6702+ // AND-like / XOR: !(L op R) doesn't pin down each operand's truth value
6703+ return false ;
6704+ case LOGICAL_OR :
6705+ case BITWISE_OR :
6706+ // OR-like: !(L op R) <=> !L && !R, so recurse into both operands
66896707 return canInvertNarrowingForElseBranch (be .getLeftExpression ())
66906708 && canInvertNarrowingForElseBranch (be .getRightExpression ());
6709+ default :
6710+ return true ; // instanceof, ==, comparisons, etc.
66916711 }
6692- return true ; // instanceof, ==, comparisons, etc.
66936712 }
66946713 if (expr instanceof TernaryExpression te ) {
6695- return canInvertNarrowingForElseBranch (te .getBooleanExpression ())
6714+ return canInvertNarrowingForElseBranch (te .getBooleanExpression (). getExpression () )
66966715 && canInvertNarrowingForElseBranch (te .getTrueExpression ())
66976716 && canInvertNarrowingForElseBranch (te .getFalseExpression ());
66986717 }
66996718 return true ;
67006719 }
67016720
6702- private boolean optInstanceOfTypeInfo (final Expression expression , final ClassNode type ) {
6703- var tti = typeCheckingContext .temporaryIfBranchTypeInformation .peek ().get (extractTemporaryTypeInfoKey (expression ));
6704- if (tti != null ) { assert !tti .isEmpty ();
6705- tti .add (type );
6706- ClassNode ut = newUnionTypeClassNode (tti );
6707- tti .clear ();
6708- tti .add (ut );
6709- return true ;
6710- }
6711- return false ;
6712- }
6713-
67146721 /**
67156722 * Computes the key to use for {@link TypeCheckingContext#temporaryIfBranchTypeInformation}.
67166723 */
0 commit comments