Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ fun getExtension(type: String): String =
"JAVA" -> "java"
"Kotlin" -> "kt"
"SQL" -> "sql"
"CLASS" -> "class"
else -> {
""
}
Expand All @@ -40,7 +41,7 @@ fun isJavaOrKotlinFileType(daoFile: PsiFile): Boolean {
if (daoFile.virtualFile == null) return false
val fileType = FileTypeManager.getInstance().getFileTypeByFile(daoFile.virtualFile)
return when (fileType.name) {
"JAVA", "Kotlin" -> true
"JAVA", "Kotlin", "CLASS" -> true
else -> false
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright Doma Tools Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.domaframework.doma.intellij.common

import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiFile
import org.domaframework.doma.intellij.common.CommonPathParameter.Companion.RESOURCES_META_INF_PATH

fun getJarRoot(
virtualFile: VirtualFile,
originalFile: PsiFile,
): VirtualFile? {
val jarRootPath = virtualFile.path.substringBefore("jar!").plus("jar!")
val jarRoot =
StandardFileSystems
.jar()
.findFileByPath("$jarRootPath/")
val methodDaoFilePath =
getMethodDaoFilePath(virtualFile, jarRootPath, originalFile)

val jarRootFile =
jarRoot?.findFileByRelativePath(methodDaoFilePath.plus(".class"))
?: jarRoot?.findFileByRelativePath(methodDaoFilePath.plus(".java"))

return jarRootFile
}

fun getMethodDaoFilePath(
virtualFile: VirtualFile,
jarRootPath: String,
originalFile: PsiFile,
): String {
val methodDaoFilePath =
virtualFile.path
.substringAfter(
jarRootPath,
).replace("/$RESOURCES_META_INF_PATH", "")
.replace("/${originalFile.name}", "")

return methodDaoFilePath
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,20 @@ package org.domaframework.doma.intellij.common.dao
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiClassOwner
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiMethod
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.PsiTreeUtil
import org.domaframework.doma.intellij.common.CommonPathParameter.Companion.RESOURCES_META_INF_PATH
import org.domaframework.doma.intellij.common.CommonPathParameter.Companion.RESOURCES_PATH
import org.domaframework.doma.intellij.common.getExtension
import org.domaframework.doma.intellij.common.getJarRoot
import org.domaframework.doma.intellij.common.getMethodDaoFilePath
import org.domaframework.doma.intellij.common.isInjectionSqlFile
import org.domaframework.doma.intellij.common.isSupportFileType
import org.domaframework.doma.intellij.common.searchDaoFile
Expand All @@ -37,10 +43,13 @@ import org.domaframework.doma.intellij.extension.getModule
/**
* Get Dao method corresponding to SQL file
*/
fun findDaoMethod(originalFile: PsiFile): PsiMethod? {
fun findDaoMethod(
originalFile: PsiFile,
daoFile: VirtualFile? = null,
): PsiMethod? {
val project = originalFile.project
val virtualFile = originalFile.virtualFile ?: return null
val module = project.getModule(virtualFile) ?: return null
val module = project.getModule(virtualFile)

if (isInjectionSqlFile(originalFile)) {
originalFile.let {
Expand All @@ -49,46 +58,78 @@ fun findDaoMethod(originalFile: PsiFile): PsiMethod? {
} else if (isSupportFileType(originalFile)) {
// TODO: Add Support Kotlin
val fileTypeName = "JAVA"
val daoFile = findDaoFile(project, originalFile) ?: return null
val relativePath =
formatDaoPathFromSqlFilePath(
originalFile,
project.getContentRoot(virtualFile)?.path ?: "",
fileTypeName,
)
val daoClassName: String =
relativePath
.substringBefore(".")
.replace("/", ".")
.replace("\\", ".")
.substringAfter(".${getExtension(fileTypeName)}")
.replace("..", ".")
.trim('.')

val daoJavaFile = project.findFile(daoFile)
findDaoClass(module, daoClassName)?.let { daoClass ->
val methodName = originalFile.name.substringBeforeLast(".")
val daoMethod =
when (daoJavaFile) {
is PsiJavaFile -> findUseSqlDaoMethod(daoJavaFile, methodName)
else -> null
}
return daoMethod
val methodName = virtualFile.nameWithoutExtension
val daoFile = daoFile ?: findDaoFile(project, originalFile) ?: return null
if (module != null) {
val relativePath =
formatDaoPathFromSqlFilePath(
originalFile,
project.getContentRoot(virtualFile)?.path ?: "",
fileTypeName,
)
// get ClassPath with package name
val daoClassName: String =
relativePath
.substringBefore(".")
.replace("/", ".")
.replace("\\", ".")
.substringAfter(".${getExtension(fileTypeName)}")
.replace("..", ".")
.trim('.')
val daoJavaFile = project.findFile(daoFile)
findDaoClass(module, daoClassName)?.let { daoClass ->
val daoMethod =
when (daoJavaFile) {
is PsiJavaFile -> findUseSqlDaoMethod(daoJavaFile, methodName)
else -> null
}
return daoMethod
}
} else {
val fileType = getExtension(daoFile.fileType.name)
val jarRootPath = virtualFile.path.substringBefore("jar!").plus("jar!")
val methodDaoFilePath = getMethodDaoFilePath(virtualFile, jarRootPath, originalFile)
val daoClassName = getDaoClassName(methodDaoFilePath, fileType)
val daoFile = getJarRoot(virtualFile, originalFile) ?: return null
val psiClassFile = PsiManager.getInstance(originalFile.project).findFile(daoFile)
val psiClassOwner = psiClassFile as? PsiClassOwner ?: return null
val psiClass =
psiClassOwner.classes
.firstOrNull { it.name == daoClassName }
?: run {
val fqn =
methodDaoFilePath
.trimStart('/')
.removeSuffix(".$fileType")
.replace('/', '.')
JavaPsiFacade
.getInstance(project)
.findClass(fqn, GlobalSearchScope.allScope(project))
} ?: return null
return psiClass.findMethodsByName(methodName, false).firstOrNull()
}
}
return null
}

private fun getDaoClassName(
methodDaoFilePath: String,
extensionName: String,
): String = methodDaoFilePath.substringBefore(".$extensionName").substringAfter("dao/")

/**
* Get jump destination Dao method file from SQL file
*/
fun findDaoFile(
project: Project,
sqlFile: PsiFile,
): VirtualFile? {
val virtualFile = sqlFile.virtualFile ?: return null
project.getModule(virtualFile) ?: return null
val contentRoot = project.getContentRoot(virtualFile) ?: return null
val virtualFile = sqlFile.virtualFile

val contentRoot = project.getContentRoot(virtualFile)
if (contentRoot == null) {
return getJarRoot(virtualFile, sqlFile)
}
// TODO: Add Support Kotlin
val relativeFilePath =
formatDaoPathFromSqlFilePath(sqlFile, contentRoot.path, "JAVA")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiAnnotation
Expand All @@ -33,6 +34,7 @@ import com.intellij.psi.PsiNameValuePair
import com.intellij.util.IncorrectOperationException
import org.domaframework.doma.intellij.common.CommonPathParameter.Companion.RESOURCES_PATH
import org.domaframework.doma.intellij.common.dao.formatSqlPathFromDaoPath
import org.domaframework.doma.intellij.common.getExtension
import org.domaframework.doma.intellij.extension.findFile
import org.domaframework.doma.intellij.extension.getContentRoot
import org.domaframework.doma.intellij.extension.getModule
Expand All @@ -53,7 +55,9 @@ class PsiDaoMethod(
var sqlFile: VirtualFile? = null
private var sqlFilePath: String = ""

private val daoFile: VirtualFile = psiMethod.containingFile.virtualFile
private val daoFile: VirtualFile =
psiMethod.containingFile.virtualFile
?: psiMethod.containingFile.originalFile.virtualFile
var daoType: DomaAnnotationType = DomaAnnotationType.Unknown
private var sqlFileOption: Boolean = false

Expand All @@ -70,6 +74,7 @@ class PsiDaoMethod(
sqlFileOption = isSqlFile == true
}

@OptIn(ExperimentalStdlibApi::class)
private fun setDaoAnnotationType() {
DomaAnnotationType.entries.forEach { type ->
if (type != DomaAnnotationType.Sql &&
Expand Down Expand Up @@ -104,23 +109,44 @@ class PsiDaoMethod(

val sqlExtension = daoType.extension
val contentRoot = this.psiProject.getContentRoot(daoFile)?.path

sqlFilePath = contentRoot?.let {
formatSqlPathFromDaoPath(it, daoFile)
.replace("main/", "")
.plus("/$methodName.$sqlExtension")
} ?: ""
if (contentRoot == null) {
val fileType = getExtension(daoFile.fileType.name)
val daoRelativePath =
psiMethod.containingFile.originalFile.virtualFile.path
.substringAfter(".jar!")
sqlFilePath =
"META-INF${daoRelativePath.replace(".$fileType","")}/$methodName.$sqlExtension"
} else {
sqlFilePath =
contentRoot.let {
formatSqlPathFromDaoPath(it, daoFile)
.replace("main/", "")
.plus("/$methodName.$sqlExtension")
}
}
}

private fun setSqlFile() {
if (isUseSqlFileMethod()) {
val module = psiProject.getModule(daoFile)
sqlFile =
module?.getResourcesSQLFile(
sqlFilePath,
isTest,
)
return
if (module == null) {
val daoPath = daoFile.path
val jarRootPath =
daoPath.substringBefore(".jar!") + ".jar!"
val jarRoot =
StandardFileSystems
.jar()
.findFileByPath("$jarRootPath/")
sqlFile = jarRoot?.findFileByRelativePath(sqlFilePath)
return
} else {
sqlFile =
module.getResourcesSQLFile(
sqlFilePath,
isTest,
)
return
}
}
// the injection part as a custom language file
getSqlAnnotation()?.let { annotation ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import org.domaframework.doma.intellij.psi.SqlElIfDirective
import org.domaframework.doma.intellij.psi.SqlElPrimaryExpr
import org.domaframework.doma.intellij.psi.SqlElStaticFieldAccessExpr
import org.domaframework.doma.intellij.psi.SqlTypes
import kotlin.invoke

val SqlElStaticFieldAccessExpr.accessElements: List<PsiElement>
get() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class SqlLineMakerProvider : RelatedItemLineMarkerProvider() {
val identifier = e.firstChild ?: e
val daoFile =
findDaoFile(project, file)?.let {
if (findDaoMethod(e.containingFile) == null) return
if (findDaoMethod(e.containingFile, it) == null) return
it
} ?: return

Expand Down
Loading