MembersCache made lazy

This commit is contained in:
Andrey Breslav
2013-04-22 20:07:27 +04:00
parent 2d50810a02
commit 7b602d4dd7
@@ -16,7 +16,9 @@
package org.jetbrains.jet.lang.resolve.java.provider; package org.jetbrains.jet.lang.resolve.java.provider;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.intellij.psi.*; import com.intellij.psi.*;
import com.intellij.psi.util.PsiFormatUtil; import com.intellij.psi.util.PsiFormatUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -38,15 +40,19 @@ import static com.intellij.psi.util.PsiFormatUtilBase.*;
public final class MembersCache { public final class MembersCache {
private static final ImmutableSet<String> OBJECT_METHODS = ImmutableSet.of("hashCode()", "equals(java.lang.Object)", "toString()"); private static final ImmutableSet<String> OBJECT_METHODS = ImmutableSet.of("hashCode()", "equals(java.lang.Object)", "toString()");
private final Multimap<Name, Runnable> memberProcessingTasks = HashMultimap.create();
private final Map<Name, NamedMembers> namedMembersMap = new HashMap<Name, NamedMembers>(); private final Map<Name, NamedMembers> namedMembersMap = new HashMap<Name, NamedMembers>();
@Nullable @Nullable
public NamedMembers get(@NotNull Name name) { public NamedMembers get(@NotNull Name name) {
runTasksByName(name);
return namedMembersMap.get(name); return namedMembersMap.get(name);
} }
@NotNull @NotNull
public Collection<NamedMembers> allMembers() { public Collection<NamedMembers> allMembers() {
runAllTasks();
memberProcessingTasks.clear();
return namedMembersMap.values(); return namedMembersMap.values();
} }
@@ -60,6 +66,33 @@ public final class MembersCache {
return r; return r;
} }
private void addTask(@NotNull PsiMember member, @NotNull RunOnce task) {
addTask(member.getName(), task);
}
private void addTask(@Nullable String name, @NotNull RunOnce task) {
if (name == null) {
return;
}
memberProcessingTasks.put(Name.identifier(name), task);
}
private void runTasksByName(Name name) {
if (!memberProcessingTasks.containsKey(name)) return;
Collection<Runnable> tasks = memberProcessingTasks.get(name);
for (Runnable task : tasks) {
task.run();
}
// Delete tasks
tasks.clear();
}
private void runAllTasks() {
for (Runnable task : memberProcessingTasks.values()) {
task.run();
}
}
@NotNull @NotNull
public static MembersCache buildMembersByNameCache( public static MembersCache buildMembersByNameCache(
@NotNull MembersCache membersCache, @NotNull MembersCache membersCache,
@@ -139,8 +172,13 @@ public final class MembersCache {
if (kotlin && !psiClass.getPsiClass().isEnum()) { if (kotlin && !psiClass.getPsiClass().isEnum()) {
return; return;
} }
for (PsiField field : psiClass.getPsiClass().getAllFields()) { for (final PsiField field : psiClass.getPsiClass().getAllFields()) {
processField(field); addTask(field, new RunOnce() {
@Override
public void doRun() {
processField(field);
}
});
} }
} }
@@ -150,14 +188,30 @@ public final class MembersCache {
} }
private void processOwnMethods() { private void processOwnMethods() {
for (PsiMethod ownMethod : psiClass.getPsiClass().getMethods()) { for (final PsiMethod method : psiClass.getPsiClass().getMethods()) {
processOwnMethod(ownMethod); RunOnce task = new RunOnce() {
@Override
public void doRun() {
processOwnMethod(method);
}
};
addTask(method, task);
PropertyParseResult propertyParseResult = PropertyNameUtils.parseMethodToProperty(method.getName());
if (propertyParseResult != null) {
addTask(propertyParseResult.getPropertyName(), task);
}
} }
} }
private void parseAllMethodsAsProperties() { private void parseAllMethodsAsProperties() {
for (PsiMethod method : psiClass.getPsiClass().getAllMethods()) { for (PsiMethod method : psiClass.getPsiClass().getAllMethods()) {
parseMethodAsProperty(method); createEmptyEntry(Name.identifier(method.getName()));
PropertyParseResult propertyParseResult = PropertyNameUtils.parseMethodToProperty(method.getName());
if (propertyParseResult != null) {
createEmptyEntry(Name.identifier(propertyParseResult.getPropertyName()));
}
} }
} }
@@ -165,8 +219,13 @@ public final class MembersCache {
if (!staticMembers) { if (!staticMembers) {
return; return;
} }
for (PsiClass nested : psiClass.getPsiClass().getInnerClasses()) { for (final PsiClass nested : psiClass.getPsiClass().getInnerClasses()) {
processNestedClass(nested); addTask(nested, new RunOnce() {
@Override
public void doRun() {
processNestedClass(nested);
}
});
} }
} }
@@ -309,15 +368,6 @@ public final class MembersCache {
} }
} }
private void parseMethodAsProperty(PsiMethod method) {
createEmptyEntry(Name.identifier(method.getName()));
PropertyParseResult propertyParseResult = PropertyNameUtils.parseMethodToProperty(method.getName());
if (propertyParseResult != null) {
createEmptyEntry(Name.identifier(propertyParseResult.getPropertyName()));
}
}
private void createEmptyEntry(@NotNull Name identifier) { private void createEmptyEntry(@NotNull Name identifier) {
getOrCreateEmpty(identifier); getOrCreateEmpty(identifier);
} }
@@ -371,4 +421,16 @@ public final class MembersCache {
return foundAbstractMethods == 1; return foundAbstractMethods == 1;
} }
private static abstract class RunOnce implements Runnable {
private boolean hasRun = false;
@Override
public final void run() {
if (hasRun) return;
hasRun = true;
doRun();
}
protected abstract void doRun();
}
} }