generated from JetBrains/intellij-platform-plugin-template
-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(kotlin): implement structure providers for Kotlin plugin #58
- Loading branch information
Showing
6 changed files
with
238 additions
and
0 deletions.
There are no files selected for viewing
53 changes: 53 additions & 0 deletions
53
languages/shire-kotlin/src/main/kotlin/com/phodal/shirelang/kotlin/KotlinPsiUtil.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package com.phodal.shirelang.kotlin | ||
|
||
import com.intellij.psi.PsiElement | ||
import com.intellij.psi.PsiMethod | ||
import com.intellij.psi.PsiNameIdentifierOwner | ||
import com.intellij.psi.PsiReference | ||
import com.intellij.psi.search.GlobalSearchScope | ||
import com.intellij.psi.search.SearchScope | ||
import com.intellij.psi.search.searches.MethodReferencesSearch | ||
import com.intellij.psi.search.searches.ReferencesSearch | ||
import org.jetbrains.kotlin.psi.KtClassOrObject | ||
import org.jetbrains.kotlin.psi.KtFile | ||
import org.jetbrains.kotlin.psi.KtFunction | ||
import org.jetbrains.kotlin.psi.KtNamedFunction | ||
|
||
object KotlinPsiUtil { | ||
fun getFunctions(kotlinClass: KtClassOrObject): List<KtFunction> { | ||
return kotlinClass.getDeclarations().filterIsInstance<KtFunction>() | ||
} | ||
|
||
fun getClasses(ktFile: KtFile): List<KtClassOrObject> { | ||
return ktFile.declarations.filterIsInstance<KtClassOrObject>() | ||
} | ||
|
||
fun signatureString(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() | ||
} | ||
|
||
fun findUsages(nameIdentifierOwner: PsiNameIdentifierOwner): List<PsiReference> { | ||
val project = nameIdentifierOwner.project | ||
val searchScope = GlobalSearchScope.allScope(project) as SearchScope | ||
|
||
return when (nameIdentifierOwner) { | ||
is PsiMethod -> { | ||
MethodReferencesSearch.search(nameIdentifierOwner, searchScope, true) | ||
} | ||
|
||
else -> { | ||
ReferencesSearch.search((nameIdentifierOwner as PsiElement), searchScope, true) | ||
} | ||
}.findAll().map { it as PsiReference } | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
...lin/src/main/kotlin/com/phodal/shirelang/kotlin/codemodel/KotlinClassStructureProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.phodal.shirelang.kotlin.codemodel | ||
|
||
import com.intellij.psi.PsiElement | ||
import com.intellij.psi.PsiNameIdentifierOwner | ||
import com.phodal.shirecore.codemodel.ClassStructureProvider | ||
import com.phodal.shirecore.codemodel.model.ClassStructure | ||
import com.phodal.shirelang.kotlin.KotlinPsiUtil | ||
import org.jetbrains.kotlin.psi.* | ||
|
||
class KotlinClassStructureProvider : ClassStructureProvider { | ||
private fun getPrimaryConstructorFields(kotlinClass: KtClassOrObject): List<KtParameter> { | ||
return kotlinClass.getPrimaryConstructorParameters().filter { it.hasValOrVar() } | ||
} | ||
|
||
override fun build(psiElement: PsiElement, gatherUsages: Boolean): ClassStructure? { | ||
if (psiElement !is KtClassOrObject) return null | ||
|
||
val text = psiElement.text | ||
val name = psiElement.name | ||
val functions = KotlinPsiUtil.getFunctions(psiElement) | ||
val allFields = getPrimaryConstructorFields(psiElement) | ||
val usages = | ||
if (gatherUsages) KotlinPsiUtil.findUsages(psiElement as PsiNameIdentifierOwner) else emptyList() | ||
|
||
val annotations: List<String> = psiElement.annotationEntries.mapNotNull { | ||
it.text | ||
} | ||
|
||
val displayName = psiElement.fqName?.asString() ?: psiElement.name ?: "" | ||
return ClassStructure( | ||
psiElement, | ||
text, | ||
name, | ||
displayName, | ||
functions, | ||
allFields, | ||
null, | ||
annotations = annotations, | ||
usages | ||
) | ||
} | ||
} | ||
|
28 changes: 28 additions & 0 deletions
28
...tlin/src/main/kotlin/com/phodal/shirelang/kotlin/codemodel/KotlinFileStructureProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.phodal.shirelang.kotlin.codemodel | ||
|
||
import com.intellij.psi.PsiFile | ||
import com.intellij.psi.util.PsiTreeUtil | ||
import com.phodal.shirecore.codemodel.FileStructureProvider | ||
import com.phodal.shirecore.codemodel.model.FileStructure | ||
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 KotlinFileStructureProvider : FileStructureProvider { | ||
override fun build(psiFile: PsiFile): FileStructure? { | ||
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 FileStructure(psiFile, name, path, packageName, imports, classOrObjects, namedFunctions) | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
...in/src/main/kotlin/com/phodal/shirelang/kotlin/codemodel/KotlinMethodStructureProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.phodal.shirelang.kotlin.codemodel | ||
|
||
import com.intellij.psi.PsiElement | ||
import com.intellij.psi.PsiNameIdentifierOwner | ||
import com.phodal.shirecore.codemodel.MethodStructureProvider | ||
import com.phodal.shirecore.codemodel.model.MethodStructure | ||
import com.phodal.shirelang.kotlin.KotlinPsiUtil | ||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.getReturnTypeReference | ||
import org.jetbrains.kotlin.psi.KtNamedFunction | ||
import org.jetbrains.kotlin.psi.psiUtil.containingClass | ||
|
||
class KotlinMethodStructureProvider : MethodStructureProvider { | ||
override fun build(psiElement: PsiElement, includeClassContext: Boolean, gatherUsages: Boolean): MethodStructure? { | ||
if (psiElement !is KtNamedFunction) return null | ||
|
||
val returnType = psiElement.getReturnTypeReference()?.text | ||
val containingClass = psiElement.containingClass() | ||
val signatureString = KotlinPsiUtil.signatureString(psiElement) | ||
val displayName = psiElement.language.displayName | ||
val valueParameters = psiElement.valueParameters.mapNotNull { it.name } | ||
val usages = | ||
if (gatherUsages) KotlinPsiUtil.findUsages(psiElement as PsiNameIdentifierOwner) else emptyList() | ||
|
||
return MethodStructure( | ||
psiElement, | ||
psiElement.text, | ||
psiElement.name, | ||
signatureString, | ||
containingClass, | ||
displayName, | ||
returnType, | ||
valueParameters, | ||
includeClassContext, | ||
usages | ||
) | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
.../src/main/kotlin/com/phodal/shirelang/kotlin/codemodel/KotlinVariableStructureProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.phodal.shirelang.kotlin.codemodel | ||
|
||
import com.intellij.psi.PsiElement | ||
import com.intellij.psi.PsiNameIdentifierOwner | ||
import com.intellij.psi.util.PsiTreeUtil | ||
import com.phodal.shirecore.codemodel.VariableStructureProvider | ||
import com.phodal.shirecore.codemodel.model.VariableStructure | ||
import com.phodal.shirelang.kotlin.KotlinPsiUtil | ||
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 KotlinVariableStructureProvider : VariableStructureProvider { | ||
override fun build( | ||
psiElement: PsiElement, | ||
withMethodContext: Boolean, | ||
withClassContext: Boolean, | ||
gatherUsages: Boolean | ||
): VariableStructure? { | ||
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) { | ||
KotlinPsiUtil.findUsages(psiNameIdentifierOwner) | ||
} else { | ||
emptyList() | ||
} | ||
|
||
return VariableStructure(psiElement, text, name, parentOfType, containingClass, usages, withMethodContext, withClassContext) | ||
} | ||
|
||
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) { | ||
KotlinPsiUtil.findUsages(psiNameIdentifierOwner) | ||
} else { | ||
emptyList() | ||
} | ||
|
||
return VariableStructure(psiElement, text, name, parentOfType, containingClass, usages, withMethodContext, withClassContext) | ||
} | ||
|
||
else -> { | ||
return null | ||
} | ||
} | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
languages/shire-kotlin/src/main/resources/com.phodal.shirelang.kotlin.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<idea-plugin package="com.phodal.shirelang.kotlin"> | ||
<!--suppress PluginXmlValidity --> | ||
<dependencies> | ||
<plugin id="org.jetbrains.kotlin"/> | ||
<plugin id="org.jetbrains.plugins.gradle"/> | ||
</dependencies> | ||
|
||
<extensions defaultExtensionNs="com.phodal"> | ||
<fileStructureProvider language="kotlin" | ||
implementationClass="com.phodal.shirelang.kotlin.codemodel.KotlinFileStructureProvider"/> | ||
<classStructureProvider language="kotlin" | ||
implementationClass="com.phodal.shirelang.kotlin.codemodel.KotlinClassStructureProvider"/> | ||
<methodStructureProvider language="kotlin" | ||
implementationClass="com.phodal.shirelang.kotlin.codemodel.KotlinMethodStructureProvider"/> | ||
<variableStructureProvider language="kotlin" | ||
implementationClass="com.phodal.shirelang.kotlin.codemodel.KotlinVariableStructureProvider"/> | ||
</extensions> | ||
</idea-plugin> |