201: J2K manual
This commit is contained in:
committed by
Nikolay Krasko
parent
b92a228fb3
commit
579dd8f8fe
@@ -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<*>> {
|
||||||
|
|||||||
+93
-72
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user