Skip to content

Commit

Permalink
feat: align kotlin context
Browse files Browse the repository at this point in the history
  • Loading branch information
phodal committed Jul 20, 2023
1 parent 50df31c commit b9bcbd9
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 6 deletions.
Expand Up @@ -2,10 +2,35 @@ package cc.unitmesh.idea.kotlin

import cc.unitmesh.devti.context.ClassContext
import cc.unitmesh.devti.context.builder.ClassContextBuilder
import cc.unitmesh.idea.context.JavaContextCollectionUtilsKt
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameIdentifierOwner
import org.jetbrains.annotations.Nullable
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtParameter

class KotlinClassContextBuilder : ClassContextBuilder {
private fun getDeclaredFields(kotlinClass: KtClassOrObject): List<KtNamedFunction> {
return kotlinClass.getDeclarations().filterIsInstance<KtNamedFunction>()
}

private fun getPrimaryConstructorFields(kotlinClass: KtClassOrObject): List<KtParameter> {
return kotlinClass.getPrimaryConstructorParameters().filter { it.hasValOrVar() }
}

@Nullable
override fun getClassContext(psiElement: PsiElement, gatherUsages: Boolean): ClassContext? {
TODO("Not yet implemented")
if (psiElement !is KtClassOrObject) return null

val text = psiElement.text
val name = psiElement.name
val declaredFields = getDeclaredFields(psiElement)
val primaryConstructorFields = getPrimaryConstructorFields(psiElement)
val allFields = declaredFields + primaryConstructorFields
val usages =
if (gatherUsages) JavaContextCollectionUtilsKt.findUsages(psiElement as PsiNameIdentifierOwner) else emptyList()

return ClassContext(psiElement, text, name, declaredFields, allFields, null, usages)
}
}
Expand Up @@ -3,9 +3,28 @@ package cc.unitmesh.idea.kotlin
import cc.unitmesh.devti.context.FileContext
import cc.unitmesh.devti.context.builder.FileContextBuilder
import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.annotations.NotNull
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtImportList
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtPackageDirective

class KotlinFileContextBuilder : FileContextBuilder {
override fun getFileContext(psiFile: PsiFile): FileContext? {
return null
@NotNull
override fun getFileContext(psiFile: PsiFile): FileContext {
val name = psiFile.name
val path = psiFile.virtualFile?.path ?: ""

val packageDirective = PsiTreeUtil.getChildrenOfTypeAsList(psiFile, KtPackageDirective::class.java).firstOrNull()
val packageName = packageDirective?.text ?: ""

val importList = PsiTreeUtil.getChildrenOfTypeAsList(psiFile, KtImportList::class.java)
val imports = importList.flatMap { it.imports }

val classOrObjects = PsiTreeUtil.getChildrenOfTypeAsList(psiFile, KtClassOrObject::class.java)
val namedFunctions = PsiTreeUtil.getChildrenOfTypeAsList(psiFile, KtNamedFunction::class.java)

return FileContext(psiFile, name, path, packageName, imports, classOrObjects, namedFunctions)
}
}
Expand Up @@ -2,14 +2,62 @@ package cc.unitmesh.idea.kotlin

import cc.unitmesh.devti.context.MethodContext
import cc.unitmesh.devti.context.builder.MethodContextBuilder
import cc.unitmesh.idea.context.JavaContextCollectionUtilsKt
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameIdentifierOwner
import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.getReturnTypeReference
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.containingClass

class KotlinMethodContextBuilder : MethodContextBuilder {
@Nullable
override fun getMethodContext(
psiElement: PsiElement,
@NotNull psiElement: PsiElement,
includeClassContext: Boolean,
gatherUsages: Boolean
): MethodContext? {
return null
if (psiElement !is KtNamedFunction) return null

val text = psiElement.text
val name = psiElement.name
val returnType = psiElement.getReturnTypeReference()?.text
val containingClass = psiElement.containingClass()
val signatureString = Util.getSignatureString(psiElement)
val displayName = psiElement.language.displayName
val valueParameters = psiElement.valueParameters.mapNotNull { it.name }
val usages =
if (gatherUsages) JavaContextCollectionUtilsKt.findUsages(psiElement as PsiNameIdentifierOwner) else emptyList()

return MethodContext(
psiElement,
text,
name,
signatureString,
containingClass,
displayName,
returnType,
valueParameters,
includeClassContext,
usages
)
}

object Util {
fun getSignatureString(@NotNull signatureString: KtNamedFunction): String {
val bodyBlockExpression = signatureString.bodyBlockExpression
val startOffsetInParent = if (bodyBlockExpression != null) {
bodyBlockExpression.startOffsetInParent
} else {
val bodyExpression = signatureString.bodyExpression
bodyExpression?.startOffsetInParent ?: signatureString.textLength
}
val text = signatureString.text
val substring = text.substring(0, startOffsetInParent)
return substring.replace('\n', ' ').trim()
}
}

}

Expand Up @@ -2,7 +2,15 @@ package cc.unitmesh.idea.kotlin

import cc.unitmesh.devti.context.VariableContext
import cc.unitmesh.devti.context.builder.VariableContextBuilder
import cc.unitmesh.idea.context.JavaContextCollectionUtilsKt
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameIdentifierOwner
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtVariableDeclaration
import org.jetbrains.kotlin.psi.psiUtil.containingClass

class KotlinVariableContextBuilder : VariableContextBuilder {
override fun getVariableContext(
Expand All @@ -11,6 +19,42 @@ class KotlinVariableContextBuilder : VariableContextBuilder {
includeClassContext: Boolean,
gatherUsages: Boolean
): VariableContext? {
return null
when (psiElement) {
is KtVariableDeclaration -> {
val text = psiElement.text
val name = psiElement.name
val parentOfType = PsiTreeUtil.getParentOfType(psiElement, KtNamedFunction::class.java, true)
val containingClass = psiElement.containingClass()
val psiNameIdentifierOwner = psiElement as? PsiNameIdentifierOwner

val usages = if (gatherUsages && psiNameIdentifierOwner != null) {
JavaContextCollectionUtilsKt.findUsages(psiNameIdentifierOwner)
} else {
emptyList()
}

return VariableContext(psiElement, text, name, parentOfType, containingClass, usages, includeMethodContext, includeClassContext)
}

is KtParameter -> {
val text = psiElement.text
val name = psiElement.name
val parentOfType = PsiTreeUtil.getParentOfType(psiElement, KtNamedFunction::class.java, true)
val containingClass = psiElement.containingClass()
val psiNameIdentifierOwner = psiElement as? PsiNameIdentifierOwner

val usages = if (gatherUsages && psiNameIdentifierOwner != null) {
JavaContextCollectionUtilsKt.findUsages(psiNameIdentifierOwner)
} else {
emptyList()
}

return VariableContext(psiElement, text, name, parentOfType, containingClass, usages, includeMethodContext, includeClassContext)
}

else -> {
return null
}
}
}
}

0 comments on commit b9bcbd9

Please sign in to comment.