Add some code to a file

Answered

Hi,

 

I got a VirtualFile from `VirtualFileManager.getInstance().findFileByUrl` so I can have a PsiFile like this:

val psi: PsiFile? = PsiManager.getInstance(event.project!!).findFile(file!!)

The file looks like this:

<?php
/**
* @package Zend Framework
* @author Rtransat
*/


namespace Rtransat;


return [
'factories' => [
Model\Infrastructure\Api\Adapter::class => Model\Infrastructure\Api\AdapterFactory::class,
]
];

I would like to add a line in the php array in the factories index, but I really don't know how to parse the PsiElement (even with the PsiViewer plugin) to add the line.

Regards.

0
9 comments

Could you please show what you tried or what specific problems you encountered? Maybe http://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/modifying_psi.html helps?

0

The thing is I don't know how to manipulate an entire PsiFile from this full content (the entire file). And the docs don't help me because I don't understand how to get some PsiElement, edit them or add other PsiElement to another.

In this forum or youtube, stackoverflow, blog post I see the psi manipulation but from the carret in the editor not from the file it self.

I've tried to follow this blog post (see findInjectParameterList function) : https://medium.com/@andresdom/developing-an-intellij-webstorm-javascript-plugin-65416f9afea3

I've tried to get the elements like this :

val arrayHashElements: Collection<ArrayCreationExpression> = PsiTreeUtil.findChildrenOfType(file, ArrayCreationExpression::class.java)
for (arrayHashElement in arrayHashElements) {
println(arrayHashElement.node.elementType)
}

In my case I think I don't need to each every ArrayCreationExpression. I just want to get the factories array (if exists) and add a key => value at the end.

The documentation about PsiFile is too small for me. I think the PsiFile/PsiElement are difficult at first and when we understand how it's works it's more simple but in the meantime I'm stuck.

0

Could you provide your help Yann? 😁

0

Please check com.jetbrains.php.lang.psi.PhpPsiElementFactory to create new PHP PSI elements. Then use standward ways of manipulating existing PSI via PsiElement#add/replace to manipulate tree. See also PsiTreeUtil for useful methods to navigate within tree.

0

Thank you. Do you have just a simple example to show me?

0

The issue is, I don't know how to get the PsiElement which contains the factories array to use PsiElement.add(newPsiElementKeyValue).

How to get the PHP array?

0

I have try something. Here my code:

private fun findFactoriesKey(file: PsiFile): PsiElement? {
val arrayCreationExpressions: Collection<ArrayCreationExpression> = PsiTreeUtil.findChildrenOfType(file, ArrayCreationExpression::class.java)

for (arrayCreationExpression in arrayCreationExpressions) {
val arrayCreationKeyMap = PhpElementsUtil.getArrayCreationKeyMap(arrayCreationExpression)
for (arrayCreationKey in arrayCreationKeyMap) {
println(arrayCreationKey.key)
if (arrayCreationKey.key == "factories") {
return arrayCreationKey.value
}
}
}
return null
}

 

val projectPath = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, event.project!!.basePath.toString())

val file: VirtualFile? = VirtualFileManager.getInstance().findFileByUrl("$projectPath/module/Intranet/config/services.config.php")
val document: Document? = FileDocumentManager.getInstance().getDocument(file!!);
val psiFile: PsiFile = PhpPsiElementFactory.createPsiFileFromText(event.project!!, document!!.text)

val factoriesKey: PsiElement? = findFactoriesKey(psiFile)
if (factoriesKey != null) {
val createFunction: Function = PhpPsiElementFactory.createFunction(event.project!!, "function test() {return \"test\"}")
val added = factoriesKey.add(createFunction)

}

But I'm stuck with this. I don't know if it's works (in this example I try to add a function just for the test) and even if it's work I don't know how to get the new PsiFile and save the file.

Can you help me please?

0

Post is closed for comments.