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) :
CallHierarchyBrowserBase(element.project, element) {
override fun createTrees(type2TreeMap: MutableMap<String, JTree>) {
val group =
ActionManager.getInstance().getAction(IdeActions.GROUP_CALL_HIERARCHY_POPUP) as ActionGroup
val group = ActionManager.getInstance().getAction(IdeActions.GROUP_CALL_HIERARCHY_POPUP) as ActionGroup
val baseOnThisMethodAction = BaseOnThisMethodAction()
val tree1 = createTree(false)
PopupHandler.installPopupHandler(
tree1,
@@ -43,13 +44,12 @@ class KotlinCallHierarchyBrowser(element: PsiElement) :
ActionPlaces.CALL_HIERARCHY_VIEW_POPUP,
ActionManager.getInstance()
)
val baseOnThisMethodAction =
BaseOnThisMethodAction()
baseOnThisMethodAction.registerCustomShortcutSet(
ActionManager.getInstance().getAction(IdeActions.ACTION_CALL_HIERARCHY).shortcutSet,
tree1
)
type2TreeMap[CALLEE_TYPE] = tree1
val tree2 = createTree(false)
PopupHandler.installPopupHandler(
tree2,
@@ -77,12 +77,11 @@ class KotlinCallHierarchyBrowser(element: PsiElement) :
psiElement: PsiElement
): HierarchyTreeStructure? {
if (psiElement !is KtElement) return null
if (typeName == CALLER_TYPE) {
return KotlinCallerTreeStructure(psiElement, currentScopeType)
return when (typeName) {
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<*>> {
@@ -29,6 +29,7 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference
import com.intellij.ui.LayeredIcon
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
@@ -43,9 +44,9 @@ class KotlinCallHierarchyNodeDescriptor(
) : HierarchyNodeDescriptor(element.project, parentDescriptor, element, isBase),
Navigatable {
private var usageCount = 1
private val references: MutableSet<PsiReference> =
HashSet()
private val references: MutableSet<PsiReference> = HashSet()
private val javaDelegate: CallHierarchyNodeDescriptor
fun incrementUsageCount() {
usageCount++
javaDelegate.incrementUsageCount()
@@ -64,53 +65,60 @@ class KotlinCallHierarchyNodeDescriptor(
override fun update(): Boolean {
val oldText = myHighlightedText
val oldIcon = icon
var flags = Iconable.ICON_FLAG_VISIBILITY
if (isMarkReadOnly) {
flags = flags or Iconable.ICON_FLAG_READ_STATUS
val flags: Int = if (isMarkReadOnly) {
Iconable.ICON_FLAG_VISIBILITY or Iconable.ICON_FLAG_READ_STATUS
} else {
Iconable.ICON_FLAG_VISIBILITY
}
var changes = super.update()
val targetElement = psiElement
val elementText = renderElement(targetElement)
val elementText = renderElement(psiElement)
if (elementText == null) {
val invalidPrefix = IdeBundle.message("node.hierarchy.invalid")
if (!myHighlightedText.text.startsWith(invalidPrefix)) {
myHighlightedText.beginning
.addText(invalidPrefix, getInvalidPrefixAttributes())
myHighlightedText.beginning.addText(invalidPrefix, getInvalidPrefixAttributes())
}
return true
}
var newIcon = targetElement!!.getIcon(flags)
if (changes && myIsBase) {
val icon = LayeredIcon(2)
icon.setIcon(newIcon, 0)
icon.setIcon(AllIcons.General.Modified, 1, -AllIcons.General.Modified.iconWidth / 2, 0)
newIcon = icon
val targetElement = psiElement
val elementIcon = targetElement!!.getIcon(flags)
icon = if (changes && myIsBase) {
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()
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)
if (usageCount > 1) {
myHighlightedText.ending.addText(
IdeBundle.message("node.call.hierarchy.N.usages", usageCount),
getUsageCountPrefixAttributes()
getUsageCountPrefixAttributes(),
)
}
if (packageName == null) {
packageName = ""
}
myHighlightedText.ending
.addText(" ($packageName)", getPackageNameAttributes())
val packageName = KtPsiUtil.getPackageName(targetElement as KtElement) ?: ""
myHighlightedText.ending.addText(" ($packageName)", getPackageNameAttributes())
myName = myHighlightedText.text
if (!(Comparing.equal(myHighlightedText, oldText) && Comparing.equal(icon, oldIcon))
) {
if (!(Comparing.equal(myHighlightedText, oldText) && Comparing.equal(icon, oldIcon))) {
changes = true
}
return changes
}
@@ -128,51 +136,64 @@ class KotlinCallHierarchyNodeDescriptor(
companion object {
private fun renderElement(element: PsiElement?): String? {
if (element is KtFile) {
return element.name
}
if (element !is KtNamedDeclaration) {
return null
}
var descriptor: DeclarationDescriptor? =
element as KtNamedDeclaration?. resolveToDescriptorIfAny BodyResolveMode.PARTIAL
?: return null
val elementText: String?
if (element is KtClassOrObject) {
if (element is KtObjectDeclaration && element.isCompanion()) {
descriptor = descriptor.containingDeclaration
if (descriptor !is ClassDescriptor) return null
elementText = renderClassOrObject(descriptor)
} else if (element is KtEnumEntry) {
elementText = element.name
} else {
elementText = if (element.name != null) {
renderClassOrObject(descriptor as ClassDescriptor)
} else {
"[anonymous]"
when (element) {
is KtFile -> {
return element.name
}
!is KtNamedDeclaration -> {
return null
}
else -> {
var descriptor: DeclarationDescriptor = element.resolveToDescriptorIfAny(BodyResolveMode.PARTIAL) ?: return null
val elementText: String?
when (element) {
is KtClassOrObject -> {
when {
element is KtObjectDeclaration && element.isCompanion() -> {
val containingDescriptor = descriptor.containingDeclaration
if (containingDescriptor !is ClassDescriptor) return null
descriptor = containingDescriptor
elementText = renderClassOrObject(descriptor)
}
element is KtEnumEntry -> {
elementText = element.name
}
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 {