Rewrite to Kotlin: super navigation markers methods
This commit is contained in:
committed by
Nikolay Krasko
parent
f7edd5abe7
commit
7bf622dd26
@@ -159,36 +159,43 @@ public class DescriptorRendererBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DescriptorRendererBuilder setIncludePropertyConstant(boolean includePropertyConstant) {
|
||||
this.includePropertyConstant = includePropertyConstant;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DescriptorRendererBuilder setIncludeSynthesizedParameterNames(boolean includeSynthesizedParameterNames) {
|
||||
this.includeSynthesizedParameterNames = includeSynthesizedParameterNames;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DescriptorRendererBuilder setWithoutTypeParameters(boolean withoutTypeParameters) {
|
||||
this.withoutTypeParameters = withoutTypeParameters;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DescriptorRendererBuilder setWithoutFunctionParameterNames(boolean withoutFunctionParameterNames) {
|
||||
this.withoutFunctionParameterNames = withoutFunctionParameterNames;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DescriptorRendererBuilder setReceiverAfterName(boolean receiverAfterName) {
|
||||
this.receiverAfterName = receiverAfterName;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DescriptorRendererBuilder setRenderClassObjectName(boolean renderClassObjectName) {
|
||||
this.renderClassObjectName = renderClassObjectName;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DescriptorRendererBuilder setWithoutSuperTypes(boolean withoutSuperTypes) {
|
||||
this.withoutSuperTypes = withoutSuperTypes;
|
||||
return this;
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.jetbrains.jet.plugin.highlighter;
|
||||
import com.google.common.collect.*;
|
||||
import com.intellij.codeHighlighting.Pass;
|
||||
import com.intellij.codeInsight.daemon.DaemonBundle;
|
||||
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
|
||||
import com.intellij.codeInsight.daemon.LineMarkerInfo;
|
||||
import com.intellij.codeInsight.daemon.LineMarkerProvider;
|
||||
import com.intellij.codeInsight.daemon.impl.GutterIconTooltipHelper;
|
||||
@@ -32,14 +31,12 @@ import com.intellij.ide.util.DefaultPsiElementCellRenderer;
|
||||
import com.intellij.ide.util.MethodCellRenderer;
|
||||
import com.intellij.ide.util.PsiClassListCellRenderer;
|
||||
import com.intellij.ide.util.PsiElementListCellRenderer;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.markup.GutterIconRenderer;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiElementProcessor;
|
||||
@@ -55,29 +52,24 @@ import kotlin.KotlinPackage;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.jet.asJava.KotlinLightMethodFromTrait;
|
||||
import org.jetbrains.jet.asJava.LightClassUtil;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.Modality;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.plugin.ProjectRootsUtil;
|
||||
import org.jetbrains.jet.plugin.caches.resolve.ResolvePackage;
|
||||
import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil;
|
||||
import org.jetbrains.jet.plugin.codeInsight.JetFunctionPsiElementCellRenderer;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.plugin.highlighter.markers.MarkersPackage;
|
||||
import org.jetbrains.jet.plugin.highlighter.markers.ResolveWithParentsResult;
|
||||
import org.jetbrains.jet.plugin.highlighter.markers.SuperDeclarationMarkerNavigationHandler;
|
||||
import org.jetbrains.jet.plugin.highlighter.markers.SuperDeclarationMarkerTooltip;
|
||||
import org.jetbrains.jet.plugin.search.ideaExtensions.KotlinDefinitionsSearcher;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.jet.renderer.DescriptorRendererBuilder;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.OverrideResolver.getDirectlyOverriddenDeclarations;
|
||||
|
||||
public class JetLineMarkerProvider implements LineMarkerProvider {
|
||||
public static final Icon OVERRIDING_MARK = AllIcons.Gutter.OverridingMethod;
|
||||
public static final Icon IMPLEMENTING_MARK = AllIcons.Gutter.ImplementingMethod;
|
||||
@@ -245,46 +237,6 @@ public class JetLineMarkerProvider implements LineMarkerProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String calculateTooltipString(JetElement element) {
|
||||
BindingContext bindingContext = AnalyzerFacadeWithCache.getContextForElement(element);
|
||||
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
|
||||
|
||||
if (!(descriptor instanceof CallableMemberDescriptor)) return "";
|
||||
CallableMemberDescriptor callableDescriptor = (CallableMemberDescriptor) descriptor;
|
||||
|
||||
Set<CallableMemberDescriptor> overriddenMembers = getDirectlyOverriddenDeclarations(callableDescriptor);
|
||||
if (overriddenMembers.isEmpty()) return "";
|
||||
|
||||
final boolean isAbstract = callableDescriptor.getModality() == Modality.ABSTRACT;
|
||||
|
||||
final DescriptorRenderer renderer = new DescriptorRendererBuilder()
|
||||
.setTextFormat(DescriptorRenderer.TextFormat.HTML)
|
||||
.setWithDefinedIn(false)
|
||||
.setStartFromName(true)
|
||||
.setWithoutSuperTypes(true)
|
||||
.build();
|
||||
|
||||
List<String> containingStrings = ContainerUtil.map(overriddenMembers, new Function<CallableMemberDescriptor, String>() {
|
||||
@Override
|
||||
public String fun(CallableMemberDescriptor overriddenDescriptor) {
|
||||
DeclarationDescriptor declaration = overriddenDescriptor.getContainingDeclaration();
|
||||
String memberKind =
|
||||
overriddenDescriptor instanceof PropertyAccessorDescriptor || overriddenDescriptor instanceof PropertyDescriptor ?
|
||||
"property" : "function";
|
||||
|
||||
boolean isBaseAbstract = overriddenDescriptor.getModality() == Modality.ABSTRACT;
|
||||
|
||||
return String.format("%s %s in '%s'",
|
||||
!isAbstract && isBaseAbstract ? "Implements" : "Overrides",
|
||||
memberKind, renderer.render(declaration));
|
||||
}
|
||||
});
|
||||
|
||||
Collections.sort(containingStrings);
|
||||
|
||||
return StringUtil.join(containingStrings, "<br/>");
|
||||
}
|
||||
|
||||
private static boolean isImplementsAndNotOverrides(
|
||||
CallableMemberDescriptor descriptor,
|
||||
Collection<? extends CallableMemberDescriptor> overriddenMembers
|
||||
@@ -340,28 +292,20 @@ public class JetLineMarkerProvider implements LineMarkerProvider {
|
||||
|
||||
if (!declaration.hasModifier(JetTokens.OVERRIDE_KEYWORD)) return;
|
||||
|
||||
DeclarationDescriptor descriptor =
|
||||
ResolvePackage.getLazyResolveSession(declaration).resolveToDescriptor(declaration);
|
||||
|
||||
if (!(descriptor instanceof CallableMemberDescriptor)) return;
|
||||
|
||||
Set<? extends CallableMemberDescriptor> overriddenMembers = getDirectlyOverriddenDeclarations((CallableMemberDescriptor) descriptor);
|
||||
if (overriddenMembers.isEmpty()) return;
|
||||
ResolveWithParentsResult resolveWithParents = MarkersPackage.resolveDeclarationWithParents(declaration);
|
||||
if (resolveWithParents.getOverriddenDescriptors().isEmpty()) return;
|
||||
|
||||
// NOTE: Don't store descriptors in line markers because line markers are not deleted while editing other files and this can prevent
|
||||
// clearing the whole BindingTrace.
|
||||
LineMarkerInfo<JetElement> marker = new LineMarkerInfo<JetElement>(
|
||||
declaration,
|
||||
declaration.getTextOffset(),
|
||||
isImplementsAndNotOverrides((CallableMemberDescriptor) descriptor, overriddenMembers) ? IMPLEMENTING_MARK : OVERRIDING_MARK,
|
||||
isImplementsAndNotOverrides(resolveWithParents.getDescriptor(), resolveWithParents.getOverriddenDescriptors()) ?
|
||||
IMPLEMENTING_MARK :
|
||||
OVERRIDING_MARK,
|
||||
Pass.UPDATE_OVERRIDEN_MARKERS,
|
||||
new Function<JetElement, String>() {
|
||||
@Override
|
||||
public String fun(JetElement element) {
|
||||
return calculateTooltipString(element);
|
||||
}
|
||||
},
|
||||
new KotlinSuperNavigationHandler()
|
||||
SuperDeclarationMarkerTooltip.INSTANCE$,
|
||||
new SuperDeclarationMarkerNavigationHandler()
|
||||
);
|
||||
|
||||
result.add(marker);
|
||||
@@ -608,50 +552,4 @@ public class JetLineMarkerProvider implements LineMarkerProvider {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static class KotlinSuperNavigationHandler implements GutterIconNavigationHandler<JetElement> {
|
||||
private List<NavigatablePsiElement> testNavigableElements;
|
||||
|
||||
@TestOnly
|
||||
@NotNull
|
||||
public List<NavigatablePsiElement> getNavigationElements() {
|
||||
List<NavigatablePsiElement> navigationResult = testNavigableElements;
|
||||
testNavigableElements = null;
|
||||
return navigationResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void navigate(MouseEvent e, JetElement element) {
|
||||
BindingContext bindingContext = AnalyzerFacadeWithCache.getContextForElement(element);
|
||||
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
|
||||
if (!(descriptor instanceof CallableMemberDescriptor)) return;
|
||||
|
||||
Set<CallableMemberDescriptor> overriddenMembers =
|
||||
getDirectlyOverriddenDeclarations((CallableMemberDescriptor) descriptor);
|
||||
if (overriddenMembers.isEmpty()) return;
|
||||
|
||||
List<NavigatablePsiElement> superDeclarations = Lists.newArrayList();
|
||||
for (CallableMemberDescriptor overriddenMember : overriddenMembers) {
|
||||
Collection<PsiElement> declarations =
|
||||
DescriptorToDeclarationUtil.INSTANCE$.resolveToPsiElements(element.getProject(), overriddenMember);
|
||||
for (PsiElement declaration : declarations) {
|
||||
if (declaration instanceof NavigatablePsiElement) {
|
||||
superDeclarations.add((NavigatablePsiElement) declaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
PsiElementListNavigator.openTargets(
|
||||
e,
|
||||
ArrayUtil.toObjectArray(superDeclarations, NavigatablePsiElement.class),
|
||||
JetBundle.message("navigation.title.super.declaration", descriptor.getName()),
|
||||
JetBundle.message("navigation.findUsages.title.super.declaration", descriptor.getName()),
|
||||
new JetFunctionPsiElementCellRenderer(bindingContext));
|
||||
}
|
||||
else {
|
||||
testNavigableElements = superDeclarations;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2010-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.plugin.highlighter.markers
|
||||
|
||||
import org.jetbrains.jet.lang.psi.JetElement
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.OverrideResolver
|
||||
import org.jetbrains.jet.lang.descriptors.Modality
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer
|
||||
import org.jetbrains.jet.renderer.DescriptorRendererBuilder
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor
|
||||
import com.intellij.psi.NavigatablePsiElement
|
||||
import java.awt.event.MouseEvent
|
||||
import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator
|
||||
import org.jetbrains.jet.plugin.JetBundle
|
||||
import org.jetbrains.jet.plugin.codeInsight.JetFunctionPsiElementCellRenderer
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler
|
||||
import java.util.ArrayList
|
||||
import com.intellij.util.Function
|
||||
|
||||
object SuperDeclarationMarkerTooltip: Function<JetElement, String> {
|
||||
override fun `fun`(param: JetElement?): String? {
|
||||
val element = param!!
|
||||
|
||||
[suppress("UNUSED_VARIABLE")]
|
||||
val (elementDescriptor, _, overriddenDescriptors) = resolveDeclarationWithParents(element)
|
||||
if (overriddenDescriptors.isEmpty()) return ""
|
||||
|
||||
val isAbstract = elementDescriptor!!.getModality() == Modality.ABSTRACT
|
||||
|
||||
val renderer = DescriptorRendererBuilder()
|
||||
.setTextFormat(DescriptorRenderer.TextFormat.HTML)
|
||||
.setWithDefinedIn(false)
|
||||
.setStartFromName(true)
|
||||
.setWithoutSuperTypes(true)
|
||||
.build()
|
||||
|
||||
val containingStrings = overriddenDescriptors.map {
|
||||
val declaration = it.getContainingDeclaration()
|
||||
val memberKind = if (it is PropertyAccessorDescriptor || it is PropertyDescriptor) "property" else "function"
|
||||
|
||||
val isBaseAbstract = it.getModality() == Modality.ABSTRACT
|
||||
"${if (!isAbstract && isBaseAbstract) "Implements" else "Overrides"} $memberKind in '${renderer.render(declaration)}'"
|
||||
}
|
||||
|
||||
return containingStrings.sort().join(separator = "<br/>")
|
||||
}
|
||||
}
|
||||
|
||||
public class SuperDeclarationMarkerNavigationHandler : GutterIconNavigationHandler<JetElement> {
|
||||
private var testNavigableElements: List<NavigatablePsiElement>? = null
|
||||
|
||||
TestOnly
|
||||
public fun getNavigationElements(): List<NavigatablePsiElement> {
|
||||
val navigationResult = testNavigableElements!!
|
||||
testNavigableElements = null
|
||||
return navigationResult
|
||||
}
|
||||
|
||||
override fun navigate(e: MouseEvent?, element: JetElement?) {
|
||||
if (element == null) return
|
||||
|
||||
val (elementDescriptor, bindingContext, overriddenDescriptors) = resolveDeclarationWithParents(element)
|
||||
if (overriddenDescriptors.isEmpty()) return
|
||||
|
||||
val superDeclarations = ArrayList<NavigatablePsiElement>()
|
||||
for (overriddenMember in overriddenDescriptors) {
|
||||
val declarations = DescriptorToDeclarationUtil.resolveToPsiElements(element.getProject(), overriddenMember)
|
||||
for (declaration in declarations) {
|
||||
if (declaration is NavigatablePsiElement) {
|
||||
superDeclarations.add(declaration as NavigatablePsiElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ApplicationManager.getApplication()!!.isUnitTestMode()) {
|
||||
val elementName = elementDescriptor!!.getName()
|
||||
|
||||
PsiElementListNavigator.openTargets(
|
||||
e,
|
||||
superDeclarations.copyToArray(),
|
||||
JetBundle.message("navigation.title.super.declaration", elementName),
|
||||
JetBundle.message("navigation.findUsages.title.super.declaration", elementName),
|
||||
JetFunctionPsiElementCellRenderer(bindingContext))
|
||||
}
|
||||
else {
|
||||
// Only store elements for retrieve in test
|
||||
testNavigableElements = superDeclarations
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public data class ResolveWithParentsResult(
|
||||
val descriptor: CallableMemberDescriptor?,
|
||||
val bindingContext: BindingContext,
|
||||
val overriddenDescriptors: Collection<CallableMemberDescriptor>)
|
||||
|
||||
public fun resolveDeclarationWithParents(element: JetElement): ResolveWithParentsResult {
|
||||
val bindingContext = AnalyzerFacadeWithCache.getContextForElement(element)
|
||||
val descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element)
|
||||
|
||||
if (descriptor !is CallableMemberDescriptor) return ResolveWithParentsResult(null, bindingContext, listOf())
|
||||
|
||||
val overriddenMembers = OverrideResolver.getDirectlyOverriddenDeclarations(descriptor)
|
||||
return ResolveWithParentsResult(descriptor, bindingContext, overriddenMembers)
|
||||
}
|
||||
@@ -33,7 +33,7 @@ import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||
import org.jetbrains.jet.plugin.highlighter.JetLineMarkerProvider;
|
||||
import org.jetbrains.jet.plugin.highlighter.markers.SuperDeclarationMarkerNavigationHandler;
|
||||
import org.jetbrains.jet.plugin.navigation.NavigationTestUtils;
|
||||
import org.jetbrains.jet.testing.HighlightTestDataUtil;
|
||||
import org.jetbrains.jet.testing.ReferenceUtils;
|
||||
@@ -113,13 +113,13 @@ public abstract class AbstractLineMarkersTest extends JetLightCodeInsightFixture
|
||||
navigateMarker);
|
||||
|
||||
GutterIconNavigationHandler handler = navigateMarker.getNavigationHandler();
|
||||
if (handler instanceof JetLineMarkerProvider.KotlinSuperNavigationHandler) {
|
||||
if (handler instanceof SuperDeclarationMarkerNavigationHandler) {
|
||||
PsiElement element = navigateMarker.getElement();
|
||||
|
||||
//noinspection unchecked
|
||||
handler.navigate(null, element);
|
||||
List<NavigatablePsiElement> navigateElements =
|
||||
((JetLineMarkerProvider.KotlinSuperNavigationHandler) handler).getNavigationElements();
|
||||
((SuperDeclarationMarkerNavigationHandler) handler).getNavigationElements();
|
||||
|
||||
Collections.sort(navigateElements, new Comparator<NavigatablePsiElement>() {
|
||||
@Override
|
||||
@@ -137,7 +137,7 @@ public abstract class AbstractLineMarkersTest extends JetLightCodeInsightFixture
|
||||
assertSameLines(getExpectedNavigationText(navigationComment), actualNavigationData);
|
||||
}
|
||||
else {
|
||||
Assert.fail("Only JetLineMarkerProvider.KotlinSuperNavigationHandler are supported in navigate check");
|
||||
Assert.fail("Only SuperDeclarationMarkerNavigationHandler are supported in navigate check");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user