Override/Implement methods: Use lazy analysis
This commit is contained in:
@@ -21,10 +21,12 @@ import com.google.common.collect.Maps;
|
|||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
|
import com.intellij.openapi.util.Condition;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.util.containers.ContainerUtil;
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
import com.intellij.util.containers.LinkedMultiMap;
|
import com.intellij.util.containers.LinkedMultiMap;
|
||||||
import com.intellij.util.containers.MultiMap;
|
import com.intellij.util.containers.MultiMap;
|
||||||
|
import kotlin.KotlinPackage;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
@@ -265,12 +267,25 @@ public class OverrideResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void collectMissingImplementations(MutableClassDescriptor classDescriptor, Set<CallableMemberDescriptor> abstractNoImpl, Set<CallableMemberDescriptor> manyImpl) {
|
public static void collectMissingImplementations(
|
||||||
|
MutableClassDescriptor classDescriptor, Set<CallableMemberDescriptor> abstractNoImpl, Set<CallableMemberDescriptor> manyImpl
|
||||||
|
) {
|
||||||
for (CallableMemberDescriptor descriptor : classDescriptor.getAllCallableMembers()) {
|
for (CallableMemberDescriptor descriptor : classDescriptor.getAllCallableMembers()) {
|
||||||
collectMissingImplementations(descriptor, abstractNoImpl, manyImpl);
|
collectMissingImplementations(descriptor, abstractNoImpl, manyImpl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void collectMissingImplementations(
|
||||||
|
ClassDescriptor classDescriptor, Set<CallableMemberDescriptor> abstractNoImpl, Set<CallableMemberDescriptor> manyImpl
|
||||||
|
) {
|
||||||
|
Iterator<CallableMemberDescriptor> callableMembers = KotlinPackage.filterIsInstance(
|
||||||
|
classDescriptor.getDefaultType().getMemberScope().getAllDescriptors().iterator(), CallableMemberDescriptor.class
|
||||||
|
);
|
||||||
|
while (callableMembers.hasNext()) {
|
||||||
|
collectMissingImplementations(callableMembers.next(), abstractNoImpl, manyImpl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void collectMissingImplementations(
|
private static void collectMissingImplementations(
|
||||||
@NotNull CallableMemberDescriptor descriptor,
|
@NotNull CallableMemberDescriptor descriptor,
|
||||||
@NotNull Set<CallableMemberDescriptor> abstractNoImpl,
|
@NotNull Set<CallableMemberDescriptor> abstractNoImpl,
|
||||||
@@ -408,9 +423,9 @@ public class OverrideResolver {
|
|||||||
return overriddenDeclarationsByDirectParent;
|
return overriddenDeclarationsByDirectParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Multimap<CallableMemberDescriptor, CallableMemberDescriptor> collectSuperMethods(MutableClassDescriptor classDescriptor) {
|
public static Multimap<CallableMemberDescriptor, CallableMemberDescriptor> collectSuperMethods(ClassDescriptor classDescriptor) {
|
||||||
Set<CallableMemberDescriptor> inheritedFunctions = Sets.newLinkedHashSet();
|
Set<CallableMemberDescriptor> inheritedFunctions = Sets.newLinkedHashSet();
|
||||||
for (JetType supertype : classDescriptor.getSupertypes()) {
|
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
|
||||||
for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) {
|
for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) {
|
||||||
if (descriptor instanceof CallableMemberDescriptor) {
|
if (descriptor instanceof CallableMemberDescriptor) {
|
||||||
CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor) descriptor;
|
CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor) descriptor;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import com.intellij.openapi.project.Project;
|
|||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
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.lang.resolve.OverrideResolver;
|
||||||
import org.jetbrains.jet.plugin.JetBundle;
|
import org.jetbrains.jet.plugin.JetBundle;
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ import java.util.Set;
|
|||||||
public class ImplementMethodsHandler extends OverrideImplementMethodsHandler implements IntentionAction {
|
public class ImplementMethodsHandler extends OverrideImplementMethodsHandler implements IntentionAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Set<CallableMemberDescriptor> collectMethodsToGenerate(MutableClassDescriptor descriptor) {
|
protected Set<CallableMemberDescriptor> collectMethodsToGenerate(ClassDescriptor descriptor) {
|
||||||
Set<CallableMemberDescriptor> missingImplementations = Sets.newLinkedHashSet();
|
Set<CallableMemberDescriptor> missingImplementations = Sets.newLinkedHashSet();
|
||||||
OverrideResolver.collectMissingImplementations(descriptor, missingImplementations, missingImplementations);
|
OverrideResolver.collectMissingImplementations(descriptor, missingImplementations, missingImplementations);
|
||||||
return missingImplementations;
|
return missingImplementations;
|
||||||
|
|||||||
@@ -206,13 +206,13 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
|
|||||||
@NotNull
|
@NotNull
|
||||||
public Set<CallableMemberDescriptor> collectMethodsToGenerate(@NotNull JetClassOrObject classOrObject, BindingContext bindingContext) {
|
public Set<CallableMemberDescriptor> collectMethodsToGenerate(@NotNull JetClassOrObject classOrObject, BindingContext bindingContext) {
|
||||||
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, classOrObject);
|
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, classOrObject);
|
||||||
if (descriptor instanceof MutableClassDescriptor) {
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
return collectMethodsToGenerate((MutableClassDescriptor) descriptor);
|
return collectMethodsToGenerate((ClassDescriptor) descriptor);
|
||||||
}
|
}
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Set<CallableMemberDescriptor> collectMethodsToGenerate(MutableClassDescriptor descriptor);
|
protected abstract Set<CallableMemberDescriptor> collectMethodsToGenerate(ClassDescriptor descriptor);
|
||||||
|
|
||||||
private MemberChooser<DescriptorClassMember> showOverrideImplementChooser(
|
private MemberChooser<DescriptorClassMember> showOverrideImplementChooser(
|
||||||
Project project,
|
Project project,
|
||||||
@@ -245,9 +245,7 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
|
|||||||
|
|
||||||
assert classOrObject != null : "ClassObject should be checked in isValidFor method";
|
assert classOrObject != null : "ClassObject should be checked in isValidFor method";
|
||||||
|
|
||||||
BindingContext bindingContext =
|
BindingContext bindingContext = AnalyzerFacadeWithCache.getContextForElement(classOrObject);
|
||||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) classOrObject.getContainingFile())
|
|
||||||
.getBindingContext();
|
|
||||||
|
|
||||||
Set<CallableMemberDescriptor> missingImplementations = collectMethodsToGenerate(classOrObject, bindingContext);
|
Set<CallableMemberDescriptor> missingImplementations = collectMethodsToGenerate(classOrObject, bindingContext);
|
||||||
if (missingImplementations.isEmpty() && !implementAll) {
|
if (missingImplementations.isEmpty() && !implementAll) {
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
package org.jetbrains.jet.plugin.codeInsight;
|
package org.jetbrains.jet.plugin.codeInsight;
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
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.OverrideResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
|
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
|
||||||
|
|
||||||
@@ -26,10 +27,15 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class OverrideMethodsHandler extends OverrideImplementMethodsHandler {
|
public class OverrideMethodsHandler extends OverrideImplementMethodsHandler {
|
||||||
@Override
|
@Override
|
||||||
protected Set<CallableMemberDescriptor> collectMethodsToGenerate(MutableClassDescriptor descriptor) {
|
protected Set<CallableMemberDescriptor> collectMethodsToGenerate(ClassDescriptor descriptor) {
|
||||||
Set<CallableMemberDescriptor> superMethods = OverrideResolver.collectSuperMethods(descriptor).keySet();
|
Set<CallableMemberDescriptor> superMethods = OverrideResolver.collectSuperMethods(descriptor).keySet();
|
||||||
for (CallableMemberDescriptor member : descriptor.getDeclaredCallableMembers()) {
|
for (DeclarationDescriptor member : descriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
|
||||||
superMethods.removeAll(member.getOverriddenDescriptors());
|
if (member instanceof CallableMemberDescriptor) {
|
||||||
|
CallableMemberDescriptor callable = (CallableMemberDescriptor) member;
|
||||||
|
if (callable.getKind().isReal()) {
|
||||||
|
superMethods.removeAll(callable.getOverriddenDescriptors());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Set<CallableMemberDescriptor> result = new HashSet<CallableMemberDescriptor>();
|
Set<CallableMemberDescriptor> result = new HashSet<CallableMemberDescriptor>();
|
||||||
for (CallableMemberDescriptor superMethod : superMethods) {
|
for (CallableMemberDescriptor superMethod : superMethods) {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
|
|||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.plugin.JetLightProjectDescriptor;
|
import org.jetbrains.jet.plugin.JetLightProjectDescriptor;
|
||||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||||
|
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -121,8 +122,9 @@ public abstract class AbstractOverrideImplementTest extends LightCodeInsightFixt
|
|||||||
assertNotNull("Caret should be inside class or object", classOrObject);
|
assertNotNull("Caret should be inside class or object", classOrObject);
|
||||||
|
|
||||||
final JetFile jetFile = (JetFile) classOrObject.getContainingFile();
|
final JetFile jetFile = (JetFile) classOrObject.getContainingFile();
|
||||||
final BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext();
|
final ResolveSessionForBodies resolveSession = AnalyzerFacadeWithCache.getLazyResolveSessionForFile(jetFile);
|
||||||
Set<CallableMemberDescriptor> descriptors = handler.collectMethodsToGenerate(classOrObject, bindingContext);
|
Set<CallableMemberDescriptor> descriptors =
|
||||||
|
handler.collectMethodsToGenerate(classOrObject, resolveSession.resolveToElement(classOrObject));
|
||||||
|
|
||||||
final CallableMemberDescriptor singleToOverride;
|
final CallableMemberDescriptor singleToOverride;
|
||||||
if (memberToOverride == null) {
|
if (memberToOverride == null) {
|
||||||
@@ -151,7 +153,7 @@ public abstract class AbstractOverrideImplementTest extends LightCodeInsightFixt
|
|||||||
OverrideImplementMethodsHandler.generateMethods(
|
OverrideImplementMethodsHandler.generateMethods(
|
||||||
myFixture.getEditor(), classOrObject,
|
myFixture.getEditor(), classOrObject,
|
||||||
OverrideImplementMethodsHandler
|
OverrideImplementMethodsHandler
|
||||||
.membersFromDescriptors(jetFile, Collections.singletonList(singleToOverride), bindingContext));
|
.membersFromDescriptors(jetFile, Collections.singletonList(singleToOverride), resolveSession.getBindingContext()));
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
}
|
}
|
||||||
@@ -162,8 +164,7 @@ public abstract class AbstractOverrideImplementTest extends LightCodeInsightFixt
|
|||||||
assertNotNull("Caret should be inside class or object", classOrObject);
|
assertNotNull("Caret should be inside class or object", classOrObject);
|
||||||
|
|
||||||
final JetFile jetFile = (JetFile) classOrObject.getContainingFile();
|
final JetFile jetFile = (JetFile) classOrObject.getContainingFile();
|
||||||
final BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile)
|
final BindingContext bindingContext = AnalyzerFacadeWithCache.getContextForElement(classOrObject);
|
||||||
.getBindingContext();
|
|
||||||
Set<CallableMemberDescriptor> descriptors = handler.collectMethodsToGenerate(classOrObject, bindingContext);
|
Set<CallableMemberDescriptor> descriptors = handler.collectMethodsToGenerate(classOrObject, bindingContext);
|
||||||
|
|
||||||
final ArrayList<CallableMemberDescriptor> descriptorsList = new ArrayList<CallableMemberDescriptor>(descriptors);
|
final ArrayList<CallableMemberDescriptor> descriptorsList = new ArrayList<CallableMemberDescriptor>(descriptors);
|
||||||
|
|||||||
Reference in New Issue
Block a user