mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-02 12:50:55 +00:00
idea: implement function call completion (limited)
This commit is contained in:
parent
d12aadf18c
commit
c92a111af7
@ -0,0 +1,7 @@
|
||||
package gay.pizza.pork.parser
|
||||
|
||||
fun CharSource.readToString(): String = buildString {
|
||||
while (peek() != CharSource.NullChar) {
|
||||
append(next())
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package gay.pizza.pork.tool
|
||||
|
||||
import com.github.ajalt.clikt.core.CliktCommand
|
||||
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||
import com.github.ajalt.clikt.parameters.arguments.default
|
||||
import gay.pizza.dough.fs.PlatformFsProvider
|
||||
import gay.pizza.dough.fs.createDirectories
|
||||
import gay.pizza.dough.fs.exists
|
||||
import gay.pizza.dough.fs.writeString
|
||||
import gay.pizza.pork.parser.readToString
|
||||
import gay.pizza.pork.stdlib.PorkStdlib
|
||||
|
||||
class CopyStdlibCommand : CliktCommand(help = "Copy Stdlib", name = "copy-stdlib") {
|
||||
val output by argument("output").default("stdlib")
|
||||
|
||||
override fun run() {
|
||||
val outputFsPath = PlatformFsProvider.resolve(output)
|
||||
for (filePath in PorkStdlib.files) {
|
||||
val outputFilePath = outputFsPath.resolve(filePath)
|
||||
if (outputFilePath.parent?.exists() == false) {
|
||||
outputFilePath.parent?.createDirectories()
|
||||
}
|
||||
outputFilePath.writeString(PorkStdlib.loadAsCharSource(filePath).readToString())
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,8 @@ class RootCommand : CliktCommand(
|
||||
ParseCommand(),
|
||||
AstCommand(),
|
||||
AttributeCommand(),
|
||||
ScopeAnalysisCommand()
|
||||
ScopeAnalysisCommand(),
|
||||
CopyStdlibCommand()
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user