mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
InjectionCache: don't load AST, search in non-Java files as well
This commit is contained in:
+1
-1
@@ -64,7 +64,7 @@ public class AnnotatedElementsSearcher implements QueryExecutor<PsiModifierListO
|
||||
final PsiModifierListOwner candidate = ApplicationManager.getApplication().runReadAction(new Computable<PsiModifierListOwner>() {
|
||||
@Override
|
||||
public PsiModifierListOwner compute() {
|
||||
PsiElement parent = ann.getParent();
|
||||
PsiElement parent = ann.getContext();
|
||||
if (!(parent instanceof PsiModifierList)) {
|
||||
return null; // Can be a PsiNameValuePair, if annotation is used to annotate annotation parameters
|
||||
}
|
||||
|
||||
@@ -18,11 +18,13 @@ package com.intellij.psi
|
||||
import com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer
|
||||
import com.intellij.psi.impl.source.PsiClassImpl
|
||||
import com.intellij.psi.impl.source.PsiFileImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.searches.AnnotatedElementsSearch
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
|
||||
class JavaStubsTest extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
public void "test resolve from annotation method default"() {
|
||||
void "test resolve from annotation method default"() {
|
||||
def cls = myFixture.addClass("""
|
||||
public @interface BrokenAnnotation {
|
||||
enum Foo {DEFAULT, OTHER}
|
||||
@@ -41,7 +43,7 @@ class JavaStubsTest extends LightCodeInsightFixtureTestCase {
|
||||
assert file.stub
|
||||
}
|
||||
|
||||
public void "test literal annotation value"() {
|
||||
void "test literal annotation value"() {
|
||||
def cls = myFixture.addClass("""
|
||||
class Foo {
|
||||
@org.jetbrains.annotations.Contract(pure=true)
|
||||
@@ -55,7 +57,23 @@ class JavaStubsTest extends LightCodeInsightFixtureTestCase {
|
||||
assert !file.contentsLoaded
|
||||
}
|
||||
|
||||
public void "test applying type annotations"() {
|
||||
void "test local variable annotation doesn't cause stub-ast switch"() {
|
||||
def cls = myFixture.addClass("""
|
||||
class Foo {
|
||||
@Anno int foo() {
|
||||
@Anno int var = 2;
|
||||
}
|
||||
}
|
||||
@interface Anno {}
|
||||
""")
|
||||
|
||||
def file = cls.containingFile as PsiFileImpl
|
||||
assert AnnotatedElementsSearch.searchPsiMethods(myFixture.findClass("Anno"), GlobalSearchScope.allScope(project)).size() == 1
|
||||
assert file.stub
|
||||
assert !file.contentsLoaded
|
||||
}
|
||||
|
||||
void "test applying type annotations"() {
|
||||
def cls = myFixture.addClass("""
|
||||
import java.lang.annotation.*;
|
||||
class Foo {
|
||||
|
||||
+5
-9
@@ -31,7 +31,6 @@ import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import gnu.trove.THashSet;
|
||||
import org.intellij.plugins.intelliLang.Configuration;
|
||||
import org.intellij.plugins.intelliLang.inject.InjectedLanguage;
|
||||
@@ -97,6 +96,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector {
|
||||
|
||||
@Override
|
||||
protected boolean areThereInjectionsWithName(String methodName, boolean annoOnly) {
|
||||
if (methodName == null) return false;
|
||||
if (getAnnotatedElementsValue().contains(methodName)) {
|
||||
return true;
|
||||
}
|
||||
@@ -206,7 +206,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector {
|
||||
if (anchor != null && !processCommentInjection(anchor)) {
|
||||
myShouldStop = true;
|
||||
}
|
||||
else if (areThereInjectionsWithName(variable.getName(), false)) {
|
||||
else {
|
||||
process(variable, null, -1);
|
||||
}
|
||||
return false;
|
||||
@@ -287,16 +287,12 @@ public class ConcatenationInjector implements ConcatenationAwareInjector {
|
||||
}
|
||||
|
||||
private boolean processAnnotationInjections(final PsiModifierListOwner annoElement) {
|
||||
final String checkName;
|
||||
if (annoElement instanceof PsiParameter) {
|
||||
final PsiElement scope = ((PsiParameter)annoElement).getDeclarationScope();
|
||||
checkName = scope instanceof PsiMethod ? ((PsiNamedElement)scope).getName() : ((PsiNamedElement)annoElement).getName();
|
||||
if (scope instanceof PsiMethod && !areThereInjectionsWithName(((PsiNamedElement)scope).getName(), true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (annoElement instanceof PsiNamedElement) {
|
||||
checkName = ((PsiNamedElement)annoElement).getName();
|
||||
}
|
||||
else checkName = null;
|
||||
if (checkName == null || !areThereInjectionsWithName(checkName, true)) return true;
|
||||
final PsiAnnotation[] annotations =
|
||||
AnnotationUtilEx.getAnnotationFrom(annoElement, myConfiguration.getAdvancedConfiguration().getLanguageAnnotationPair(), true);
|
||||
if (annotations.length > 0) {
|
||||
|
||||
+34
-39
@@ -17,11 +17,10 @@ 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.search.searches.AnnotatedElementsSearch;
|
||||
import com.intellij.psi.util.CachedValue;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
@@ -33,21 +32,20 @@ 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 org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by Max Medvedev on 22/03/14
|
||||
*/
|
||||
public class InjectionCache {
|
||||
private final CachedValue<Collection<String>> myAnnoIndex;
|
||||
private final CachedValue<Set<String>> myAnnoIndex;
|
||||
private final CachedValue<Collection<String>> myXmlIndex;
|
||||
private final Project myProject;
|
||||
|
||||
public InjectionCache(final Project project, final Configuration configuration) {
|
||||
|
||||
myProject = project;
|
||||
myXmlIndex = CachedValuesManager.getManager(project).createCachedValue(() -> {
|
||||
final Map<ElementPattern<?>, BaseInjection> map = new THashMap<>();
|
||||
for (BaseInjection injection : configuration.getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID)) {
|
||||
@@ -61,45 +59,42 @@ public class InjectionCache {
|
||||
}, false);
|
||||
|
||||
myAnnoIndex = CachedValuesManager.getManager(project).createCachedValue(() -> {
|
||||
final String annotationClass = configuration.getAdvancedConfiguration().getLanguageAnnotationClass();
|
||||
final Collection<String> result = new THashSet<>();
|
||||
final ArrayList<String> annoClasses = new ArrayList<>(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(result, ((PsiNamedElement)scope).getName());
|
||||
}
|
||||
else {
|
||||
ContainerUtil.addIfNotNull(result, ((PsiNamedElement)element).getName());
|
||||
}
|
||||
}
|
||||
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(result, ((PsiNamedElement)element).getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Set<String> result = collectMethodNamesWithLanguage(
|
||||
configuration.getAdvancedConfiguration().getLanguageAnnotationClass());
|
||||
return new CachedValueProvider.Result<>(result, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, configuration);
|
||||
}, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Set<String> collectMethodNamesWithLanguage(String annotationClassName) {
|
||||
GlobalSearchScope allScope = GlobalSearchScope.allScope(myProject);
|
||||
Set<String> result = new THashSet<>();
|
||||
ArrayList<PsiClass> annoClasses = ContainerUtil.newArrayList(JavaPsiFacade.getInstance(myProject).findClasses(annotationClassName, allScope));
|
||||
for (int cursor = 0; cursor < annoClasses.size(); cursor++) {
|
||||
AnnotatedElementsSearch.searchElements(annoClasses.get(cursor), allScope, PsiClass.class, PsiParameter.class, PsiMethod.class).forEach(element -> {
|
||||
if (element instanceof PsiParameter) {
|
||||
final PsiElement scope = ((PsiParameter)element).getDeclarationScope();
|
||||
if (scope instanceof PsiMethod) {
|
||||
ContainerUtil.addIfNotNull(result, ((PsiMethod)scope).getName());
|
||||
}
|
||||
}
|
||||
else if (element instanceof PsiClass && ((PsiClass)element).isAnnotationType() && !annoClasses.contains(element)) {
|
||||
annoClasses.add((PsiClass)element);
|
||||
}
|
||||
else if (element instanceof PsiMethod) {
|
||||
ContainerUtil.addIfNotNull(result, element.getName());
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static InjectionCache getInstance(Project project) {
|
||||
return ServiceManager.getService(project, InjectionCache.class);
|
||||
}
|
||||
|
||||
public Collection<String> getAnnoIndex() {
|
||||
public Set<String> getAnnoIndex() {
|
||||
return myAnnoIndex.getValue();
|
||||
}
|
||||
|
||||
|
||||
+5
-8
@@ -93,6 +93,7 @@ public class GrConcatenationAwareInjector implements ConcatenationAwareInjector
|
||||
|
||||
@Override
|
||||
protected boolean areThereInjectionsWithName(String methodName, boolean annoOnly) {
|
||||
if (methodName == null) return false;
|
||||
if (getAnnotatedElementsValue().contains(methodName)) {
|
||||
return true;
|
||||
}
|
||||
@@ -201,7 +202,7 @@ public class GrConcatenationAwareInjector implements ConcatenationAwareInjector
|
||||
if (!processCommentInjections(variable)) {
|
||||
myShouldStop = true;
|
||||
}
|
||||
else if (areThereInjectionsWithName(variable.getName(), false)) {
|
||||
else {
|
||||
process(variable, null, -1);
|
||||
}
|
||||
return false;
|
||||
@@ -266,16 +267,12 @@ public class GrConcatenationAwareInjector implements ConcatenationAwareInjector
|
||||
}
|
||||
|
||||
private boolean processAnnotationInjections(final PsiModifierListOwner annoElement) {
|
||||
final String checkName;
|
||||
if (annoElement instanceof PsiParameter) {
|
||||
final PsiElement scope = ((PsiParameter)annoElement).getDeclarationScope();
|
||||
checkName = scope instanceof PsiMethod ? ((PsiNamedElement)scope).getName() : ((PsiNamedElement)annoElement).getName();
|
||||
if (scope instanceof PsiMethod && !areThereInjectionsWithName(((PsiNamedElement)scope).getName(), true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (annoElement instanceof PsiNamedElement) {
|
||||
checkName = ((PsiNamedElement)annoElement).getName();
|
||||
}
|
||||
else checkName = null;
|
||||
if (checkName == null || !areThereInjectionsWithName(checkName, true)) return true;
|
||||
final PsiAnnotation[] annotations =
|
||||
GrConcatenationInjector.getAnnotationFrom(annoElement, myConfiguration.getAdvancedConfiguration().getLanguageAnnotationPair(), true, true);
|
||||
if (annotations.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user