From ca50f94b2fb971787a4f46b6541732079b01c0c8 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Thu, 25 Jul 2013 12:10:42 +0400 Subject: [PATCH] allow customization of stub root for multi-root psi files (CR-IC-1700) --- .../core-api/src/com/intellij/psi/FileViewProvider.java | 3 +++ .../src/com/intellij/psi/DummyHolderViewProvider.java | 6 ++++++ .../src/com/intellij/psi/SingleRootFileViewProvider.java | 8 ++++++++ .../src/com/intellij/psi/impl/source/PsiFileImpl.java | 8 +++++++- .../src/com/intellij/psi/stubs/StubTreeBuilder.java | 1 + .../com/intellij/psi/stubs/StubProcessingHelperBase.java | 3 ++- 6 files changed, 27 insertions(+), 2 deletions(-) diff --git a/platform/core-api/src/com/intellij/psi/FileViewProvider.java b/platform/core-api/src/com/intellij/psi/FileViewProvider.java index 182adf188e21..d307e50f1a7b 100644 --- a/platform/core-api/src/com/intellij/psi/FileViewProvider.java +++ b/platform/core-api/src/com/intellij/psi/FileViewProvider.java @@ -100,4 +100,7 @@ public interface FileViewProvider extends Cloneable, UserDataHolder { @NotNull FileViewProvider createCopy(@NotNull VirtualFile copy); + + @NotNull + PsiFile getStubBindingRoot(); } diff --git a/platform/core-impl/src/com/intellij/psi/DummyHolderViewProvider.java b/platform/core-impl/src/com/intellij/psi/DummyHolderViewProvider.java index fac7ec4ec4b7..ff795fbcb5e3 100644 --- a/platform/core-impl/src/com/intellij/psi/DummyHolderViewProvider.java +++ b/platform/core-impl/src/com/intellij/psi/DummyHolderViewProvider.java @@ -162,6 +162,12 @@ public class DummyHolderViewProvider extends UserDataHolderBase implements FileV throw new RuntimeException("Clone is not supported for DummyHolderProviders. Use DummyHolder clone directly."); } + @NotNull + @Override + public PsiFile getStubBindingRoot() { + return getPsi(getBaseLanguage()); + } + @Override public PsiElement findElementAt(final int offset) { final LeafElement element = ((PsiFileImpl)getPsi(getBaseLanguage())).calcTreeElement().findLeafElementAt(offset); diff --git a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java index 7f6ac1799aa7..5449fe938e36 100644 --- a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java +++ b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java @@ -578,4 +578,12 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi return myModificationStamp; } } + + @NotNull + @Override + public PsiFile getStubBindingRoot() { + final PsiFile psi = getPsi(getBaseLanguage()); + assert psi != null; + return psi; + } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index 2e9b1cf43349..aa4feacb33ea 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -257,7 +257,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF } } - protected List> calcStubAstBindings(final ASTNode root, final Document cachedDocument) { + private List> calcStubAstBindings(final ASTNode root, final Document cachedDocument) { final StubTree stubTree = derefStub(); if (stubTree == null) { return Collections.emptyList(); @@ -695,6 +695,12 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF final VirtualFile vFile = getVirtualFile(); if (!(vFile instanceof VirtualFileWithId)) return null; + final PsiFile stubBindingRoot = getViewProvider().getStubBindingRoot(); + if (stubBindingRoot != this) { + LOG.error("Attempted to create stubs for non-root file: " + this + ", stub binding root: " + stubBindingRoot); + return null; + } + ObjectStubTree tree = StubTreeLoader.getInstance().readOrBuild(getProject(), vFile, this); if (!(tree instanceof StubTree)) return null; StubTree stubHolder = (StubTree)tree; diff --git a/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java b/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java index c5ff361a3c3d..2483749439bb 100644 --- a/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java +++ b/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java @@ -56,6 +56,7 @@ public class StubTreeBuilder { final IFileElementType type = LanguageParserDefinitions.INSTANCE.forLanguage(l).getFileNodeType(); PsiFile psi = inputData.getPsiFile(); + psi = psi.getViewProvider().getStubBindingRoot(); CharSequence contentAsText = inputData.getContentAsText(); psi.putUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY, contentAsText); diff --git a/platform/indexing-impl/src/com/intellij/psi/stubs/StubProcessingHelperBase.java b/platform/indexing-impl/src/com/intellij/psi/stubs/StubProcessingHelperBase.java index 70631c4e3f5f..2e92e551ea2e 100644 --- a/platform/indexing-impl/src/com/intellij/psi/stubs/StubProcessingHelperBase.java +++ b/platform/indexing-impl/src/com/intellij/psi/stubs/StubProcessingHelperBase.java @@ -34,10 +34,11 @@ public abstract class StubProcessingHelperBase { public boolean processStubsInFile(final Project project, final VirtualFile file, StubIdList value, final Processor processor) { StubTree stubTree = null; - final PsiFile _psifile = PsiManager.getInstance(project).findFile(file); + PsiFile _psifile = PsiManager.getInstance(project).findFile(file); PsiFileWithStubSupport psiFile = null; if (_psifile != null && !(_psifile instanceof PsiPlainTextFile)) { + _psifile = _psifile.getViewProvider().getStubBindingRoot(); if (_psifile instanceof PsiFileWithStubSupport) { psiFile = (PsiFileWithStubSupport)_psifile; stubTree = psiFile.getStubTree();