201: J2K manual

This commit is contained in:
Nikolay Krasko
2020-02-02 02:50:26 +03:00
committed by Nikolay Krasko
parent b92a228fb3
commit 579dd8f8fe
2 changed files with 101 additions and 81 deletions
@@ -34,8 +34,9 @@ import javax.swing.JTree
class KotlinCallHierarchyBrowser(element: PsiElement) : class KotlinCallHierarchyBrowser(element: PsiElement) :
CallHierarchyBrowserBase(element.project, element) { CallHierarchyBrowserBase(element.project, element) {
override fun createTrees(type2TreeMap: MutableMap<String, JTree>) { override fun createTrees(type2TreeMap: MutableMap<String, JTree>) {
val group = val group = ActionManager.getInstance().getAction(IdeActions.GROUP_CALL_HIERARCHY_POPUP) as ActionGroup
ActionManager.getInstance().getAction(IdeActions.GROUP_CALL_HIERARCHY_POPUP) as ActionGroup val baseOnThisMethodAction = BaseOnThisMethodAction()
val tree1 = createTree(false) val tree1 = createTree(false)
PopupHandler.installPopupHandler( PopupHandler.installPopupHandler(
tree1, tree1,
@@ -43,13 +44,12 @@ class KotlinCallHierarchyBrowser(element: PsiElement) :
ActionPlaces.CALL_HIERARCHY_VIEW_POPUP, ActionPlaces.CALL_HIERARCHY_VIEW_POPUP,
ActionManager.getInstance() ActionManager.getInstance()
) )
val baseOnThisMethodAction =
BaseOnThisMethodAction()
baseOnThisMethodAction.registerCustomShortcutSet( baseOnThisMethodAction.registerCustomShortcutSet(
ActionManager.getInstance().getAction(IdeActions.ACTION_CALL_HIERARCHY).shortcutSet, ActionManager.getInstance().getAction(IdeActions.ACTION_CALL_HIERARCHY).shortcutSet,
tree1 tree1
) )
type2TreeMap[CALLEE_TYPE] = tree1 type2TreeMap[CALLEE_TYPE] = tree1
val tree2 = createTree(false) val tree2 = createTree(false)
PopupHandler.installPopupHandler( PopupHandler.installPopupHandler(
tree2, tree2,
@@ -77,12 +77,11 @@ class KotlinCallHierarchyBrowser(element: PsiElement) :
psiElement: PsiElement psiElement: PsiElement
): HierarchyTreeStructure? { ): HierarchyTreeStructure? {
if (psiElement !is KtElement) return null if (psiElement !is KtElement) return null
if (typeName == CALLER_TYPE) { return when (typeName) {
return KotlinCallerTreeStructure(psiElement, currentScopeType) CALLER_TYPE -> KotlinCallerTreeStructure(psiElement, currentScopeType)
CALLEE_TYPE -> KotlinCalleeTreeStructure(psiElement, currentScopeType)
else -> null
} }
return if (typeName == CALLEE_TYPE) {
KotlinCalleeTreeStructure(psiElement, currentScopeType)
} else null
} }
override fun getComparator(): Comparator<NodeDescriptor<*>> { override fun getComparator(): Comparator<NodeDescriptor<*>> {
@@ -29,6 +29,7 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference import com.intellij.psi.PsiReference
import com.intellij.ui.LayeredIcon import com.intellij.ui.LayeredIcon
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
@@ -43,9 +44,9 @@ class KotlinCallHierarchyNodeDescriptor(
) : HierarchyNodeDescriptor(element.project, parentDescriptor, element, isBase), ) : HierarchyNodeDescriptor(element.project, parentDescriptor, element, isBase),
Navigatable { Navigatable {
private var usageCount = 1 private var usageCount = 1
private val references: MutableSet<PsiReference> = private val references: MutableSet<PsiReference> = HashSet()
HashSet()
private val javaDelegate: CallHierarchyNodeDescriptor private val javaDelegate: CallHierarchyNodeDescriptor
fun incrementUsageCount() { fun incrementUsageCount() {
usageCount++ usageCount++
javaDelegate.incrementUsageCount() javaDelegate.incrementUsageCount()
@@ -64,53 +65,60 @@ class KotlinCallHierarchyNodeDescriptor(
override fun update(): Boolean { override fun update(): Boolean {
val oldText = myHighlightedText val oldText = myHighlightedText
val oldIcon = icon val oldIcon = icon
var flags = Iconable.ICON_FLAG_VISIBILITY
if (isMarkReadOnly) { val flags: Int = if (isMarkReadOnly) {
flags = flags or Iconable.ICON_FLAG_READ_STATUS Iconable.ICON_FLAG_VISIBILITY or Iconable.ICON_FLAG_READ_STATUS
} else {
Iconable.ICON_FLAG_VISIBILITY
} }
var changes = super.update() var changes = super.update()
val targetElement = psiElement
val elementText = renderElement(targetElement) val elementText = renderElement(psiElement)
if (elementText == null) { if (elementText == null) {
val invalidPrefix = IdeBundle.message("node.hierarchy.invalid") val invalidPrefix = IdeBundle.message("node.hierarchy.invalid")
if (!myHighlightedText.text.startsWith(invalidPrefix)) { if (!myHighlightedText.text.startsWith(invalidPrefix)) {
myHighlightedText.beginning myHighlightedText.beginning.addText(invalidPrefix, getInvalidPrefixAttributes())
.addText(invalidPrefix, getInvalidPrefixAttributes())
} }
return true return true
} }
var newIcon = targetElement!!.getIcon(flags)
if (changes && myIsBase) { val targetElement = psiElement
val icon = LayeredIcon(2) val elementIcon = targetElement!!.getIcon(flags)
icon.setIcon(newIcon, 0)
icon.setIcon(AllIcons.General.Modified, 1, -AllIcons.General.Modified.iconWidth / 2, 0) icon = if (changes && myIsBase) {
newIcon = icon LayeredIcon(2).apply {
setIcon(elementIcon, 0)
setIcon(AllIcons.General.Modified, 1, -AllIcons.General.Modified.iconWidth / 2, 0)
}
} else {
elementIcon
} }
icon = newIcon
val mainTextAttributes: TextAttributes? = if (myColor != null) {
TextAttributes(myColor, null, null, null, Font.PLAIN)
} else {
null
}
myHighlightedText = CompositeAppearance() myHighlightedText = CompositeAppearance()
var mainTextAttributes: TextAttributes? = null
if (myColor != null) {
mainTextAttributes = TextAttributes(myColor, null, null, null, Font.PLAIN)
}
var packageName =
KtPsiUtil.getPackageName((targetElement as KtElement?)!!)
myHighlightedText.ending.addText(elementText, mainTextAttributes) myHighlightedText.ending.addText(elementText, mainTextAttributes)
if (usageCount > 1) { if (usageCount > 1) {
myHighlightedText.ending.addText( myHighlightedText.ending.addText(
IdeBundle.message("node.call.hierarchy.N.usages", usageCount), IdeBundle.message("node.call.hierarchy.N.usages", usageCount),
getUsageCountPrefixAttributes() getUsageCountPrefixAttributes(),
) )
} }
if (packageName == null) {
packageName = "" val packageName = KtPsiUtil.getPackageName(targetElement as KtElement) ?: ""
}
myHighlightedText.ending myHighlightedText.ending.addText(" ($packageName)", getPackageNameAttributes())
.addText(" ($packageName)", getPackageNameAttributes())
myName = myHighlightedText.text myName = myHighlightedText.text
if (!(Comparing.equal(myHighlightedText, oldText) && Comparing.equal(icon, oldIcon))
) { if (!(Comparing.equal(myHighlightedText, oldText) && Comparing.equal(icon, oldIcon))) {
changes = true changes = true
} }
return changes return changes
} }
@@ -128,51 +136,64 @@ class KotlinCallHierarchyNodeDescriptor(
companion object { companion object {
private fun renderElement(element: PsiElement?): String? { private fun renderElement(element: PsiElement?): String? {
if (element is KtFile) { when (element) {
return element.name is KtFile -> {
} return element.name
if (element !is KtNamedDeclaration) { }
return null !is KtNamedDeclaration -> {
} return null
var descriptor: DeclarationDescriptor? = }
element as KtNamedDeclaration?. resolveToDescriptorIfAny BodyResolveMode.PARTIAL else -> {
?: return null var descriptor: DeclarationDescriptor = element.resolveToDescriptorIfAny(BodyResolveMode.PARTIAL) ?: return null
val elementText: String? val elementText: String?
if (element is KtClassOrObject) { when (element) {
if (element is KtObjectDeclaration && element.isCompanion()) { is KtClassOrObject -> {
descriptor = descriptor.containingDeclaration when {
if (descriptor !is ClassDescriptor) return null element is KtObjectDeclaration && element.isCompanion() -> {
elementText = renderClassOrObject(descriptor) val containingDescriptor = descriptor.containingDeclaration
} else if (element is KtEnumEntry) { if (containingDescriptor !is ClassDescriptor) return null
elementText = element.name descriptor = containingDescriptor
} else { elementText = renderClassOrObject(descriptor)
elementText = if (element.name != null) { }
renderClassOrObject(descriptor as ClassDescriptor) element is KtEnumEntry -> {
} else { elementText = element.name
"[anonymous]" }
else -> {
elementText = if (element.name != null) {
renderClassOrObject(descriptor as ClassDescriptor)
} else {
"[anonymous]"
}
}
}
}
is KtNamedFunction, is KtConstructor<*> -> {
if (descriptor !is FunctionDescriptor) return null
elementText = renderNamedFunction(descriptor)
}
is KtProperty -> {
elementText = element.name
}
else -> return null
} }
if (elementText == null) return null
var containerText: String? = null
var containerDescriptor = descriptor.containingDeclaration
while (containerDescriptor != null) {
if (containerDescriptor is PackageFragmentDescriptor || containerDescriptor is ModuleDescriptor) {
break
}
val name = containerDescriptor.name
if (!name.isSpecial) {
val identifier = name.identifier
containerText = if (containerText != null) "$identifier.$containerText" else identifier
}
containerDescriptor = containerDescriptor.containingDeclaration
}
return if (containerText != null) "$containerText.$elementText" else elementText
} }
} else if (element is KtNamedFunction || element is KtConstructor<*>) {
if (descriptor !is FunctionDescriptor) return null
elementText = renderNamedFunction(descriptor)
} else if (element is KtProperty) {
elementText = element.name
} else return null
if (elementText == null) return null
var containerText: String? = null
var containerDescriptor = descriptor.containingDeclaration
while (containerDescriptor != null) {
if (containerDescriptor is PackageFragmentDescriptor || containerDescriptor is ModuleDescriptor) {
break
}
val name = containerDescriptor.name
if (!name.isSpecial) {
val identifier = name.identifier
containerText = if (containerText != null) "$identifier.$containerText" else identifier
}
containerDescriptor = containerDescriptor.containingDeclaration
} }
return if (containerText != null) "$containerText.$elementText" else elementText
} }
fun renderNamedFunction(descriptor: FunctionDescriptor): String { fun renderNamedFunction(descriptor: FunctionDescriptor): String {