blob: 56e3cdc956f28e70a0e965f9e15f89bba25dd235 [file] [log] [blame]
/*
* 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 org.intellij.plugins.intelliLang.inject.java;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.ElementPattern;
import com.intellij.psi.*;
import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.PatternValuesIndex;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.intellij.plugins.intelliLang.Configuration;
import org.intellij.plugins.intelliLang.inject.config.BaseInjection;
import org.intellij.plugins.intelliLang.inject.config.InjectionPlace;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
/**
* Created by Max Medvedev on 22/03/14
*/
public class InjectionCache {
private final CachedValue<Collection<String>> myAnnoIndex;
private final CachedValue<Collection<String>> myXmlIndex;
public InjectionCache(final Project project, final Configuration configuration) {
myXmlIndex = CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider<Collection<String>>() {
public Result<Collection<String>> compute() {
final Map<ElementPattern<?>, BaseInjection> map = new THashMap<ElementPattern<?>, BaseInjection>();
for (BaseInjection injection : configuration.getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID)) {
for (InjectionPlace place : injection.getInjectionPlaces()) {
if (!place.isEnabled() || place.getElementPattern() == null) continue;
map.put(place.getElementPattern(), injection);
}
}
final Set<String> stringSet = PatternValuesIndex.buildStringIndex(map.keySet());
return new Result<Collection<String>>(stringSet, configuration);
}
}, false);
myAnnoIndex = CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider<Collection<String>>() {
public Result<Collection<String>> compute() {
final String annotationClass = configuration.getAdvancedConfiguration().getLanguageAnnotationClass();
final Collection<String> result = new THashSet<String>();
final ArrayList<String> annoClasses = new ArrayList<String>(3);
annoClasses.add(StringUtil.getShortName(annotationClass));
for (int cursor = 0; cursor < annoClasses.size(); cursor++) {
final String annoClass = annoClasses.get(cursor);
for (PsiAnnotation annotation : JavaAnnotationIndex.getInstance().get(annoClass, project, GlobalSearchScope.allScope(project))) {
final PsiElement modList = annotation.getParent();
if (!(modList instanceof PsiModifierList)) continue;
final PsiElement element = modList.getParent();
if (element instanceof PsiParameter) {
final PsiElement scope = ((PsiParameter)element).getDeclarationScope();
if (scope instanceof PsiNamedElement) {
ContainerUtil.addIfNotNull(((PsiNamedElement)scope).getName(), result);
}
else {
ContainerUtil.addIfNotNull(((PsiNamedElement)element).getName(), result);
}
}
else if (element instanceof PsiNamedElement) {
if (element instanceof PsiClass && ((PsiClass)element).isAnnotationType()) {
final String s = ((PsiClass)element).getName();
if (!annoClasses.contains(s)) annoClasses.add(s);
}
else {
ContainerUtil.addIfNotNull(((PsiNamedElement)element).getName(), result);
}
}
}
}
return new Result<Collection<String>>(result, PsiModificationTracker.MODIFICATION_COUNT, configuration);
}
}, false);
}
public static InjectionCache getInstance(Project project) {
return ServiceManager.getService(project, InjectionCache.class);
}
public Collection<String> getAnnoIndex() {
return myAnnoIndex.getValue();
}
public Collection<String> getXmlIndex() {
return myXmlIndex.getValue();
}
}