Merge remote-tracking branch 'origin/master'
@@ -501,7 +501,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
!isOverriddenOrOverrides(method)) &&
|
||||
!method.hasModifierProperty(PsiModifier.NATIVE) &&
|
||||
!HighlightMethodUtil.isSerializationRelatedMethod(method, method.getContainingClass()) &&
|
||||
!PsiClassImplUtil.isMainMethod(method)) {
|
||||
!PsiClassImplUtil.isMainOrPremainMethod(method)) {
|
||||
if (UnusedSymbolLocalInspection.isInjected(method)) return null;
|
||||
HighlightInfo highlightInfo = checkUnusedParameter(parameter, identifier, progress);
|
||||
if (highlightInfo != null) {
|
||||
|
||||
@@ -439,7 +439,7 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
|
||||
public boolean isEntryPoint(@NotNull PsiElement element) {
|
||||
final Project project = element.getProject();
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
|
||||
if (element instanceof PsiMethod && isAddMainsEnabled() && PsiClassImplUtil.isMainMethod((PsiMethod)element)) {
|
||||
if (element instanceof PsiMethod && isAddMainsEnabled() && PsiClassImplUtil.isMainOrPremainMethod((PsiMethod)element)) {
|
||||
return true;
|
||||
}
|
||||
if (element instanceof PsiClass) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||
import com.intellij.openapi.roots.FileIndexFacade;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.OrFilter;
|
||||
import com.intellij.psi.impl.compiled.ClsElementImpl;
|
||||
@@ -40,8 +41,11 @@ import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.ui.IconDeferrer;
|
||||
import com.intellij.ui.RowIcon;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.NullableFunction;
|
||||
import com.intellij.util.SmartList;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -56,52 +60,65 @@ import java.util.*;
|
||||
*/
|
||||
public class PsiClassImplUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiClassImplUtil");
|
||||
private static final Key<ParameterizedCachedValue<MembersMap, PsiClass>> MAP_IN_CLASS_KEY = Key.create("MAP_KEY");
|
||||
|
||||
private static final Key<CachedValue<Map>> MAP_IN_CLASS_KEY = Key.create("MAP_KEY");
|
||||
private PsiClassImplUtil() {
|
||||
}
|
||||
|
||||
private PsiClassImplUtil() { }
|
||||
public static void cacheEverything(PsiClass aClass) {
|
||||
getValues(aClass).getValue(aClass);
|
||||
}
|
||||
|
||||
@NotNull public static PsiField[] getAllFields(final PsiClass aClass) {
|
||||
List<PsiField> map = getAllByMap(aClass, PsiField.class);
|
||||
@NotNull
|
||||
public static PsiField[] getAllFields(@NotNull PsiClass aClass) {
|
||||
List<PsiField> map = getAllByMap(aClass, MemberType.FIELD);
|
||||
return map.toArray(new PsiField[map.size()]);
|
||||
}
|
||||
|
||||
@NotNull public static PsiMethod[] getAllMethods(final PsiClass aClass) {
|
||||
List<PsiMethod> methods = getAllByMap(aClass, PsiMethod.class);
|
||||
@NotNull
|
||||
public static PsiMethod[] getAllMethods(@NotNull PsiClass aClass) {
|
||||
List<PsiMethod> methods = getAllByMap(aClass, MemberType.METHOD);
|
||||
return methods.toArray(new PsiMethod[methods.size()]);
|
||||
}
|
||||
|
||||
@NotNull public static PsiClass[] getAllInnerClasses(PsiClass aClass) {
|
||||
List<PsiClass> classes = getAllByMap(aClass, PsiClass.class);
|
||||
@NotNull
|
||||
public static PsiClass[] getAllInnerClasses(@NotNull PsiClass aClass) {
|
||||
List<PsiClass> classes = getAllByMap(aClass, MemberType.CLASS);
|
||||
return classes.toArray(new PsiClass[classes.size()]);
|
||||
}
|
||||
|
||||
@Nullable public static PsiField findFieldByName(PsiClass aClass, String name, boolean checkBases) {
|
||||
final List<PsiField> byMap = findByMap(aClass, name, checkBases, PsiField.class);
|
||||
return byMap.isEmpty() ? null : byMap.get(0);
|
||||
@Nullable
|
||||
public static PsiField findFieldByName(@NotNull PsiClass aClass, String name, boolean checkBases) {
|
||||
List<PsiMember> byMap = findByMap(aClass, name, checkBases, MemberType.FIELD);
|
||||
return byMap.isEmpty() ? null : (PsiField)byMap.get(0);
|
||||
}
|
||||
|
||||
@NotNull public static PsiMethod[] findMethodsByName(PsiClass aClass, String name, boolean checkBases) {
|
||||
List<PsiMethod> methods = findByMap(aClass, name, checkBases, PsiMethod.class);
|
||||
@NotNull
|
||||
public static PsiMethod[] findMethodsByName(@NotNull PsiClass aClass, String name, boolean checkBases) {
|
||||
List<PsiMember> methods = findByMap(aClass, name, checkBases, MemberType.METHOD);
|
||||
//noinspection SuspiciousToArrayCall
|
||||
return methods.toArray(new PsiMethod[methods.size()]);
|
||||
}
|
||||
|
||||
@Nullable public static PsiMethod findMethodBySignature(final PsiClass aClass, final PsiMethod patternMethod, final boolean checkBases) {
|
||||
@Nullable
|
||||
public static PsiMethod findMethodBySignature(@NotNull PsiClass aClass, @NotNull PsiMethod patternMethod, final boolean checkBases) {
|
||||
final List<PsiMethod> result = findMethodsBySignature(aClass, patternMethod, checkBases, true);
|
||||
return result.isEmpty() ? null : result.get(0);
|
||||
}
|
||||
|
||||
// ----------------------------- findMethodsBySignature -----------------------------------
|
||||
|
||||
@NotNull public static PsiMethod[] findMethodsBySignature(final PsiClass aClass, final PsiMethod patternMethod, final boolean checkBases) {
|
||||
@NotNull
|
||||
public static PsiMethod[] findMethodsBySignature(@NotNull PsiClass aClass, @NotNull PsiMethod patternMethod, final boolean checkBases) {
|
||||
List<PsiMethod> methods = findMethodsBySignature(aClass, patternMethod, checkBases, false);
|
||||
return methods.toArray(new PsiMethod[methods.size()]);
|
||||
}
|
||||
|
||||
@NotNull private static List<PsiMethod> findMethodsBySignature(final PsiClass aClass,
|
||||
final PsiMethod patternMethod,
|
||||
final boolean checkBases,
|
||||
final boolean stopOnFirst) {
|
||||
@NotNull
|
||||
private static List<PsiMethod> findMethodsBySignature(@NotNull PsiClass aClass,
|
||||
@NotNull PsiMethod patternMethod,
|
||||
boolean checkBases,
|
||||
boolean stopOnFirst) {
|
||||
final PsiMethod[] methodsByName = aClass.findMethodsByName(patternMethod.getName(), checkBases);
|
||||
if (methodsByName.length == 0) return Collections.emptyList();
|
||||
final List<PsiMethod> methods = new SmartList<PsiMethod>();
|
||||
@@ -128,57 +145,62 @@ public class PsiClassImplUtil {
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
@Nullable public static PsiClass findInnerByName(PsiClass aClass, String name, boolean checkBases) {
|
||||
final List<PsiClass> byMap = findByMap(aClass, name, checkBases, PsiClass.class);
|
||||
return byMap.isEmpty() ? null : byMap.get(0);
|
||||
@Nullable
|
||||
public static PsiClass findInnerByName(@NotNull PsiClass aClass, String name, boolean checkBases) {
|
||||
List<PsiMember> byMap = findByMap(aClass, name, checkBases, MemberType.CLASS);
|
||||
return byMap.isEmpty() ? null : (PsiClass)byMap.get(0);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@NotNull private static <T extends PsiMember> List<T> findByMap(PsiClass aClass, String name, boolean checkBases, Class<T> type) {
|
||||
@NotNull
|
||||
private static List<PsiMember> findByMap(@NotNull PsiClass aClass, String name, boolean checkBases, @NotNull MemberType type) {
|
||||
if (name == null) return Collections.emptyList();
|
||||
|
||||
if (!checkBases) {
|
||||
T[] members = null;
|
||||
if (ReflectionCache.isAssignable(type,PsiMethod.class)) {
|
||||
members = (T[])aClass.getMethods();
|
||||
}
|
||||
else if (ReflectionCache.isAssignable(type,PsiClass.class)) {
|
||||
members = (T[])aClass.getInnerClasses();
|
||||
}
|
||||
else if (ReflectionCache.isAssignable(type,PsiField.class)) {
|
||||
members = (T[])aClass.getFields();
|
||||
}
|
||||
if (members == null) return Collections.emptyList();
|
||||
|
||||
List<T> list = new ArrayList<T>();
|
||||
for (T member : members) {
|
||||
if (name.equals(member.getName())) list.add(member);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
else {
|
||||
final Map<String, List<Pair<T, PsiSubstitutor>>> allMethodsMap = getMap(aClass, type);
|
||||
final List<Pair<T, PsiSubstitutor>> list = allMethodsMap.get(name);
|
||||
if (checkBases) {
|
||||
Map<String, List<Pair<PsiMember, PsiSubstitutor>>> allMethodsMap = getMap(aClass, type);
|
||||
List<Pair<PsiMember, PsiSubstitutor>> list = allMethodsMap.get(name);
|
||||
if (list == null) return Collections.emptyList();
|
||||
final List<T> ret = new ArrayList<T>();
|
||||
for (final Pair<T, PsiSubstitutor> info : list) {
|
||||
List<PsiMember> ret = new ArrayList<PsiMember>(list.size());
|
||||
for (final Pair<PsiMember, PsiSubstitutor> info : list) {
|
||||
ret.add(info.getFirst());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
PsiMember[] members = null;
|
||||
switch (type) {
|
||||
case METHOD:
|
||||
members = aClass.getMethods();
|
||||
break;
|
||||
case CLASS:
|
||||
members = aClass.getInnerClasses();
|
||||
break;
|
||||
case FIELD:
|
||||
members = aClass.getFields();
|
||||
break;
|
||||
}
|
||||
|
||||
List<PsiMember> list = new ArrayList<PsiMember>();
|
||||
for (PsiMember member : members) {
|
||||
if (name.equals(member.getName())) {
|
||||
list.add(member);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends PsiMember> List<Pair<T, PsiSubstitutor>> getAllWithSubstitutorsByMap(PsiClass aClass, Class<T> type) {
|
||||
final Map<String, List<Pair<T, PsiSubstitutor>>> allMap = getMap(aClass, type);
|
||||
return allMap.get(ALL);
|
||||
@NotNull
|
||||
public static <T extends PsiMember> List<Pair<T, PsiSubstitutor>> getAllWithSubstitutorsByMap(@NotNull PsiClass aClass, @NotNull MemberType type) {
|
||||
Map<String, List<Pair<PsiMember, PsiSubstitutor>>> allMap = getMap(aClass, type);
|
||||
//noinspection unchecked
|
||||
return (List)allMap.get(ALL);
|
||||
}
|
||||
|
||||
@NotNull private static <T extends PsiMember> List<T> getAllByMap(PsiClass aClass, Class<T> type) {
|
||||
@NotNull
|
||||
private static <T extends PsiMember> List<T> getAllByMap(@NotNull PsiClass aClass, @NotNull MemberType type) {
|
||||
List<Pair<T, PsiSubstitutor>> pairs = getAllWithSubstitutorsByMap(aClass, type);
|
||||
|
||||
assert pairs != null : "pairs should be already computed. Wrong allMap: " + getMap(aClass, type);
|
||||
|
||||
final List<T> ret = new ArrayList<T>(pairs.size());
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0; i < pairs.size(); i++) {
|
||||
@@ -192,7 +214,10 @@ public class PsiClassImplUtil {
|
||||
|
||||
@NonNls private static final String ALL = "Intellij-IDEA-ALL";
|
||||
|
||||
private static Map<Class<? extends PsiMember>, Map<String, List<Pair<PsiMember, PsiSubstitutor>>>> buildAllMaps(final PsiClass psiClass) {
|
||||
public enum MemberType {CLASS, FIELD, METHOD}
|
||||
|
||||
@NotNull
|
||||
private static MembersMap buildAllMaps(@NotNull PsiClass psiClass) {
|
||||
final List<Pair<PsiMember, PsiSubstitutor>> classes = new ArrayList<Pair<PsiMember, PsiSubstitutor>>();
|
||||
final List<Pair<PsiMember, PsiSubstitutor>> fields = new ArrayList<Pair<PsiMember, PsiSubstitutor>>();
|
||||
final List<Pair<PsiMember, PsiSubstitutor>> methods = new ArrayList<Pair<PsiMember, PsiSubstitutor>>();
|
||||
@@ -202,31 +227,33 @@ public class PsiClassImplUtil {
|
||||
@Override
|
||||
protected void add(PsiElement element, PsiSubstitutor substitutor) {
|
||||
if (element instanceof PsiMethod) {
|
||||
methods.add(new Pair<PsiMember, PsiSubstitutor>((PsiMethod)element, substitutor));
|
||||
methods.add(Pair.create((PsiMember)element, substitutor));
|
||||
}
|
||||
else if (element instanceof PsiField) {
|
||||
fields.add(new Pair<PsiMember, PsiSubstitutor>((PsiField)element, substitutor));
|
||||
fields.add(Pair.create((PsiMember)element, substitutor));
|
||||
}
|
||||
else if (element instanceof PsiClass) {
|
||||
classes.add(new Pair<PsiMember, PsiSubstitutor>((PsiClass)element, substitutor));
|
||||
classes.add(Pair.create((PsiMember)element, substitutor));
|
||||
}
|
||||
}
|
||||
};
|
||||
processDeclarationsInClassNotCached(psiClass, processor, ResolveState.initial(), new THashSet<PsiClass>(), null, psiClass, false);
|
||||
processDeclarationsInClassNotCached(psiClass, processor, ResolveState.initial(), null, null, psiClass, false,
|
||||
PsiUtil.getLanguageLevel(psiClass));
|
||||
|
||||
Map<Class<? extends PsiMember>, Map<String, List<Pair<PsiMember, PsiSubstitutor>>>> result = new HashMap<Class<? extends PsiMember>, Map<String, List<Pair<PsiMember, PsiSubstitutor>>>>(3);
|
||||
result.put(PsiClass.class, generateMapByList(classes));
|
||||
result.put(PsiMethod.class, generateMapByList(methods));
|
||||
result.put(PsiField.class, generateMapByList(fields));
|
||||
MembersMap result = new MembersMap(MemberType.class);
|
||||
result.put(MemberType.CLASS, generateMapByList(classes));
|
||||
result.put(MemberType.METHOD, generateMapByList(methods));
|
||||
result.put(MemberType.FIELD, generateMapByList(fields));
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<String, List<Pair<PsiMember, PsiSubstitutor>>> generateMapByList(@NotNull final List<Pair<PsiMember, PsiSubstitutor>> list) {
|
||||
Map<String, List<Pair<PsiMember, PsiSubstitutor>>> map = new HashMap<String, List<Pair<PsiMember, PsiSubstitutor>>>();
|
||||
Map<String, List<Pair<PsiMember, PsiSubstitutor>>> map = new THashMap<String, List<Pair<PsiMember, PsiSubstitutor>>>();
|
||||
map.put(ALL, list);
|
||||
for (final Pair<PsiMember, PsiSubstitutor> info : list) {
|
||||
final PsiMember element = info.getFirst();
|
||||
final String currentName = element.getName();
|
||||
PsiMember element = info.getFirst();
|
||||
String currentName = element.getName();
|
||||
List<Pair<PsiMember, PsiSubstitutor>> listByName = map.get(currentName);
|
||||
if (listByName == null) {
|
||||
listByName = new ArrayList<Pair<PsiMember, PsiSubstitutor>>(1);
|
||||
@@ -237,31 +264,30 @@ public class PsiClassImplUtil {
|
||||
return map;
|
||||
}
|
||||
|
||||
private static <T extends PsiMember> Map<String, List<Pair<T, PsiSubstitutor>>> getMap(final PsiClass aClass, Class<T> memberClazz) {
|
||||
CachedValue<Map> value = aClass.getUserData(MAP_IN_CLASS_KEY);
|
||||
private static Map<String, List<Pair<PsiMember, PsiSubstitutor>>> getMap(@NotNull PsiClass aClass, @NotNull MemberType type) {
|
||||
ParameterizedCachedValue<MembersMap, PsiClass> value = getValues(aClass);
|
||||
return value.getValue(aClass).get(type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ParameterizedCachedValue<MembersMap, PsiClass> getValues(@NotNull PsiClass aClass) {
|
||||
ParameterizedCachedValue<MembersMap, PsiClass> value = aClass.getUserData(MAP_IN_CLASS_KEY);
|
||||
if (value == null) {
|
||||
final CachedValueProvider<Map> provider = new ByNameCachedValueProvider(aClass);
|
||||
value = CachedValuesManager.getManager(aClass.getProject()).createCachedValue(provider, false);
|
||||
value = CachedValuesManager.getManager(aClass.getProject()).createParameterizedCachedValue(ByNameCachedValueProvider.INSTANCE, false);
|
||||
//Do not cache for nonphysical elements
|
||||
if (aClass.isPhysical()) {
|
||||
value = ((UserDataHolderEx)aClass).putUserDataIfAbsent(MAP_IN_CLASS_KEY, value);
|
||||
}
|
||||
}
|
||||
return getCachedMembers(value, memberClazz);
|
||||
}
|
||||
|
||||
private static <T extends PsiMember> Map<String, List<Pair<T, PsiSubstitutor>>> getCachedMembers(CachedValue<Map> value,
|
||||
Class<T> memberClazz) {
|
||||
//noinspection unchecked
|
||||
return (Map<String, List<Pair<T, PsiSubstitutor>>>)value.getValue().get(memberClazz);
|
||||
return value;
|
||||
}
|
||||
|
||||
private static class ClassIconRequest {
|
||||
public final PsiClass psiClass;
|
||||
public final int flags;
|
||||
public final Icon symbolIcon;
|
||||
@NotNull private final PsiClass psiClass;
|
||||
private final int flags;
|
||||
private final Icon symbolIcon;
|
||||
|
||||
private ClassIconRequest(PsiClass psiClass, int flags, Icon symbolIcon) {
|
||||
private ClassIconRequest(@NotNull PsiClass psiClass, int flags, Icon symbolIcon) {
|
||||
this.psiClass = psiClass;
|
||||
this.flags = flags;
|
||||
this.symbolIcon = symbolIcon;
|
||||
@@ -274,15 +300,12 @@ public class PsiClassImplUtil {
|
||||
|
||||
ClassIconRequest that = (ClassIconRequest)o;
|
||||
|
||||
if (flags != that.flags) return false;
|
||||
if (psiClass != null ? !psiClass.equals(that.psiClass) : that.psiClass != null) return false;
|
||||
|
||||
return true;
|
||||
return flags == that.flags && psiClass.equals(that.psiClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = psiClass != null ? psiClass.hashCode() : 0;
|
||||
int result = psiClass.hashCode();
|
||||
result = 31 * result + flags;
|
||||
return result;
|
||||
}
|
||||
@@ -302,11 +325,11 @@ public class PsiClassImplUtil {
|
||||
}
|
||||
};
|
||||
|
||||
public static Icon getClassIcon(final int flags, final PsiClass aClass) {
|
||||
public static Icon getClassIcon(final int flags, @NotNull PsiClass aClass) {
|
||||
return getClassIcon(flags, aClass, null);
|
||||
}
|
||||
|
||||
public static Icon getClassIcon(int flags, PsiClass aClass, @Nullable Icon symbolIcon) {
|
||||
public static Icon getClassIcon(int flags, @NotNull PsiClass aClass, @Nullable Icon symbolIcon) {
|
||||
Icon base = Iconable.LastComputedIcon.get(aClass, flags);
|
||||
if (base == null) {
|
||||
if (symbolIcon == null) {
|
||||
@@ -319,17 +342,18 @@ public class PsiClassImplUtil {
|
||||
return IconDeferrer.getInstance().defer(base, new ClassIconRequest(aClass, flags, symbolIcon), FULL_ICON_EVALUATOR);
|
||||
}
|
||||
|
||||
public static SearchScope getClassUseScope(final PsiClass aClass) {
|
||||
final GlobalSearchScope maximalUseScope = ResolveScopeManager.getElementUseScope(aClass);
|
||||
@NotNull
|
||||
public static SearchScope getClassUseScope(@NotNull PsiClass aClass) {
|
||||
if (aClass instanceof PsiAnonymousClass) {
|
||||
return new LocalSearchScope(aClass);
|
||||
}
|
||||
final GlobalSearchScope maximalUseScope = ResolveScopeManager.getElementUseScope(aClass);
|
||||
PsiFile file = aClass.getContainingFile();
|
||||
if (PsiImplUtil.isInServerPage(file)) return maximalUseScope;
|
||||
final PsiClass containingClass = aClass.getContainingClass();
|
||||
if (aClass.hasModifierProperty(PsiModifier.PUBLIC) ||
|
||||
aClass.hasModifierProperty(PsiModifier.PROTECTED)) {
|
||||
return containingClass != null ? containingClass.getUseScope() : maximalUseScope;
|
||||
return containingClass == null ? maximalUseScope : containingClass.getUseScope();
|
||||
}
|
||||
else if (aClass.hasModifierProperty(PsiModifier.PRIVATE) || aClass instanceof PsiTypeParameter) {
|
||||
PsiClass topClass = PsiUtil.getTopLevelClass(aClass);
|
||||
@@ -358,7 +382,7 @@ public class PsiClassImplUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isMainMethod(PsiMethod method) {
|
||||
public static boolean isMainOrPremainMethod(@NotNull PsiMethod method) {
|
||||
if (!PsiType.VOID.equals(method.getReturnType())) return false;
|
||||
String name = method.getName();
|
||||
if (!("main".equals(name) || "premain".equals(name))) return false;
|
||||
@@ -378,75 +402,85 @@ public class PsiClassImplUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static MethodSignature createSignatureFromText(PsiElementFactory factory, String text) {
|
||||
@NotNull
|
||||
private static MethodSignature createSignatureFromText(@NotNull PsiElementFactory factory, @NotNull String text) {
|
||||
return factory.createMethodFromText(text, null).getSignature(PsiSubstitutor.EMPTY);
|
||||
}
|
||||
|
||||
private static class ByNameCachedValueProvider implements CachedValueProvider<Map> {
|
||||
private final PsiClass myClass;
|
||||
|
||||
private ByNameCachedValueProvider(final PsiClass aClass) {
|
||||
myClass = aClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Map> compute() {
|
||||
final Map<Class<? extends PsiMember>, Map<String, List<Pair<PsiMember, PsiSubstitutor>>>> map = buildAllMaps(myClass);
|
||||
return new Result<Map>(map, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
|
||||
private static class MembersMap extends EnumMap<MemberType, Map<String, List<Pair<PsiMember, PsiSubstitutor>>>> {
|
||||
public MembersMap(@NotNull Class<MemberType> keyType) {
|
||||
super(keyType);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean processDeclarationsInClass(PsiClass aClass,
|
||||
PsiScopeProcessor processor,
|
||||
ResolveState state,
|
||||
private static class ByNameCachedValueProvider implements ParameterizedCachedValueProvider<MembersMap, PsiClass> {
|
||||
private static final ByNameCachedValueProvider INSTANCE = new ByNameCachedValueProvider();
|
||||
|
||||
@Override
|
||||
public CachedValueProvider.Result<MembersMap> compute(@NotNull PsiClass myClass) {
|
||||
MembersMap map = buildAllMaps(myClass);
|
||||
return new CachedValueProvider.Result<MembersMap>(map, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean processDeclarationsInClass(@NotNull PsiClass aClass,
|
||||
@NotNull final PsiScopeProcessor processor,
|
||||
@NotNull ResolveState state,
|
||||
@Nullable Set<PsiClass> visited,
|
||||
PsiElement last,
|
||||
PsiElement place,
|
||||
@NotNull PsiElement place,
|
||||
boolean isRaw) {
|
||||
if (last instanceof PsiTypeParameterList || last instanceof PsiModifierList) return true; //TypeParameterList and ModifierList do not see our declarations
|
||||
if (last instanceof PsiTypeParameterList || last instanceof PsiModifierList) {
|
||||
return true; //TypeParameterList and ModifierList do not see our declarations
|
||||
}
|
||||
if (visited != null && visited.contains(aClass)) return true;
|
||||
|
||||
PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
|
||||
isRaw = isRaw || PsiUtil.isRawSubstitutor(aClass, substitutor);
|
||||
|
||||
CachedValue<Map> cache = aClass.getUserData(MAP_IN_CLASS_KEY);
|
||||
if (cache != null && cache.hasUpToDateValue()) {
|
||||
ParameterizedCachedValue<MembersMap, PsiClass> cache = getValues(aClass); //aClass.getUserData(MAP_IN_CLASS_KEY);
|
||||
boolean upToDate = cache.hasUpToDateValue();
|
||||
LanguageLevel languageLevel = PsiUtil.getLanguageLevel(place);
|
||||
if (/*true || */upToDate) {
|
||||
final NameHint nameHint = processor.getHint(NameHint.KEY);
|
||||
if (nameHint != null) {
|
||||
return processCachedMembersByName(aClass, processor, state, visited, last, place, isRaw, substitutor, cache, nameHint);
|
||||
String name = nameHint.getName(state);
|
||||
return processCachedMembersByName(aClass, processor, state, visited, last, place, isRaw, substitutor, cache.getValue(aClass), name,languageLevel);
|
||||
}
|
||||
}
|
||||
return processDeclarationsInClassNotCached(aClass, processor, state, visited, last, place, isRaw);
|
||||
return processDeclarationsInClassNotCached(aClass, processor, state, visited, last, place, isRaw, languageLevel);
|
||||
}
|
||||
|
||||
private static boolean processCachedMembersByName(PsiClass aClass,
|
||||
PsiScopeProcessor processor,
|
||||
ResolveState state,
|
||||
private static boolean processCachedMembersByName(@NotNull PsiClass aClass,
|
||||
@NotNull PsiScopeProcessor processor,
|
||||
@NotNull ResolveState state,
|
||||
@Nullable Set<PsiClass> visited,
|
||||
PsiElement last,
|
||||
PsiElement place,
|
||||
@NotNull PsiElement place,
|
||||
boolean isRaw,
|
||||
PsiSubstitutor substitutor,
|
||||
CachedValue<Map> cache, NameHint nameHint) {
|
||||
@NotNull PsiSubstitutor substitutor,
|
||||
@NotNull MembersMap value,
|
||||
String name,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
final ElementClassHint classHint = processor.getHint(ElementClassHint.KEY);
|
||||
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();
|
||||
|
||||
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.FIELD)) {
|
||||
final PsiField fieldByName = aClass.findFieldByName(nameHint.getName(state), false);
|
||||
final PsiField fieldByName = aClass.findFieldByName(name, false);
|
||||
if (fieldByName != null) {
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
|
||||
if (!processor.execute(fieldByName, state)) return false;
|
||||
}
|
||||
else {
|
||||
final Map<String, List<Pair<PsiField, PsiSubstitutor>>> allFieldsMap = getCachedMembers(cache, PsiField.class);
|
||||
final Map<String, List<Pair<PsiMember, PsiSubstitutor>>> allFieldsMap = value.get(MemberType.FIELD);
|
||||
|
||||
final List<Pair<PsiField, PsiSubstitutor>> list = allFieldsMap.get(nameHint.getName(state));
|
||||
final List<Pair<PsiMember, PsiSubstitutor>> list = allFieldsMap.get(name);
|
||||
if (list != null) {
|
||||
for (final Pair<PsiField, PsiSubstitutor> candidate : list) {
|
||||
PsiField candidateField = candidate.getFirst();
|
||||
for (final Pair<PsiMember, PsiSubstitutor> candidate : list) {
|
||||
PsiMember candidateField = candidate.getFirst();
|
||||
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(candidateField.getContainingClass(), candidate.getSecond(), aClass,
|
||||
substitutor, place, factory);
|
||||
substitutor, factory, languageLevel);
|
||||
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, candidateField.getContainingClass());
|
||||
if (!processor.execute(candidateField, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
|
||||
@@ -464,22 +498,22 @@ public class PsiClassImplUtil {
|
||||
if (list != null && !list.processDeclarations(processor, state, last, place)) return false;
|
||||
}
|
||||
if (!(last instanceof PsiReferenceList)) {
|
||||
final PsiClass classByName = aClass.findInnerClassByName(nameHint.getName(state), false);
|
||||
final PsiClass classByName = aClass.findInnerClassByName(name, false);
|
||||
if (classByName != null) {
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
|
||||
if (!processor.execute(classByName, state)) return false;
|
||||
}
|
||||
else {
|
||||
final Map<String, List<Pair<PsiClass, PsiSubstitutor>>> allClassesMap = getCachedMembers(cache, PsiClass.class);
|
||||
Map<String, List<Pair<PsiMember, PsiSubstitutor>>> allClassesMap = value.get(MemberType.CLASS);
|
||||
|
||||
final List<Pair<PsiClass, PsiSubstitutor>> list = allClassesMap.get(nameHint.getName(state));
|
||||
List<Pair<PsiMember, PsiSubstitutor>> list = allClassesMap.get(name);
|
||||
if (list != null) {
|
||||
for (final Pair<PsiClass, PsiSubstitutor> candidate : list) {
|
||||
final PsiClass inner = candidate.getFirst();
|
||||
final PsiClass containingClass = inner.getContainingClass();
|
||||
for (final Pair<PsiMember, PsiSubstitutor> candidate : list) {
|
||||
PsiMember inner = candidate.getFirst();
|
||||
PsiClass containingClass = inner.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
|
||||
substitutor, place, factory);
|
||||
substitutor, factory, languageLevel);
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
|
||||
if (!processor.execute(inner, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
|
||||
}
|
||||
@@ -500,12 +534,12 @@ public class PsiClassImplUtil {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
final Map<String, List<Pair<PsiMethod, PsiSubstitutor>>> allMethodsMap = getCachedMembers(cache, PsiMethod.class);
|
||||
final List<Pair<PsiMethod, PsiSubstitutor>> list = allMethodsMap.get(nameHint.getName(state));
|
||||
Map<String, List<Pair<PsiMember, PsiSubstitutor>>> allMethodsMap = value.get(MemberType.METHOD);
|
||||
List<Pair<PsiMember, PsiSubstitutor>> list = allMethodsMap.get(name);
|
||||
if (list != null) {
|
||||
for (final Pair<PsiMethod, PsiSubstitutor> candidate : list) {
|
||||
for (final Pair<PsiMember, PsiSubstitutor> candidate : list) {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
PsiMethod candidateMethod = candidate.getFirst();
|
||||
PsiMethod candidateMethod = (PsiMethod)candidate.getFirst();
|
||||
if (processor instanceof MethodResolverProcessor) {
|
||||
if (candidateMethod.isConstructor() != ((MethodResolverProcessor)processor).isConstructor()) continue;
|
||||
}
|
||||
@@ -515,24 +549,26 @@ public class PsiClassImplUtil {
|
||||
}
|
||||
|
||||
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
|
||||
substitutor, place, factory);
|
||||
substitutor, factory, languageLevel);
|
||||
finalSubstitutor = checkRaw(isRaw, factory, candidateMethod, finalSubstitutor);
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
|
||||
if (!processor.execute(candidateMethod, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
|
||||
}
|
||||
|
||||
if (visited != null) {
|
||||
for (Pair<PsiMethod, PsiSubstitutor> aList : list) {
|
||||
for (Pair<PsiMember, PsiSubstitutor> aList : list) {
|
||||
visited.add(aList.getFirst().getContainingClass());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiSubstitutor checkRaw(boolean isRaw, PsiElementFactory factory, PsiMethod candidateMethod, PsiSubstitutor substitutor) {
|
||||
private static PsiSubstitutor checkRaw(boolean isRaw,
|
||||
@NotNull PsiElementFactory factory,
|
||||
@NotNull PsiMethod candidateMethod,
|
||||
@NotNull PsiSubstitutor substitutor) {
|
||||
if (isRaw && !candidateMethod.hasModifierProperty(PsiModifier.STATIC)) { //static methods are not erased due to raw overriding
|
||||
PsiTypeParameter[] methodTypeParameters = candidateMethod.getTypeParameters();
|
||||
substitutor = factory.createRawSubstitutor(substitutor, methodTypeParameters);
|
||||
@@ -540,27 +576,29 @@ public class PsiClassImplUtil {
|
||||
return substitutor;
|
||||
}
|
||||
|
||||
public static PsiSubstitutor obtainFinalSubstitutor(@NotNull PsiClass candidateClass, PsiSubstitutor candidateSubstitutor, PsiClass aClass,
|
||||
PsiSubstitutor substitutor,
|
||||
final PsiElement place,
|
||||
PsiElementFactory elementFactory) {
|
||||
public static PsiSubstitutor obtainFinalSubstitutor(@NotNull PsiClass candidateClass,
|
||||
@NotNull PsiSubstitutor candidateSubstitutor,
|
||||
@NotNull PsiClass aClass,
|
||||
@NotNull PsiSubstitutor substitutor,
|
||||
@NotNull PsiElementFactory elementFactory,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
if (PsiUtil.isRawSubstitutor(aClass, substitutor)) {
|
||||
return elementFactory.createRawSubstitutor(candidateClass);
|
||||
}
|
||||
|
||||
final PsiType containingType = elementFactory.createType(candidateClass, candidateSubstitutor, PsiUtil.getLanguageLevel(place));
|
||||
final PsiType containingType = elementFactory.createType(candidateClass, candidateSubstitutor, languageLevel);
|
||||
PsiType type = substitutor.substitute(containingType);
|
||||
if (!(type instanceof PsiClassType)) return candidateSubstitutor;
|
||||
return ((PsiClassType)type).resolveGenerics().getSubstitutor();
|
||||
}
|
||||
|
||||
private static boolean processDeclarationsInClassNotCached(PsiClass aClass,
|
||||
PsiScopeProcessor processor,
|
||||
ResolveState state,
|
||||
private static boolean processDeclarationsInClassNotCached(@NotNull PsiClass aClass,
|
||||
@NotNull PsiScopeProcessor processor,
|
||||
@NotNull ResolveState state,
|
||||
@Nullable Set<PsiClass> visited,
|
||||
PsiElement last,
|
||||
PsiElement place,
|
||||
boolean isRaw) {
|
||||
@NotNull PsiElement place,
|
||||
boolean isRaw,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
if (visited == null) visited = new THashSet<PsiClass>();
|
||||
if (!visited.add(aClass)) return true;
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
|
||||
@@ -571,9 +609,7 @@ public class PsiClassImplUtil {
|
||||
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.FIELD)) {
|
||||
if (nameHint != null) {
|
||||
final PsiField fieldByName = aClass.findFieldByName(nameHint.getName(state), false);
|
||||
if (fieldByName != null) {
|
||||
if (!processor.execute(fieldByName, state)) return false;
|
||||
}
|
||||
if (fieldByName != null && !processor.execute(fieldByName, state)) return false;
|
||||
}
|
||||
else {
|
||||
final PsiField[] fields = aClass.getFields();
|
||||
@@ -619,23 +655,26 @@ public class PsiClassImplUtil {
|
||||
}
|
||||
}
|
||||
|
||||
return last instanceof PsiReferenceList || processSuperTypes(aClass, processor, visited, last, place, state, isRaw, factory);
|
||||
return last instanceof PsiReferenceList || processSuperTypes(aClass, processor, visited, last, place, state, isRaw, factory,
|
||||
languageLevel);
|
||||
}
|
||||
|
||||
private static boolean processSuperTypes(PsiClass aClass,
|
||||
PsiScopeProcessor processor,
|
||||
Set<PsiClass> visited,
|
||||
private static boolean processSuperTypes(@NotNull PsiClass aClass,
|
||||
@NotNull PsiScopeProcessor processor,
|
||||
@Nullable Set<PsiClass> visited,
|
||||
PsiElement last,
|
||||
PsiElement place,
|
||||
ResolveState state,
|
||||
boolean isRaw, PsiElementFactory factory) {
|
||||
@NotNull PsiElement place,
|
||||
@NotNull ResolveState state,
|
||||
boolean isRaw,
|
||||
@NotNull PsiElementFactory factory,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
boolean resolved = false;
|
||||
for (final PsiClassType superType : aClass.getSuperTypes()) {
|
||||
final PsiClassType.ClassResolveResult superTypeResolveResult = superType.resolveGenerics();
|
||||
PsiClass superClass = superTypeResolveResult.getElement();
|
||||
if (superClass == null) continue;
|
||||
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(superClass, superTypeResolveResult.getSubstitutor(), aClass, state.get(PsiSubstitutor.KEY),
|
||||
place, factory);
|
||||
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(superClass, superTypeResolveResult.getSubstitutor(), aClass,
|
||||
state.get(PsiSubstitutor.KEY), factory, languageLevel);
|
||||
if (!processDeclarationsInClass(superClass, processor, state.put(PsiSubstitutor.KEY, finalSubstitutor), visited, last, place, isRaw)) {
|
||||
resolved = true;
|
||||
}
|
||||
@@ -644,7 +683,7 @@ public class PsiClassImplUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiClass getSuperClass(PsiClass psiClass) {
|
||||
public static PsiClass getSuperClass(@NotNull PsiClass psiClass) {
|
||||
PsiManager manager = psiClass.getManager();
|
||||
GlobalSearchScope resolveScope = psiClass.getResolveScope();
|
||||
|
||||
@@ -673,7 +712,8 @@ public class PsiClassImplUtil {
|
||||
return psiResoved == null ? facade.findClass(CommonClassNames.JAVA_LANG_OBJECT, resolveScope) : psiResoved;
|
||||
}
|
||||
|
||||
@NotNull public static PsiClass[] getSupers(PsiClass psiClass) {
|
||||
@NotNull
|
||||
public static PsiClass[] getSupers(@NotNull PsiClass psiClass) {
|
||||
final PsiClass[] supers = getSupersInner(psiClass);
|
||||
for (final PsiClass aSuper : supers) {
|
||||
LOG.assertTrue(aSuper != null);
|
||||
@@ -681,13 +721,13 @@ public class PsiClassImplUtil {
|
||||
return supers;
|
||||
}
|
||||
|
||||
private static PsiClass[] getSupersInner(PsiClass psiClass) {
|
||||
@NotNull
|
||||
private static PsiClass[] getSupersInner(@NotNull PsiClass psiClass) {
|
||||
PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes();
|
||||
PsiClassType[] implementsListTypes = psiClass.getImplementsListTypes();
|
||||
|
||||
if (psiClass.isInterface()) {
|
||||
return resolveClassReferenceList(extendsListTypes,
|
||||
psiClass.getManager(), psiClass.getResolveScope(), true);
|
||||
return resolveClassReferenceList(extendsListTypes, psiClass.getManager(), psiClass.getResolveScope(), true);
|
||||
}
|
||||
|
||||
if (psiClass instanceof PsiAnonymousClass) {
|
||||
@@ -696,23 +736,24 @@ public class PsiClassImplUtil {
|
||||
PsiClass baseClass = baseClassReference.resolve();
|
||||
if (baseClass != null) {
|
||||
if (baseClass.isInterface()) {
|
||||
PsiClass objectClass = JavaPsiFacade.getInstance(psiClass.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, psiClass.getResolveScope());
|
||||
PsiClass objectClass =
|
||||
JavaPsiFacade.getInstance(psiClass.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, psiClass.getResolveScope());
|
||||
return objectClass != null ? new PsiClass[]{objectClass, baseClass} : new PsiClass[]{baseClass};
|
||||
}
|
||||
return new PsiClass[]{baseClass};
|
||||
}
|
||||
|
||||
PsiClass objectClass = JavaPsiFacade.getInstance(psiClass.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, psiClass.getResolveScope());
|
||||
PsiClass objectClass =
|
||||
JavaPsiFacade.getInstance(psiClass.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, psiClass.getResolveScope());
|
||||
return objectClass != null ? new PsiClass[]{objectClass} : PsiClass.EMPTY_ARRAY;
|
||||
}
|
||||
else if (psiClass instanceof PsiTypeParameter) {
|
||||
if (psiClass instanceof PsiTypeParameter) {
|
||||
if (extendsListTypes.length == 0) {
|
||||
final PsiClass objectClass =
|
||||
JavaPsiFacade.getInstance(psiClass.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, psiClass.getResolveScope());
|
||||
return objectClass != null ? new PsiClass[]{objectClass} : PsiClass.EMPTY_ARRAY;
|
||||
}
|
||||
return resolveClassReferenceList(extendsListTypes, psiClass.getManager(),
|
||||
psiClass.getResolveScope(), false);
|
||||
return resolveClassReferenceList(extendsListTypes, psiClass.getManager(), psiClass.getResolveScope(), false);
|
||||
}
|
||||
|
||||
PsiClass[] interfaces = resolveClassReferenceList(implementsListTypes, psiClass.getManager(), psiClass.getResolveScope(), false);
|
||||
@@ -726,7 +767,8 @@ public class PsiClassImplUtil {
|
||||
return types;
|
||||
}
|
||||
|
||||
@NotNull public static PsiClassType[] getSuperTypes(PsiClass psiClass) {
|
||||
@NotNull
|
||||
public static PsiClassType[] getSuperTypes(@NotNull PsiClass psiClass) {
|
||||
if (psiClass instanceof PsiAnonymousClass) {
|
||||
PsiClassType baseClassType = ((PsiAnonymousClass)psiClass).getBaseClassType();
|
||||
PsiClass baseClass = baseClassType.resolve();
|
||||
@@ -762,11 +804,12 @@ public class PsiClassImplUtil {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static PsiClassType getAnnotationSuperType(PsiClass psiClass, PsiElementFactory factory) {
|
||||
@NotNull
|
||||
private static PsiClassType getAnnotationSuperType(@NotNull PsiClass psiClass, @NotNull PsiElementFactory factory) {
|
||||
return factory.createTypeByFQClassName("java.lang.annotation.Annotation", psiClass.getResolveScope());
|
||||
}
|
||||
|
||||
private static PsiClassType getEnumSuperType(PsiClass psiClass, PsiElementFactory factory) {
|
||||
private static PsiClassType getEnumSuperType(@NotNull PsiClass psiClass, @NotNull PsiElementFactory factory) {
|
||||
PsiClassType superType;
|
||||
final PsiManager manager = psiClass.getManager();
|
||||
final PsiClass enumClass = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Enum", psiClass.getResolveScope());
|
||||
@@ -789,9 +832,13 @@ public class PsiClassImplUtil {
|
||||
return superType;
|
||||
}
|
||||
|
||||
public static PsiClass[] getInterfaces(PsiTypeParameter typeParameter) {
|
||||
final ArrayList<PsiClass> result = new ArrayList<PsiClass>();
|
||||
@NotNull
|
||||
public static PsiClass[] getInterfaces(@NotNull PsiTypeParameter typeParameter) {
|
||||
final PsiClassType[] referencedTypes = typeParameter.getExtendsListTypes();
|
||||
if (referencedTypes.length == 0) {
|
||||
return PsiClass.EMPTY_ARRAY;
|
||||
}
|
||||
final List<PsiClass> result = new ArrayList<PsiClass>(referencedTypes.length);
|
||||
for (PsiClassType referencedType : referencedTypes) {
|
||||
final PsiClass psiClass = referencedType.resolve();
|
||||
if (psiClass != null && psiClass.isInterface()) {
|
||||
@@ -801,7 +848,8 @@ public class PsiClassImplUtil {
|
||||
return result.toArray(new PsiClass[result.size()]);
|
||||
}
|
||||
|
||||
public static PsiClass[] getInterfaces(PsiClass psiClass) {
|
||||
@NotNull
|
||||
public static PsiClass[] getInterfaces(@NotNull PsiClass psiClass) {
|
||||
if (psiClass.isInterface()) {
|
||||
final PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes();
|
||||
return resolveClassReferenceList(extendsListTypes, psiClass.getManager(), psiClass.getResolveScope(), false);
|
||||
@@ -817,13 +865,14 @@ public class PsiClassImplUtil {
|
||||
return resolveClassReferenceList(implementsListTypes, psiClass.getManager(), psiClass.getResolveScope(), false);
|
||||
}
|
||||
|
||||
private static PsiClass[] resolveClassReferenceList(final PsiClassType[] listOfTypes,
|
||||
final PsiManager manager,
|
||||
final GlobalSearchScope resolveScope,
|
||||
@NotNull
|
||||
private static PsiClass[] resolveClassReferenceList(@NotNull PsiClassType[] listOfTypes,
|
||||
@NotNull PsiManager manager,
|
||||
@NotNull GlobalSearchScope resolveScope,
|
||||
boolean includeObject) {
|
||||
PsiClass objectClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, resolveScope);
|
||||
if (objectClass == null) includeObject = false;
|
||||
if (listOfTypes == null || listOfTypes.length == 0) {
|
||||
if (listOfTypes.length == 0) {
|
||||
if (includeObject) return new PsiClass[]{objectClass};
|
||||
return PsiClass.EMPTY_ARRAY;
|
||||
}
|
||||
@@ -849,7 +898,10 @@ public class PsiClassImplUtil {
|
||||
return resolved;
|
||||
}
|
||||
|
||||
public static List<Pair<PsiMethod, PsiSubstitutor>> findMethodsAndTheirSubstitutorsByName(PsiClass psiClass, String name, boolean checkBases) {
|
||||
@NotNull
|
||||
public static List<Pair<PsiMethod, PsiSubstitutor>> findMethodsAndTheirSubstitutorsByName(@NotNull PsiClass psiClass,
|
||||
String name,
|
||||
boolean checkBases) {
|
||||
if (!checkBases) {
|
||||
final PsiMethod[] methodsByName = psiClass.findMethodsByName(name, false);
|
||||
final List<Pair<PsiMethod, PsiSubstitutor>> ret = new ArrayList<Pair<PsiMethod, PsiSubstitutor>>(methodsByName.length);
|
||||
@@ -858,18 +910,21 @@ public class PsiClassImplUtil {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
final Map<String, List<Pair<PsiMethod, PsiSubstitutor>>> map = getMap(psiClass, PsiMethod.class);
|
||||
final List<Pair<PsiMethod, PsiSubstitutor>> list = map.get(name);
|
||||
Map<String, List<Pair<PsiMember, PsiSubstitutor>>> map = getMap(psiClass, MemberType.METHOD);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Pair<PsiMethod, PsiSubstitutor>> list = (List)map.get(name);
|
||||
return list == null ?
|
||||
Collections.<Pair<PsiMethod, PsiSubstitutor>>emptyList() :
|
||||
Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
public static PsiClassType[] getExtendsListTypes(PsiClass psiClass) {
|
||||
@NotNull
|
||||
public static PsiClassType[] getExtendsListTypes(@NotNull PsiClass psiClass) {
|
||||
if (psiClass.isEnum()) {
|
||||
return new PsiClassType[]{getEnumSuperType(psiClass, JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory())};
|
||||
PsiClassType enumSuperType = getEnumSuperType(psiClass, JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory());
|
||||
return enumSuperType == null ? PsiClassType.EMPTY_ARRAY : new PsiClassType[]{enumSuperType};
|
||||
}
|
||||
else if (psiClass.isAnnotationType()) {
|
||||
if (psiClass.isAnnotationType()) {
|
||||
return new PsiClassType[]{getAnnotationSuperType(psiClass, JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory())};
|
||||
}
|
||||
final PsiReferenceList extendsList = psiClass.getExtendsList();
|
||||
@@ -879,7 +934,8 @@ public class PsiClassImplUtil {
|
||||
return PsiClassType.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
public static PsiClassType[] getImplementsListTypes(PsiClass psiClass) {
|
||||
@NotNull
|
||||
public static PsiClassType[] getImplementsListTypes(@NotNull PsiClass psiClass) {
|
||||
final PsiReferenceList extendsList = psiClass.getImplementsList();
|
||||
if (extendsList != null) {
|
||||
return extendsList.getReferencedTypes();
|
||||
@@ -887,13 +943,13 @@ public class PsiClassImplUtil {
|
||||
return PsiClassType.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
public static boolean isClassEquivalentTo(PsiClass aClass, PsiElement another) {
|
||||
public static boolean isClassEquivalentTo(@NotNull PsiClass aClass, PsiElement another) {
|
||||
if (aClass == another) return true;
|
||||
if (!(another instanceof PsiClass)) return false;
|
||||
String name1 = aClass.getName();
|
||||
if (name1 == null) return false;
|
||||
if (!another.isValid()) return false;
|
||||
String name2 = ((PsiClass)another).getName();
|
||||
String name2 = ((PsiClass)another).getName();
|
||||
if (name2 == null) return false;
|
||||
if (name1.hashCode() != name2.hashCode()) return false;
|
||||
if (!name1.equals(name2)) return false;
|
||||
@@ -909,7 +965,6 @@ public class PsiClassImplUtil {
|
||||
|
||||
return p1.getIndex() == p2.getIndex() &&
|
||||
aClass.getManager().areElementsEquivalent(p1.getOwner(), p2.getOwner());
|
||||
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
@@ -932,7 +987,7 @@ public class PsiClassImplUtil {
|
||||
final PsiFile original2 = file2.getUserData(PsiFileFactory.ORIGINAL_FILE);
|
||||
if (original1 == original2 && original1 != null || original1 == file2 || original2 == file1 || file1 == file2) {
|
||||
return compareClassSeqNumber(aClass, (PsiClass)another);
|
||||
}
|
||||
}
|
||||
|
||||
final FileIndexFacade fileIndex = ServiceManager.getService(file1.getProject(), FileIndexFacade.class);
|
||||
final VirtualFile vfile1 = file1.getViewProvider().getVirtualFile();
|
||||
@@ -941,7 +996,7 @@ public class PsiClassImplUtil {
|
||||
(fileIndex.isInSource(vfile2) || fileIndex.isInLibraryClasses(vfile2));
|
||||
}
|
||||
|
||||
private static boolean compareClassSeqNumber(PsiClass aClass, PsiClass another) {
|
||||
private static boolean compareClassSeqNumber(@NotNull PsiClass aClass, @NotNull PsiClass another) {
|
||||
// there may be several classes in one file, they must not be equal
|
||||
int index1 = getSeqNumber(aClass);
|
||||
if (index1 == -1) return true;
|
||||
@@ -949,7 +1004,7 @@ public class PsiClassImplUtil {
|
||||
return index1 == index2;
|
||||
}
|
||||
|
||||
private static int getSeqNumber(PsiClass aClass) {
|
||||
private static int getSeqNumber(@NotNull PsiClass aClass) {
|
||||
// sequence number of this class among its parent' child classes named the same
|
||||
PsiElement parent = aClass.getParent();
|
||||
if (parent == null) return -1;
|
||||
@@ -963,7 +1018,8 @@ public class PsiClassImplUtil {
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static PsiElement originalElement(PsiClass aClass) {
|
||||
@NotNull
|
||||
private static PsiElement originalElement(@NotNull PsiClass aClass) {
|
||||
final PsiElement originalElement = aClass.getOriginalElement();
|
||||
ASTNode node = originalElement.getNode();
|
||||
if (node != null) {
|
||||
@@ -975,7 +1031,7 @@ public class PsiClassImplUtil {
|
||||
return originalElement;
|
||||
}
|
||||
|
||||
public static boolean isFieldEquivalentTo(PsiField field, PsiElement another) {
|
||||
public static boolean isFieldEquivalentTo(@NotNull PsiField field, PsiElement another) {
|
||||
if (!(another instanceof PsiField)) return false;
|
||||
String name1 = field.getName();
|
||||
if (name1 == null) return false;
|
||||
@@ -988,7 +1044,7 @@ public class PsiClassImplUtil {
|
||||
return aClass1 != null && aClass2 != null && field.getManager().areElementsEquivalent(aClass1, aClass2);
|
||||
}
|
||||
|
||||
public static boolean isMethodEquivalentTo(PsiMethod method1, PsiElement another) {
|
||||
public static boolean isMethodEquivalentTo(@NotNull PsiMethod method1, PsiElement another) {
|
||||
if (method1 == another) return true;
|
||||
if (!(another instanceof PsiMethod)) return false;
|
||||
PsiMethod method2 = (PsiMethod)another;
|
||||
@@ -1007,15 +1063,15 @@ public class PsiClassImplUtil {
|
||||
PsiParameter parameter2 = parameters2[i];
|
||||
PsiType type1 = parameter1.getType();
|
||||
PsiType type2 = parameter2.getType();
|
||||
if (!compareParamTypes(manager,type1, type2)) return false;
|
||||
if (!compareParamTypes(manager, type1, type2)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean compareParamTypes(@NotNull PsiManager manager, @NotNull PsiType type1, @NotNull PsiType type2) {
|
||||
if (type1 instanceof PsiArrayType) {
|
||||
if (!(type2 instanceof PsiArrayType)) return false;
|
||||
return compareParamTypes(manager, ((PsiArrayType)type1).getComponentType(), ((PsiArrayType)type2).getComponentType());
|
||||
return type2 instanceof PsiArrayType &&
|
||||
compareParamTypes(manager, ((PsiArrayType)type1).getComponentType(), ((PsiArrayType)type2).getComponentType());
|
||||
}
|
||||
|
||||
if (!(type1 instanceof PsiClassType) || !(type2 instanceof PsiClassType)) {
|
||||
|
||||
@@ -321,7 +321,7 @@ public class ClsClassImpl extends ClsRepositoryPsiElement<PsiClassStub<?>> imple
|
||||
@Override
|
||||
@NotNull
|
||||
public List<Pair<PsiMethod, PsiSubstitutor>> getAllMethodsAndTheirSubstitutors() {
|
||||
return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiMethod.class);
|
||||
return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiClassImplUtil.MemberType.METHOD);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -115,7 +115,7 @@ public class ClsTypeParameterImpl extends ClsRepositoryPsiElement<PsiTypeParamet
|
||||
@Override
|
||||
@NotNull
|
||||
public List<Pair<PsiMethod, PsiSubstitutor>> getAllMethodsAndTheirSubstitutors() {
|
||||
return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiMethod.class);
|
||||
return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiClassImplUtil.MemberType.METHOD);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -260,7 +260,7 @@ public abstract class AbstractLightClass extends LightElement implements PsiClas
|
||||
@Override
|
||||
@NotNull
|
||||
public List<Pair<PsiMethod, PsiSubstitutor>> getAllMethodsAndTheirSubstitutors() {
|
||||
return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiMethod.class);
|
||||
return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiClassImplUtil.MemberType.METHOD);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -382,7 +382,7 @@ public class PsiClassImpl extends JavaStubPsiElement<PsiClassStub<?>> implements
|
||||
@Override
|
||||
@NotNull
|
||||
public List<Pair<PsiMethod, PsiSubstitutor>> getAllMethodsAndTheirSubstitutors() {
|
||||
return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiMethod.class);
|
||||
return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiClassImplUtil.MemberType.METHOD);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -220,15 +220,14 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
}
|
||||
|
||||
private void resolveAllQualifiers() {
|
||||
// to avoid SOE
|
||||
// to avoid SOE, resolve all qualifiers starting from the innermost
|
||||
PsiElement qualifier = getQualifier();
|
||||
if (qualifier == null) return;
|
||||
final ResolveCache resolveCache = ResolveCache.getInstance(getProject());
|
||||
//resolveCache.resolveWithCaching(this, OurGenericsResolver.INSTANCE, true, incompleteCode)
|
||||
qualifier.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
if (!(expression instanceof PsiReferenceExpressionImpl) || resolveCache.isCached(expression, true, false)) {
|
||||
if (!(expression instanceof PsiReferenceExpressionImpl) || resolveCache.isCached(expression, true, false, true)) {
|
||||
return;
|
||||
}
|
||||
visitElement(expression);
|
||||
@@ -238,17 +237,9 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
protected void elementFinished(PsiElement element) {
|
||||
if (!(element instanceof PsiReferenceExpressionImpl)) return;
|
||||
PsiReferenceExpressionImpl expression = (PsiReferenceExpressionImpl)element;
|
||||
//IElementType type = expression.getTreeParent().getElementType();
|
||||
//expression.resolve();
|
||||
ResolveResult[] results = resolveCache.resolveWithCaching(expression, OurGenericsResolver.INSTANCE, false, false);
|
||||
//System.out.println("resolveWithCaching "+element);
|
||||
//if (!resolveCache.isCached(expression, element.isPhysical(), false)) {
|
||||
// assert resolveCache.isCached(expression, element.isPhysical(), false);
|
||||
//}
|
||||
assert results != null;
|
||||
resolveCache.resolveWithCaching(expression, OurGenericsResolver.INSTANCE, false, false);
|
||||
}
|
||||
});
|
||||
int i = 0;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -470,7 +461,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
final String qualifiedName = element.getQualifiedName();
|
||||
return qualifiedName != null &&
|
||||
qualifiedName.length() <= 2 &&
|
||||
qualifiedName.length() > 0 &&
|
||||
!qualifiedName.isEmpty() &&
|
||||
Character.isLowerCase(qualifiedName.charAt(0));
|
||||
}
|
||||
|
||||
@@ -554,7 +545,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
}
|
||||
else if (element instanceof PsiPackage) {
|
||||
final String qName = ((PsiPackage)element).getQualifiedName();
|
||||
if (qName.length() == 0) {
|
||||
if (qName.isEmpty()) {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
final PsiExpression ref = parserFacade.createExpressionFromText(qName, this);
|
||||
|
||||
@@ -125,7 +125,7 @@ public class PsiTypeParameterImpl extends JavaStubPsiElement<PsiTypeParameterStu
|
||||
@Override
|
||||
@NotNull
|
||||
public List<Pair<PsiMethod, PsiSubstitutor>> getAllMethodsAndTheirSubstitutors() {
|
||||
return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiMethod.class);
|
||||
return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiClassImplUtil.MemberType.METHOD);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,98 +1,16 @@
|
||||
import java.io.*;
|
||||
|
||||
public class Main {
|
||||
static interface A
|
||||
{
|
||||
interface B { }
|
||||
}
|
||||
|
||||
static class D implements A
|
||||
{
|
||||
private interface B { }
|
||||
}
|
||||
|
||||
|
||||
static class C extends D implements A
|
||||
{
|
||||
interface E extends B { }
|
||||
interface E1 extends D.B { }
|
||||
interface E2 extends A.B { }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Main1 {
|
||||
static interface A
|
||||
{
|
||||
interface B { }
|
||||
}
|
||||
|
||||
static class D implements A
|
||||
{
|
||||
interface B { }
|
||||
}
|
||||
|
||||
|
||||
static class C extends D implements A
|
||||
{
|
||||
interface E extends <error descr="Reference to 'B' is ambiguous, both 'Main1.D.B' and 'Main1.A.B' match">B</error> { }
|
||||
interface E1 extends D.B {
|
||||
}
|
||||
interface E2 extends A.B { }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
interface A
|
||||
{
|
||||
interface B { }
|
||||
interface B1 { }
|
||||
}
|
||||
|
||||
class D implements A
|
||||
{
|
||||
private interface B { }
|
||||
interface B1 { }
|
||||
}
|
||||
|
||||
|
||||
class C extends D implements A
|
||||
{
|
||||
interface E extends B { }
|
||||
interface E1 extends D.<error descr="'D.B' has private access in 'D'">B</error> { }
|
||||
interface E2 extends A.B { }
|
||||
|
||||
interface F extends <error descr="Reference to 'B1' is ambiguous, both 'D.B1' and 'A.B1' match">B1</error> { }
|
||||
interface F1 extends D.B1 { }
|
||||
interface F2 extends A.B1 { }
|
||||
|
||||
}
|
||||
|
||||
|
||||
class AO {}
|
||||
class BAO {
|
||||
AO bar = new AO();
|
||||
{
|
||||
bar.foo();
|
||||
}
|
||||
private class AO {
|
||||
void foo(){}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class WithFileInputStream {
|
||||
private static final Runnable runn = new Runnable() {
|
||||
public void run() {
|
||||
new FileInputStream("path");
|
||||
}
|
||||
};
|
||||
|
||||
private static class FileInputStream {
|
||||
private FileInputStream(String str) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,8 +33,8 @@ import java.io.File;
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myTempDirectory = FileUtil.createTempDirectory(getTestName(true), "test");
|
||||
myFilesToDelete.add(getTestContentFile());
|
||||
myTempDirectory = FileUtil.createTempDirectory(getTestName(true), "test",false);
|
||||
myFilesToDelete.add(myTempDirectory);
|
||||
final File testRoot = new File(getTestDataPath(), getTestPath());
|
||||
assertTrue(testRoot.getAbsolutePath(), testRoot.isDirectory());
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.ide.caches;
|
||||
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -25,8 +26,6 @@ import java.io.IOException;
|
||||
* @author max
|
||||
*/
|
||||
public class FileContent extends UserDataHolderBase {
|
||||
private static final byte[] EMPTY_CONTENT = new byte[0];
|
||||
|
||||
private final VirtualFile myVirtualFile;
|
||||
private byte[] myCachedBytes;
|
||||
private long myCachedLength = -1;
|
||||
@@ -53,7 +52,7 @@ public class FileContent extends UserDataHolderBase {
|
||||
}
|
||||
|
||||
public void setEmptyContent() {
|
||||
myCachedBytes = EMPTY_CONTENT;
|
||||
myCachedBytes = ArrayUtil.EMPTY_BYTE_ARRAY;
|
||||
myCachedLength = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
*/
|
||||
package com.intellij.openapi.util;
|
||||
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Map;
|
||||
|
||||
public interface Iconable {
|
||||
int ICON_FLAG_VISIBILITY = 0x0001;
|
||||
@@ -34,24 +34,20 @@ public interface Iconable {
|
||||
Icon getIcon(@IconFlags int flags);
|
||||
|
||||
class LastComputedIcon {
|
||||
private static final Key<Map<Integer, Icon>> LAST_COMPUTED_ICON = Key.create("lastComputedIcon");
|
||||
private static final Key<TIntObjectHashMap<Icon>> LAST_COMPUTED_ICON = Key.create("lastComputedIcon");
|
||||
|
||||
@Nullable
|
||||
public static Icon get(UserDataHolder holder, int flags) {
|
||||
Map<Integer, Icon> map = holder.getUserData(LAST_COMPUTED_ICON);
|
||||
return map != null ? map.get(flags) : null;
|
||||
public static Icon get(@NotNull UserDataHolder holder, int flags) {
|
||||
TIntObjectHashMap<Icon> map = holder.getUserData(LAST_COMPUTED_ICON);
|
||||
return map == null ? null : map.get(flags);
|
||||
}
|
||||
|
||||
public static void put(UserDataHolder holder, Icon icon, int flags) {
|
||||
Map<Integer, Icon> map = holder.getUserData(LAST_COMPUTED_ICON);
|
||||
public static void put(@NotNull UserDataHolder holder, Icon icon, int flags) {
|
||||
TIntObjectHashMap<Icon> map = holder.getUserData(LAST_COMPUTED_ICON);
|
||||
if (map == null) {
|
||||
map = new HashMap<Integer, Icon>();
|
||||
holder.putUserData(LAST_COMPUTED_ICON, map);
|
||||
map = ((UserDataHolderEx)holder).putUserDataIfAbsent(LAST_COMPUTED_ICON, new TIntObjectHashMap<Icon>());
|
||||
}
|
||||
|
||||
map.put(flags, icon);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -21,10 +21,7 @@ import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.RecursionGuard;
|
||||
import com.intellij.openapi.util.RecursionManager;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiPolyVariantReference;
|
||||
import com.intellij.psi.PsiReference;
|
||||
@@ -38,14 +35,12 @@ import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class ResolveCache {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.resolve.ResolveCache");
|
||||
private final Map<PsiPolyVariantReference,Reference<ResolveResult[]>>[] myPolyVariantResolveMaps = new Map[4];
|
||||
private final Map<PsiReference,Reference>[] myResolveMaps = new Map[4];
|
||||
private final Map[] myMaps = new Map[2*2*2]; //boolean physical, boolean incompleteCode, boolean isPoly
|
||||
private final AtomicInteger myClearCount = new AtomicInteger(0);
|
||||
private final RecursionGuard myGuard = RecursionManager.createGuard("resolveCache");
|
||||
|
||||
@@ -66,62 +61,47 @@ public class ResolveCache {
|
||||
public interface Resolver extends AbstractResolver<PsiReference,PsiElement>{
|
||||
}
|
||||
|
||||
public ResolveCache(@Nullable MessageBus messageBus) {
|
||||
myPolyVariantResolveMaps[0] = createWeakMap();
|
||||
myPolyVariantResolveMaps[1] = createWeakMap();
|
||||
myResolveMaps[0] = createWeakMap();
|
||||
myResolveMaps[1] = createWeakMap();
|
||||
|
||||
myPolyVariantResolveMaps[2] = createWeakMap();
|
||||
myPolyVariantResolveMaps[3] = createWeakMap();
|
||||
myResolveMaps[2] = createWeakMap();
|
||||
myResolveMaps[3] = createWeakMap();
|
||||
|
||||
if (messageBus != null) {
|
||||
messageBus.connect().subscribe(PsiManagerImpl.ANY_PSI_CHANGE_TOPIC, new AnyPsiChangeListener() {
|
||||
@Override
|
||||
public void beforePsiChanged(boolean isPhysical) {
|
||||
clearCache(isPhysical);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPsiChanged(boolean isPhysical) {
|
||||
}
|
||||
});
|
||||
public ResolveCache(@NotNull MessageBus messageBus) {
|
||||
for (int i = 0; i < myMaps.length; i++) {
|
||||
myMaps[i] = createWeakMap();
|
||||
}
|
||||
messageBus.connect().subscribe(PsiManagerImpl.ANY_PSI_CHANGE_TOPIC, new AnyPsiChangeListener() {
|
||||
@Override
|
||||
public void beforePsiChanged(boolean isPhysical) {
|
||||
clearCache(isPhysical);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPsiChanged(boolean isPhysical) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <K,V> ConcurrentWeakHashMap<K, V> createWeakMap() {
|
||||
//noinspection unchecked
|
||||
return new ConcurrentWeakHashMap<K,V>(100, 0.75f, Runtime.getRuntime().availableProcessors(), TObjectHashingStrategy.CANONICAL);
|
||||
}
|
||||
|
||||
public void clearCache(boolean isPhysical) {
|
||||
myClearCount.incrementAndGet();
|
||||
if (isPhysical) {
|
||||
myPolyVariantResolveMaps[0].clear(); //physical complete
|
||||
myPolyVariantResolveMaps[1].clear(); //physical incomplete
|
||||
myResolveMaps[0].clear(); //physical complete
|
||||
myResolveMaps[1].clear(); //physical incomplete
|
||||
}
|
||||
|
||||
myPolyVariantResolveMaps[2].clear(); //nonphysical complete
|
||||
myPolyVariantResolveMaps[3].clear(); //nonphysical incomplete
|
||||
myResolveMaps[2].clear(); //nonphysical complete
|
||||
myResolveMaps[3].clear(); //nonphysical incomplete
|
||||
int startIndex = isPhysical ? 0 : 1;
|
||||
for (int i=startIndex;i<2;i++)for (int j=0;j<2;j++)for (int k=0;k<2;k++) myMaps[i*4+j*2+k].clear();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private <TRef extends PsiReference, TResult> TResult resolve(@NotNull final TRef ref,
|
||||
@NotNull final AbstractResolver<TRef, TResult> resolver,
|
||||
@NotNull Map<? super TRef,Reference<TResult>>[] maps,
|
||||
boolean needToPreventRecursion,
|
||||
final boolean incompleteCode, boolean poly) {
|
||||
final boolean incompleteCode,
|
||||
boolean isPoly) {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||
|
||||
int clearCountOnStart = myClearCount.intValue();
|
||||
boolean physical = ref.getElement().isPhysical();
|
||||
TResult result = getCached(ref, maps, physical, incompleteCode);
|
||||
Map<TRef, Getter<TResult>> map = getMap(physical, incompleteCode, isPoly);
|
||||
Getter<TResult> reference = map.get(ref);
|
||||
TResult result = reference == null ? null : reference.get();
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
@@ -134,30 +114,36 @@ public class ResolveCache {
|
||||
};
|
||||
|
||||
RecursionGuard.StackStamp stamp = myGuard.markStack();
|
||||
result = needToPreventRecursion ? myGuard.doPreventingRecursion(Trinity.create(ref, incompleteCode, poly), true, computable) : computable.compute();
|
||||
if (stamp.mayCacheNow()) {
|
||||
cache(ref, result, maps, physical, incompleteCode, clearCountOnStart);
|
||||
result = needToPreventRecursion ? myGuard.doPreventingRecursion(Trinity.create(ref, incompleteCode, isPoly), true, computable) : computable.compute();
|
||||
PsiElement element = result instanceof ResolveResult ? ((ResolveResult)result).getElement() : null;
|
||||
LOG.assertTrue(element == null || element.isValid(), result);
|
||||
|
||||
if (stamp.mayCacheNow() && clearCountOnStart == myClearCount.intValue()) {
|
||||
cache(ref, map, result, isPoly);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public <T extends PsiPolyVariantReference> ResolveResult[] resolveWithCaching(@NotNull T ref,
|
||||
@NotNull PolyVariantResolver<T> resolver,
|
||||
boolean needToPreventRecursion,
|
||||
boolean incompleteCode) {
|
||||
ResolveResult[] result = resolve(ref, resolver, myPolyVariantResolveMaps, needToPreventRecursion, incompleteCode, true);
|
||||
@NotNull
|
||||
public <T extends PsiPolyVariantReference> ResolveResult[] resolveWithCaching(@NotNull T ref,
|
||||
@NotNull PolyVariantResolver<T> resolver,
|
||||
boolean needToPreventRecursion,
|
||||
boolean incompleteCode) {
|
||||
ResolveResult[] result = resolve(ref, resolver, needToPreventRecursion, incompleteCode, true);
|
||||
return result == null ? ResolveResult.EMPTY_ARRAY : result;
|
||||
}
|
||||
|
||||
public <T extends PsiPolyVariantReference> boolean isCached(@NotNull T ref, boolean physical, boolean incompleteCode) {
|
||||
return getCached(ref, myPolyVariantResolveMaps, physical, incompleteCode) != null;
|
||||
public <T extends PsiPolyVariantReference> boolean isCached(@NotNull T ref, boolean physical, boolean incompleteCode, boolean isPoly) {
|
||||
Map<T, Getter<ResolveResult[]>> map = getMap(physical, incompleteCode, isPoly);
|
||||
Getter<ResolveResult[]> reference = map.get(ref);
|
||||
return reference != null && reference.get() != null;
|
||||
}
|
||||
|
||||
public PsiElement resolveWithCaching(@NotNull PsiReference ref,
|
||||
@NotNull Resolver resolver,
|
||||
boolean needToPreventRecursion,
|
||||
boolean incompleteCode) {
|
||||
return resolve(ref, resolver, (Map[]) myResolveMaps, needToPreventRecursion, incompleteCode, false);
|
||||
return resolve(ref, resolver, needToPreventRecursion, incompleteCode, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -165,33 +151,44 @@ public class ResolveCache {
|
||||
@NotNull AbstractResolver<TRef, TResult> resolver,
|
||||
boolean needToPreventRecursion,
|
||||
boolean incompleteCode) {
|
||||
return (TResult)resolve(ref, resolver, (Map[]) myResolveMaps, needToPreventRecursion, incompleteCode, false);
|
||||
return resolve(ref, resolver, needToPreventRecursion, incompleteCode, false);
|
||||
}
|
||||
|
||||
private static int getIndex(boolean physical, boolean incompleteCode){
|
||||
return (physical ? 0 : 1) << 1 | (incompleteCode ? 1 : 0);
|
||||
private <TRef extends PsiReference,TResult> Map<TRef, Getter<TResult>> getMap(boolean physical, boolean incompleteCode, boolean isPoly) {
|
||||
//noinspection unchecked
|
||||
return myMaps[(physical ? 0 : 1)*4 + (incompleteCode ? 0 : 1)*2 + (isPoly ? 0 : 1)];
|
||||
}
|
||||
|
||||
private static <TRef, TResult> TResult getCached(TRef ref, Map<? super TRef,Reference<TResult>>[] maps, boolean physical, boolean incompleteCode){
|
||||
int index = getIndex(physical, incompleteCode);
|
||||
Reference<TResult> reference = maps[index].get(ref);
|
||||
if(reference == null) return null;
|
||||
return reference.get();
|
||||
private static class SoftGetter<T> extends SoftReference<T> implements Getter<T> {
|
||||
public SoftGetter(T referent) {
|
||||
super(referent);
|
||||
}
|
||||
}
|
||||
|
||||
private <TRef extends PsiReference, TResult> void cache(TRef ref, TResult result, Map<? super TRef,Reference<TResult>>[] maps, boolean physical, boolean incompleteCode, final int clearCountOnStart) {
|
||||
if (clearCountOnStart != myClearCount.intValue() && result != null) return;
|
||||
PsiElement element = result instanceof ResolveResult ? ((ResolveResult)result).getElement() : null;
|
||||
LOG.assertTrue(element == null || element.isValid(), result);
|
||||
|
||||
int index = getIndex(physical, incompleteCode);
|
||||
// optimization: lower contention
|
||||
Map<? super TRef, Reference<TResult>> map = maps[index];
|
||||
Reference<TResult> cached = map.get(ref);
|
||||
private static final Getter<ResolveResult[]> EMPTY_POLY_RESULT = new StaticGetter<ResolveResult[]>(ResolveResult.EMPTY_ARRAY);
|
||||
private static final Getter<Object> NULL_RESULT = new StaticGetter<Object>(null);
|
||||
private static <TRef extends PsiReference, TResult> void cache(@NotNull TRef ref,
|
||||
@NotNull Map<TRef, Getter<TResult>> map,
|
||||
TResult result,
|
||||
boolean isPoly) {
|
||||
// optimization: less contention
|
||||
Getter<TResult> cached = map.get(ref);
|
||||
if (cached != null && cached.get() == result) {
|
||||
return;
|
||||
}
|
||||
|
||||
map.put(ref, new SoftReference<TResult>(result/*, myQueue*/));
|
||||
Getter<TResult> reference;
|
||||
if (result == null) {
|
||||
// no use in creating SoftReference to null
|
||||
//noinspection unchecked
|
||||
reference = (Getter<TResult>)NULL_RESULT;
|
||||
}
|
||||
else if (isPoly && ((Object[])result).length == 0 && result.getClass() == ResolveResult[].class) {
|
||||
// no use in creating SoftReference to empty array
|
||||
//noinspection unchecked
|
||||
reference = (Getter<TResult>)EMPTY_POLY_RESULT;
|
||||
}
|
||||
else {
|
||||
reference = new SoftGetter<TResult>(result);
|
||||
}
|
||||
map.put(ref, reference);
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 546 B After Width: | Height: | Size: 546 B |
|
Before Width: | Height: | Size: 540 B After Width: | Height: | Size: 540 B |
|
Before Width: | Height: | Size: 103 B After Width: | Height: | Size: 103 B |
|
Before Width: | Height: | Size: 524 B After Width: | Height: | Size: 524 B |
|
Before Width: | Height: | Size: 278 B After Width: | Height: | Size: 278 B |
|
Before Width: | Height: | Size: 111 B After Width: | Height: | Size: 111 B |
|
Before Width: | Height: | Size: 761 B After Width: | Height: | Size: 761 B |
|
Before Width: | Height: | Size: 156 B After Width: | Height: | Size: 156 B |
|
Before Width: | Height: | Size: 403 B After Width: | Height: | Size: 403 B |
@@ -292,7 +292,7 @@ public class LocalFileSystemTest extends PlatformLangTestCase {
|
||||
if (!SystemInfo.isWindows && !SystemInfo.isUnix) return;
|
||||
|
||||
final boolean safeWrite = GeneralSettings.getInstance().isUseSafeWrite();
|
||||
final File dir = FileUtil.createTempDirectory("hardlinks", "");
|
||||
final File dir = FileUtil.createTempDirectory("hardlinks", "",false);
|
||||
try {
|
||||
GeneralSettings.getInstance().setUseSafeWrite(false);
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public abstract class FlyIdeaTestCase extends TestCase {
|
||||
|
||||
public File getTempDir() throws IOException {
|
||||
if (myTempDir == null) {
|
||||
myTempDir = FileUtil.createTempDirectory(getName(), getClass().getName());
|
||||
myTempDir = FileUtil.createTempDirectory(getName(), getClass().getName(),false);
|
||||
}
|
||||
|
||||
return myTempDir;
|
||||
|
||||
@@ -53,6 +53,7 @@ import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl;
|
||||
@@ -722,7 +723,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
|
||||
}
|
||||
|
||||
public static File createTempDir(@NonNls final String prefix, final boolean refresh) throws IOException {
|
||||
final File tempDirectory = FileUtil.createTempDirectory(TEST_DIR_PREFIX + prefix, null);
|
||||
final File tempDirectory = FileUtilRt.createTempDirectory(TEST_DIR_PREFIX + prefix, null, false);
|
||||
myFilesToDelete.add(tempDirectory);
|
||||
if (refresh) {
|
||||
getVirtualFile(tempDirectory);
|
||||
|
||||
@@ -87,7 +87,7 @@ import java.util.List;
|
||||
final String rootPath,
|
||||
final Collection<File> filesToDelete,
|
||||
final boolean addProjectRoots) throws Exception {
|
||||
File dir = FileUtil.createTempDirectory(tempName, null);
|
||||
File dir = FileUtil.createTempDirectory(tempName, null,false);
|
||||
filesToDelete.add(dir);
|
||||
|
||||
final VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByPath(dir.getCanonicalPath().replace(File.separatorChar, '/'));
|
||||
|
||||
@@ -19,36 +19,36 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TempFiles {
|
||||
private final Collection<File> myFilesToDelete;
|
||||
|
||||
public TempFiles(Collection<File> filesToDelete) {
|
||||
public TempFiles(@NotNull Collection<File> filesToDelete) {
|
||||
myFilesToDelete = filesToDelete;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public VirtualFile createVFile(String prefix) {
|
||||
public VirtualFile createVFile(@NotNull String prefix) {
|
||||
return getVFileByFile(createTempFile(prefix));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public VirtualFile createVFile(String prefix, String postfix) {
|
||||
public VirtualFile createVFile(@NotNull String prefix, String postfix) {
|
||||
return getVFileByFile(createTempFile(prefix, postfix));
|
||||
}
|
||||
|
||||
public File createTempFile(String prefix) {
|
||||
public File createTempFile(@NotNull String prefix) {
|
||||
return createTempFile(prefix, "_Temp_File_");
|
||||
}
|
||||
|
||||
public File createTempFile(String prefix, String postfix) {
|
||||
public File createTempFile(@NotNull String prefix, String postfix) {
|
||||
try {
|
||||
File tempFile = FileUtil.createTempFile(prefix, postfix);
|
||||
tempFileCreated(tempFile);
|
||||
@@ -60,13 +60,12 @@ public class TempFiles {
|
||||
}
|
||||
}
|
||||
|
||||
private void tempFileCreated(File tempFile) {
|
||||
private void tempFileCreated(@NotNull File tempFile) {
|
||||
myFilesToDelete.add(tempFile);
|
||||
tempFile.deleteOnExit();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile getVFileByFile(File tempFile) {
|
||||
public static VirtualFile getVFileByFile(@NotNull File tempFile) {
|
||||
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile);
|
||||
}
|
||||
|
||||
@@ -74,9 +73,9 @@ public class TempFiles {
|
||||
return createTempDir("dir");
|
||||
}
|
||||
|
||||
private File createTempDir(String prefix) {
|
||||
private File createTempDir(@NotNull String prefix) {
|
||||
try {
|
||||
File dir = FileUtil.createTempDirectory(prefix, "test");
|
||||
File dir = FileUtil.createTempDirectory(prefix, "test",false);
|
||||
tempFileCreated(dir);
|
||||
getVFileByFile(dir);
|
||||
return dir;
|
||||
@@ -92,20 +91,22 @@ public class TempFiles {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public VirtualFile createTempVDir(String prefix) {
|
||||
public VirtualFile createTempVDir(@NotNull String prefix) {
|
||||
return getVFileByFile(createTempDir(prefix));
|
||||
}
|
||||
|
||||
public String createTempPath() {
|
||||
File tempFile = createTempFile("xxx");
|
||||
String absolutePath = tempFile.getAbsolutePath();
|
||||
assertTrue(absolutePath, tempFile.delete());
|
||||
Assert.assertTrue(absolutePath, tempFile.delete());
|
||||
return absolutePath;
|
||||
}
|
||||
|
||||
public void deleteAll() {
|
||||
for (File file : myFilesToDelete) {
|
||||
FileUtil.delete(file);
|
||||
if (!FileUtil.delete(file)) {
|
||||
file.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ public class TempDirTestFixtureImpl extends BaseFixture implements TempDirTestFi
|
||||
try {
|
||||
if (myTempDir == null) {
|
||||
File th = getTempHome();
|
||||
myTempDir = th != null ? FileUtil.createTempDirectory(th, "unitTest", null) : FileUtil.createTempDirectory("unitTest", null);
|
||||
myTempDir = th != null ? FileUtil.createTempDirectory(th, "unitTest", null,false) : FileUtil.createTempDirectory("unitTest", null,false);
|
||||
myFilesToDelete.add(myTempDir);
|
||||
}
|
||||
return myTempDir;
|
||||
|
||||
@@ -60,7 +60,7 @@ public class TestFileSystemItem {
|
||||
try {
|
||||
Assert.assertEquals("in " + relativePath, myName, file.getName());
|
||||
if (myArchive) {
|
||||
final File dirForExtracted = FileUtil.createTempDirectory("extracted_archive", null);
|
||||
final File dirForExtracted = FileUtil.createTempDirectory("extracted_archive", null,false);
|
||||
ZipUtil.extract(file, dirForExtracted, null);
|
||||
assertDirectoryEqual(dirForExtracted, relativePath);
|
||||
FileUtil.delete(dirForExtracted);
|
||||
|
||||
@@ -37,6 +37,7 @@ public class FileUtilRt {
|
||||
private static final LoggerRt LOG = LoggerRt.getInstance("#com.intellij.openapi.util.io.FileUtilLight");
|
||||
|
||||
protected static final ThreadLocal<byte[]> BUFFER = new ThreadLocal<byte[]>() {
|
||||
@Override
|
||||
protected byte[] initialValue() {
|
||||
return new byte[1024 * 20];
|
||||
}
|
||||
@@ -130,19 +131,31 @@ public class FileUtilRt {
|
||||
|
||||
@NotNull
|
||||
public static File createTempDirectory(@NotNull @NonNls String prefix, @Nullable @NonNls String suffix) throws IOException {
|
||||
return createTempDirectory(prefix, suffix, true);
|
||||
}
|
||||
|
||||
public static File createTempDirectory(@NotNull @NonNls String prefix, @Nullable @NonNls String suffix, boolean deleteOnExit) throws IOException {
|
||||
File file = doCreateTempFile(prefix, suffix);
|
||||
file.delete();
|
||||
file.mkdir();
|
||||
file.deleteOnExit();
|
||||
if (deleteOnExit) {
|
||||
file.deleteOnExit();
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static File createTempDirectory(File dir, @NotNull @NonNls String prefix, @Nullable @NonNls String suffix) throws IOException {
|
||||
File file = doCreateTempFile(prefix, suffix, dir);
|
||||
public static File createTempDirectory(@NotNull File dir, @NotNull @NonNls String prefix, @Nullable @NonNls String suffix) throws IOException {
|
||||
return createTempDirectory(dir, prefix, suffix,true);
|
||||
}
|
||||
@NotNull
|
||||
public static File createTempDirectory(@NotNull File dir, @NotNull @NonNls String prefix, @Nullable @NonNls String suffix,boolean deleteOnExit) throws IOException {
|
||||
File file = doCreateTempFile(dir, prefix, suffix);
|
||||
file.delete();
|
||||
file.mkdir();
|
||||
file.deleteOnExit();
|
||||
if (deleteOnExit) {
|
||||
file.deleteOnExit();
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
@@ -157,7 +170,7 @@ public class FileUtilRt {
|
||||
@Nullable @NonNls String suffix,
|
||||
final boolean create,
|
||||
boolean deleteOnExit) throws IOException {
|
||||
File file = doCreateTempFile(prefix, suffix, dir);
|
||||
File file = doCreateTempFile(dir, prefix, suffix);
|
||||
file.delete();
|
||||
if (create) {
|
||||
file.createNewFile();
|
||||
@@ -186,11 +199,11 @@ public class FileUtilRt {
|
||||
|
||||
@NotNull
|
||||
private static File doCreateTempFile(String prefix, String suffix) throws IOException {
|
||||
return doCreateTempFile(prefix, suffix, new File(getTempDirectory()));
|
||||
return doCreateTempFile(new File(getTempDirectory()), prefix, suffix);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static File doCreateTempFile(@NotNull String prefix, String suffix, final File dir) throws IOException {
|
||||
private static File doCreateTempFile(@NotNull File dir, @NotNull String prefix, String suffix) throws IOException {
|
||||
dir.mkdirs();
|
||||
|
||||
if (prefix.length() < 3) {
|
||||
|
||||
@@ -8,9 +8,8 @@ public class AllIcons {
|
||||
|
||||
public static class Actions {
|
||||
public static final Icon AddFacesSupport = IconLoader.getIcon("/actions/addFacesSupport.png");
|
||||
public static final Icon Annotate = IconLoader.getIcon("/actions/annotate.png");
|
||||
public static final Icon Apache = IconLoader.getIcon("/actions/apache.png");
|
||||
public static final Icon Back = IconLoader.getIcon("/actions/back.png");
|
||||
public static final Icon Annotate = IconLoader.getIcon("/actions/annotate.png");
|
||||
public static final Icon Back = IconLoader.getIcon("/actions/back.png");
|
||||
public static final Icon Browser_externalJavaDoc = IconLoader.getIcon("/actions/browser-externalJavaDoc.png");
|
||||
public static final Icon Cancel = IconLoader.getIcon("/actions/cancel.png");
|
||||
public static final Icon Checked = IconLoader.getIcon("/actions/checked.png");
|
||||
@@ -57,10 +56,8 @@ public class AllIcons {
|
||||
public static final Icon GC = IconLoader.getIcon("/actions/gc.png");
|
||||
public static final Icon Get = IconLoader.getIcon("/actions/get.png");
|
||||
public static final Icon GroupByMethod = IconLoader.getIcon("/actions/groupByMethod.png");
|
||||
public static final Icon Help = IconLoader.getIcon("/actions/help.png");
|
||||
public static final Icon Hibernate = IconLoader.getIcon("/actions/hibernate.png");
|
||||
public static final Icon Ibm = IconLoader.getIcon("/actions/ibm.png");
|
||||
public static final Icon Import = IconLoader.getIcon("/actions/import.png");
|
||||
public static final Icon Help = IconLoader.getIcon("/actions/help.png");
|
||||
public static final Icon Import = IconLoader.getIcon("/actions/import.png");
|
||||
public static final Icon Install = IconLoader.getIcon("/actions/install.png");
|
||||
public static final Icon IntentionBulb = IconLoader.getIcon("/actions/intentionBulb.png");
|
||||
public static final Icon IntentionOffBulb = IconLoader.getIcon("/actions/intentionOffBulb.png");
|
||||
@@ -71,24 +68,20 @@ public class AllIcons {
|
||||
public static final Icon Menu_open = IconLoader.getIcon("/actions/menu-open.png");
|
||||
public static final Icon Menu_paste = IconLoader.getIcon("/actions/menu-paste.png");
|
||||
public static final Icon Menu_replace = IconLoader.getIcon("/actions/menu-replace.png");
|
||||
public static final Icon Menu_saveall = IconLoader.getIcon("/actions/menu-saveall.png");
|
||||
public static final Icon Microsoft = IconLoader.getIcon("/actions/microsoft.png");
|
||||
public static final Icon Minimize = IconLoader.getIcon("/actions/minimize.png");
|
||||
public static final Icon Menu_saveall = IconLoader.getIcon("/actions/menu-saveall.png");
|
||||
public static final Icon Minimize = IconLoader.getIcon("/actions/minimize.png");
|
||||
public static final Icon Modul = IconLoader.getIcon("/actions/modul.png");
|
||||
public static final Icon Move_to_button_top = IconLoader.getIcon("/actions/move-to-button-top.png");
|
||||
public static final Icon Move_to_button = IconLoader.getIcon("/actions/move-to-button.png");
|
||||
public static final Icon MoveDown = IconLoader.getIcon("/actions/moveDown.png");
|
||||
public static final Icon MoveUp = IconLoader.getIcon("/actions/moveUp.png");
|
||||
public static final Icon Mysql = IconLoader.getIcon("/actions/mysql.png");
|
||||
public static final Icon New = IconLoader.getIcon("/actions/new.png");
|
||||
public static final Icon MoveUp = IconLoader.getIcon("/actions/moveUp.png");
|
||||
public static final Icon New = IconLoader.getIcon("/actions/new.png");
|
||||
public static final Icon NewFolder = IconLoader.getIcon("/actions/newFolder.png");
|
||||
public static final Icon Nextfile = IconLoader.getIcon("/actions/nextfile.png");
|
||||
public static final Icon NextOccurence = IconLoader.getIcon("/actions/nextOccurence.png");
|
||||
public static final Icon Oracle = IconLoader.getIcon("/actions/oracle.png");
|
||||
public static final Icon Pause = IconLoader.getIcon("/actions/pause.png");
|
||||
public static final Icon PopFrame = IconLoader.getIcon("/actions/popFrame.png");
|
||||
public static final Icon Postgresql = IconLoader.getIcon("/actions/postgresql.png");
|
||||
public static final Icon Prevfile = IconLoader.getIcon("/actions/prevfile.png");
|
||||
public static final Icon NextOccurence = IconLoader.getIcon("/actions/nextOccurence.png");
|
||||
public static final Icon Pause = IconLoader.getIcon("/actions/pause.png");
|
||||
public static final Icon PopFrame = IconLoader.getIcon("/actions/popFrame.png");
|
||||
public static final Icon Prevfile = IconLoader.getIcon("/actions/prevfile.png");
|
||||
public static final Icon Preview = IconLoader.getIcon("/actions/preview.png");
|
||||
public static final Icon PreviousOccurence = IconLoader.getIcon("/actions/previousOccurence.png");
|
||||
public static final Icon ProfileCPU = IconLoader.getIcon("/actions/profileCPU.png");
|
||||
@@ -125,13 +118,11 @@ public class AllIcons {
|
||||
public static final Icon SortAsc = IconLoader.getIcon("/actions/sortAsc.png");
|
||||
public static final Icon SortDesc = IconLoader.getIcon("/actions/sortDesc.png");
|
||||
public static final Icon SplitHorizontally = IconLoader.getIcon("/actions/splitHorizontally.png");
|
||||
public static final Icon SplitVertically = IconLoader.getIcon("/actions/splitVertically.png");
|
||||
public static final Icon Sqlite = IconLoader.getIcon("/actions/sqlite.png");
|
||||
public static final Icon StartDebugger = IconLoader.getIcon("/actions/startDebugger.png");
|
||||
public static final Icon SplitVertically = IconLoader.getIcon("/actions/splitVertically.png");
|
||||
public static final Icon StartDebugger = IconLoader.getIcon("/actions/startDebugger.png");
|
||||
public static final Icon StepOut = IconLoader.getIcon("/actions/stepOut.png");
|
||||
public static final Icon Submit1 = IconLoader.getIcon("/actions/submit1.png");
|
||||
public static final Icon Sun = IconLoader.getIcon("/actions/sun.png");
|
||||
public static final Icon Suspend = IconLoader.getIcon("/actions/suspend.png");
|
||||
public static final Icon Submit1 = IconLoader.getIcon("/actions/submit1.png");
|
||||
public static final Icon Suspend = IconLoader.getIcon("/actions/suspend.png");
|
||||
public static final Icon SwapPanels = IconLoader.getIcon("/actions/swapPanels.png");
|
||||
public static final Icon Sync = IconLoader.getIcon("/actions/sync.png");
|
||||
public static final Icon SyncPanels = IconLoader.getIcon("/actions/syncPanels.png");
|
||||
@@ -144,6 +135,18 @@ public class AllIcons {
|
||||
public static final Icon Unshare = IconLoader.getIcon("/actions/unshare.png");
|
||||
|
||||
}
|
||||
|
||||
public static class Providers {
|
||||
public static final Icon Apache = IconLoader.getIcon("/providers/apache.png");
|
||||
public static final Icon Ibm = IconLoader.getIcon("/providers/ibm.png");
|
||||
public static final Icon Microsoft = IconLoader.getIcon("/providers/microsoft.png");
|
||||
public static final Icon Oracle = IconLoader.getIcon("/providers/oracle.png");
|
||||
public static final Icon Sqlite = IconLoader.getIcon("/providers/sqlite.png");
|
||||
public static final Icon Sun = IconLoader.getIcon("/providers/sun.png");
|
||||
public static final Icon Mysql = IconLoader.getIcon("/providers/mysql.png");
|
||||
public static final Icon Postgresql = IconLoader.getIcon("/providers/postgresql.png");
|
||||
public static final Icon Hibernate = IconLoader.getIcon("/providers/hibernate.png");
|
||||
}
|
||||
|
||||
public static class Ant {
|
||||
public static final Icon AllJarsInDir = IconLoader.getIcon("/ant/allJarsInDir.png");
|
||||
|
||||
@@ -1127,11 +1127,19 @@ public class FileUtil extends FileUtilRt {
|
||||
public static File createTempDirectory(@NotNull @NonNls String prefix, @Nullable @NonNls String suffix) throws IOException {
|
||||
return FileUtilRt.createTempDirectory(prefix, suffix);
|
||||
}
|
||||
@NotNull
|
||||
public static File createTempDirectory(@NotNull @NonNls String prefix, @Nullable @NonNls String suffix, boolean deleteOnExit) throws IOException {
|
||||
return FileUtilRt.createTempDirectory(prefix, suffix, deleteOnExit);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static File createTempDirectory(File dir, @NotNull @NonNls String prefix, @Nullable @NonNls String suffix) throws IOException {
|
||||
public static File createTempDirectory(@NotNull File dir, @NotNull @NonNls String prefix, @Nullable @NonNls String suffix) throws IOException {
|
||||
return FileUtilRt.createTempDirectory(dir, prefix, suffix);
|
||||
}
|
||||
@NotNull
|
||||
public static File createTempDirectory(File dir, @NotNull @NonNls String prefix, @Nullable @NonNls String suffix, boolean deleteOnExit) throws IOException {
|
||||
return FileUtilRt.createTempDirectory(dir, prefix, suffix,deleteOnExit);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static File createTempFile(@NonNls File dir, @NotNull @NonNls String prefix, @Nullable @NonNls String suffix, boolean create) throws IOException {
|
||||
|
||||
@@ -36,7 +36,7 @@ public class FileUtilFindFileTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
myTempFile = FileUtil.createTempDirectory("tEF", ""); //NON-NLS
|
||||
myTempFile = FileUtil.createTempDirectory("tEF", "",false); //NON-NLS
|
||||
myFirstFile = new File(myTempFile, "first");
|
||||
mySecondFile = new File(myTempFile, "second"); //NON-NLS
|
||||
assertTrue(myFirstFile.createNewFile());
|
||||
|
||||
@@ -180,7 +180,7 @@ public class GroovyPostHighlightingPass extends TextEditorHighlightingPass {
|
||||
!isOverriddenOrOverrides(method)) &&
|
||||
!method.hasModifierProperty(PsiModifier.NATIVE) &&
|
||||
!HighlightMethodUtil.isSerializationRelatedMethod(method, method.getContainingClass()) &&
|
||||
!PsiClassImplUtil.isMainMethod(method)) {
|
||||
!PsiClassImplUtil.isMainOrPremainMethod(method)) {
|
||||
HighlightInfo highlightInfo = PostHighlightingPass
|
||||
.createUnusedSymbolInfo(parameter.getNameIdentifierGroovy(), "Parameter " + parameter.getName() + " is unused",
|
||||
HighlightInfoType.UNUSED_SYMBOL);
|
||||
|
||||
@@ -20,13 +20,14 @@ import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.RecursionManager;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiClassImplUtil;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.scope.NameHint;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -294,6 +295,7 @@ public class GrClassImplUtil {
|
||||
final PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getProject());
|
||||
|
||||
LanguageLevel level = PsiUtil.getLanguageLevel(place);
|
||||
if (classHint == null || classHint.shouldProcess(ClassHint.ResolveKind.PROPERTY)) {
|
||||
Map<String, CandidateInfo> fieldsMap = CollectClassMembersUtil.getAllFields(grType);
|
||||
if (name != null) {
|
||||
@@ -301,8 +303,9 @@ public class GrClassImplUtil {
|
||||
if (fieldInfo != null) {
|
||||
final PsiField field = (PsiField)fieldInfo.getElement();
|
||||
if (!isSameDeclaration(place, field)) { //the same variable declaration
|
||||
final PsiSubstitutor finalSubstitutor = PsiClassImplUtil
|
||||
.obtainFinalSubstitutor(field.getContainingClass(), fieldInfo.getSubstitutor(), grType, substitutor, place, factory);
|
||||
final PsiSubstitutor finalSubstitutor =
|
||||
PsiClassImplUtil.obtainFinalSubstitutor(field.getContainingClass(), fieldInfo.getSubstitutor(), grType, substitutor, factory,
|
||||
level);
|
||||
if (!processor.execute(field, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
|
||||
}
|
||||
}
|
||||
@@ -311,8 +314,9 @@ public class GrClassImplUtil {
|
||||
for (CandidateInfo info : fieldsMap.values()) {
|
||||
final PsiField field = (PsiField)info.getElement();
|
||||
if (!isSameDeclaration(place, field)) { //the same variable declaration
|
||||
final PsiSubstitutor finalSubstitutor = PsiClassImplUtil
|
||||
.obtainFinalSubstitutor(field.getContainingClass(), info.getSubstitutor(), grType, substitutor, place, factory);
|
||||
final PsiSubstitutor finalSubstitutor =
|
||||
PsiClassImplUtil.obtainFinalSubstitutor(field.getContainingClass(), info.getSubstitutor(), grType, substitutor, factory,
|
||||
level);
|
||||
if (!processor.execute(field, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
|
||||
}
|
||||
}
|
||||
@@ -327,8 +331,9 @@ public class GrClassImplUtil {
|
||||
for (CandidateInfo info : list) {
|
||||
PsiMethod method = (PsiMethod)info.getElement();
|
||||
if (!isSameDeclaration(place, method) && isMethodVisible(isPlaceGroovy, method)) {
|
||||
final PsiSubstitutor finalSubstitutor = PsiClassImplUtil
|
||||
.obtainFinalSubstitutor(method.getContainingClass(), info.getSubstitutor(), grType, substitutor, place, factory);
|
||||
final PsiSubstitutor finalSubstitutor =
|
||||
PsiClassImplUtil.obtainFinalSubstitutor(method.getContainingClass(), info.getSubstitutor(), grType, substitutor, factory,
|
||||
level);
|
||||
if (!processor.execute(method, state.put(PsiSubstitutor.KEY, finalSubstitutor))) {
|
||||
return false;
|
||||
}
|
||||
@@ -342,8 +347,9 @@ public class GrClassImplUtil {
|
||||
for (CandidateInfo info : byName) {
|
||||
PsiMethod method = (PsiMethod)info.getElement();
|
||||
if (!isSameDeclaration(place, method) && isMethodVisible(isPlaceGroovy, method)) {
|
||||
final PsiSubstitutor finalSubstitutor = PsiClassImplUtil
|
||||
.obtainFinalSubstitutor(method.getContainingClass(), info.getSubstitutor(), grType, substitutor, place, factory);
|
||||
final PsiSubstitutor finalSubstitutor =
|
||||
PsiClassImplUtil.obtainFinalSubstitutor(method.getContainingClass(), info.getSubstitutor(), grType, substitutor, factory,
|
||||
level);
|
||||
if (!processor.execute(method, state.put(PsiSubstitutor.KEY, finalSubstitutor))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,6 @@ public class GroovyCopyClassTest extends LightCodeInsightFixtureTestCase {
|
||||
def psiFile = myFixture.psiManager.findFile(file)
|
||||
//would be copied as file
|
||||
assertFalse(CopyClassesHandler.canCopyClass(myFixture.javaFacade.findClass("foo.$testName", GlobalSearchScope.allScope(project))));
|
||||
assertTrue(CopyClassesHandler.canCopyClass(psiFile));
|
||||
assertFalse(CopyClassesHandler.canCopyClass(psiFile));
|
||||
}
|
||||
}
|
||||
|
||||