From 7c1e28a7489b10cb3abfe3a434ab6d5a62642e53 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 30 Jan 2014 18:13:40 +0400 Subject: [PATCH] Override/Implement methods: Use lazy analysis --- .../jet/lang/resolve/OverrideResolver.java | 21 ++++++++++++++++--- .../codeInsight/ImplementMethodsHandler.java | 4 ++-- .../OverrideImplementMethodsHandler.java | 10 ++++----- .../codeInsight/OverrideMethodsHandler.java | 14 +++++++++---- .../AbstractOverrideImplementTest.java | 11 +++++----- 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java index 16b648aea28..ddf968db1d1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java @@ -21,10 +21,12 @@ import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiElement; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.LinkedMultiMap; import com.intellij.util.containers.MultiMap; +import kotlin.KotlinPackage; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -265,12 +267,25 @@ public class OverrideResolver { } } - public static void collectMissingImplementations(MutableClassDescriptor classDescriptor, Set abstractNoImpl, Set manyImpl) { + public static void collectMissingImplementations( + MutableClassDescriptor classDescriptor, Set abstractNoImpl, Set manyImpl + ) { for (CallableMemberDescriptor descriptor : classDescriptor.getAllCallableMembers()) { collectMissingImplementations(descriptor, abstractNoImpl, manyImpl); } } + public static void collectMissingImplementations( + ClassDescriptor classDescriptor, Set abstractNoImpl, Set manyImpl + ) { + Iterator callableMembers = KotlinPackage.filterIsInstance( + classDescriptor.getDefaultType().getMemberScope().getAllDescriptors().iterator(), CallableMemberDescriptor.class + ); + while (callableMembers.hasNext()) { + collectMissingImplementations(callableMembers.next(), abstractNoImpl, manyImpl); + } + } + private static void collectMissingImplementations( @NotNull CallableMemberDescriptor descriptor, @NotNull Set abstractNoImpl, @@ -408,9 +423,9 @@ public class OverrideResolver { return overriddenDeclarationsByDirectParent; } - public static Multimap collectSuperMethods(MutableClassDescriptor classDescriptor) { + public static Multimap collectSuperMethods(ClassDescriptor classDescriptor) { Set inheritedFunctions = Sets.newLinkedHashSet(); - for (JetType supertype : classDescriptor.getSupertypes()) { + for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) { for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) { if (descriptor instanceof CallableMemberDescriptor) { CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor) descriptor; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ImplementMethodsHandler.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/ImplementMethodsHandler.java index f18d19b15b5..42c7b360a41 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ImplementMethodsHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/ImplementMethodsHandler.java @@ -23,7 +23,7 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; -import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.resolve.OverrideResolver; import org.jetbrains.jet.plugin.JetBundle; @@ -32,7 +32,7 @@ import java.util.Set; public class ImplementMethodsHandler extends OverrideImplementMethodsHandler implements IntentionAction { @Override - protected Set collectMethodsToGenerate(MutableClassDescriptor descriptor) { + protected Set collectMethodsToGenerate(ClassDescriptor descriptor) { Set missingImplementations = Sets.newLinkedHashSet(); OverrideResolver.collectMissingImplementations(descriptor, missingImplementations, missingImplementations); return missingImplementations; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/OverrideImplementMethodsHandler.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/OverrideImplementMethodsHandler.java index e47d92db512..7d7bc4bf4d1 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/OverrideImplementMethodsHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/OverrideImplementMethodsHandler.java @@ -206,13 +206,13 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns @NotNull public Set collectMethodsToGenerate(@NotNull JetClassOrObject classOrObject, BindingContext bindingContext) { DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, classOrObject); - if (descriptor instanceof MutableClassDescriptor) { - return collectMethodsToGenerate((MutableClassDescriptor) descriptor); + if (descriptor instanceof ClassDescriptor) { + return collectMethodsToGenerate((ClassDescriptor) descriptor); } return Collections.emptySet(); } - protected abstract Set collectMethodsToGenerate(MutableClassDescriptor descriptor); + protected abstract Set collectMethodsToGenerate(ClassDescriptor descriptor); private MemberChooser showOverrideImplementChooser( Project project, @@ -245,9 +245,7 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns assert classOrObject != null : "ClassObject should be checked in isValidFor method"; - BindingContext bindingContext = - AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) classOrObject.getContainingFile()) - .getBindingContext(); + BindingContext bindingContext = AnalyzerFacadeWithCache.getContextForElement(classOrObject); Set missingImplementations = collectMethodsToGenerate(classOrObject, bindingContext); if (missingImplementations.isEmpty() && !implementAll) { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/OverrideMethodsHandler.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/OverrideMethodsHandler.java index d8151e55cc3..f94c5846523 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/OverrideMethodsHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/OverrideMethodsHandler.java @@ -17,7 +17,8 @@ package org.jetbrains.jet.plugin.codeInsight; import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; -import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.resolve.OverrideResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil; @@ -26,10 +27,15 @@ import java.util.Set; public class OverrideMethodsHandler extends OverrideImplementMethodsHandler { @Override - protected Set collectMethodsToGenerate(MutableClassDescriptor descriptor) { + protected Set collectMethodsToGenerate(ClassDescriptor descriptor) { Set superMethods = OverrideResolver.collectSuperMethods(descriptor).keySet(); - for (CallableMemberDescriptor member : descriptor.getDeclaredCallableMembers()) { - superMethods.removeAll(member.getOverriddenDescriptors()); + for (DeclarationDescriptor member : descriptor.getDefaultType().getMemberScope().getAllDescriptors()) { + if (member instanceof CallableMemberDescriptor) { + CallableMemberDescriptor callable = (CallableMemberDescriptor) member; + if (callable.getKind().isReal()) { + superMethods.removeAll(callable.getOverriddenDescriptors()); + } + } } Set result = new HashSet(); for (CallableMemberDescriptor superMethod : superMethods) { diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/AbstractOverrideImplementTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/AbstractOverrideImplementTest.java index 06064b6e2a6..2c023c75be8 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/AbstractOverrideImplementTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/AbstractOverrideImplementTest.java @@ -38,6 +38,7 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.plugin.JetLightProjectDescriptor; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; +import org.jetbrains.jet.plugin.project.ResolveSessionForBodies; import java.util.ArrayList; import java.util.Collections; @@ -121,8 +122,9 @@ public abstract class AbstractOverrideImplementTest extends LightCodeInsightFixt assertNotNull("Caret should be inside class or object", classOrObject); final JetFile jetFile = (JetFile) classOrObject.getContainingFile(); - final BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); - Set descriptors = handler.collectMethodsToGenerate(classOrObject, bindingContext); + final ResolveSessionForBodies resolveSession = AnalyzerFacadeWithCache.getLazyResolveSessionForFile(jetFile); + Set descriptors = + handler.collectMethodsToGenerate(classOrObject, resolveSession.resolveToElement(classOrObject)); final CallableMemberDescriptor singleToOverride; if (memberToOverride == null) { @@ -151,7 +153,7 @@ public abstract class AbstractOverrideImplementTest extends LightCodeInsightFixt OverrideImplementMethodsHandler.generateMethods( myFixture.getEditor(), classOrObject, OverrideImplementMethodsHandler - .membersFromDescriptors(jetFile, Collections.singletonList(singleToOverride), bindingContext)); + .membersFromDescriptors(jetFile, Collections.singletonList(singleToOverride), resolveSession.getBindingContext())); } }.execute(); } @@ -162,8 +164,7 @@ public abstract class AbstractOverrideImplementTest extends LightCodeInsightFixt assertNotNull("Caret should be inside class or object", classOrObject); final JetFile jetFile = (JetFile) classOrObject.getContainingFile(); - final BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile) - .getBindingContext(); + final BindingContext bindingContext = AnalyzerFacadeWithCache.getContextForElement(classOrObject); Set descriptors = handler.collectMethodsToGenerate(classOrObject, bindingContext); final ArrayList descriptorsList = new ArrayList(descriptors);