mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
subType pointcut working on types
This commit is contained in:
@@ -1,10 +1,7 @@
|
||||
package org.jetbrains.plugins.groovy.dsl;
|
||||
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -36,13 +33,42 @@ public abstract class DslPointcut<T,V> {
|
||||
|
||||
abstract boolean operatesOn(Class c);
|
||||
|
||||
public static DslPointcut<GdslType, GdslType> subType(final Object arg) {
|
||||
return new DslPointcut<GdslType, GdslType>() {
|
||||
|
||||
@Override
|
||||
List<GdslType> matches(GdslType src, ProcessingContext context) {
|
||||
final PsiFile placeFile = context.get(GroovyDslScript.INITIAL_CONTEXT).getPlaceFile();
|
||||
if (ClassContextFilter.isSubtype(src.psiType, placeFile, (String)arg)) {
|
||||
return Arrays.asList(src);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean operatesOn(Class c) {
|
||||
return GdslType.class == c;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public static DslPointcut<GroovyClassDescriptor, GdslType> currentType(final Object arg) {
|
||||
final DslPointcut<GdslType,?> inner;
|
||||
if (arg instanceof String) {
|
||||
inner = subType(arg);
|
||||
} else {
|
||||
inner = (DslPointcut<GdslType, ?>)arg;
|
||||
assert inner.operatesOn(GdslType.class) : "The argument to currentType should be a pointcut working with types, e.g. subType";
|
||||
}
|
||||
|
||||
return new DslPointcut<GroovyClassDescriptor, GdslType>() {
|
||||
|
||||
@Override
|
||||
List<GdslType> matches(GroovyClassDescriptor src, ProcessingContext context) {
|
||||
if (ClassContextFilter.subtypeOf((String)arg).isApplicable(src, context)) {
|
||||
return Arrays.asList(new GdslType(ClassContextFilter.findPsiType(src, context)));
|
||||
final GdslType currentType = new GdslType(ClassContextFilter.findPsiType(src, context));
|
||||
if (inner.matches(currentType, context) != null) {
|
||||
return Arrays.asList(currentType);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@ import com.intellij.psi.PsiWildcardType;
|
||||
* @author peter
|
||||
*/
|
||||
public class GdslType {
|
||||
private final PsiType myPsiType;
|
||||
public final PsiType psiType;
|
||||
|
||||
public GdslType(PsiType psiType) {
|
||||
myPsiType = psiType;
|
||||
this.psiType = psiType;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
PsiType type = myPsiType;
|
||||
PsiType type = psiType;
|
||||
if (type instanceof PsiWildcardType) {
|
||||
type = ((PsiWildcardType)type).getBound();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -29,6 +30,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
* @author peter
|
||||
*/
|
||||
public class GroovyDslScript {
|
||||
public static final Key<GroovyClassDescriptor> INITIAL_CONTEXT = Key.create("gdsl.initialContext");
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.dsl.GroovyDslScript");
|
||||
private final Project project;
|
||||
@Nullable private final VirtualFile file;
|
||||
@@ -76,6 +78,7 @@ public class GroovyDslScript {
|
||||
private CustomMembersHolder addGdslMembers(GroovyClassDescriptor descriptor, String qname, final PsiType psiType) {
|
||||
final ProcessingContext ctx = new ProcessingContext();
|
||||
ctx.put(ClassContextFilter.getClassKey(qname), psiType);
|
||||
ctx.put(INITIAL_CONTEXT, descriptor);
|
||||
try {
|
||||
if (!isApplicable(executor, descriptor, ctx)) {
|
||||
return CustomMembersHolder.EMPTY;
|
||||
|
||||
+8
-6
@@ -63,18 +63,20 @@ public class ClassContextFilter implements ContextFilter {
|
||||
return new ClassContextFilter(new Condition<Pair<PsiType, PsiFile>>() {
|
||||
@Override
|
||||
public boolean value(Pair<PsiType, PsiFile> p) {
|
||||
PsiFile place = p.second;
|
||||
//PsiType myType = JavaPsiFacade.getElementFactory(place.getProject()).createTypeFromText(typeText, place);
|
||||
PsiType myType = getCachedType(typeText, place);
|
||||
if (p.first == PsiType.NULL) return myType == PsiType.NULL;
|
||||
return TypesUtil.isAssignable(myType, p.first, place.getManager(), place.getResolveScope(), false);
|
||||
return isSubtype(p.first, p.second, typeText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean isSubtype(PsiType checked, PsiFile placeFile, String typeText) {
|
||||
PsiType myType = getCachedType(typeText, placeFile);
|
||||
if (checked == PsiType.NULL) return myType == PsiType.NULL;
|
||||
return TypesUtil.isAssignable(myType, checked, placeFile.getManager(), placeFile.getResolveScope(), false);
|
||||
}
|
||||
|
||||
private static final Key<Map<String, PsiType>> CACHED_TYPES = Key.create("Cached types");
|
||||
|
||||
private static PsiType getCachedType(String typeText, PsiFile context) {
|
||||
public static PsiType getCachedType(String typeText, PsiFile context) {
|
||||
Map<String, PsiType> map = context.getUserData(CACHED_TYPES);
|
||||
if (map == null) {
|
||||
map = new ConcurrentHashMap<String, PsiType>();
|
||||
|
||||
@@ -22,6 +22,11 @@ class DsldTest extends LightGroovyTestCase {
|
||||
'println "".foo + [].<warning>foo</warning>'
|
||||
}
|
||||
|
||||
public void testSubType() {
|
||||
checkHighlighting 'contribute(currentType(subType("java.lang.String"))) { property name:"foo" }',
|
||||
'println "".foo + [].<warning>foo</warning>'
|
||||
}
|
||||
|
||||
public void testBind() {
|
||||
checkHighlighting 'contribute(bind(types:currentType("java.lang.CharSequence"))) { property name:types[0].name[-3..-1] }',
|
||||
'println "".ing + "".<warning>foo</warning>'
|
||||
@@ -53,6 +58,7 @@ class Foo {
|
||||
'''
|
||||
}
|
||||
|
||||
|
||||
private def checkHighlighting(String dsl, String code) {
|
||||
def file = myFixture.addFileToProject('a.gdsl', dsl)
|
||||
GroovyDslFileIndex.activateUntilModification(file.virtualFile)
|
||||
|
||||
Reference in New Issue
Block a user