| import org.checkerframework.common.aliasing.qual.*; |
| |
| public class TypeRefinement { |
| |
| /** |
| * Type refinement is treated in the usual way, except that at (pseudo-)assignments the RHS may |
| * lose its type refinement, before the LHS is type-refined. |
| * |
| * <p>The RHS always loses its type refinement (it is widened to @MaybeAliased, and its declared |
| * type must have been @MaybeAliased) except in the following cases: |
| * |
| * <ol> |
| * <li>The RHS is a fresh expression. |
| * <li>The LHS is a @NonLeaked formal parameter and the RHS is an argument in a method call or |
| * constructor invocation. |
| * <li>The LHS is a @LeakedToResult formal parameter, the RHS is an argument in a method call or |
| * constructor invocation, and the method's return value is discarded. |
| * <ol> |
| */ |
| |
| // Test cases for the Aliasing type refinement cases below. |
| // One method for each exception case. The usual case is tested in every method too. |
| // As annotated in stubfile.astub, String() has type @Unique @NonLeaked. |
| |
| void rule1() { |
| String unique = new String(); |
| // unique is refined to @Unique here, according to the definition. |
| isUnique(unique); |
| |
| String notUnique = unique; // unique loses its refinement. |
| |
| // :: error: (argument) |
| isUnique(unique); |
| // :: error: (argument) |
| isUnique(notUnique); |
| } |
| |
| void rule2() { |
| String unique = new String(); |
| |
| isUnique(unique); |
| nonLeaked(unique); |
| isUnique(unique); |
| |
| leaked(unique); |
| // :: error: (argument) |
| isUnique(unique); |
| } |
| |
| void rule3() { |
| String unique = new String(); |
| isUnique(unique); |
| leakedToResult(unique); |
| isUnique(unique); |
| |
| String notUnique = leakedToResult(unique); |
| // :: error: (argument) |
| isUnique(unique); |
| } |
| |
| void nonLeaked(@NonLeaked String s) {} |
| |
| void leaked(String s) {} |
| |
| String leakedToResult(@LeakedToResult String s) { |
| return s; |
| } |
| |
| // @NonLeaked so it doesn't refine the type of the argument. |
| void isUnique(@NonLeaked @Unique String s) {} |
| } |