diff --git a/platform/core-api/src/com/intellij/psi/stubs/SerializerNotFoundException.java b/platform/core-api/src/com/intellij/psi/stubs/SerializerNotFoundException.java new file mode 100644 index 000000000000..245855b98d38 --- /dev/null +++ b/platform/core-api/src/com/intellij/psi/stubs/SerializerNotFoundException.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2012 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.stubs; + +/** + * @author Dmitry Avdeev + * Date: 8/31/12 + */ +public class SerializerNotFoundException extends Exception { + + public SerializerNotFoundException(String message) { + super(message); + } +} diff --git a/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java b/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java index 0b17fdea397a..2e1d882b5c6f 100644 --- a/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java +++ b/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java @@ -155,7 +155,7 @@ public class StubSerializationHelper { private final RecentStringInterner myStringInterner = new RecentStringInterner(8192); - public Stub deserialize(InputStream stream) throws IOException { + public Stub deserialize(InputStream stream) throws IOException, SerializerNotFoundException { FileLocalStringEnumerator storage = new FileLocalStringEnumerator(); StubInputStream inputStream = new StubInputStream(stream, storage); final int size = DataInputOutputUtil.readINT(inputStream); @@ -171,11 +171,11 @@ public class StubSerializationHelper { return deserialize(inputStream, null); } - private Stub deserialize(StubInputStream stream, Stub parentStub) throws IOException { + private Stub deserialize(StubInputStream stream, @Nullable Stub parentStub) throws IOException, SerializerNotFoundException { final int id = DataInputOutputUtil.readINT(stream); final ObjectStubSerializer serializer = getClassById(id); if (serializer == null) { - LOG.error("No serializer registered for stub: ID=" + id + "; parent stub class=" + (parentStub != null? parentStub.getClass().getName() : "null")); + throw new SerializerNotFoundException("No serializer registered for stub: ID=" + id + "; parent stub class=" + (parentStub != null? parentStub.getClass().getName() : "null")); } Stub stub = serializer.deserialize(stream, parentStub); diff --git a/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerEx.java b/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerEx.java index eca9a71fe73f..2db4c17f4bd2 100644 --- a/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerEx.java +++ b/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerEx.java @@ -29,7 +29,7 @@ public abstract class SerializationManagerEx extends SerializationManager { public abstract void serialize(Stub rootStub, OutputStream stream); - public abstract Stub deserialize(InputStream stream); + public abstract Stub deserialize(InputStream stream) throws SerializerNotFoundException; public abstract boolean isNameStorageCorrupted(); diff --git a/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerImpl.java b/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerImpl.java index 7bcc2a9383cf..7778a0d5b561 100644 --- a/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerImpl.java +++ b/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerImpl.java @@ -158,7 +158,7 @@ public class SerializationManagerImpl extends SerializationManagerEx implements } @Override - public Stub deserialize(InputStream stream) { + public Stub deserialize(InputStream stream) throws SerializerNotFoundException { initSerializers(); try { diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/SerializedStubTree.java b/platform/lang-impl/src/com/intellij/psi/stubs/SerializedStubTree.java index e389a452780a..f161d453a44e 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/SerializedStubTree.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/SerializedStubTree.java @@ -48,7 +48,7 @@ public class SerializedStubTree { } // willIndexStub is one time optimization hint, once can safely pass false - public Stub getStub(boolean willIndexStub) { + public Stub getStub(boolean willIndexStub) throws SerializerNotFoundException { Stub stubElement = myStubElement; if (stubElement != null) { // not null myStubElement means we just built SerializedStubTree for indexing, diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java index dfc98bc1c1c2..f0a4bdd93bd3 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java @@ -88,32 +88,46 @@ public class StubTreeLoaderImpl extends StubTreeLoader { } final int id = Math.abs(FileBasedIndex.getFileId(vFile)); - if (id > 0) { - final List datas = FileBasedIndex.getInstance().getValues(StubUpdatingIndex.INDEX_ID, id, GlobalSearchScope - .fileScope(project, vFile)); - final int size = datas.size(); - - if (size == 1) { - Stub stub = datas.get(0).getStub(false); - return stub instanceof PsiFileStub ? new StubTree((PsiFileStub)stub) : new ObjectStubTree((ObjectStubBase)stub, true); - } - else if (size != 0) { - LOG.error("Twin stubs: " + vFile.getPresentableUrl() + " has " + size + " stub versions. Should only have one. id=" + id); - - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - final Document doc = FileDocumentManager.getInstance().getCachedDocument(vFile); - if (doc != null) { - FileDocumentManager.getInstance().saveDocument(doc); - } - } - }, ModalityState.NON_MODAL); - - FileBasedIndex.getInstance().requestReindex(vFile); - } + if (id <= 0) { + return null; } + final List datas = FileBasedIndex.getInstance().getValues(StubUpdatingIndex.INDEX_ID, id, GlobalSearchScope + .fileScope(project, vFile)); + final int size = datas.size(); + + if (size == 1) { + Stub stub; + try { + stub = datas.get(0).getStub(false); + } + catch (SerializerNotFoundException e) { + return processError(vFile, "No stub serializer: " + vFile.getPresentableUrl() + ": " + e.getMessage(), e); + } + return stub instanceof PsiFileStub ? new StubTree((PsiFileStub)stub) : new ObjectStubTree((ObjectStubBase)stub, true); + } + else if (size != 0) { + return processError(vFile, "Twin stubs: " + vFile.getPresentableUrl() + " has " + size + " stub versions. Should only have one. id=" + id, + null); + } + + return null; + } + + private static ObjectStubTree processError(final VirtualFile vFile, String message, @Nullable Exception e) { + LOG.error(message, e); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + final Document doc = FileDocumentManager.getInstance().getCachedDocument(vFile); + if (doc != null) { + FileDocumentManager.getInstance().saveDocument(doc); + } + } + }, ModalityState.NON_MODAL); + + FileBasedIndex.getInstance().requestReindex(vFile); return null; } diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java index 889d7f58bec1..4bd26d2c4899 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java @@ -254,7 +254,13 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi throws StorageException { checkNameStorage(); - final Map> newStubTree = getStubTree(newData); + final Map> newStubTree; + try { + newStubTree = getStubTree(newData); + } + catch (SerializerNotFoundException e) { + throw new StorageException(e); + } final StubIndexImpl stubIndex = getStubIndex(); final Collection allStubIndices = stubIndex.getAllStubIndexKeys(); @@ -268,7 +274,13 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi getWriteLock().lock(); final Map oldData = readOldData(inputId); - final Map> oldStubTree = getStubTree(oldData); + final Map> oldStubTree; + try { + oldStubTree = getStubTree(oldData); + } + catch (SerializerNotFoundException e) { + throw new StorageException(e); + } super.updateWithMap(inputId, newData, oldKeysGetter); @@ -302,7 +314,8 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi } } - private static Map> getStubTree(@NotNull final Map data) { + private static Map> getStubTree(@NotNull final Map data) + throws SerializerNotFoundException { final Map> stubTree; if (!data.isEmpty()) { final SerializedStubTree stub = data.values().iterator().next();