Merge branch 'master' of git@git.labs.intellij.net:idea/community

This commit is contained in:
Kirill Kalishev
2011-03-29 15:30:17 +04:00
48 changed files with 1064 additions and 331 deletions
@@ -234,6 +234,7 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
presentation.setItemTextBold(getAttribute(HIGHLIGHTED_ATTR) != null);
MemberLookupHelper helper = myHelper != null ? myHelper : new MemberLookupHelper(myMethod, myContainingClass, false, false);
helper.renderElement(presentation, getAttribute(FORCE_QUALIFY) != null, getSubstitutor());
final Boolean qualify = getAttribute(FORCE_QUALIFY) != null ? Boolean.TRUE : myHelper == null ? Boolean.FALSE : null;
helper.renderElement(presentation, qualify, getSubstitutor());
}
}
@@ -45,18 +45,18 @@ public class MemberLookupHelper {
return myShouldImport;
}
public void renderElement(LookupElementPresentation presentation, boolean forceQualify, PsiSubstitutor substitutor) {
public void renderElement(LookupElementPresentation presentation, @Nullable Boolean qualify, PsiSubstitutor substitutor) {
final String className = myContainingClass == null ? "???" : myContainingClass.getName();
final String memberName = myMember.getName();
if (!myShouldImport && StringUtil.isNotEmpty(className) || forceQualify) {
if (!Boolean.FALSE.equals(qualify) && (!myShouldImport && StringUtil.isNotEmpty(className) || Boolean.TRUE.equals(qualify))) {
presentation.setItemText(className + "." + memberName);
} else {
presentation.setItemText(memberName);
}
final String qname = myContainingClass == null ? "" : myContainingClass.getQualifiedName();
String pkg = StringUtil.getPackageName(qname);
String pkg = qname == null ? "" : StringUtil.getPackageName(qname);
String location = StringUtil.isEmpty(pkg) ? "" : " (" + pkg + ")";
final String params = myMergedOverloads
@@ -57,7 +57,6 @@ import java.util.*;
*/
public class PsiClassImplUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiClassImplUtil");
private static final Key<Boolean> NAME_MAPS_BUILT_FLAG = Key.create("NAME_MAPS_BUILT_FLAG");
private static final Key<CachedValue<Map>> MAP_IN_CLASS_KEY = Key.create("MAP_KEY");
@@ -102,35 +101,6 @@ public class PsiClassImplUtil {
final PsiMethod patternMethod,
final boolean checkBases,
final boolean stopOnFirst) {
/* final MethodSignature patternSignature = MethodSignatureBackedByPsiMethod.create(patternMethod, PsiSubstitutor.EMPTY);
if (!checkBases) {
final PsiMethod[] methodsByName = aClass.findMethodsByName(patternMethod.getName(), false);
if (methodsByName.length == 0) return PsiMethod.EMPTY_ARRAY;
List<PsiMethod> result = new ArrayList<PsiMethod>();
for (PsiMethod method : methodsByName) {
final MethodSignature otherSignature = method.getSignature(PsiSubstitutor.EMPTY);
if (otherSignature.equals(patternSignature)) {
result.add(method);
if (stopOnFirst) break;
}
}
return result.toArray(new PsiMethod[result.size()]);
}
else {
final Set<HierarchicalMethodSignature> signatures = getOverrideEquivalentSignatures(aClass);
final HierarchicalMethodSignature signatureWithSupers = signatures.get(patternSignature);
if (signatureWithSupers == null) return PsiMethod.EMPTY_ARRAY;
final List<PsiMethod> result = new ArrayList<PsiMethod>();
MethodSignatureUtil.processMethodHierarchy(signatureWithSupers, new Processor<HierarchicalMethodSignature>() {
public boolean process(final HierarchicalMethodSignature sig) {
result.add(sig.getSignature().getMethod());
return !stopOnFirst;
}
});
return result.toArray(new PsiMethod[result.size()]);
}*/
final PsiMethod[] methodsByName = aClass.findMethodsByName(patternMethod.getName(), checkBases);
if (methodsByName.length == 0) return Collections.emptyList();
final List<PsiMethod> methods = new SmartList<PsiMethod>();
@@ -238,14 +208,12 @@ public class PsiClassImplUtil {
}
}
};
PsiElementFactory factory = JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory();
processDeclarationsInClassNotCached(psiClass, processor, ResolveState.initial(), new THashSet<PsiClass>(), null, psiClass, false, factory);
processDeclarationsInClassNotCached(psiClass, processor, ResolveState.initial(), new THashSet<PsiClass>(), null, psiClass, false);
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));
psiClass.putUserData(NAME_MAPS_BUILT_FLAG, Boolean.TRUE);
return result;
}
@@ -275,6 +243,12 @@ public class PsiClassImplUtil {
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);
}
@@ -308,7 +282,7 @@ public class PsiClassImplUtil {
}
}
private static final Function<ClassIconRequest, Icon> FULL_ICON_EVALUATOR = new Function<ClassIconRequest, Icon>() {
private static final Function<ClassIconRequest, Icon> FULL_ICON_EVALUATOR = new NullableFunction<ClassIconRequest, Icon>() {
public Icon fun(ClassIconRequest r) {
if (!r.psiClass.isValid() || r.psiClass.getProject().isDisposed()) return null;
@@ -406,112 +380,140 @@ public class PsiClassImplUtil {
PsiElement last,
PsiElement place,
boolean isRaw) {
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);
if (last instanceof PsiTypeParameterList || last instanceof PsiModifierList) return true; //TypeParameterList and ModifierList do not see our declarations
final Boolean built = aClass.getUserData(NAME_MAPS_BUILT_FLAG);
PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();
if (built == null) {
return processDeclarationsInClassNotCached(aClass, processor, state, visited, last, place, isRaw, factory);
}
final NameHint nameHint = processor.getHint(NameHint.KEY);
CachedValue<Map> cache = aClass.getUserData(MAP_IN_CLASS_KEY);
if (cache != null && cache.hasUpToDateValue()) {
final NameHint nameHint = processor.getHint(NameHint.KEY);
if (nameHint != null) {
return processCachedMembersByName(aClass, processor, state, visited, last, place, isRaw, substitutor, cache, nameHint);
}
}
return processDeclarationsInClassNotCached(aClass, processor, state, visited, last, place, isRaw);
}
private static boolean processCachedMembersByName(PsiClass aClass,
PsiScopeProcessor processor,
ResolveState state,
Set<PsiClass> visited,
PsiElement last,
PsiElement place,
boolean isRaw,
PsiSubstitutor substitutor,
CachedValue<Map> cache, NameHint nameHint) {
final ElementClassHint classHint = processor.getHint(ElementClassHint.KEY);
if (nameHint != null) {
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.FIELD)) {
final PsiField fieldByName = aClass.findFieldByName(nameHint.getName(state), 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 = getMap(aClass, PsiField.class);
PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();
final List<Pair<PsiField, PsiSubstitutor>> list = allFieldsMap.get(nameHint.getName(state));
if (list != null) {
for (final Pair<PsiField, PsiSubstitutor> candidate : list) {
PsiField candidateField = candidate.getFirst();
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(candidateField.getContainingClass(), candidate.getSecond(), aClass,
substitutor, place, factory);
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.FIELD)) {
final PsiField fieldByName = aClass.findFieldByName(nameHint.getName(state), 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);
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, candidateField.getContainingClass());
if (!processor.execute(candidateField, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
}
final List<Pair<PsiField, PsiSubstitutor>> list = allFieldsMap.get(nameHint.getName(state));
if (list != null) {
for (final Pair<PsiField, PsiSubstitutor> candidate : list) {
PsiField candidateField = candidate.getFirst();
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(candidateField.getContainingClass(), candidate.getSecond(), aClass,
substitutor, place, factory);
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, candidateField.getContainingClass());
if (!processor.execute(candidateField, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
}
}
}
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) {
if (last != null && last.getParent() == aClass) {
if (last instanceof PsiClass) {
if (!processor.execute(last, state)) return false;
}
// Parameters
final PsiTypeParameterList list = aClass.getTypeParameterList();
if (list != null && !list.processDeclarations(processor, state, last, place)) return false;
}
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) {
if (last != null && last.getParent() == aClass) {
if (last instanceof PsiClass) {
if (!processor.execute(last, state)) return false;
}
if (!(last instanceof PsiReferenceList)) {
final PsiClass classByName = aClass.findInnerClassByName(nameHint.getName(state), 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 = getMap(aClass, PsiClass.class);
// Parameters
final PsiTypeParameterList list = aClass.getTypeParameterList();
if (list != null && !list.processDeclarations(processor, state, last, place)) return false;
}
if (!(last instanceof PsiReferenceList)) {
final PsiClass classByName = aClass.findInnerClassByName(nameHint.getName(state), 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);
final List<Pair<PsiClass, PsiSubstitutor>> list = allClassesMap.get(nameHint.getName(state));
if (list != null) {
for (final Pair<PsiClass, PsiSubstitutor> candidate : list) {
final PsiClass inner = candidate.getFirst();
final PsiClass containingClass = inner.getContainingClass();
if (containingClass != null) {
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
substitutor, place, factory);
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
if (!processor.execute(inner, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
}
final List<Pair<PsiClass, PsiSubstitutor>> list = allClassesMap.get(nameHint.getName(state));
if (list != null) {
for (final Pair<PsiClass, PsiSubstitutor> candidate : list) {
final PsiClass inner = candidate.getFirst();
final PsiClass containingClass = inner.getContainingClass();
if (containingClass != null) {
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
substitutor, place, factory);
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
if (!processor.execute(inner, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
}
}
}
}
}
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.METHOD)) {
if (processor instanceof MethodResolverProcessor) {
final MethodResolverProcessor methodResolverProcessor = (MethodResolverProcessor)processor;
if (methodResolverProcessor.isConstructor()) {
final PsiMethod[] constructors = aClass.getConstructors();
methodResolverProcessor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
for (PsiMethod constructor : constructors) {
if (!methodResolverProcessor.execute(constructor, state)) return false;
}
return true;
}
}
final Map<String, List<Pair<PsiMethod, PsiSubstitutor>>> allMethodsMap = getMap(aClass, PsiMethod.class);
final List<Pair<PsiMethod, PsiSubstitutor>> list = allMethodsMap.get(nameHint.getName(state));
if (list != null) {
for (final Pair<PsiMethod, PsiSubstitutor> candidate : list) {
PsiMethod candidateMethod = candidate.getFirst();
if (processor instanceof MethodResolverProcessor) {
if (candidateMethod.isConstructor() != ((MethodResolverProcessor)processor).isConstructor()) continue;
}
final PsiClass containingClass = candidateMethod.getContainingClass();
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
substitutor, place, factory);
if (isRaw && !candidateMethod.hasModifierProperty(PsiModifier.STATIC)) { //static methods are not erased due to raw overriding
PsiTypeParameter[] methodTypeParameters = candidateMethod.getTypeParameters();
finalSubstitutor = factory.createRawSubstitutor(finalSubstitutor, methodTypeParameters);
}
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
if (!processor.execute(candidateMethod, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
}
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.METHOD)) {
if (processor instanceof MethodResolverProcessor) {
final MethodResolverProcessor methodResolverProcessor = (MethodResolverProcessor)processor;
if (methodResolverProcessor.isConstructor()) {
final PsiMethod[] constructors = aClass.getConstructors();
methodResolverProcessor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
for (PsiMethod constructor : constructors) {
if (!methodResolverProcessor.execute(constructor, state)) return false;
}
return true;
}
}
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));
if (list != null) {
for (final Pair<PsiMethod, PsiSubstitutor> candidate : list) {
PsiMethod candidateMethod = candidate.getFirst();
if (processor instanceof MethodResolverProcessor) {
if (candidateMethod.isConstructor() != ((MethodResolverProcessor)processor).isConstructor()) continue;
}
final PsiClass containingClass = candidateMethod.getContainingClass();
if (visited != null && visited.contains(candidateMethod.getContainingClass())) {
continue;
}
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
substitutor, place, factory);
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) {
visited.add(aList.getFirst().getContainingClass());
}
}
}
}
return true;
}
return processDeclarationsInClassNotCached(aClass, processor, state, visited, last, place, isRaw, factory);
private static PsiSubstitutor checkRaw(boolean isRaw, PsiElementFactory factory, PsiMethod candidateMethod, 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);
}
return substitutor;
}
public static PsiSubstitutor obtainFinalSubstitutor(@NotNull PsiClass candidateClass, PsiSubstitutor candidateSubstitutor, PsiClass aClass,
@@ -531,8 +533,7 @@ public class PsiClassImplUtil {
private static boolean processDeclarationsInClassNotCached(PsiClass aClass, PsiScopeProcessor processor, ResolveState state, Set<PsiClass> visited,
PsiElement last,
PsiElement place,
boolean isRaw,
PsiElementFactory factory) {
boolean isRaw) {
if (visited == null) visited = new THashSet<PsiClass>();
if (!visited.add(aClass)) return true;
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
@@ -555,15 +556,15 @@ public class PsiClassImplUtil {
}
}
PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.METHOD)) {
PsiSubstitutor baseSubstitutor = state.get(PsiSubstitutor.KEY);
final PsiMethod[] methods = nameHint != null ? aClass.findMethodsByName(nameHint.getName(state), false) : aClass.getMethods();
for (final PsiMethod method : methods) {
if (isRaw && !method.hasModifierProperty(PsiModifier.STATIC)) { //static methods are not erased due to raw overriding
PsiTypeParameter[] methodTypeParameters = method.getTypeParameters();
PsiSubstitutor raw = factory.createRawSubstitutor(state.get(PsiSubstitutor.KEY), methodTypeParameters);
state = state.put(PsiSubstitutor.KEY, raw);
}
if (!processor.execute(method, state)) return false;
PsiSubstitutor finalSubstitutor = checkRaw(isRaw, factory, method, baseSubstitutor);
ResolveState methodState = finalSubstitutor == baseSubstitutor ? state : state.put(PsiSubstitutor.KEY, finalSubstitutor);
if (!processor.execute(method, methodState)) return false;
}
}