Skip to content

Commit

Permalink
add utils
Browse files Browse the repository at this point in the history
  • Loading branch information
956237586 committed Oct 29, 2023
1 parent 4884f45 commit 27989d8
Show file tree
Hide file tree
Showing 6 changed files with 285 additions and 1 deletion.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -513,3 +513,5 @@ $SKYKOMA_PYTHON_BIN/jupyter lab --ip=0.0.0.0
#allow root
$SKYKOMA_PYTHON_BIN/jupyter lab --ip=0.0.0.0 --allow-root
```
## 编译
`./gradlew buildPlugin -PprojVersion=VERSION`
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ group = "cn.hylstudio.skykoma.plugin.idea"
version = if (project.hasProperty("projVersion")) {
project.findProperty("projVersion") as String
} else {
"0.0.16"
"v0.0.17"
}

kotlin {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package cn.hylstudio.skykoma.plugin.idea.util

import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.util.Computable
import com.intellij.openapi.util.ThrowableComputable

fun runReadAction(runnable: Runnable) {
ApplicationManager.getApplication().runReadAction(runnable)
}

fun <T> runReadAction(computable: Computable<T>): T {
return ApplicationManager.getApplication().runReadAction(computable)
}

fun <T, E : Throwable?> runReadAction(throwableComputable: ThrowableComputable<T, E>): T {
return ApplicationManager.getApplication().runReadAction(throwableComputable)
}

fun runWriteAction(runnable: Runnable) {
ApplicationManager.getApplication().runWriteAction(runnable)
}

fun <T> runWriteAction(computable: Computable<T>): T {
return ApplicationManager.getApplication().runWriteAction(computable)
}

fun <T, E : Throwable?> runWriteAction(throwableComputable: ThrowableComputable<T, E>): T {
return ApplicationManager.getApplication().runWriteAction(throwableComputable)
}

fun invokeLater(runnable: () -> Unit): Unit {
ApplicationManager.getApplication().invokeLater(runnable)
}
40 changes: 40 additions & 0 deletions src/main/kotlin/cn/hylstudio/skykoma/plugin/idea/util/GitUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package cn.hylstudio.skykoma.plugin.idea.util

import java.io.BufferedReader
import java.io.File
import java.io.IOException
import java.io.InputStreamReader

fun getDirName(dir: String?): String {
return if (dir != null) File(dir).name else ""
}

fun execCmd(cmd: String): Pair<String, String> {
try {
val process: Process = Runtime.getRuntime().exec(cmd)
val stdout: BufferedReader = BufferedReader(InputStreamReader(process.inputStream))
val stderr: BufferedReader = BufferedReader(InputStreamReader(process.errorStream))
val stdOutput: String = stdout.readLine() ?: ""
val stdErrOutput: String = stderr.readLine() ?: ""
// println("exec, cmd = $cmd, stdout = $stdOutput, stderr = $stdErrOutput")
return Pair(stdOutput, stdErrOutput)
} catch (e: IOException) {
println("exec error, cmd = $cmd, e = ${e.message}")
}
return Pair("", "")
}

val String?.gitCurrentHash: String
get() {
val cmd = "git -C $this rev-parse HEAD"
val output: Pair<String, String> = execCmd(cmd)
return output.first
}


val String?.gitCurrentBranch: String
get() {
val cmd = "git -C $this rev-parse --abbrev-ref HEAD"
val output: Pair<String, String> = execCmd(cmd)
return output.first
}
130 changes: 130 additions & 0 deletions src/main/kotlin/cn/hylstudio/skykoma/plugin/idea/util/ProjectUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package cn.hylstudio.skykoma.plugin.idea.util

import com.intellij.ide.DataManager
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.actionSystem.LangDataKeys
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectLocator
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.wm.WindowManager
import com.intellij.psi.PsiManager
import com.intellij.ui.AppIcon
import org.jetbrains.jps.model.java.JavaResourceRootType
import org.jetbrains.jps.model.java.JavaSourceRootType
import javax.swing.JFrame

val Module.rootManager: ModuleRootManager get() = ModuleRootManager.getInstance(this)
val ModuleRootManager.srcRoots: List<VirtualFile> get() = getSourceRoots(JavaSourceRootType.SOURCE)
val ModuleRootManager.resourceRoots: List<VirtualFile> get() = getSourceRoots(JavaResourceRootType.RESOURCE)
val ModuleRootManager.testSrcRoots: List<VirtualFile> get() = getSourceRoots(JavaSourceRootType.TEST_SOURCE)
val ModuleRootManager.testResourceRoots: List<VirtualFile> get() = getSourceRoots(JavaResourceRootType.TEST_RESOURCE)
val Module.srcRoots: List<VirtualFile> get() = this.rootManager.srcRoots
val Module.testSrcRoots: List<VirtualFile> get() = this.rootManager.testSrcRoots
val Module.resourceRoots: List<VirtualFile> get() = this.rootManager.resourceRoots
val Module.testResourceRoots: List<VirtualFile> get() = this.rootManager.testResourceRoots
fun Module.printInfo() {
val module = this
val moduleName: String = module.name
val sourceRoots: List<VirtualFile> = module.srcRoots
val testSrcRoots: List<VirtualFile> = module.testSrcRoots
val resourceRoots: List<VirtualFile> = module.resourceRoots
val testResourceRoots: List<VirtualFile> = module.testResourceRoots
println("moduleName:$moduleName")
println("sourceRoots:$sourceRoots,testSrcRoots:$testSrcRoots,resourceRoots:$resourceRoots,testResourceRoots:$testResourceRoots")
}

fun getCurrentProject(): Project? {
val dataContext: DataContext? = DataManager.getInstance().dataContextFromFocusAsync.blockingGet(2000)
return LangDataKeys.PROJECT.getData(dataContext!!)
}

fun getOpenedProjects(): Array<Project> {
return ProjectManager.getInstance().openProjects
}

fun openProjectByFolder(projectFolderDir: String): Project? {
val openedProjects: Array<Project> = getOpenedProjects()
val project: Project? = openedProjects.filter { it.basePath == projectFolderDir }.firstOrNull()
if (project != null) {
project.requestFocus()
return project
}
return ProjectManager.getInstance().loadAndOpenProject(projectFolderDir)
}

fun filterProjectByName(projectName: String): Project? {
return getOpenedProjects().filter { it.name == projectName }.firstOrNull()
}

val Project.psiManager: PsiManager get() = PsiManager.getInstance(this)
val Project.fileEditorManager: FileEditorManager get() = FileEditorManager.getInstance(this)
val Project.moduleManager: ModuleManager get() = ModuleManager.getInstance(this)
val Project.modules: Array<Module> get() = this.moduleManager.modules

fun Project.printInfo() {
val it = this
val projectName: String = it.name
val projectDir: String? = it.basePath
val projectDirName: String = getDirName(projectDir)
val currentBranch = it.currentBranch
val currentHash = it.currentHash
println("projectName:$projectName, basePath:$projectDir, projectDirName:$projectDirName")
println("currentBranch:$currentBranch, currentHash:$currentHash")
println()
}

fun Project.requestFocus() {
invokeLater {
val frame: JFrame? = WindowManager.getInstance().getFrame(this)
frame!!.toFront()
AppIcon.getInstance().requestFocus(frame)
}
}

fun Project.closeProject() {
invokeLater {
ProjectManager.getInstance().closeAndDispose(this)
}
}

val Project.currentHash: String
get() {
val projectDir = this.basePath
return projectDir.gitCurrentHash
}

val Project.currentBranch: String
get() {
val projectDir = this.basePath
return projectDir.gitCurrentBranch
}

fun filterJavaFile(sourceRoot: VirtualFile): List<VirtualFile> =
mutableListOf<VirtualFile>().also { javaFiles ->
VfsUtil.iterateChildrenRecursively(
sourceRoot,
{ true },
{ if (!it.isDirectory && it.name.endsWith(".java")) javaFiles.add(it); true }
)
}

fun Project.scanJavaFile(scanCb: (Module, VirtualFile, Int, Int, VirtualFile) -> Unit) {
val modules: Array<Module> = this.modules
modules.forEach { module ->
module.srcRoots.forEach { srcRoot ->
val javaFiles: List<VirtualFile> = filterJavaFile(srcRoot)
// println("scan moduleName:${module.name},javaFiles:${javaFiles.size},srcRoot:${srcRoot}")
javaFiles.forEachIndexed { i, it ->
scanCb(module, srcRoot, i, javaFiles.size, it)
}
}
}
}

val VirtualFile.project:Project? get() = ProjectLocator.getInstance().guessProjectForFile(this)
79 changes: 79 additions & 0 deletions src/main/kotlin/cn/hylstudio/skykoma/plugin/idea/util/PsiUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package cn.hylstudio.skykoma.plugin.idea.util

import com.intellij.lang.jvm.annotation.*
import com.intellij.openapi.editor.Document
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.fileEditor.OpenFileDescriptor
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.*

val PsiElement.lineNumber
get():Int {
val v: PsiElement = this
val containingFile: PsiFile = v.containingFile
val fileViewProvider: FileViewProvider = containingFile.viewProvider
val document: Document = fileViewProvider.document
val textOffset: Int = v.textOffset
if (textOffset < 0) {
return 1
}
val lineNumber: Int = document.getLineNumber(textOffset)
return lineNumber + 1
}

fun PsiElement.requestFocus() {
val v: PsiElement = this
val lineNum: Int = v.lineNumber
val project: Project = v.project
val psiFile: PsiFile = v.containingFile
val virtualFile: VirtualFile = psiFile.virtualFile
val openFileDescriptor: OpenFileDescriptor = OpenFileDescriptor(project, virtualFile, lineNum - 1, 0)
val fileEditorManager: FileEditorManager = project.fileEditorManager
invokeLater { fileEditorManager.openTextEditor(openFileDescriptor, true); }
}

fun PsiClass.findAnnotation(fullyQualifiedName: String): PsiAnnotation? {
return this.modifierList?.findAnnotation(fullyQualifiedName)
}

val PsiClass.psiAnnotations: Array<PsiAnnotation> get() = this.modifierList?.annotations ?: arrayOf()
val PsiClass.isController: Boolean
get() {
val psiClass: PsiClass = this
return runReadAction<Boolean> {
val annotationRestController: PsiAnnotation? = psiClass.findAnnotation("org.springframework.web.bind.annotation.RestController")
val annotationController: PsiAnnotation? = psiClass.findAnnotation("org.springframework.stereotype.Controller")
annotationRestController != null || annotationController != null
}
}

fun JvmAnnotationAttributeValue.parseValue(): List<String> {
when (this) {
is JvmAnnotationConstantValue -> { // For PsiAnnotationConstantValue
return listOf("const", this.constantValue as String)
}

is JvmAnnotationEnumFieldValue -> { // For PsiAnnotationEnumFieldValue
return listOf("enum", "${this.containingClassName}.${this.fieldName}")
}

is JvmAnnotationArrayValue -> { // For PsiAnnotationArrayValue
return this.values.map { it.parseValue() }.flatten()
}

is JvmAnnotationClassValue -> { // For PsiAnnotationClassValue
return listOf("class", this.qualifiedName ?: "")
}
// is JvmNestedAnnotationValue -> { // For PsiNestedAnnotationValue
// // println(this.value)
// return listOf("annotation", "")//TODO
// }
else -> {
// handle unexpected type
return listOf("unknown", "")
}
}


}

0 comments on commit 27989d8

Please sign in to comment.