manage DummyHolder's tree in the same way as PsiFileImpl does (EA-96901 - assert: FileTrees.withGreenStub)

This commit is contained in:
peter
2017-03-04 21:50:38 +01:00
parent bc8bb830df
commit 78eebe6590
4 changed files with 38 additions and 9 deletions
@@ -213,6 +213,24 @@ public Foo() {
"""
}
void "test delegate to a method calling local class constructor"() {
myFixture.addClass("""
class Another {
static Object method() {
class LocalClass {
LocalClass() { launchMissiles(); }
}
return new LocalClass();
}
}
""")
assertPure false, """
Object smth() {
return Another.method();
}
"""
}
private void assertPure(boolean expected, String classBody) {
def clazz = myFixture.addClass("final class Foo { $classBody }")
assert !((PsiFileImpl) clazz.containingFile).contentsLoaded
@@ -20,6 +20,8 @@ import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes
import com.intellij.psi.impl.source.DummyHolder
import com.intellij.psi.impl.source.PsiClassImpl
import com.intellij.psi.impl.source.PsiFileImpl
import com.intellij.psi.impl.source.PsiJavaFileImpl
@@ -317,4 +319,14 @@ class B {
}
}
}
void "test DummyHolder calcStubTree does not fail"() {
def text = "{ new Runnable() { public void run() {} }; }"
def file = JavaPsiFacade.getElementFactory(project).createCodeBlockFromText(text, null).containingFile
// main thing is it doesn't fail; DummyHolder.calcStubTree can be changed to null in future if we decide we don't need it
def stubTree = assertInstanceOf(file, DummyHolder).calcStubTree()
assert stubTree.plainList.find { it.stubType == JavaStubElementTypes.ANONYMOUS_CLASS }
}
}
@@ -34,7 +34,6 @@ public class DummyHolder extends PsiFileImpl {
private final CharTable myTable;
private final Boolean myExplicitlyValid;
private final Language myLanguage;
private volatile FileElement myFileElement;
@SuppressWarnings("EmptyClass") private static class DummyHolderTreeLock {}
private final DummyHolderTreeLock myTreeElementLock = new DummyHolderTreeLock();
@@ -71,9 +70,9 @@ public class DummyHolder extends PsiFileImpl {
myContext = context;
myTable = table != null ? table : IdentityCharTable.INSTANCE;
if (contentElement instanceof FileElement) {
myFileElement = (FileElement)contentElement;
myFileElement.setPsi(this);
myFileElement.setCharTable(myTable);
((FileElement)contentElement).setPsi(this);
((FileElement)contentElement).setCharTable(myTable);
setTreeElementPointer((FileElement)contentElement);
}
else if (contentElement != null) {
getTreeElement().rawAddChildren(contentElement);
@@ -130,16 +129,16 @@ public class DummyHolder extends PsiFileImpl {
@Override
@NotNull
public FileElement getTreeElement() {
FileElement fileElement = myFileElement;
FileElement fileElement = super.derefTreeElement();
if (fileElement != null) return fileElement;
synchronized (myTreeElementLock) {
fileElement = myFileElement;
fileElement = super.derefTreeElement();
if (fileElement == null) {
fileElement = new FileElement(TokenType.DUMMY_HOLDER, null);
fileElement.setPsi(this);
if (myTable != null) fileElement.setCharTable(myTable);
myFileElement = fileElement;
setTreeElementPointer(fileElement);
clearCaches();
}
return fileElement;
@@ -155,7 +154,7 @@ public class DummyHolder extends PsiFileImpl {
@Override
@SuppressWarnings({"CloneDoesntDeclareCloneNotSupportedException"})
protected PsiFileImpl clone() {
final PsiFileImpl psiClone = cloneImpl(myFileElement);
final PsiFileImpl psiClone = cloneImpl(getTreeElement());
final DummyHolderViewProvider dummyHolderViewProvider = new DummyHolderViewProvider(getManager());
myViewProvider = dummyHolderViewProvider;
dummyHolderViewProvider.setDummyHolder((DummyHolder)psiClone);
@@ -131,7 +131,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
return null;
}
private FileElement derefTreeElement() {
protected FileElement derefTreeElement() {
return myTrees.derefTreeElement();
}