by the time PSI listeners are called the document should be already committed: IDEA-125010

This commit is contained in:
Alexey Kudravtsev
2014-06-12 19:05:47 +04:00
parent 524e73c845
commit a3c8331247
2 changed files with 114 additions and 2 deletions
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.impl.file.impl;
@@ -640,4 +655,90 @@ public class PsiEventsTest extends PsiTestCase {
getPsiManager().removePsiTreeChangeListener(listener);
}
}
public void testPsiEventsComeWhenDocumentAlreadyCommitted() throws Exception {
myFile = createFile("A.java", "class A { int i; }");
getPsiManager().addPsiTreeChangeListener(new PsiTreeChangeListener() {
@Override
public void beforeChildAddition(@NotNull PsiTreeChangeEvent event) {
// did not decide whether the doc should be committed at this point
//checkCommitted(false, event);
}
@Override
public void beforeChildRemoval(@NotNull PsiTreeChangeEvent event) {
// did not decide whether the doc should be committed at this point
//checkCommitted(false, event);
}
@Override
public void beforeChildReplacement(@NotNull PsiTreeChangeEvent event) {
// did not decide whether the doc should be committed at this point
//checkCommitted(false, event);
}
@Override
public void beforeChildMovement(@NotNull PsiTreeChangeEvent event) {
// did not decide whether the doc should be committed at this point
//checkCommitted(false, event);
}
@Override
public void beforeChildrenChange(@NotNull PsiTreeChangeEvent event) {
// did not decide whether the doc should be committed at this point
//checkCommitted(false, event);
}
@Override
public void beforePropertyChange(@NotNull PsiTreeChangeEvent event) {
// did not decide whether the doc should be committed at this point
//checkCommitted(false, event);
}
@Override
public void childAdded(@NotNull PsiTreeChangeEvent event) {
checkCommitted(true, event);
}
@Override
public void childRemoved(@NotNull PsiTreeChangeEvent event) {
checkCommitted(true, event);
}
@Override
public void childReplaced(@NotNull PsiTreeChangeEvent event) {
checkCommitted(true, event);
}
@Override
public void childrenChanged(@NotNull PsiTreeChangeEvent event) {
checkCommitted(true, event);
}
@Override
public void childMoved(@NotNull PsiTreeChangeEvent event) {
checkCommitted(true, event);
}
@Override
public void propertyChanged(@NotNull PsiTreeChangeEvent event) {
checkCommitted(true, event);
}
}, myTestRootDisposable);
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject());
Document document = documentManager.getDocument(getFile());
assertTrue(documentManager.isCommitted(document));
document.setText("");
documentManager.commitAllDocuments();
assertTrue(documentManager.isCommitted(document));
}
private void checkCommitted(boolean shouldBeCommitted, PsiTreeChangeEvent event) {
PsiFile file = event.getFile();
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(file.getProject());
Document document = documentManager.getDocument(file);
assertEquals(shouldBeCommitted, documentManager.isCommitted(document));
}
}
@@ -85,6 +85,16 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
mySmartPointerManager = (SmartPointerManagerImpl)smartPointerManager;
mySynchronizer = new PsiToDocumentSynchronizer(this, bus);
myPsiManager.addPsiTreeChangeListener(mySynchronizer);
bus.connect().subscribe(PsiDocumentTransactionListener.TOPIC, new PsiDocumentTransactionListener() {
@Override
public void transactionStarted(@NotNull Document document, @NotNull PsiFile file) {
myUncommittedDocuments.remove(document);
}
@Override
public void transactionCompleted(@NotNull Document document, @NotNull PsiFile file) {
}
});
}
@Override
@@ -384,8 +394,9 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
runnable.run();
}
else {
LOG.assertTrue(!ApplicationManager.getApplication().isReadAccessAllowed(),
"Don't call commitAndRunReadAction inside ReadAction, it will cause a deadlock otherwise.");
if (ApplicationManager.getApplication().isReadAccessAllowed()) {
LOG.error("Don't call commitAndRunReadAction inside ReadAction, it will cause a deadlock otherwise. "+Thread.currentThread());
}
final Semaphore s1 = new Semaphore();
final Semaphore s2 = new Semaphore();