Add PsiElement to another
Answered
Hi,
I have a PHP array like this:
<?php
namespace Intranet;
return [
'factories' => [
// Api
Model\Infrastructure\Api\Adapter::class => Model\Infrastructure\Api\AdapterFactory::class,
// Command
Model\Application\Command\Application\CreateApplication::class => Model\Application\Command\Application\CreateApplicationFactory::class,
],
'foo' => [
'bar' => 'baz'
],
Model\Application\Query\Search\FindApplicationForUser::class => 'test'
];
My goal is to add a key/value inside the factories index (I want to add a ClassConstantReference \namespace\something::class not a StringLiteralExpression like 'foo').
Currently I have this code:
fun findFactoriesValuesArray(file: PsiFile): PsiElement? {
val phpReturn = PsiTreeUtil.findChildOfType(file, PhpReturn::class.java)
if (phpReturn != null) {
val arrayCreation: PhpPsiElement? = phpReturn.firstPsiChild
if (arrayCreation is ArrayCreationExpression) {
for (hashElement in arrayCreation.hashElements) {
val arrayKey = hashElement.key
if (arrayKey is StringLiteralExpression && arrayKey.text == "'factories'") {
val arrayValue = hashElement.value
val lastArrayHashElement: PsiElement = arrayValue!!.children[arrayValue.children.size - 1]
if (lastArrayHashElement is ArrayHashElement) {
println(lastArrayHashElement)
return lastArrayHashElement
}
}
}
}
}
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 arrayCreation = findFactoriesValuesArray(psiFile)
if (arrayCreation != null) {
val createString: PsiElement = PhpPsiElementFactory.createPhpPsiFromText(event.project!!, ArrayHashElement::class.java, "test::class => testtest::class")
arrayCreation.add(createString)
println(psiFile.text)
}
I have an error:
java.lang.AssertionError: cannot create element from text:
<?php
test::class => testtest::class
at com.jetbrains.php.lang.psi.PhpPsiElementFactory.createPhpPsiFromText(PhpPsiElementFactory.java:294)
Why is try to add the open PHP tag and not only the string passed to the method?
Thanks.
Please sign in to leave a comment.
I've updated my method findFactoriesValuesArray which now return the last ArrayHashElement:
The output is:
So my string is added to the end of line of the last ArrayHashElement but I need to add a comma and a new line.
PS : I don't know why the ouput contain two PHP open tag.
Please do not create multiple threads for the same problem. https://intellij-support.jetbrains.com/hc/en-us/community/posts/360004324519-Add-some-code-to-a-file?page=1#community_comment_360000662460
Please try creating "," as separate element and append it before appending new array element
Thank you for your reply.
I add the comma like this: (It's work, after that I will need to check if the comma exists and add it if not the case)
The same exception is thrown:
java.lang.AssertionError: cannot create element from text:
<?php
'test' => 'test'
at com.jetbrains.php.lang.psi.PhpPsiElementFactory.createPhpPsiFromText(PhpPsiElementFactory.java:272)
The PsiTreeView plugin tell me an ArrayHashElement has a key => value as text
I really don't know why an exception is thrown.
I really need help. 4 evening and still not the Psi I want.
java.lang.IllegalArgumentException: Argument for @NotNull parameter 'element' of com/intellij/extapi/psi/ASTDelegatePsiElement.addAfter must not be null
at com.intellij.extapi.psi.ASTDelegatePsiElement.$$$reportNull$$$0(ASTDelegatePsiElement.java)
at com.intellij.extapi.psi.ASTDelegatePsiElement.addAfter(ASTDelegatePsiElement.java)
Why the element parameter is null?
What is the correct way to create a HashArrayElement from text?
I don't understand at all how to add a HashArrayElement to my psi element.
I found something but I don't think it's the best way to do.
It's working, but why the reformat method don't add a new line after the comma?
It's possible to refactor this code?