From 7b602d4dd7cd3167b39b471b3148383b93f57fb2 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 22 Apr 2013 20:07:27 +0400 Subject: [PATCH] MembersCache made lazy --- .../resolve/java/provider/MembersCache.java | 94 +++++++++++++++---- 1 file changed, 78 insertions(+), 16 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java index b306dbd6dc7..2eafd5b1130 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java @@ -16,7 +16,9 @@ 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.Multimap; import com.intellij.psi.*; import com.intellij.psi.util.PsiFormatUtil; import org.jetbrains.annotations.NotNull; @@ -38,15 +40,19 @@ import static com.intellij.psi.util.PsiFormatUtilBase.*; public final class MembersCache { private static final ImmutableSet OBJECT_METHODS = ImmutableSet.of("hashCode()", "equals(java.lang.Object)", "toString()"); + private final Multimap memberProcessingTasks = HashMultimap.create(); private final Map namedMembersMap = new HashMap(); @Nullable public NamedMembers get(@NotNull Name name) { + runTasksByName(name); return namedMembersMap.get(name); } @NotNull public Collection allMembers() { + runAllTasks(); + memberProcessingTasks.clear(); return namedMembersMap.values(); } @@ -60,6 +66,33 @@ public final class MembersCache { 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 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 public static MembersCache buildMembersByNameCache( @NotNull MembersCache membersCache, @@ -139,8 +172,13 @@ public final class MembersCache { if (kotlin && !psiClass.getPsiClass().isEnum()) { return; } - for (PsiField field : psiClass.getPsiClass().getAllFields()) { - processField(field); + for (final PsiField field : psiClass.getPsiClass().getAllFields()) { + addTask(field, new RunOnce() { + @Override + public void doRun() { + processField(field); + } + }); } } @@ -150,14 +188,30 @@ public final class MembersCache { } private void processOwnMethods() { - for (PsiMethod ownMethod : psiClass.getPsiClass().getMethods()) { - processOwnMethod(ownMethod); + for (final PsiMethod method : psiClass.getPsiClass().getMethods()) { + 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() { 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) { return; } - for (PsiClass nested : psiClass.getPsiClass().getInnerClasses()) { - processNestedClass(nested); + for (final PsiClass nested : psiClass.getPsiClass().getInnerClasses()) { + 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) { getOrCreateEmpty(identifier); } @@ -371,4 +421,16 @@ public final class MembersCache { 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(); + } }