Summary: This diff adds a new issue type for reporting modifications to immutable fields (when `report-immutable-modifications` is enabled). The underlying analysis depends on impurity analysis which itself is based on post-processing of pulse's summaries. Reviewed By: skcho Differential Revision: D25216637 fbshipit-source-id: 42e843793master
parent
11141cb100
commit
b46433642c
@ -0,0 +1,13 @@
|
||||
This issue type indicates modifications to fields marked as @Immutable. For instance, below function `mutateArray` would be marked as modifying immutable field `testArray`:
|
||||
```java
|
||||
@Immutable int[] testArray = new int[]{0, 1, 2, 4};
|
||||
|
||||
int[] getTestArray() {
|
||||
return testArray;
|
||||
}
|
||||
|
||||
void mutateArray() {
|
||||
int[] array = getTestArray();
|
||||
array[2] = 7;
|
||||
}
|
||||
```
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
package codetoanalyze.java.immutability;
|
||||
|
||||
import com.moblica.common.xmob.utils.Immutable;
|
||||
|
||||
class ArrayTest {
|
||||
@Immutable final int[] testArray = new int[] {0, 1, 2, 4};
|
||||
@Immutable static String[] suitArray = {"spades", "hearts", "diamonds", "clubs"};
|
||||
int[] mutableArray = new int[] {0};
|
||||
|
||||
void array_mod_bad() {
|
||||
testArray[3] = 3; // modifications to an immutable array are not ok
|
||||
}
|
||||
|
||||
int[] get_testArray() {
|
||||
return testArray;
|
||||
}
|
||||
|
||||
void mutate_array_via_getter_bad() {
|
||||
int[] array = get_testArray();
|
||||
array[2] = 7; // ERROR!
|
||||
}
|
||||
|
||||
void mutate_array_via_aliasing_bad() {
|
||||
int[] array = get_testArray();
|
||||
int[] otherArray = array;
|
||||
otherArray[2] = 7; // ERROR!
|
||||
}
|
||||
|
||||
void mutate_array_via_callee_bad() {
|
||||
int[] array = get_testArray();
|
||||
int[] otherArray = array;
|
||||
mutate_param_ok(array); // ERROR!
|
||||
}
|
||||
|
||||
void mutate_param_ok(int[] array) {
|
||||
array[2] = 7;
|
||||
}
|
||||
|
||||
void mutate_static_array_bad() {
|
||||
suitArray[0] = "pades"; // ERROR!
|
||||
}
|
||||
|
||||
void mutable_array_mod_ok() {
|
||||
mutableArray[0] = 3; // modifications to mutable arrays are ok
|
||||
}
|
||||
|
||||
void mixed_mod_bad() {
|
||||
mutableArray[0] = 3; // modifications to mutable arrays are ok
|
||||
mutate_array_via_callee_bad(); // // modifications to immutables are not
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
package com.moblica.common.xmob.utils;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/*
|
||||
* add this annotation to a field to tell the static analyser that it should not be mutated, making
|
||||
* tighter restrictions than normal. e.g. an @Immutable array can't have elements reassigned or to a
|
||||
* method to tell that the return value shouldn't be mutated past that point
|
||||
*/
|
||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
||||
public @interface Immutable {}
|
@ -0,0 +1,13 @@
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
TESTS_DIR = ../../..
|
||||
|
||||
ANALYZER = checkers
|
||||
INFER_OPTIONS = --impurity-only --report-immutable-modifications --disable-issue-type IMPURE_FUNCTION
|
||||
INFERPRINT_OPTIONS = --issues-tests
|
||||
SOURCES = $(wildcard *.java)
|
||||
|
||||
include $(TESTS_DIR)/javac.make
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
package codetoanalyze.java.immutability;
|
||||
|
||||
class OuterTest {
|
||||
|
||||
ArrayTest[] arrays;
|
||||
|
||||
void mutate_via_field_bad() {
|
||||
ArrayTest atest = arrays[0];
|
||||
int[] array = atest.get_testArray();
|
||||
atest.mutate_param_ok(array); // ERROR!
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
codetoanalyze/java/immutability/ArrayTest.java, codetoanalyze.java.immutability.ArrayTest.array_mod_bad():void, 0, MODIFIES_IMMUTABLE, no_bucket, ERROR, [Function void ArrayTest.array_mod_bad() modifies immutable fields,parameter `this.*testArray*[]` modified here]
|
||||
codetoanalyze/java/immutability/ArrayTest.java, codetoanalyze.java.immutability.ArrayTest.mixed_mod_bad():void, 0, MODIFIES_IMMUTABLE, no_bucket, ERROR, [Function void ArrayTest.mixed_mod_bad() modifies immutable fields,when calling `void ArrayTest.mutate_array_via_callee_bad()` here,when calling `void ArrayTest.mutate_param_ok(int[])` here,parameter `this.*testArray*[]` modified here]
|
||||
codetoanalyze/java/immutability/ArrayTest.java, codetoanalyze.java.immutability.ArrayTest.mutate_array_via_aliasing_bad():void, 0, MODIFIES_IMMUTABLE, no_bucket, ERROR, [Function void ArrayTest.mutate_array_via_aliasing_bad() modifies immutable fields,parameter `this.*testArray*[]` modified here]
|
||||
codetoanalyze/java/immutability/ArrayTest.java, codetoanalyze.java.immutability.ArrayTest.mutate_array_via_callee_bad():void, 0, MODIFIES_IMMUTABLE, no_bucket, ERROR, [Function void ArrayTest.mutate_array_via_callee_bad() modifies immutable fields,when calling `void ArrayTest.mutate_param_ok(int[])` here,parameter `this.*testArray*[]` modified here]
|
||||
codetoanalyze/java/immutability/ArrayTest.java, codetoanalyze.java.immutability.ArrayTest.mutate_array_via_getter_bad():void, 0, MODIFIES_IMMUTABLE, no_bucket, ERROR, [Function void ArrayTest.mutate_array_via_getter_bad() modifies immutable fields,parameter `this.*testArray*[]` modified here]
|
||||
codetoanalyze/java/immutability/ArrayTest.java, codetoanalyze.java.immutability.ArrayTest.mutate_static_array_bad():void, 0, MODIFIES_IMMUTABLE, no_bucket, ERROR, [Function void ArrayTest.mutate_static_array_bad() modifies immutable fields,global variable `immutability.ArrayTest.*suitArray*[]` modified here]
|
||||
codetoanalyze/java/immutability/OuterTest.java, codetoanalyze.java.immutability.OuterTest.mutate_via_field_bad():void, 0, MODIFIES_IMMUTABLE, no_bucket, ERROR, [Function void OuterTest.mutate_via_field_bad() modifies immutable fields,when calling `void ArrayTest.mutate_param_ok(int[])` here,parameter `this.*arrays*[]*testArray*[]` modified here]
|
Loading…
Reference in new issue