Skip to content

Commit

Permalink
release 1.0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
mdddj committed Jun 25, 2024
1 parent 1be6435 commit 6468530
Show file tree
Hide file tree
Showing 16 changed files with 388 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:

# 准备插件并将其发布到 JetBrains Marketplace 存储库
release:
name: Publish Plugin
name: 准备插件并将其发布到 JetBrains Marketplace 存储库
runs-on: ubuntu-latest
permissions:
contents: write
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## [1.0.3] - 2024-06-25

- 添加java转kotlin自动修复功能,@Autowired,和 @Resource, ?? -> lateinit var
- 添加kotlin接口和class可空转不可空一键修复功能


## [1.0.1] - 2024-05-25

Expand Down
3 changes: 1 addition & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ plugins {
}

group = "shop.itbug"
version = "1.0.1"
version = "1.0.3"

repositories {
mavenLocal()
mavenCentral()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package shop.itbug.dd_kotlin_util.annotator

import com.intellij.codeInsight.intention.impl.BaseIntentionAction
import com.intellij.lang.annotation.AnnotationHolder
import com.intellij.lang.annotation.Annotator
import com.intellij.lang.annotation.HighlightSeverity
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Iconable
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiReference
import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.psi.util.elementType
import com.intellij.psi.util.lastLeaf
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.psi.KtOperationReferenceExpression
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.psiUtil.prevLeaf
import shop.itbug.dd_kotlin_util.help.helper
import shop.itbug.dd_kotlin_util.icons.DDIcon
import shop.itbug.dd_kotlin_util.util.MyKtPsiFactory
import shop.itbug.dd_kotlin_util.util.filterByType
import shop.itbug.dd_kotlin_util.util.findByTypeAndText
import javax.swing.Icon

class FixBeanProperties : Annotator, DumbAware {

override fun annotate(element: PsiElement, holder: AnnotationHolder) {
if (element !is KtProperty) return
if (!element.helper.isNullableType()) return
if (!element.helper.isAutowiredOrResource()) return
holder.newAnnotation(HighlightSeverity.WARNING, "Change to lateinit var").range(element).withFix(MyFix(element))
.create()
}


private class MyFix(val element: KtProperty) : BaseIntentionAction(), Iconable {
override fun getFamilyName(): String {
return "Change to lateinit var"
}

override fun getText(): String {
return familyName
}

override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?): Boolean {
return true
}

override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
val factory = KtPsiFactory(project)
val myFactory = MyKtPsiFactory(project)
//1. 去除问号
element.typeReference?.let {
val newEle = factory.createType(it.text.removeSuffix("?"))
it.replace(newEle)
}

// 2. 删除null和null前面的=号
val nullPsi = element.children.find { it.elementType == KtNodeTypes.NULL }
nullPsi?.let {
it.prevLeaf { p -> p.text == "=" }?.delete()
it.delete()
}


// 3替换val
element.filterByType<LeafPsiElement>().find { it.text == "val" }?.let {
val lateinitPsi = myFactory.createLateinit()

/// 添加lateinit
val ws = factory.createWhiteSpace(" ")
element.modifierList?.let { modis ->
modis.addAfter(ws, modis.lastLeaf())
modis.addAfter(lateinitPsi, modis.lastLeaf())
}

///替换var
val valPsi = element.findByTypeAndText<LeafPsiElement>("val")
val newVar = factory.createVarKeyword()
valPsi?.replace(newVar) // val 替换为 var

}


//======= 修复双!!号
if (file != null) {
val find: MutableCollection<PsiReference> =
ReferencesSearch.search(element, LocalSearchScope(file)).findAll()
find.forEach { ele ->
when (val e = ele.element.nextSibling) {
is KtOperationReferenceExpression -> {
if (e.text == "!!") {
val newPsi = myFactory.createNameReferenceExpression(element.nameIdentifier?.text ?: "")
ele.element.parent.replace(newPsi)
}
}
}
}
}

}

override fun getIcon(flags: Int): Icon {
return DDIcon.FixIcon
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package shop.itbug.dd_kotlin_util.annotator

import com.intellij.codeInsight.intention.impl.BaseIntentionAction
import com.intellij.lang.annotation.AnnotationHolder
import com.intellij.lang.annotation.Annotator
import com.intellij.lang.annotation.HighlightSeverity
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Iconable
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtSuperTypeListEntry
import shop.itbug.dd_kotlin_util.help.helper
import shop.itbug.dd_kotlin_util.icons.DDIcon
import javax.swing.Icon


///将接口定义的函数列表里面可空的类型全部设置为不可空类型
class RemoveAllNullType : Annotator, DumbAware, Iconable {

override fun getIcon(flags: Int): Icon {
return DDIcon.FixIcon
}

override fun annotate(element: PsiElement, holder: AnnotationHolder) {
if (element is KtClass) {
println("name psi : ${element.nameIdentifier?.text}")
val namePsi = element.nameIdentifier ?: return
holder.newAnnotation(HighlightSeverity.INFORMATION,"Set all nullable types to non-nullable")
.range(namePsi)
.withFix(Fix(element))
.create()
}
}

private class Fix(val ktClass: KtClass): BaseIntentionAction(),Iconable {
override fun getFamilyName(): String {
return "Set all nullable types to non-nullable"
}

override fun getText(): String {
return familyName
}

override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?): Boolean {
return true
}

override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
val functions = ktClass.body?.functions ?: emptyList()
functions.forEach {
it.valueParameterList?.parameters?.forEach { prop ->
prop.typeReference?.helper?.nullableRemove()
}
it.typeReference?.helper?.nullableRemove()
}

ktClass.superTypeListEntries.forEach { type: KtSuperTypeListEntry ->
type.typeReference?.helper?.nullableRemove()
}

}

override fun getIcon(flags: Int): Icon {
return DDIcon.FixIcon
}


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,7 @@ class GenerateModuleConfigurationDialog(private val project: Project, event: AnA
override fun createCenterPanel(): JComponent {
contentPanel = panel {
row("类名") {
textField().bindText(configuration::className).validationInfo {
val empty = it.text.isEmpty()
if (empty) {
this.error("")
}
this.warning("").withOKEnabled()
}
textField().bindText(configuration::className)
}
row("包名") {
textField().bindText(configuration::packageName)
Expand Down
26 changes: 26 additions & 0 deletions src/main/kotlin/shop/itbug/dd_kotlin_util/help/KtPropertyHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package shop.itbug.dd_kotlin_util.help

import org.jetbrains.kotlin.psi.KtNullableType
import org.jetbrains.kotlin.psi.KtProperty

val KtProperty.helper: KtPropertyHelper get() = KtPropertyHelper(this)
///帮助类
class KtPropertyHelper(private val element: KtProperty) {




///是否有[name]注解
fun hasAnnotation(name: String): Boolean {
return element.modifierList?.annotationEntries?.any { it.shortName?.asString() == name } == true
}


fun isAutowired() = hasAnnotation("Autowired")
fun isResource() = hasAnnotation("Resource")
fun isAutowiredOrResource() = isAutowired() || isResource()

///
fun isNullableType() = element.typeReference?.typeElement is KtNullableType

}
30 changes: 30 additions & 0 deletions src/main/kotlin/shop/itbug/dd_kotlin_util/help/KtTypeHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package shop.itbug.dd_kotlin_util.help

import org.jetbrains.kotlin.psi.KtNullableType
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.psi.KtUserType

val KtTypeReference.helper: KtTypeHelper get() = KtTypeHelper(this)

///类型转换帮助类
class KtTypeHelper(private val element: KtTypeReference) {
private val factory = KtPsiFactory(element.project)

//可空替换为不可空
fun nullableRemove() {
when (val ele = element.firstChild) {
is KtNullableType -> {
val typeText = ele.firstChild.text
val newType = factory.createType(typeText)
element.replace(newType)
}

is KtUserType -> {
ele.typeArgumentsAsTypes.forEach { ref: KtTypeReference ->
ref.helper.nullableRemove()
}
}
}
}
}
12 changes: 12 additions & 0 deletions src/main/kotlin/shop/itbug/dd_kotlin_util/icons/DDIcon.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package shop.itbug.dd_kotlin_util.icons

import com.intellij.openapi.util.IconLoader
import javax.swing.Icon

object DDIcon {
val FixIcon = getIconName("fix")
private fun getIconName(iconName: String): Icon {
return IconLoader.getIcon("/icons/$iconName.svg",DDIcon::class.java)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package shop.itbug.dd_kotlin_util.intention

import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Iconable
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtTypeReference
import shop.itbug.dd_kotlin_util.help.helper
import shop.itbug.dd_kotlin_util.icons.DDIcon
import javax.swing.Icon

class FixBeanProperties: PsiElementBaseIntentionAction(),IntentionAction,DumbAware,Iconable {

override fun getIcon(flags: Int): Icon = DDIcon.FixIcon

override fun getFamilyName(): String = "Change to latevar init"

override fun getText(): String = getFamilyName()

override fun isAvailable(project: Project, editor: Editor?, element: PsiElement): Boolean {
println(element::class.java)
return element is KtTypeReference && (element.parent is KtProperty && (element.parent as KtProperty).helper.isAutowiredOrResource() && (element.parent as KtProperty).helper.isNullableType())
}

override fun invoke(project: Project, editor: Editor?, element: PsiElement) {
}
}
40 changes: 40 additions & 0 deletions src/main/kotlin/shop/itbug/dd_kotlin_util/util/MyKtPsiFactory.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package shop.itbug.dd_kotlin_util.util

import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.util.firstLeaf
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.KtPsiFactory


class Test {
val test: String = ""
fun test(){
test.plus("")
}
}

class MyKtPsiFactory(val project: Project) {

private var factory = KtPsiFactory(project)


fun createLateinit(): PsiElement {
return factory.createParameter("lateinit var test: String").modifierList!!.firstLeaf()
}

fun createNameReferenceExpression(name: String): KtNameReferenceExpression {
val clazz = factory.createClass("""
class Test {
val $name: String = ""
fun test(){
$name.plus("")
}
}
""".trimIndent())
return clazz.body?.functions?.first()?.bodyBlockExpression?.filterByType<KtDotQualifiedExpression>()?.first()?.firstChild as KtNameReferenceExpression
}


}
Loading

0 comments on commit 6468530

Please sign in to comment.