Add some code to a file




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:

* @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.



Could you please show what you tried or what specific problems you encountered? Maybe helps?


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) :

I've tried to get the elements like this :

val arrayHashElements: Collection<ArrayCreationExpression> = PsiTreeUtil.findChildrenOfType(file,
for (arrayHashElement in arrayHashElements) {

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.


Could you provide your help Yann? 😁


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.


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


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?


I have try something. Here my code:

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

for (arrayCreationExpression in arrayCreationExpressions) {
val arrayCreationKeyMap = PhpElementsUtil.getArrayCreationKeyMap(arrayCreationExpression)
for (arrayCreationKey in arrayCreationKeyMap) {
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?


Post is closed for comments.