Help with "matter.PsiBasedFormattingModel - Invalid element found"
I am getting the error "matter.PsiBasedFormattingModel - Invalid element found…"
I'm trying to replace a doc comment inside an action and then reformat it. The code I'm using is
PsiDocComment comment = factory.createDocCommentFromText(expanded,
member);
PsiDocComment curComment = member.getDocComment();
if (curComment != null)
comment = (PsiDocComment) curComment.replace(comment);
else
comment = (PsiDocComment) member.addBefore(comment, member);
CodeStyleManager.getInstance(project).reformat(comment);
In my case there is a comment, so curComment is not null, so the comment is replaced via curComment.replace(). When I call reformat(), I get the error:
[ 22308] ERROR - matter.PsiBasedFormattingModel - Invalid element found in '
/**
* This is documentation. See {@link #proField}.
* Then there is <i>another line!</i>.
*
* This is a good thing
*
* @see #proField
* @javadoced
*/
' at 117(* This is
java.lang.Throwable
at com.intellij.openapi.diagnostic.Logger.error(Logger.java:48)
at com.intellij.psi.formatter.PsiBasedFormattingModel.replaceWithPSI(PsiBasedFormattingModel.java:88)
at com.intellij.psi.formatter.PsiBasedFormattingModel.replaceWhiteSpace(PsiBasedFormattingModel.java:55)
at com.intellij.formatting.FormatProcessor.replaceWhiteSpace(FormatProcessor.java:224)
at com.intellij.formatting.FormatProcessor.doModify(FormatProcessor.java:187)
at com.intellij.formatting.FormatProcessor.performModifications(FormatProcessor.java:168)
at com.intellij.formatting.FormatProcessor.format(FormatProcessor.java:122)
at com.intellij.formatting.FormatterImpl.format(FormatterImpl.java:129)
at com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade.processRange(CodeFormatterFacade.java:78)
at com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade.process(CodeFormatterFacade.java:56)
at com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl.reformat(CodeStyleManagerImpl.java:88)
at com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl.reformat(CodeStyleManagerImpl.java:70)
at org.simplx.idea.javadoced.actions.SyncBopCommentAction.applyBopComment(SyncBopCommentAction.java:154)
at org.simplx.idea.javadoced.actions.SyncBopCommentAction.run(SyncBopCommentAction.java:116)
at com.intellij.openapi.command.WriteCommandAction$Simple.run(WriteCommandAction.java:170)
at com.intellij.openapi.application.RunResult.run(RunResult.java:37)
at com.intellij.openapi.command.WriteCommandAction$2$1.run(WriteCommandAction.java:122)
at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:752)
at com.intellij.openapi.command.WriteCommandAction$2.run(WriteCommandAction.java:120)
at com.intellij.openapi.command.impl.CommandProcessorImpl.executeCommand(CommandProcessorImpl.java:110)
at com.intellij.openapi.command.impl.CommandProcessorImpl.executeCommand(CommandProcessorImpl.java:86)
at com.intellij.openapi.command.WriteCommandAction.performWriteCommandAction(WriteCommandAction.java:118)
at com.intellij.openapi.command.WriteCommandAction.access$000(WriteCommandAction.java:34)
at com.intellij.openapi.command.WriteCommandAction$1.run(WriteCommandAction.java:73)
at com.intellij.openapi.command.WriteCommandAction.execute(WriteCommandAction.java:78)
at org.simplx.idea.javadoced.JavadocEdMember.<init>(JavadocEdMember.java:17)
[…]
/**
* This is documentation. See {@link #proField}.
* Then there is <i>another line!</i>.
*
* This is a good thing
*
* @see #proField
* @javadoced
*/
' at 117(* This is
java.lang.Throwable
at com.intellij.openapi.diagnostic.Logger.error(Logger.java:48)
at com.intellij.psi.formatter.PsiBasedFormattingModel.replaceWithPSI(PsiBasedFormattingModel.java:88)
at com.intellij.psi.formatter.PsiBasedFormattingModel.replaceWhiteSpace(PsiBasedFormattingModel.java:55)
at com.intellij.formatting.FormatProcessor.replaceWhiteSpace(FormatProcessor.java:224)
at com.intellij.formatting.FormatProcessor.doModify(FormatProcessor.java:187)
at com.intellij.formatting.FormatProcessor.performModifications(FormatProcessor.java:168)
at com.intellij.formatting.FormatProcessor.format(FormatProcessor.java:122)
at com.intellij.formatting.FormatterImpl.format(FormatterImpl.java:129)
at com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade.processRange(CodeFormatterFacade.java:78)
at com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade.process(CodeFormatterFacade.java:56)
at com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl.reformat(CodeStyleManagerImpl.java:88)
at com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl.reformat(CodeStyleManagerImpl.java:70)
at org.simplx.idea.javadoced.actions.SyncBopCommentAction.applyBopComment(SyncBopCommentAction.java:154)
at org.simplx.idea.javadoced.actions.SyncBopCommentAction.run(SyncBopCommentAction.java:116)
at com.intellij.openapi.command.WriteCommandAction$Simple.run(WriteCommandAction.java:170)
at com.intellij.openapi.application.RunResult.run(RunResult.java:37)
at com.intellij.openapi.command.WriteCommandAction$2$1.run(WriteCommandAction.java:122)
at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:752)
at com.intellij.openapi.command.WriteCommandAction$2.run(WriteCommandAction.java:120)
at com.intellij.openapi.command.impl.CommandProcessorImpl.executeCommand(CommandProcessorImpl.java:110)
at com.intellij.openapi.command.impl.CommandProcessorImpl.executeCommand(CommandProcessorImpl.java:86)
at com.intellij.openapi.command.WriteCommandAction.performWriteCommandAction(WriteCommandAction.java:118)
at com.intellij.openapi.command.WriteCommandAction.access$000(WriteCommandAction.java:34)
at com.intellij.openapi.command.WriteCommandAction$1.run(WriteCommandAction.java:73)
at com.intellij.openapi.command.WriteCommandAction.execute(WriteCommandAction.java:78)
at org.simplx.idea.javadoced.JavadocEdMember.<init>(JavadocEdMember.java:17)
[…]
This doesn't happen if I reformat the entire file, by passing member.getContainingFile() instead of member, but I don't want to actually do that.
Why would this happen?
Please sign in to leave a comment.
Hello Ken,
Your code looks correct - maybe the exception is caused by some problem in
the formatter core, but I can't tell what the problem is right away. However,
modified PSI elements should be automatically reformatted at the end of the
command in which you're modifying the PSI. Do you get correct results if
you remove the reformat() call altogether?
--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"
It doesn't seem to reformat. Specifically, the new comment has a blank line between two paragraphs. I have the option set to put in <p/> for blank paragraphs. After the comment is replaced it has a blank line. If I reformat the comment afterwards, the <p/> is added.
By the way, what does "invalid" mean in this case? Badly structured? Not yet re-validated?
Hello Ken,
"Invalid" means "belonging to an old version of the PSI tree" (the file has
since then been reparsed and you have an element from the tree before reparse).
--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"
Hello Ken,
Yep, that makes sense. One more workaround to try is to get a new instance
of the PsiDocComment after replace() by calling method.getDocComment(), instead
of using the replace() return value.
--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"
Good thought, but it doesn't actually work. I have the original PsiDocCommentOwner ref around; calling getDocComment() on that returns a tree with the same problem. I stored that ref through a smart ref before the comment creation, and then fetched it out afterwards, and it had the same value (and problem). I tried getting the parent of the new comment, which also returns the same ref (with the same problem).
The comment object returned by this consistent parent is different from the pre-modification comment, so it's not holding on to the old ref.