From 4f159b1c40a7eb97ee0b6024ea0aaf3bdf3a6168 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurkevich Date: Sat, 25 Feb 2023 01:50:22 +0400 Subject: [PATCH] [workspace model] Add inspection to check that all fields are immutable in inheritors of WorkspaceEntity interface GitOrigin-RevId: f9e164b80a98a248b89f5508f0a3bdcaa0c5494c --- .../WorkspaceEntityMutableField.html | 9 +++++ .../intellij.devkit.workspaceModel.xml | 7 ++++ .../DevKitWorkspaceModelBundle.properties | 2 + .../WorkspaceEntityMutableFieldInspection.kt | 37 +++++++++++++++++++ 4 files changed, 55 insertions(+) create mode 100644 plugins/devkit/intellij.devkit.workspaceModel/resources/inspectionDescriptions/WorkspaceEntityMutableField.html create mode 100644 plugins/devkit/intellij.devkit.workspaceModel/src/WorkspaceEntityMutableFieldInspection.kt diff --git a/plugins/devkit/intellij.devkit.workspaceModel/resources/inspectionDescriptions/WorkspaceEntityMutableField.html b/plugins/devkit/intellij.devkit.workspaceModel/resources/inspectionDescriptions/WorkspaceEntityMutableField.html new file mode 100644 index 000000000000..fbc06b74f7a5 --- /dev/null +++ b/plugins/devkit/intellij.devkit.workspaceModel/resources/inspectionDescriptions/WorkspaceEntityMutableField.html @@ -0,0 +1,9 @@ + + +Detects unsupported var fields in the inheritors of WorkspaceEntity interface +

+ Interface implementing WorkspaceEntity have to have only val fields because it's immutable. + Implementation of WorkspaceEntity.Builder will be generated for the mutation +

+ + \ No newline at end of file diff --git a/plugins/devkit/intellij.devkit.workspaceModel/resources/intellij.devkit.workspaceModel.xml b/plugins/devkit/intellij.devkit.workspaceModel/resources/intellij.devkit.workspaceModel.xml index cce4cd0b4998..6eec4e914001 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/resources/intellij.devkit.workspaceModel.xml +++ b/plugins/devkit/intellij.devkit.workspaceModel/resources/intellij.devkit.workspaceModel.xml @@ -30,5 +30,12 @@ enabledByDefault="true" level="WARNING" implementationClass="com.intellij.devkit.workspaceModel.WorkspaceImplAbsentInspection" key="inspection.workspace.absent.model.display.name"/> + diff --git a/plugins/devkit/intellij.devkit.workspaceModel/resources/messages/DevKitWorkspaceModelBundle.properties b/plugins/devkit/intellij.devkit.workspaceModel/resources/messages/DevKitWorkspaceModelBundle.properties index 7b436879ec33..9853467b2c13 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/resources/messages/DevKitWorkspaceModelBundle.properties +++ b/plugins/devkit/intellij.devkit.workspaceModel/resources/messages/DevKitWorkspaceModelBundle.properties @@ -6,6 +6,8 @@ inspection.workspace.msg.obsolete.implementation=Obsolete entity implementation inspection.workspace.msg.regenerate.implementation=Regenerate implementation inspection.workspace.absent.model.display.name=Absent entity implementation inspection.workspace.msg.generate.implementation=Generate implementation +inspection.workspace.mutable.field.display.name=Unsupported 'var' field in entity +inspection.workspace.msg.change.field.to.val=Change to 'val' progress.title.generating.code=Generating code progress.text.removing.old.code=Removing old code diff --git a/plugins/devkit/intellij.devkit.workspaceModel/src/WorkspaceEntityMutableFieldInspection.kt b/plugins/devkit/intellij.devkit.workspaceModel/src/WorkspaceEntityMutableFieldInspection.kt new file mode 100644 index 000000000000..e376ae6eac33 --- /dev/null +++ b/plugins/devkit/intellij.devkit.workspaceModel/src/WorkspaceEntityMutableFieldInspection.kt @@ -0,0 +1,37 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.devkit.workspaceModel + +import com.intellij.codeInspection.* +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.psi.KtClass +import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.psi.KtPsiFactory +import org.jetbrains.kotlin.psi.KtVisitorVoid + +class WorkspaceEntityMutableFieldInspection: LocalInspectionTool() { + override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = object : KtVisitorVoid() { + override fun visitClass(klass: KtClass) { + if (!klass.isWorkspaceEntity()) return + if (klass.name == "Builder") return + klass.getProperties().forEach { property -> + if (property.isVar) { + holder.registerProblem(property, DevKitWorkspaceModelBundle.message("inspection.workspace.mutable.field.display.name"), + ProblemHighlightType.GENERIC_ERROR, MakeFieldImmutableFix()) + } + } + } + } +} + +private class MakeFieldImmutableFix : LocalQuickFix { + override fun getName() = DevKitWorkspaceModelBundle.message("inspection.workspace.msg.change.field.to.val") + override fun getFamilyName() = name + override fun applyFix(project: Project, descriptor: ProblemDescriptor) { + val psiElement = descriptor.psiElement + if (!psiElement.isValid) return + if (psiElement !is KtProperty) return + + val factory = KtPsiFactory(project) + psiElement.valOrVarKeyword.replace(factory.createValKeyword()) + } +} \ No newline at end of file