Why does the BasePlatformTestCase throw an IllegalStateException: Attempt to modify PSI for non-committed Document! on backspace?

Answered

I have a unit test set up for my plugin like:

class MyTest : BasePlatformTestCase() {

// setup stuff here...

    fun testCharBeforeCaret() {
        myFixture.configureByFiles("$currentTestName/foo.kt")
        myFixture.type("\b")
        myFixture.checkResultByFile("$currentTestName/foo_after.kt")
    }
}

where foo.kt is

package com.loganmay.test

/*
hello hello wor<caret>
 */

and foo_after.kt is

package com.loganmay.test

/*
hello hello wo<caret>
 */

It fails with:

Attempt to modify PSI for non-committed Document!
java.lang.IllegalStateException: Attempt to modify PSI for non-committed Document!
    at com.intellij.pom.core.impl.PomModelImpl.startTransaction(PomModelImpl.java:266)
    at com.intellij.pom.core.impl.PomModelImpl.lambda$runTransaction$2(PomModelImpl.java:96)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeNonCancelableSection$3(CoreProgressManager.java:222)
    at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:698)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:646)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computeInNonCancelableSection(CoreProgressManager.java:237)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeNonCancelableSection(CoreProgressManager.java:221)
    at com.intellij.pom.core.impl.PomModelImpl.runTransaction(PomModelImpl.java:93)
    at com.intellij.psi.impl.source.tree.ChangeUtil.prepareAndRunChangeAction(ChangeUtil.java:142)
    at com.intellij.psi.impl.source.tree.CompositeElement.replaceChild(CompositeElement.java:625)
    at com.intellij.psi.impl.source.codeStyle.CodeEditUtil.replaceChild(CodeEditUtil.java:162)
    at com.intellij.psi.impl.source.tree.CompositeElement.replaceChildInternal(CompositeElement.java:455)
    at com.intellij.psi.impl.source.tree.SharedImplUtil.doReplace(SharedImplUtil.java:196)
    at com.intellij.psi.impl.source.tree.LeafPsiElement.replace(LeafPsiElement.java:198)
    at org.jetbrains.plugins.template.BackspaceHandler.charDeleted(BackspaceHandler.kt:111)
    at com.intellij.codeInsight.editorActions.BackspaceHandler.handleBackspace(BackspaceHandler.java:96)
   

 The line `myFixture.type("\b")` is the issue, because when I change it to `myFixture.type("b")`, the test runs and fails as expected, but this exception is not thrown. Also, this same exception is thrown if I replace the errant line with `myFixture.performEditorAction(IdeActions.ACTION_EDITOR_BACKSPACE)`.

Does anyone know the root cause of this issue and how to resolve it? Any help is much appreciated. Thanks!

1 comment
Comment actions Permalink

It turned out that this exception was being thrown when I ran the plugin. The issue was with my plugin. I used:

psiElement.replace(newPsiElement)

to modify text. Since the PsiElement wasn't synced, it was throwing the exception. Fixing it involved swapping that line out with a write action to the document:

val document = PsiDocumentManager.getInstance(project).getDocument(psiFile)!!
WriteCommandAction.runWriteCommandAction(project) {
document.replaceString(startOffset, endOffset, newText)
}
0

Please sign in to leave a comment.