/* * Copyright 2000-2013 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. */ /* * @author max */ package com.intellij.psi.stubs; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.ObjectUtils; import com.intellij.util.Processor; import com.intellij.util.indexing.FileBasedIndex; import com.intellij.util.indexing.IdFilter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Iterator; public abstract class StubIndex { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.stubs.StubIndex"); private static class StubIndexHolder { private static final StubIndex ourInstance = ApplicationManager.getApplication().getComponent(StubIndex.class); } public static StubIndex getInstance() { return StubIndexHolder.ourInstance; } /** * @deprecated use {@link #getElements(StubIndexKey, Object, com.intellij.openapi.project.Project, com.intellij.psi.search.GlobalSearchScope, Class)} */ public abstract Collection get(@NotNull StubIndexKey indexKey, @NotNull Key key, @NotNull Project project, @Nullable final GlobalSearchScope scope); /** * @deprecated use {@link #getElements(StubIndexKey, Object, com.intellij.openapi.project.Project, com.intellij.psi.search.GlobalSearchScope, Class)} */ public Collection get(@NotNull StubIndexKey indexKey, @NotNull Key key, @NotNull Project project, @Nullable final GlobalSearchScope scope, IdFilter filter) { return get(indexKey, key, project, scope); } /** * @deprecated use processElements */ public boolean process(@NotNull StubIndexKey indexKey, @NotNull Key key, @NotNull Project project, @Nullable GlobalSearchScope scope, @NotNull Processor processor) { return processElements(indexKey, key, project, scope, (Class)PsiElement.class, processor); } public abstract boolean processElements(@NotNull StubIndexKey indexKey, @NotNull Key key, @NotNull Project project, @Nullable GlobalSearchScope scope, Class requiredClass, @NotNull Processor processor); /** * @deprecated use processElements */ public boolean process(@NotNull StubIndexKey indexKey, @NotNull Key key, @NotNull Project project, @Nullable GlobalSearchScope scope, @SuppressWarnings("UnusedParameters") IdFilter idFilter, @NotNull Processor processor) { return process(indexKey, key, project, scope, processor); } public boolean processElements(@NotNull StubIndexKey indexKey, @NotNull Key key, @NotNull Project project, @Nullable GlobalSearchScope scope, IdFilter idFilter, @NotNull Class requiredClass, @NotNull Processor processor) { return process(indexKey, key, project, scope, processor); } @NotNull public abstract Collection getAllKeys(@NotNull StubIndexKey indexKey, @NotNull Project project); public abstract boolean processAllKeys(@NotNull StubIndexKey indexKey, @NotNull Project project, Processor processor); public boolean processAllKeys(@NotNull StubIndexKey indexKey, @NotNull Processor processor, @NotNull GlobalSearchScope scope, @Nullable IdFilter idFilter) { return processAllKeys(indexKey, ObjectUtils.assertNotNull(scope.getProject()), processor); } /** * @deprecated use {@link #getElements(StubIndexKey, Object, com.intellij.openapi.project.Project, com.intellij.psi.search.GlobalSearchScope, Class)} */ public Collection safeGet(@NotNull StubIndexKey indexKey, @NotNull Key key, @NotNull final Project project, final GlobalSearchScope scope, @NotNull Class requiredClass) { return getElements(indexKey, key, project, scope, requiredClass); } public static Collection getElements(@NotNull StubIndexKey indexKey, @NotNull Key key, @NotNull final Project project, @Nullable final GlobalSearchScope scope, @NotNull Class requiredClass) { return getElements(indexKey, key, project, scope, null, requiredClass); } public static Collection getElements(@NotNull StubIndexKey indexKey, @NotNull Key key, @NotNull final Project project, @Nullable final GlobalSearchScope scope, @Nullable IdFilter idFilter, @NotNull Class requiredClass) { //noinspection deprecation Collection collection = getInstance().get(indexKey, key, project, scope, idFilter); for (Iterator iterator = collection.iterator(); iterator.hasNext(); ) { Psi psi = iterator.next(); if (!requiredClass.isInstance(psi)) { iterator.remove(); VirtualFile faultyContainer = PsiUtilCore.getVirtualFile(psi); if (faultyContainer != null && faultyContainer.isValid()) { FileBasedIndex.getInstance().requestReindex(faultyContainer); } getInstance().reportStubPsiMismatch(psi, faultyContainer, requiredClass); } } return collection; } protected void reportStubPsiMismatch(Psi psi, VirtualFile file, Class requiredClass) { LOG.error("Invalid stub element type in index: " + file + ". found: " + psi + ". expected: " + requiredClass); } }