@Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL = true;
@SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_GETTER = true;
@SuppressWarnings({"WeakerAccess"}) public boolean IGNORE_EXTERNAL_SUPER_NOTNULL = false;
+ @SuppressWarnings({"WeakerAccess"}) public boolean REQUIRE_NOTNULL_FIELDS_INITIALIZED = true;
@SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOTNULL_PARAMETERS_OVERRIDES_NOT_ANNOTATED = false;
@Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_SETTER_PARAMETER = true;
@Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true; // remains for test
String name = child.getAttributeValue("name");
String value = child.getAttributeValue("value");
if ("IGNORE_EXTERNAL_SUPER_NOTNULL".equals(name) && "false".equals(value) ||
- "REPORT_NOTNULL_PARAMETERS_OVERRIDES_NOT_ANNOTATED".equals(name) && "false".equals(value)) {
+ "REPORT_NOTNULL_PARAMETERS_OVERRIDES_NOT_ANNOTATED".equals(name) && "false".equals(value) ||
+ "REQUIRE_NOTNULL_FIELDS_INITIALIZED".equals(name) && "true".equals(value)) {
node.removeContent(child);
}
}
}
List<PsiExpression> initializers = DfaPsiUtil.findAllConstructorInitializers(field);
- if (annotated.isDeclaredNotNull && initializers.isEmpty()) {
- final PsiAnnotation annotation = AnnotationUtil.findAnnotation(field, manager.getNotNulls());
- if (annotation != null) {
- holder.registerProblem(annotation.isPhysical() ? annotation : field.getNameIdentifier(),
- "Not-null fields must be initialized",
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
+ if (REQUIRE_NOTNULL_FIELDS_INITIALIZED) {
+ if (annotated.isDeclaredNotNull && initializers.isEmpty()) {
+ final PsiAnnotation annotation = AnnotationUtil.findAnnotation(field, manager.getNotNulls());
+ if (annotation != null) {
+ holder.registerProblem(annotation.isPhysical() ? annotation : field.getNameIdentifier(),
+ "Not-null fields must be initialized",
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
+ }
}
}
private JButton myConfigureAnnotationsButton;
private JCheckBox myIgnoreExternalSuperNotNull;
private JCheckBox myNNParameterOverridesNA;
+ private JCheckBox myRequireNNFieldsInitialized;
private OptionsPanel() {
super(new BorderLayout());
myNNParameterOverridesNA.addActionListener(actionListener);
myReportNotAnnotatedGetter.addActionListener(actionListener);
myIgnoreExternalSuperNotNull.addActionListener(actionListener);
+ myRequireNNFieldsInitialized.addActionListener(actionListener);
myConfigureAnnotationsButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myReportNotAnnotatedGetter.setSelected(REPORT_NOT_ANNOTATED_GETTER);
myIgnoreExternalSuperNotNull.setSelected(IGNORE_EXTERNAL_SUPER_NOTNULL);
myNNParameterOverridesNA.setSelected(REPORT_NOTNULL_PARAMETERS_OVERRIDES_NOT_ANNOTATED);
+ myRequireNNFieldsInitialized.setSelected(REQUIRE_NOTNULL_FIELDS_INITIALIZED);
myIgnoreExternalSuperNotNull.setEnabled(myNAMethodOverridesNN.isSelected());
}
REPORT_NOT_ANNOTATED_GETTER = myReportNotAnnotatedGetter.isSelected();
IGNORE_EXTERNAL_SUPER_NOTNULL = myIgnoreExternalSuperNotNull.isSelected();
REPORT_NOTNULL_PARAMETERS_OVERRIDES_NOT_ANNOTATED = myNNParameterOverridesNA.isSelected();
+ REQUIRE_NOTNULL_FIELDS_INITIALIZED = myRequireNNFieldsInitialized.isSelected();
REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL;
myIgnoreExternalSuperNotNull.setEnabled(myNAMethodOverridesNN.isSelected());
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.codeInspection.nullable.NullableStuffInspection.OptionsPanel">
- <grid id="cc1c9" binding="myPanel" layout-manager="GridLayoutManager" row-count="7" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="cc1c9" binding="myPanel" layout-manager="GridLayoutManager" row-count="8" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <xy x="69" y="57" width="634" height="235"/>
+ <xy x="69" y="57" width="634" height="239"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<vspacer id="c3eef">
<constraints>
- <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ <grid row="7" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="2f304" class="javax.swing.JCheckBox" binding="myReportNotAnnotatedGetter">
</component>
<component id="ef852" class="javax.swing.JButton" binding="myConfigureAnnotationsButton" default-binding="true">
<constraints>
- <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/InspectionsBundle" key="configure.annotations.option"/>
<text value="Report @NotNull &parameters overriding non-annotated"/>
</properties>
</component>
+ <component id="f6e46" class="javax.swing.JCheckBox" binding="myRequireNNFieldsInitialized">
+ <constraints>
+ <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Require @NotNull fields to be initialized explicitly"/>
+ </properties>
+ </component>
</children>
</grid>
</form>
--- /dev/null
+import org.jetbrains.annotations.*;
+
+class Test {
+ @NotNull Object member;
+
+ private void accessMember() {
+ member = new Object();
+ }
+}
\ No newline at end of file
public void testNullableFieldNotnullParam() throws Exception{ doTest(); }
public void testNotNullFieldNullableParam() throws Exception{ doTest(); }
public void testNotNullCustomException() throws Exception{ doTest(); }
+
public void testNotNullFieldNotInitialized() throws Exception{ doTest(); }
+ public void testNotNullFieldNotInitializedSetting() {
+ myInspection.REQUIRE_NOTNULL_FIELDS_INITIALIZED = false;
+ doTest();
+ }
+
public void testNotNullAnnotationChecksInChildClassMethods() { doTest(); }
public void testGetterSetterProblems() throws Exception{ doTest(); }