Improve class loading in GroovyMethodInfo.

This commit is contained in:
Sergey Evdokimov
2011-10-21 14:52:30 +04:00
parent aa9b3b1b65
commit cf9bf0e52c
3 changed files with 14 additions and 35 deletions
@@ -1,21 +1,19 @@
package org.jetbrains.plugins.groovy.extensions; package org.jetbrains.plugins.groovy.extensions;
import com.intellij.openapi.extensions.AbstractExtensionPointBean;
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiMethod;
import com.intellij.util.xmlb.annotations.AbstractCollection; import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Attribute; import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Property; import com.intellij.util.xmlb.annotations.Property;
import com.intellij.util.xmlb.annotations.Tag; import com.intellij.util.xmlb.annotations.Tag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
import java.util.*; import java.util.*;
/** /**
* @author Sergey Evdokimov * @author Sergey Evdokimov
*/ */
public class GroovyMethodDescriptor { public class GroovyMethodDescriptor extends AbstractExtensionPointBean {
private static final String ATTR_NAMES_DELIMITER = " \t\n\r,;"; private static final String ATTR_NAMES_DELIMITER = " \t\n\r,;";
@@ -21,7 +21,8 @@ public class GroovyMethodInfo {
private static Map<String, Map<String, List<GroovyMethodInfo>>> LIGHT_METHOD_INFOS; private static Map<String, Map<String, List<GroovyMethodInfo>>> LIGHT_METHOD_INFOS;
private final List<String> myParams; private final List<String> myParams;
private final ClassLoader myClassLoader;
private final String myReturnType; private final String myReturnType;
private final String myReturnTypeCalculatorClassName; private final String myReturnTypeCalculatorClassName;
private PairFunction<GrMethodCall, PsiMethod, PsiType> myReturnTypeCalculatorInstance; private PairFunction<GrMethodCall, PsiMethod, PsiType> myReturnTypeCalculatorInstance;
@@ -121,6 +122,7 @@ public class GroovyMethodInfo {
} }
public GroovyMethodInfo(GroovyMethodDescriptor method) { public GroovyMethodInfo(GroovyMethodDescriptor method) {
myClassLoader = method.getLoaderForClass();
myParams = method.getParams(); myParams = method.getParams();
myReturnType = method.returnType; myReturnType = method.returnType;
myReturnTypeCalculatorClassName = method.returnTypeCalculator; myReturnTypeCalculatorClassName = method.returnTypeCalculator;
@@ -177,7 +179,7 @@ public class GroovyMethodInfo {
@NotNull @NotNull
public PairFunction<GrMethodCall, PsiMethod, PsiType> getReturnTypeCalculator() { public PairFunction<GrMethodCall, PsiMethod, PsiType> getReturnTypeCalculator() {
if (myReturnTypeCalculatorInstance == null) { if (myReturnTypeCalculatorInstance == null) {
myReturnTypeCalculatorInstance = ClassInstanceCache.getInstance(myReturnTypeCalculatorClassName); myReturnTypeCalculatorInstance = ClassInstanceCache.getInstance(myReturnTypeCalculatorClassName, myClassLoader);
} }
return myReturnTypeCalculatorInstance; return myReturnTypeCalculatorInstance;
} }
@@ -193,7 +195,7 @@ public class GroovyMethodInfo {
public GroovyNamedArgumentProvider getNamedArgProvider() { public GroovyNamedArgumentProvider getNamedArgProvider() {
if (myNamedArgProviderInstance == null) { if (myNamedArgProviderInstance == null) {
myNamedArgProviderInstance = ClassInstanceCache.getInstance(myNamedArgProviderClassName); myNamedArgProviderInstance = ClassInstanceCache.getInstance(myNamedArgProviderClassName, myClassLoader);
} }
return myNamedArgProviderInstance; return myNamedArgProviderInstance;
} }
@@ -1,7 +1,5 @@
package org.jetbrains.plugins.groovy.util; package org.jetbrains.plugins.groovy.util;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.util.containers.ConcurrentHashMap; import com.intellij.util.containers.ConcurrentHashMap;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -15,34 +13,16 @@ public class ClassInstanceCache {
private ClassInstanceCache() { private ClassInstanceCache() {
} }
private static Object createInstance(@NotNull String className) {
try {
try {
return Class.forName(className).newInstance();
}
catch (ClassNotFoundException e) {
for (IdeaPluginDescriptor descriptor : PluginManager.getPlugins()) {
try {
return descriptor.getPluginClassLoader().loadClass(className).newInstance();
}
catch (ClassNotFoundException ignored) {
}
}
throw new RuntimeException("Class not found: " + className);
}
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T getInstance(@NotNull String className) { public static <T> T getInstance(@NotNull String className, ClassLoader classLoader) {
Object res = CACHE.get(className); Object res = CACHE.get(className);
if (res == null) { if (res == null) {
res = createInstance(className); try {
res = classLoader.loadClass(className).newInstance();
}
catch (Exception e) {
throw new RuntimeException(e);
}
Object oldValue = CACHE.putIfAbsent(className, res); Object oldValue = CACHE.putIfAbsent(className, res);
if (oldValue != null) { if (oldValue != null) {
@@ -52,5 +32,4 @@ public class ClassInstanceCache {
return (T)res; return (T)res;
} }
} }