idea: implement function call completion (limited)

This commit is contained in:
2023-09-21 21:33:34 -07:00
parent d12aadf18c
commit c92a111af7
5 changed files with 76 additions and 12 deletions

View File

@ -8,15 +8,34 @@ import gay.pizza.pork.idea.psi.gen.PorkElement
class PorkFunctionReference(element: PorkElement, textRange: TextRange) : PorkReference(element, textRange) {
override fun resolve(): PorkElement? {
val functionName = canonicalText
for (file in getRelevantFiles()) {
val thisFileFunctionDefinitions = PsiTreeUtil.collectElementsOfType(file, FunctionDefinitionElement::class.java)
val thisFileFoundFunctionDefinition = thisFileFunctionDefinitions.firstOrNull {
it.name == functionName
}
if (thisFileFoundFunctionDefinition != null) {
return thisFileFoundFunctionDefinition
}
val functionDefinitions = findFunctionDefinitions(functionName)
if (functionDefinitions.isNotEmpty()) {
return functionDefinitions.first()
}
return null
}
override fun getVariants(): Array<Any> {
return findFunctionDefinitions().toTypedArray()
}
fun findFunctionDefinitions(name: String? = null): List<FunctionDefinitionElement> {
val foundFunctionDefinitions = mutableListOf<FunctionDefinitionElement>()
for (file in getRelevantFiles()) {
val fileFunctionDefinitions = PsiTreeUtil.collectElementsOfType(file, FunctionDefinitionElement::class.java)
if (name != null) {
val fileFoundDefinition = fileFunctionDefinitions.firstOrNull {
it.name == name
}
if (fileFoundDefinition != null) {
foundFunctionDefinitions.add(fileFoundDefinition)
return foundFunctionDefinitions
}
} else {
foundFunctionDefinitions.addAll(fileFunctionDefinitions)
}
}
return foundFunctionDefinitions
}
}

View File

@ -5,6 +5,7 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiReferenceBase
import com.intellij.psi.search.FilenameIndex
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.childrenOfType
import gay.pizza.pork.idea.psi.gen.ImportDeclarationElement
@ -13,9 +14,12 @@ import gay.pizza.pork.idea.psi.gen.SymbolElement
abstract class PorkReference(element: PorkElement, textRange: TextRange) : PsiReferenceBase<PsiElement>(element, textRange) {
fun getRelevantFiles(): List<PsiFile> {
val containingFile = element.containingFile
val containingFile = element.containingFile ?: return emptyList()
if (containingFile.virtualFile == null) {
return getAllProjectPorkFiles()
}
val importDeclarationElements = PsiTreeUtil.collectElementsOfType(containingFile, ImportDeclarationElement::class.java)
val files = mutableListOf<PsiFile>(containingFile)
val files = mutableListOf(containingFile)
for (importDeclaration in importDeclarationElements) {
val symbolElements = importDeclaration.childrenOfType<SymbolElement>()
val importType = importDeclaration.childrenOfType<SymbolElement>().first().text
@ -25,10 +29,17 @@ abstract class PorkReference(element: PorkElement, textRange: TextRange) : PsiRe
val basicImportPath = symbolElements.drop(1).joinToString("/") { it.text.trim() }
val actualImportPath = "../${basicImportPath}.pork"
val virtualFile = containingFile.virtualFile.findFileByRelativePath(actualImportPath) ?: continue
val virtualFile = containingFile.virtualFile?.findFileByRelativePath(actualImportPath) ?: continue
val psiFile = PsiManager.getInstance(element.project).findFile(virtualFile) ?: continue
files.add(psiFile)
}
return files
}
fun getAllProjectPorkFiles(): List<PsiFile> {
val porkVirtualFiles = FilenameIndex.getAllFilesByExt(element.project, "pork")
return porkVirtualFiles.mapNotNull { virtualFile ->
PsiManager.getInstance(element.project).findFile(virtualFile)
}
}
}