more performance tweaks in GroovyDSL support

This commit is contained in:
Ilya Sergey
2009-10-22 16:43:19 +04:00
parent 0a3a27be3a
commit 75132b30d3
2 changed files with 26 additions and 8 deletions
@@ -1,9 +1,11 @@
package org.jetbrains.plugins.groovy.dsl.toplevel
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.util.Pair
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.util.containers.HashSet
import org.jetbrains.plugins.groovy.GroovyFileType
import org.jetbrains.plugins.groovy.dsl.toplevel.scopes.ClassScope
import org.jetbrains.plugins.groovy.dsl.toplevel.scopes.ClosureScope
@@ -16,7 +18,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrRefere
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition
import com.intellij.psi.*
import com.intellij.util.containers.HashSet
/**
* @author ilyas
@@ -26,6 +27,7 @@ class Context {
private List<Closure> myFilters = []
private final Set<Pair<String, String>> ASSIGNABLE_TYPES = new HashSet<Pair<String, String>>();
private final Set<Pair<String, String>> NON_ASSIGNABLE_TYPES = new HashSet<Pair<String, String>>();
public Context(Map args) {
// Basic filter, all contexts are applicable for reference expressions only
@@ -39,18 +41,29 @@ class Context {
if (!(ctype instanceof String)) return false
final def pair = new Pair(((String) ctype), fqn)
if (NON_ASSIGNABLE_TYPES.contains(pair)) return false
if (ASSIGNABLE_TYPES.contains(pair)) return true
if (ctype.equals(fqn)) {
ASSIGNABLE_TYPES.add(pair)
return true
}
PsiManager manager = PsiManager.getInstance(ref.getProject())
def scope = GlobalSearchScope.allScope(ref.getProject())
PsiType superType = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().
createTypeByFQClassName(((String)ctype), scope)
createTypeByFQClassName(((String) ctype), scope)
if (!superType) return false
def type = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(fqn, scope)
def result = type && superType?.isAssignableFrom(type) && type.isAssignableFrom(superType)
if (result) {
if (!type) return false
if (!type.isAssignableFrom(superType) || !superType?.isAssignableFrom(type)) {
NON_ASSIGNABLE_TYPES.add(pair)
return false
} else {
ASSIGNABLE_TYPES.add(pair)
return true
}
return result
}
}
@@ -167,7 +180,12 @@ class Context {
*/
boolean isApplicable(PsiElement place, String fqn) {
for (f in myFilters) {
if (!f(place, fqn)) return false
try {
if (!f(place, fqn)) return false
}
catch (ProcessCanceledException e) {
return false
}
}
return true
}
@@ -21,7 +21,7 @@ class Contributor {
}
def getApplyFunction(delegate, PsiElement place, String fqn) {
def f = whatToDo.clone()
Closure f = whatToDo.clone()
f.delegate = delegate
f.resolveStrategy = Closure.DELEGATE_FIRST
@@ -38,7 +38,7 @@ class Contributor {
try {
if (ctx && ctx.isApplicable(place, fqn)) {
use(cats) {
f()
f.call()
}
}
}