From bcbd01ca202bd9c3dcec4b07cdcc0a21dd7638be Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sun, 7 Apr 2024 23:58:30 +0200 Subject: [PATCH] [java] ignore non-serializable fields in enums (IDEA-274137) GitOrigin-RevId: 2268d012377931be155463a846f7a257208d7e1d --- .../InspectionGadgetsBundle.properties | 3 ++- ...bleFieldInSerializableClassInspection.java | 25 ++++++++++--------- .../Serializable.java | 9 ++++--- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/java/java-analysis-impl/resources/messages/InspectionGadgetsBundle.properties b/java/java-analysis-impl/resources/messages/InspectionGadgetsBundle.properties index e45f2c4b2b5d..9f30111db4f4 100644 --- a/java/java-analysis-impl/resources/messages/InspectionGadgetsBundle.properties +++ b/java/java-analysis-impl/resources/messages/InspectionGadgetsBundle.properties @@ -1478,7 +1478,8 @@ bad.oddness.problem.descriptor=Oddness check will fail on negative values #loc comparator.not.serializable.display.name='Comparator' class not declared 'Serializable' comparator.not.serializable.problem.descriptor=Comparator class #ref is not declared as Serializable #loc non.serializable.field.in.serializable.class.display.name=Non-serializable field in a 'Serializable' class -non.serializable.field.in.serializable.class.problem.descriptor=Non-serializable field '#ref' in a Serializable class #loc +non.serializable.field.in.serializable.class.problem.descriptor=Non-serializable field '#ref' in Serializable class #loc +non.serializable.component.in.serializable.record.problem.descriptor=Non-serializable component '#ref' in Serializable record #loc non.serializable.object.passed.to.object.stream.display.name=Non-serializable object passed to 'ObjectOutputStream' non.serializable.object.passed.to.object.stream.problem.descriptor=Non-serializable object passed to ObjectOutputStream #loc non.serializable.object.bound.to.http.session.display.name=Non-serializable object bound to 'HttpSession' diff --git a/java/java-impl/src/com/siyeh/ig/serialization/NonSerializableFieldInSerializableClassInspection.java b/java/java-impl/src/com/siyeh/ig/serialization/NonSerializableFieldInSerializableClassInspection.java index fc8e4e224138..21ce6546f21a 100644 --- a/java/java-impl/src/com/siyeh/ig/serialization/NonSerializableFieldInSerializableClassInspection.java +++ b/java/java-impl/src/com/siyeh/ig/serialization/NonSerializableFieldInSerializableClassInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2018 Dave Griffith, Bas Leijdekkers + * Copyright 2006-2024 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,13 +45,15 @@ public final class NonSerializableFieldInSerializableClassInspection extends Ser @Override @NotNull public String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "non.serializable.field.in.serializable.class.problem.descriptor"); + boolean isRecord = (boolean)infos[1]; + return isRecord + ? InspectionGadgetsBundle.message("non.serializable.component.in.serializable.record.problem.descriptor") + :InspectionGadgetsBundle.message("non.serializable.field.in.serializable.class.problem.descriptor"); } @Override protected LocalQuickFix @NotNull [] buildFixes(Object... infos) { - final PsiModifierListOwner field = (PsiModifierListOwner)infos[0]; + final PsiVariable field = (PsiVariable)infos[0]; return SpecialAnnotationsUtilBase.createAddAnnotationToListFixes(field, this, insp -> insp.ignorableAnnotations) .toArray(LocalQuickFix.EMPTY_ARRAY); } @@ -66,7 +68,8 @@ public final class NonSerializableFieldInSerializableClassInspection extends Ser @Override public void visitField(@NotNull PsiField field) { PsiClass containingClass = field.getContainingClass(); - if (containingClass == null) { + if (containingClass == null || containingClass.isEnum()) { + // https://docs.oracle.com/javase/1.5.0/docs/guide/serialization/spec/serial-arch.html#enum return; } if (ignoreAnonymousInnerClasses && containingClass instanceof PsiAnonymousClass) { @@ -83,14 +86,14 @@ public final class NonSerializableFieldInSerializableClassInspection extends Ser visitVariable(recordComponent, recordComponent.getContainingClass()); } - private void visitVariable(@NotNull PsiVariable psiVariable, @Nullable PsiClass containingClass) { - if (psiVariable.hasModifierProperty(PsiModifier.TRANSIENT) || psiVariable.hasModifierProperty(PsiModifier.STATIC)) { + private void visitVariable(@NotNull PsiVariable variable, @Nullable PsiClass containingClass) { + if (variable.hasModifierProperty(PsiModifier.TRANSIENT) || variable.hasModifierProperty(PsiModifier.STATIC)) { return; } if (!SerializationUtils.isSerializable(containingClass)) { return; } - PsiType variableType = psiVariable.getType(); + PsiType variableType = variable.getType(); if (SerializationUtils.isProbablySerializable(variableType)) { return; } @@ -101,12 +104,10 @@ public final class NonSerializableFieldInSerializableClassInspection extends Ser if (SerializationUtils.hasWriteObject(containingClass) || SerializationUtils.hasWriteReplace(containingClass)) { return; } - if (AnnotationUtil.isAnnotated(psiVariable, ignorableAnnotations, 0)) { + if (AnnotationUtil.isAnnotated(variable, ignorableAnnotations, 0)) { return; } - PsiIdentifier nameIdentifier = psiVariable.getNameIdentifier(); - assert nameIdentifier != null; - registerError(nameIdentifier, psiVariable); + registerVariableError(variable, variable, containingClass.isRecord()); } } } \ No newline at end of file diff --git a/java/java-tests/testData/ig/com/siyeh/igtest/serialization/non_serializable_field_in_serializable_class/Serializable.java b/java/java-tests/testData/ig/com/siyeh/igtest/serialization/non_serializable_field_in_serializable_class/Serializable.java index cfe766fe07d2..82c368511bdf 100644 --- a/java/java-tests/testData/ig/com/siyeh/igtest/serialization/non_serializable_field_in_serializable_class/Serializable.java +++ b/java/java-tests/testData/ig/com/siyeh/igtest/serialization/non_serializable_field_in_serializable_class/Serializable.java @@ -1,13 +1,16 @@ import java.io.*; class C implements Serializable { - private Foo foo; + private Foo foo; private Bar bar; } -record R(Foo foo, Bar bar) implements Serializable { +record R(Foo foo, Bar bar) implements Serializable { +} +enum E { + A, B; + private final Foo foo = new Foo(); } - class Foo { }