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