问题
I would like to know what the "proper" way to create new PsiElement instances and add them to the Psi tree is.
I looked at the tutorial provided by JetBrains (http://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/quick_fix.html). The method they use there seems suitable for the simple properties language they introduce but I don't think it's the way to go with a more complicated syntax, where I want to add a child PsiElement that cannot appear at the root level of a PsiFile.
What would be best for me is to be able to parse a text snippet as an element and have it added to the tree. I tried to do something like this:
myLangTopElement.getNode().addLeaf(MyLangTypes.CHILD_EXPRESSION, "fish = '42'", null);
It actually seems to work - the text is added to the document and a node is created but when I edit the text inside the quotes in the editor - some exceptions are thrown...
What am I doing wrong? What is the correct way to add new elements?
回答1:
PSI is complicated :(. A usual way is to create a whole file from a carefully prepared text (PsiFileFactory#createFileFromText), extract from it the PSI element you need to add into the tree, and then call PsiElement#add/addBefore/addAfter passing the extracted element as an argument. If your PSI element is a wrapper over AST (i.e. AstDelegatePsiElement), its add* methods already do the magic necessary for the exceptions not to be thrown.
You can study GrCreateSubclassAction#startTemplate from the IDEA CE source for an example, and the implementation of createCodeReferenceElementFromText that it calls.
来源:https://stackoverflow.com/questions/35713431/intellij-idea-plugin-development-how-to-modify-the-psi-tree