Reformat: idea.highlighter package

This commit is contained in:
Nikolay Krasko
2018-04-28 18:35:40 +03:00
parent 732e25a3f0
commit b19ad7e94c
16 changed files with 323 additions and 277 deletions
@@ -103,8 +103,7 @@ var <PACKAGE_PROPERTY><MUTABLE_VARIABLE>globalCounter</MUTABLE_VARIABLE></PACKAG
if (Modifier.isStatic(field.modifiers)) { if (Modifier.isStatic(field.modifiers)) {
try { try {
map.put(field.name, field.get(null) as TextAttributesKey) map.put(field.name, field.get(null) as TextAttributesKey)
} } catch (e: IllegalAccessException) {
catch (e: IllegalAccessException) {
assert(false) assert(false)
} }
@@ -118,66 +117,68 @@ var <PACKAGE_PROPERTY><MUTABLE_VARIABLE>globalCounter</MUTABLE_VARIABLE></PACKAG
override fun getAttributeDescriptors(): Array<AttributesDescriptor> { override fun getAttributeDescriptors(): Array<AttributesDescriptor> {
infix fun String.to(key: TextAttributesKey) = AttributesDescriptor(this, key) infix fun String.to(key: TextAttributesKey) = AttributesDescriptor(this, key)
return arrayOf(OptionsBundle.message("options.java.attribute.descriptor.keyword") to KotlinHighlightingColors.KEYWORD, return arrayOf(
KotlinBundle.message("options.kotlin.attribute.descriptor.builtin.annotation") to KotlinHighlightingColors.BUILTIN_ANNOTATION, OptionsBundle.message("options.java.attribute.descriptor.keyword") to KotlinHighlightingColors.KEYWORD,
OptionsBundle.message("options.java.attribute.descriptor.number") to KotlinHighlightingColors.NUMBER, KotlinBundle.message("options.kotlin.attribute.descriptor.builtin.annotation") to KotlinHighlightingColors.BUILTIN_ANNOTATION,
OptionsBundle.message("options.java.attribute.descriptor.string") to KotlinHighlightingColors.STRING, OptionsBundle.message("options.java.attribute.descriptor.number") to KotlinHighlightingColors.NUMBER,
KotlinBundle.message("options.kotlin.attribute.descriptor.string.escape") to KotlinHighlightingColors.STRING_ESCAPE, OptionsBundle.message("options.java.attribute.descriptor.string") to KotlinHighlightingColors.STRING,
OptionsBundle.message("options.java.attribute.descriptor.invalid.escape.in.string") to KotlinHighlightingColors.INVALID_STRING_ESCAPE, KotlinBundle.message("options.kotlin.attribute.descriptor.string.escape") to KotlinHighlightingColors.STRING_ESCAPE,
OptionsBundle.message("options.java.attribute.descriptor.operator.sign") to KotlinHighlightingColors.OPERATOR_SIGN, OptionsBundle.message("options.java.attribute.descriptor.invalid.escape.in.string") to KotlinHighlightingColors.INVALID_STRING_ESCAPE,
OptionsBundle.message("options.java.attribute.descriptor.parentheses") to KotlinHighlightingColors.PARENTHESIS, OptionsBundle.message("options.java.attribute.descriptor.operator.sign") to KotlinHighlightingColors.OPERATOR_SIGN,
OptionsBundle.message("options.java.attribute.descriptor.braces") to KotlinHighlightingColors.BRACES, OptionsBundle.message("options.java.attribute.descriptor.parentheses") to KotlinHighlightingColors.PARENTHESIS,
KotlinBundle.message("options.kotlin.attribute.descriptor.closure.braces") to KotlinHighlightingColors.FUNCTION_LITERAL_BRACES_AND_ARROW, OptionsBundle.message("options.java.attribute.descriptor.braces") to KotlinHighlightingColors.BRACES,
KotlinBundle.message("options.kotlin.attribute.descriptor.arrow") to KotlinHighlightingColors.ARROW, KotlinBundle.message("options.kotlin.attribute.descriptor.closure.braces") to KotlinHighlightingColors.FUNCTION_LITERAL_BRACES_AND_ARROW,
OptionsBundle.message("options.java.attribute.descriptor.brackets") to KotlinHighlightingColors.BRACKETS, KotlinBundle.message("options.kotlin.attribute.descriptor.arrow") to KotlinHighlightingColors.ARROW,
OptionsBundle.message("options.java.attribute.descriptor.comma") to KotlinHighlightingColors.COMMA, OptionsBundle.message("options.java.attribute.descriptor.brackets") to KotlinHighlightingColors.BRACKETS,
OptionsBundle.message("options.java.attribute.descriptor.semicolon") to KotlinHighlightingColors.SEMICOLON, OptionsBundle.message("options.java.attribute.descriptor.comma") to KotlinHighlightingColors.COMMA,
KotlinBundle.message("options.kotlin.attribute.descriptor.colon") to KotlinHighlightingColors.COLON, OptionsBundle.message("options.java.attribute.descriptor.semicolon") to KotlinHighlightingColors.SEMICOLON,
KotlinBundle.message("options.kotlin.attribute.descriptor.double.colon") to KotlinHighlightingColors.DOUBLE_COLON, KotlinBundle.message("options.kotlin.attribute.descriptor.colon") to KotlinHighlightingColors.COLON,
OptionsBundle.message("options.java.attribute.descriptor.dot") to KotlinHighlightingColors.DOT, KotlinBundle.message("options.kotlin.attribute.descriptor.double.colon") to KotlinHighlightingColors.DOUBLE_COLON,
KotlinBundle.message("options.kotlin.attribute.descriptor.safe.access") to KotlinHighlightingColors.SAFE_ACCESS, OptionsBundle.message("options.java.attribute.descriptor.dot") to KotlinHighlightingColors.DOT,
KotlinBundle.message("options.kotlin.attribute.descriptor.quest") to KotlinHighlightingColors.QUEST, KotlinBundle.message("options.kotlin.attribute.descriptor.safe.access") to KotlinHighlightingColors.SAFE_ACCESS,
KotlinBundle.message("options.kotlin.attribute.descriptor.exclexcl") to KotlinHighlightingColors.EXCLEXCL, KotlinBundle.message("options.kotlin.attribute.descriptor.quest") to KotlinHighlightingColors.QUEST,
OptionsBundle.message("options.java.attribute.descriptor.line.comment") to KotlinHighlightingColors.LINE_COMMENT, KotlinBundle.message("options.kotlin.attribute.descriptor.exclexcl") to KotlinHighlightingColors.EXCLEXCL,
OptionsBundle.message("options.java.attribute.descriptor.block.comment") to KotlinHighlightingColors.BLOCK_COMMENT, OptionsBundle.message("options.java.attribute.descriptor.line.comment") to KotlinHighlightingColors.LINE_COMMENT,
KotlinBundle.message("options.kotlin.attribute.descriptor.kdoc.comment") to KotlinHighlightingColors.DOC_COMMENT, OptionsBundle.message("options.java.attribute.descriptor.block.comment") to KotlinHighlightingColors.BLOCK_COMMENT,
KotlinBundle.message("options.kotlin.attribute.descriptor.kdoc.tag") to KotlinHighlightingColors.KDOC_TAG, KotlinBundle.message("options.kotlin.attribute.descriptor.kdoc.comment") to KotlinHighlightingColors.DOC_COMMENT,
KotlinBundle.message("options.kotlin.attribute.descriptor.kdoc.value") to KotlinHighlightingColors.KDOC_LINK, KotlinBundle.message("options.kotlin.attribute.descriptor.kdoc.tag") to KotlinHighlightingColors.KDOC_TAG,
OptionsBundle.message("options.java.attribute.descriptor.class") to KotlinHighlightingColors.CLASS, KotlinBundle.message("options.kotlin.attribute.descriptor.kdoc.value") to KotlinHighlightingColors.KDOC_LINK,
OptionsBundle.message("options.java.attribute.descriptor.type.parameter") to KotlinHighlightingColors.TYPE_PARAMETER, OptionsBundle.message("options.java.attribute.descriptor.class") to KotlinHighlightingColors.CLASS,
OptionsBundle.message("options.java.attribute.descriptor.abstract.class") to KotlinHighlightingColors.ABSTRACT_CLASS, OptionsBundle.message("options.java.attribute.descriptor.type.parameter") to KotlinHighlightingColors.TYPE_PARAMETER,
OptionsBundle.message("options.java.attribute.descriptor.interface") to KotlinHighlightingColors.TRAIT, OptionsBundle.message("options.java.attribute.descriptor.abstract.class") to KotlinHighlightingColors.ABSTRACT_CLASS,
KotlinBundle.message("options.kotlin.attribute.descriptor.annotation") to KotlinHighlightingColors.ANNOTATION, OptionsBundle.message("options.java.attribute.descriptor.interface") to KotlinHighlightingColors.TRAIT,
KotlinBundle.message("options.kotlin.attribute.descriptor.object") to KotlinHighlightingColors.OBJECT, KotlinBundle.message("options.kotlin.attribute.descriptor.annotation") to KotlinHighlightingColors.ANNOTATION,
KotlinBundle.message("options.kotlin.attribute.descriptor.enumEntry") to KotlinHighlightingColors.ENUM_ENTRY, KotlinBundle.message("options.kotlin.attribute.descriptor.object") to KotlinHighlightingColors.OBJECT,
KotlinBundle.message("options.kotlin.attribute.descriptor.typeAlias") to KotlinHighlightingColors.TYPE_ALIAS, KotlinBundle.message("options.kotlin.attribute.descriptor.enumEntry") to KotlinHighlightingColors.ENUM_ENTRY,
KotlinBundle.message("options.kotlin.attribute.descriptor.var") to KotlinHighlightingColors.MUTABLE_VARIABLE, KotlinBundle.message("options.kotlin.attribute.descriptor.typeAlias") to KotlinHighlightingColors.TYPE_ALIAS,
KotlinBundle.message("options.kotlin.attribute.descriptor.local.variable") to KotlinHighlightingColors.LOCAL_VARIABLE, KotlinBundle.message("options.kotlin.attribute.descriptor.var") to KotlinHighlightingColors.MUTABLE_VARIABLE,
OptionsBundle.message("options.java.attribute.descriptor.parameter") to KotlinHighlightingColors.PARAMETER, KotlinBundle.message("options.kotlin.attribute.descriptor.local.variable") to KotlinHighlightingColors.LOCAL_VARIABLE,
KotlinBundle.message("options.kotlin.attribute.descriptor.captured.variable") to KotlinHighlightingColors.WRAPPED_INTO_REF, OptionsBundle.message("options.java.attribute.descriptor.parameter") to KotlinHighlightingColors.PARAMETER,
KotlinBundle.message("options.kotlin.attribute.descriptor.instance.property") to KotlinHighlightingColors.INSTANCE_PROPERTY, KotlinBundle.message("options.kotlin.attribute.descriptor.captured.variable") to KotlinHighlightingColors.WRAPPED_INTO_REF,
KotlinBundle.message("options.kotlin.attribute.descriptor.package.property") to KotlinHighlightingColors.PACKAGE_PROPERTY, KotlinBundle.message("options.kotlin.attribute.descriptor.instance.property") to KotlinHighlightingColors.INSTANCE_PROPERTY,
KotlinBundle.message("options.kotlin.attribute.descriptor.field") to KotlinHighlightingColors.BACKING_FIELD_VARIABLE, KotlinBundle.message("options.kotlin.attribute.descriptor.package.property") to KotlinHighlightingColors.PACKAGE_PROPERTY,
KotlinBundle.message("options.kotlin.attribute.descriptor.extension.property") to KotlinHighlightingColors.EXTENSION_PROPERTY, KotlinBundle.message("options.kotlin.attribute.descriptor.field") to KotlinHighlightingColors.BACKING_FIELD_VARIABLE,
KotlinBundle.message("options.kotlin.attribute.descriptor.synthetic.extension.property") to KotlinHighlightingColors.SYNTHETIC_EXTENSION_PROPERTY, KotlinBundle.message("options.kotlin.attribute.descriptor.extension.property") to KotlinHighlightingColors.EXTENSION_PROPERTY,
KotlinBundle.message("options.kotlin.attribute.descriptor.dynamic.property") to KotlinHighlightingColors.DYNAMIC_PROPERTY_CALL, KotlinBundle.message("options.kotlin.attribute.descriptor.synthetic.extension.property") to KotlinHighlightingColors.SYNTHETIC_EXTENSION_PROPERTY,
KotlinBundle.message("options.kotlin.attribute.descriptor.android.extensions.property") to KotlinHighlightingColors.ANDROID_EXTENSIONS_PROPERTY_CALL, KotlinBundle.message("options.kotlin.attribute.descriptor.dynamic.property") to KotlinHighlightingColors.DYNAMIC_PROPERTY_CALL,
KotlinBundle.message("options.kotlin.attribute.descriptor.it") to KotlinHighlightingColors.FUNCTION_LITERAL_DEFAULT_PARAMETER, KotlinBundle.message("options.kotlin.attribute.descriptor.android.extensions.property") to KotlinHighlightingColors.ANDROID_EXTENSIONS_PROPERTY_CALL,
KotlinBundle.message("options.kotlin.attribute.descriptor.fun") to KotlinHighlightingColors.FUNCTION_DECLARATION, KotlinBundle.message("options.kotlin.attribute.descriptor.it") to KotlinHighlightingColors.FUNCTION_LITERAL_DEFAULT_PARAMETER,
KotlinBundle.message("options.kotlin.attribute.descriptor.fun.call") to KotlinHighlightingColors.FUNCTION_CALL, KotlinBundle.message("options.kotlin.attribute.descriptor.fun") to KotlinHighlightingColors.FUNCTION_DECLARATION,
KotlinBundle.message("options.kotlin.attribute.descriptor.dynamic.fun.call") to KotlinHighlightingColors.DYNAMIC_FUNCTION_CALL, KotlinBundle.message("options.kotlin.attribute.descriptor.fun.call") to KotlinHighlightingColors.FUNCTION_CALL,
KotlinBundle.message("options.kotlin.attribute.descriptor.package.fun.call") to KotlinHighlightingColors.PACKAGE_FUNCTION_CALL, KotlinBundle.message("options.kotlin.attribute.descriptor.dynamic.fun.call") to KotlinHighlightingColors.DYNAMIC_FUNCTION_CALL,
KotlinBundle.message("options.kotlin.attribute.descriptor.extension.fun.call") to KotlinHighlightingColors.EXTENSION_FUNCTION_CALL, KotlinBundle.message("options.kotlin.attribute.descriptor.package.fun.call") to KotlinHighlightingColors.PACKAGE_FUNCTION_CALL,
KotlinBundle.message("options.kotlin.attribute.descriptor.constructor.call") to KotlinHighlightingColors.CONSTRUCTOR_CALL, KotlinBundle.message("options.kotlin.attribute.descriptor.extension.fun.call") to KotlinHighlightingColors.EXTENSION_FUNCTION_CALL,
KotlinBundle.message("options.kotlin.attribute.descriptor.variable.as.function.call") to KotlinHighlightingColors.VARIABLE_AS_FUNCTION_CALL, KotlinBundle.message("options.kotlin.attribute.descriptor.constructor.call") to KotlinHighlightingColors.CONSTRUCTOR_CALL,
KotlinBundle.message("options.kotlin.attribute.descriptor.variable.as.function.like.call") to KotlinHighlightingColors.VARIABLE_AS_FUNCTION_LIKE_CALL, KotlinBundle.message("options.kotlin.attribute.descriptor.variable.as.function.call") to KotlinHighlightingColors.VARIABLE_AS_FUNCTION_CALL,
KotlinBundle.message("options.kotlin.attribute.descriptor.smart.cast") to KotlinHighlightingColors.SMART_CAST_VALUE, KotlinBundle.message("options.kotlin.attribute.descriptor.variable.as.function.like.call") to KotlinHighlightingColors.VARIABLE_AS_FUNCTION_LIKE_CALL,
KotlinBundle.message("options.kotlin.attribute.descriptor.smart.constant") to KotlinHighlightingColors.SMART_CONSTANT, KotlinBundle.message("options.kotlin.attribute.descriptor.smart.cast") to KotlinHighlightingColors.SMART_CAST_VALUE,
KotlinBundle.message("options.kotlin.attribute.descriptor.smart.cast.receiver") to KotlinHighlightingColors.SMART_CAST_RECEIVER, KotlinBundle.message("options.kotlin.attribute.descriptor.smart.constant") to KotlinHighlightingColors.SMART_CONSTANT,
KotlinBundle.message("options.kotlin.attribute.descriptor.label") to KotlinHighlightingColors.LABEL, KotlinBundle.message("options.kotlin.attribute.descriptor.smart.cast.receiver") to KotlinHighlightingColors.SMART_CAST_RECEIVER,
"Named argument" to KotlinHighlightingColors.NAMED_ARGUMENT) + KotlinBundle.message("options.kotlin.attribute.descriptor.label") to KotlinHighlightingColors.LABEL,
DslHighlighterExtension.descriptionsToStyles.map { (description, key) -> description to key }.toTypedArray() "Named argument" to KotlinHighlightingColors.NAMED_ARGUMENT
) +
DslHighlighterExtension.descriptionsToStyles.map { (description, key) -> description to key }.toTypedArray()
} }
override fun getColorDescriptors(): Array<ColorDescriptor> = ColorDescriptor.EMPTY_ARRAY override fun getColorDescriptors(): Array<ColorDescriptor> = ColorDescriptor.EMPTY_ARRAY
@@ -185,6 +186,6 @@ var <PACKAGE_PROPERTY><MUTABLE_VARIABLE>globalCounter</MUTABLE_VARIABLE></PACKAG
override fun isRainbowType(type: TextAttributesKey): Boolean { override fun isRainbowType(type: TextAttributesKey): Boolean {
return type == KotlinHighlightingColors.LOCAL_VARIABLE || return type == KotlinHighlightingColors.LOCAL_VARIABLE ||
type == KotlinHighlightingColors.PARAMETER type == KotlinHighlightingColors.PARAMETER
} }
} }
@@ -40,9 +40,9 @@ class KotlinHighlightExitPointsHandlerFactory : HighlightUsagesHandlerFactoryBas
override fun createHighlightUsagesHandler(editor: Editor, file: PsiFile, target: PsiElement): HighlightUsagesHandlerBase<*>? { override fun createHighlightUsagesHandler(editor: Editor, file: PsiFile, target: PsiElement): HighlightUsagesHandlerBase<*>? {
if (target is LeafPsiElement && (target.elementType in RETURN_AND_THROW)) { if (target is LeafPsiElement && (target.elementType in RETURN_AND_THROW)) {
val returnOrThrow = PsiTreeUtil.getParentOfType<KtExpression>( val returnOrThrow = PsiTreeUtil.getParentOfType<KtExpression>(
target, target,
KtReturnExpression::class.java, KtReturnExpression::class.java,
KtThrowExpression::class.java KtThrowExpression::class.java
) ?: return null ) ?: return null
return MyHandler(editor, file, returnOrThrow) return MyHandler(editor, file, returnOrThrow)
@@ -50,7 +50,8 @@ class KotlinHighlightExitPointsHandlerFactory : HighlightUsagesHandlerFactoryBas
return null return null
} }
private class MyHandler(editor: Editor, file: PsiFile, val target: KtExpression) : HighlightUsagesHandlerBase<PsiElement>(editor, file) { private class MyHandler(editor: Editor, file: PsiFile, val target: KtExpression) :
HighlightUsagesHandlerBase<PsiElement>(editor, file) {
override fun getTargets() = listOf(target) override fun getTargets() = listOf(target)
override fun selectTargets(targets: MutableList<PsiElement>, selectionConsumer: Consumer<MutableList<PsiElement>>) { override fun selectTargets(targets: MutableList<PsiElement>, selectionConsumer: Consumer<MutableList<PsiElement>>) {
@@ -38,19 +38,19 @@ class KotlinHighlightImplicitItHandlerFactory : HighlightUsagesHandlerFactoryBas
override fun getTargets() = listOf(refExpr) override fun getTargets() = listOf(refExpr)
override fun selectTargets( override fun selectTargets(
targets: MutableList<KtNameReferenceExpression>, targets: MutableList<KtNameReferenceExpression>,
selectionConsumer: Consumer<MutableList<KtNameReferenceExpression>> selectionConsumer: Consumer<MutableList<KtNameReferenceExpression>>
) = selectionConsumer.consume(targets) ) = selectionConsumer.consume(targets)
override fun computeUsages(targets: MutableList<KtNameReferenceExpression>?) { override fun computeUsages(targets: MutableList<KtNameReferenceExpression>?) {
lambda.accept( lambda.accept(
object : KtTreeVisitorVoid() { object : KtTreeVisitorVoid() {
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) { override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
if (expression is KtNameReferenceExpression && getLambdaByImplicitItReference(expression) == lambda) { if (expression is KtNameReferenceExpression && getLambdaByImplicitItReference(expression) == lambda) {
addOccurrence(expression) addOccurrence(expression)
}
} }
} }
}
) )
} }
} }
@@ -62,7 +62,12 @@ class KotlinRecursiveCallLineMarkerProvider : LineMarkerProvider {
private fun getEnclosingFunction(element: KtElement, stopOnNonInlinedLambdas: Boolean): KtNamedFunction? { private fun getEnclosingFunction(element: KtElement, stopOnNonInlinedLambdas: Boolean): KtNamedFunction? {
for (parent in element.parents) { for (parent in element.parents) {
when (parent) { when (parent) {
is KtFunctionLiteral -> if (stopOnNonInlinedLambdas && !InlineUtil.isInlinedArgument(parent, parent.analyze(), false)) return null is KtFunctionLiteral -> if (stopOnNonInlinedLambdas && !InlineUtil.isInlinedArgument(
parent,
parent.analyze(),
false
)
) return null
is KtNamedFunction -> { is KtNamedFunction -> {
when (parent.parent) { when (parent.parent) {
is KtBlockExpression, is KtClassBody, is KtFile, is KtScript -> return parent is KtBlockExpression, is KtClassBody, is KtFile, is KtScript -> return parent
@@ -84,7 +89,8 @@ class KotlinRecursiveCallLineMarkerProvider : LineMarkerProvider {
val enclosingFunctionName = enclosingFunction.name val enclosingFunctionName = enclosingFunction.name
if (enclosingFunctionName != OperatorNameConventions.INVOKE.asString() if (enclosingFunctionName != OperatorNameConventions.INVOKE.asString()
&& enclosingFunctionName != resolveName.asString()) return false && enclosingFunctionName != resolveName.asString()
) return false
// Check that there were no not-inlined lambdas on the way to enclosing function // Check that there were no not-inlined lambdas on the way to enclosing function
if (enclosingFunction != getEnclosingFunction(element, true)) return false if (enclosingFunction != getEnclosingFunction(element, true)) return false
@@ -113,15 +119,14 @@ class KotlinRecursiveCallLineMarkerProvider : LineMarkerProvider {
return true return true
} }
private class RecursiveMethodCallMarkerInfo(callElement: PsiElement) private class RecursiveMethodCallMarkerInfo(callElement: PsiElement) : LineMarkerInfo<PsiElement>(
: LineMarkerInfo<PsiElement>( callElement,
callElement, callElement.textRange,
callElement.textRange, AllIcons.Gutter.RecursiveMethod,
AllIcons.Gutter.RecursiveMethod, Pass.LINE_MARKERS,
Pass.LINE_MARKERS, { "Recursive call" },
{ "Recursive call" }, null,
null, GutterIconRenderer.Alignment.RIGHT
GutterIconRenderer.Alignment.RIGHT
) { ) {
override fun createGutterRenderer(): GutterIconRenderer? { override fun createGutterRenderer(): GutterIconRenderer? {
@@ -134,13 +139,13 @@ class KotlinRecursiveCallLineMarkerProvider : LineMarkerProvider {
} }
internal fun getElementForLineMark(callElement: PsiElement): PsiElement = internal fun getElementForLineMark(callElement: PsiElement): PsiElement =
when (callElement) { when (callElement) {
is KtSimpleNameExpression -> callElement.getReferencedNameElement() is KtSimpleNameExpression -> callElement.getReferencedNameElement()
else -> else ->
// a fallback, // a fallback,
//but who knows what to reference in KtArrayAccessExpression ? //but who knows what to reference in KtArrayAccessExpression ?
generateSequence(callElement, { it.firstChild }).last() generateSequence(callElement, { it.firstChild }).last()
} }
private fun PsiElement.getLineNumber(): Int { private fun PsiElement.getLineNumber(): Int {
return PsiDocumentManager.getInstance(project).getDocument(containingFile)!!.getLineNumber(textOffset) return PsiDocumentManager.getInstance(project).getDocument(containingFile)!!.getLineNumber(textOffset)
@@ -158,13 +163,12 @@ private fun getCallNameFromPsi(element: KtElement): Name? {
val node = operationReference.getReferencedNameElementType() val node = operationReference.getReferencedNameElementType()
return if (node is KtToken) { return if (node is KtToken) {
val conventionName = if (elementParent is KtPrefixExpression) val conventionName = if (elementParent is KtPrefixExpression)
OperatorConventions.getNameForOperationSymbol(node, true, false) OperatorConventions.getNameForOperationSymbol(node, true, false)
else else
OperatorConventions.getNameForOperationSymbol(node) OperatorConventions.getNameForOperationSymbol(node)
conventionName ?: Name.identifier(element.getText()) conventionName ?: Name.identifier(element.getText())
} } else {
else {
Name.identifier(element.getText()) Name.identifier(element.getText())
} }
} }
@@ -62,7 +62,12 @@ class KotlinRecursiveCallLineMarkerProvider : LineMarkerProvider {
private fun getEnclosingFunction(element: KtElement, stopOnNonInlinedLambdas: Boolean): KtNamedFunction? { private fun getEnclosingFunction(element: KtElement, stopOnNonInlinedLambdas: Boolean): KtNamedFunction? {
for (parent in element.parents) { for (parent in element.parents) {
when (parent) { when (parent) {
is KtFunctionLiteral -> if (stopOnNonInlinedLambdas && !InlineUtil.isInlinedArgument(parent, parent.analyze(), false)) return null is KtFunctionLiteral -> if (stopOnNonInlinedLambdas && !InlineUtil.isInlinedArgument(
parent,
parent.analyze(),
false
)
) return null
is KtNamedFunction -> { is KtNamedFunction -> {
when (parent.parent) { when (parent.parent) {
is KtBlockExpression, is KtClassBody, is KtFile, is KtScript -> return parent is KtBlockExpression, is KtClassBody, is KtFile, is KtScript -> return parent
@@ -84,7 +89,8 @@ class KotlinRecursiveCallLineMarkerProvider : LineMarkerProvider {
val enclosingFunctionName = enclosingFunction.name val enclosingFunctionName = enclosingFunction.name
if (enclosingFunctionName != OperatorNameConventions.INVOKE.asString() if (enclosingFunctionName != OperatorNameConventions.INVOKE.asString()
&& enclosingFunctionName != resolveName.asString()) return false && enclosingFunctionName != resolveName.asString()
) return false
// Check that there were no not-inlined lambdas on the way to enclosing function // Check that there were no not-inlined lambdas on the way to enclosing function
if (enclosingFunction != getEnclosingFunction(element, true)) return false if (enclosingFunction != getEnclosingFunction(element, true)) return false
@@ -113,15 +119,14 @@ class KotlinRecursiveCallLineMarkerProvider : LineMarkerProvider {
return true return true
} }
private class RecursiveMethodCallMarkerInfo(callElement: KtElement) private class RecursiveMethodCallMarkerInfo(callElement: KtElement) : LineMarkerInfo<KtElement>(
: LineMarkerInfo<KtElement>( callElement,
callElement, callElement.textRange,
callElement.textRange, AllIcons.Gutter.RecursiveMethod,
AllIcons.Gutter.RecursiveMethod, Pass.LINE_MARKERS,
Pass.LINE_MARKERS, { "Recursive call" },
{ "Recursive call" }, null,
null, GutterIconRenderer.Alignment.RIGHT
GutterIconRenderer.Alignment.RIGHT
) { ) {
override fun createGutterRenderer(): GutterIconRenderer? { override fun createGutterRenderer(): GutterIconRenderer? {
@@ -149,13 +154,12 @@ private fun getCallNameFromPsi(element: KtElement): Name? {
val node = operationReference.getReferencedNameElementType() val node = operationReference.getReferencedNameElementType()
return if (node is KtToken) { return if (node is KtToken) {
val conventionName = if (elementParent is KtPrefixExpression) val conventionName = if (elementParent is KtPrefixExpression)
OperatorConventions.getNameForOperationSymbol(node, true, false) OperatorConventions.getNameForOperationSymbol(node, true, false)
else else
OperatorConventions.getNameForOperationSymbol(node) OperatorConventions.getNameForOperationSymbol(node)
conventionName ?: Name.identifier(element.getText()) conventionName ?: Name.identifier(element.getText())
} } else {
else {
Name.identifier(element.getText()) Name.identifier(element.getText())
} }
} }
@@ -23,19 +23,18 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContext.* import org.jetbrains.kotlin.resolve.BindingContext.*
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.checkers.isBuiltInCoroutineContext
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class KotlinSuspendCallLineMarkerProvider : LineMarkerProvider { class KotlinSuspendCallLineMarkerProvider : LineMarkerProvider {
private class SuspendCallMarkerInfo(callElement: PsiElement, message: String) : LineMarkerInfo<PsiElement>( private class SuspendCallMarkerInfo(callElement: PsiElement, message: String) : LineMarkerInfo<PsiElement>(
callElement, callElement,
callElement.textRange, callElement.textRange,
KotlinIcons.SUSPEND_CALL, KotlinIcons.SUSPEND_CALL,
Pass.LINE_MARKERS, Pass.LINE_MARKERS,
{ message }, { message },
null, null,
GutterIconRenderer.Alignment.RIGHT GutterIconRenderer.Alignment.RIGHT
) { ) {
override fun createGutterRenderer(): GutterIconRenderer? { override fun createGutterRenderer(): GutterIconRenderer? {
return object : LineMarkerInfo.LineMarkerGutterIconRenderer<PsiElement>(this) { return object : LineMarkerInfo.LineMarkerGutterIconRenderer<PsiElement>(this) {
@@ -47,8 +46,8 @@ class KotlinSuspendCallLineMarkerProvider : LineMarkerProvider {
override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo<*>? = null override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo<*>? = null
override fun collectSlowLineMarkers( override fun collectSlowLineMarkers(
elements: MutableList<PsiElement>, elements: MutableList<PsiElement>,
result: MutableCollection<LineMarkerInfo<*>> result: MutableCollection<LineMarkerInfo<*>>
) { ) {
val markedLineNumbers = HashSet<Int>() val markedLineNumbers = HashSet<Int>()
@@ -29,13 +29,13 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class KotlinSuspendCallLineMarkerProvider : LineMarkerProvider { class KotlinSuspendCallLineMarkerProvider : LineMarkerProvider {
private class SuspendCallMarkerInfo(callElement: KtElement, message: String) : LineMarkerInfo<KtElement>( private class SuspendCallMarkerInfo(callElement: KtElement, message: String) : LineMarkerInfo<KtElement>(
callElement, callElement,
callElement.textRange, callElement.textRange,
KotlinIcons.SUSPEND_CALL, KotlinIcons.SUSPEND_CALL,
Pass.LINE_MARKERS, Pass.LINE_MARKERS,
{ message }, { message },
null, null,
GutterIconRenderer.Alignment.RIGHT GutterIconRenderer.Alignment.RIGHT
) { ) {
override fun createGutterRenderer(): GutterIconRenderer? { override fun createGutterRenderer(): GutterIconRenderer? {
return object : LineMarkerInfo.LineMarkerGutterIconRenderer<KtElement>(this) { return object : LineMarkerInfo.LineMarkerGutterIconRenderer<KtElement>(this) {
@@ -47,8 +47,8 @@ class KotlinSuspendCallLineMarkerProvider : LineMarkerProvider {
override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo<*>? = null override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo<*>? = null
override fun collectSlowLineMarkers( override fun collectSlowLineMarkers(
elements: MutableList<PsiElement>, elements: MutableList<PsiElement>,
result: MutableCollection<LineMarkerInfo<*>> result: MutableCollection<LineMarkerInfo<*>>
) { ) {
val markedLineNumbers = HashSet<Int>() val markedLineNumbers = HashSet<Int>()
@@ -95,7 +95,7 @@ class KotlinTestRunLineMarkerContributor : RunLineMarkerContributor() {
} }
private fun DeclarationDescriptor.isIgnored(): Boolean = private fun DeclarationDescriptor.isIgnored(): Boolean =
annotations.any { it.fqName == IGNORE_FQ_NAME } || ((containingDeclaration as? ClassDescriptor)?.isIgnored() ?: false) annotations.any { it.fqName == IGNORE_FQ_NAME } || ((containingDeclaration as? ClassDescriptor)?.isIgnored() ?: false)
private fun DeclarationDescriptor.isTest(): Boolean { private fun DeclarationDescriptor.isTest(): Boolean {
if (isIgnored()) return false if (isIgnored()) return false
@@ -51,8 +51,10 @@ class PlatformExpectedAnnotator : Annotator {
val trace = BindingTraceContext() val trace = BindingTraceContext()
for (module in implementingModules) { for (module in implementingModules) {
ExpectedActualDeclarationChecker.checkExpectedDeclarationHasActual(declaration, descriptor, trace, module, ExpectedActualDeclarationChecker.checkExpectedDeclarationHasActual(
ExpectActualTracker.DoNothing) declaration, descriptor, trace, module,
ExpectActualTracker.DoNothing
)
} }
val suppressionCache = KotlinCacheService.getInstance(declaration.project).getSuppressionCache() val suppressionCache = KotlinCacheService.getInstance(declaration.project).getSuppressionCache()
@@ -66,6 +68,6 @@ class PlatformExpectedAnnotator : Annotator {
private fun isExpectedDeclaration(declaration: KtDeclaration): Boolean { private fun isExpectedDeclaration(declaration: KtDeclaration): Boolean {
return declaration.hasExpectModifier() || return declaration.hasExpectModifier() ||
declaration is KtClassOrObject && KtPsiUtil.getOutermostClassOrObject(declaration)?.hasExpectModifier() == true declaration is KtClassOrObject && KtPsiUtil.getOutermostClassOrObject(declaration)?.hasExpectModifier() == true
} }
} }
@@ -51,9 +51,11 @@ fun navigateToPlatformActual(e: MouseEvent?, declaration: KtDeclaration?) {
val renderer = object : DefaultPsiElementCellRenderer() { val renderer = object : DefaultPsiElementCellRenderer() {
override fun getContainerText(element: PsiElement?, name: String?) = "" override fun getContainerText(element: PsiElement?, name: String?) = ""
} }
PsiElementListNavigator.openTargets(e, PsiElementListNavigator.openTargets(
actualDeclarations.toTypedArray(), e,
"Choose actual for ${declaration.name}", actualDeclarations.toTypedArray(),
"Actuals for ${declaration.name}", "Choose actual for ${declaration.name}",
renderer) "Actuals for ${declaration.name}",
renderer
)
} }
@@ -21,10 +21,14 @@ import com.intellij.psi.CommonClassNames
import com.intellij.psi.PsiClass import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.asJava.* import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightClass import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightClass
import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightMethod import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightMethod
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtSecondaryConstructor
import java.util.* import java.util.*
fun collectContainingClasses(methods: Collection<PsiMethod>): Set<PsiClass> { fun collectContainingClasses(methods: Collection<PsiMethod>): Set<PsiClass> {
@@ -57,7 +57,8 @@ class KotlinLineMarkerProvider : LineMarkerProvider {
if (element.canHaveSeparator()) { if (element.canHaveSeparator()) {
val prevSibling = element.getPrevSiblingIgnoringWhitespaceAndComments() val prevSibling = element.getPrevSiblingIgnoringWhitespaceAndComments()
if (prevSibling.canHaveSeparator() && if (prevSibling.canHaveSeparator() &&
(element.wantsSeparator() || prevSibling?.wantsSeparator() == true)) { (element.wantsSeparator() || prevSibling?.wantsSeparator() == true)
) {
return createLineSeparatorByElement(element) return createLineSeparatorByElement(element)
} }
} }
@@ -122,8 +123,7 @@ class KotlinLineMarkerProvider : LineMarkerProvider {
if (element.isExpectDeclaration()) { if (element.isExpectDeclaration()) {
collectActualMarkers(element, result) collectActualMarkers(element, result)
} } else if (element.isEffectivelyActual()) {
else if (element.isEffectivelyActual()) {
collectExpectedMarkers(element, result) collectExpectedMarkers(element, result)
} }
} }
@@ -136,11 +136,11 @@ private val OVERRIDDEN_MARK: Icon = AllIcons.Gutter.OverridenMethod
private val IMPLEMENTED_MARK: Icon = AllIcons.Gutter.ImplementedMethod private val IMPLEMENTED_MARK: Icon = AllIcons.Gutter.ImplementedMethod
data class NavigationPopupDescriptor( data class NavigationPopupDescriptor(
val targets: Collection<NavigatablePsiElement>, val targets: Collection<NavigatablePsiElement>,
val title: String, val title: String,
val findUsagesTitle: String, val findUsagesTitle: String,
val renderer: ListCellRenderer<*>, val renderer: ListCellRenderer<*>,
val updater: ListBackgroundUpdaterTask? = null val updater: ListBackgroundUpdaterTask? = null
) { ) {
fun showPopup(e: MouseEvent?) { fun showPopup(e: MouseEvent?) {
PsiElementListNavigator.openTargets(e, targets.toTypedArray(), title, findUsagesTitle, renderer, updater) PsiElementListNavigator.openTargets(e, targets.toTypedArray(), title, findUsagesTitle, renderer, updater)
@@ -151,7 +151,7 @@ interface TestableLineMarkerNavigator {
fun getTargetsPopupDescriptor(element: PsiElement?): NavigationPopupDescriptor? fun getTargetsPopupDescriptor(element: PsiElement?): NavigationPopupDescriptor?
} }
private class SubclassRenderer: PsiClassOrFunctionalExpressionListCellRenderer() { private class SubclassRenderer : PsiClassOrFunctionalExpressionListCellRenderer() {
override fun getComparingObject(element: NavigatablePsiElement?): Comparable<Nothing> { override fun getComparingObject(element: NavigatablePsiElement?): Comparable<Nothing> {
val baseText = super.getComparingObject(element) val baseText = super.getComparingObject(element)
val moduleName = element?.module?.name ?: return baseText val moduleName = element?.module?.name ?: return baseText
@@ -160,22 +160,22 @@ private class SubclassRenderer: PsiClassOrFunctionalExpressionListCellRenderer()
} }
private val SUBCLASSED_CLASS = MarkerType( private val SUBCLASSED_CLASS = MarkerType(
"SUBCLASSED_CLASS", "SUBCLASSED_CLASS",
{ getPsiClass(it)?.let { MarkerType.getSubclassedClassTooltip(it) } }, { getPsiClass(it)?.let { MarkerType.getSubclassedClassTooltip(it) } },
object : LineMarkerNavigator() { object : LineMarkerNavigator() {
override fun browse(e: MouseEvent?, element: PsiElement?) { override fun browse(e: MouseEvent?, element: PsiElement?) {
getPsiClass(element)?.let { MarkerType.navigateToSubclassedClass(e, it, SubclassRenderer()) } getPsiClass(element)?.let { MarkerType.navigateToSubclassedClass(e, it, SubclassRenderer()) }
} }
}) })
private val OVERRIDDEN_FUNCTION = object : MarkerType( private val OVERRIDDEN_FUNCTION = object : MarkerType(
"OVERRIDDEN_FUNCTION", "OVERRIDDEN_FUNCTION",
{ getPsiMethod(it)?.let(::getOverriddenMethodTooltip) }, { getPsiMethod(it)?.let(::getOverriddenMethodTooltip) },
object : LineMarkerNavigator() { object : LineMarkerNavigator() {
override fun browse(e: MouseEvent?, element: PsiElement?) { override fun browse(e: MouseEvent?, element: PsiElement?) {
buildNavigateToOverriddenMethodPopup(e, element)?.showPopup(e) buildNavigateToOverriddenMethodPopup(e, element)?.showPopup(e)
} }
}) { }) {
override fun getNavigationHandler(): GutterIconNavigationHandler<PsiElement> { override fun getNavigationHandler(): GutterIconNavigationHandler<PsiElement> {
val superHandler = super.getNavigationHandler() val superHandler = super.getNavigationHandler()
@@ -190,13 +190,13 @@ private val OVERRIDDEN_FUNCTION = object : MarkerType(
} }
private val OVERRIDDEN_PROPERTY = object : MarkerType( private val OVERRIDDEN_PROPERTY = object : MarkerType(
"OVERRIDDEN_PROPERTY", "OVERRIDDEN_PROPERTY",
{ it?.let { getOverriddenPropertyTooltip(it.parent as KtNamedDeclaration) } }, { it?.let { getOverriddenPropertyTooltip(it.parent as KtNamedDeclaration) } },
object : LineMarkerNavigator() { object : LineMarkerNavigator() {
override fun browse(e: MouseEvent?, element: PsiElement?) { override fun browse(e: MouseEvent?, element: PsiElement?) {
buildNavigateToPropertyOverriddenDeclarationsPopup(e, element)?.showPopup(e) buildNavigateToPropertyOverriddenDeclarationsPopup(e, element)?.showPopup(e)
} }
}) { }) {
override fun getNavigationHandler(): GutterIconNavigationHandler<PsiElement> { override fun getNavigationHandler(): GutterIconNavigationHandler<PsiElement> {
val superHandler = super.getNavigationHandler() val superHandler = super.getNavigationHandler()
@@ -214,26 +214,29 @@ private val PsiElement.markerDeclaration
get() = (this as? KtDeclaration) ?: (parent as? KtDeclaration) get() = (this as? KtDeclaration) ?: (parent as? KtDeclaration)
private val PLATFORM_ACTUAL = MarkerType( private val PLATFORM_ACTUAL = MarkerType(
"PLATFORM_ACTUAL", "PLATFORM_ACTUAL",
{ it?.let { getPlatformActualTooltip(it.markerDeclaration) } }, { it?.let { getPlatformActualTooltip(it.markerDeclaration) } },
object : LineMarkerNavigator() { object : LineMarkerNavigator() {
override fun browse(e: MouseEvent?, element: PsiElement?) { override fun browse(e: MouseEvent?, element: PsiElement?) {
element?.let { navigateToPlatformActual(e, it.markerDeclaration) } element?.let { navigateToPlatformActual(e, it.markerDeclaration) }
}
} }
}
) )
private val EXPECTED_DECLARATION = MarkerType( private val EXPECTED_DECLARATION = MarkerType(
"EXPECTED_DECLARATION", "EXPECTED_DECLARATION",
{ it?.let { getExpectedDeclarationTooltip(it.markerDeclaration) } }, { it?.let { getExpectedDeclarationTooltip(it.markerDeclaration) } },
object : LineMarkerNavigator() { object : LineMarkerNavigator() {
override fun browse(e: MouseEvent?, element: PsiElement?) { override fun browse(e: MouseEvent?, element: PsiElement?) {
element?.let { navigateToExpectedDeclaration(it.markerDeclaration) } element?.let { navigateToExpectedDeclaration(it.markerDeclaration) }
}
} }
}
) )
private fun isImplementsAndNotOverrides(descriptor: CallableMemberDescriptor, overriddenMembers: Collection<CallableMemberDescriptor>): Boolean { private fun isImplementsAndNotOverrides(
descriptor: CallableMemberDescriptor,
overriddenMembers: Collection<CallableMemberDescriptor>
): Boolean {
return descriptor.modality != Modality.ABSTRACT && overriddenMembers.all { it.modality == Modality.ABSTRACT } return descriptor.modality != Modality.ABSTRACT && overriddenMembers.all { it.modality == Modality.ABSTRACT }
} }
@@ -297,8 +300,10 @@ private fun collectInheritedClassMarker(element: KtClass, result: MutableCollect
result.add(lineMarkerInfo) result.add(lineMarkerInfo)
} }
private fun collectOverriddenPropertyAccessors(properties: Collection<KtNamedDeclaration>, private fun collectOverriddenPropertyAccessors(
result: MutableCollection<LineMarkerInfo<*>>) { properties: Collection<KtNamedDeclaration>,
result: MutableCollection<LineMarkerInfo<*>>
) {
val mappingToJava = HashMap<PsiElement, KtNamedDeclaration>() val mappingToJava = HashMap<PsiElement, KtNamedDeclaration>()
for (property in properties) { for (property in properties) {
if (property.isOverridable()) { if (property.isOverridable()) {
@@ -335,13 +340,15 @@ private fun collectOverriddenPropertyAccessors(properties: Collection<KtNamedDec
private val KtNamedDeclaration.expectOrActualAnchor private val KtNamedDeclaration.expectOrActualAnchor
get() = get() =
nameIdentifier nameIdentifier
?: (this as? KtConstructor<*>)?.let { ?: (this as? KtConstructor<*>)?.let {
it.getConstructorKeyword() ?: it.getValueParameterList()?.leftParenthesis it.getConstructorKeyword() ?: it.getValueParameterList()?.leftParenthesis
} }
?: this ?: this
private fun collectActualMarkers(declaration: KtNamedDeclaration, private fun collectActualMarkers(
result: MutableCollection<LineMarkerInfo<*>>) { declaration: KtNamedDeclaration,
result: MutableCollection<LineMarkerInfo<*>>
) {
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
@@ -367,8 +374,10 @@ private fun collectActualMarkers(declaration: KtNamedDeclaration,
result.add(lineMarkerInfo) result.add(lineMarkerInfo)
} }
private fun collectExpectedMarkers(declaration: KtNamedDeclaration, private fun collectExpectedMarkers(
result: MutableCollection<LineMarkerInfo<*>>) { declaration: KtNamedDeclaration,
result: MutableCollection<LineMarkerInfo<*>>
) {
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
val platformModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() val platformModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
@@ -56,7 +56,8 @@ class KotlinLineMarkerProvider : LineMarkerProvider {
if (element.canHaveSeparator()) { if (element.canHaveSeparator()) {
val prevSibling = element.getPrevSiblingIgnoringWhitespaceAndComments() val prevSibling = element.getPrevSiblingIgnoringWhitespaceAndComments()
if (prevSibling.canHaveSeparator() && if (prevSibling.canHaveSeparator() &&
(element.wantsSeparator() || prevSibling?.wantsSeparator() == true)) { (element.wantsSeparator() || prevSibling?.wantsSeparator() == true)
) {
return createLineSeparatorByElement(element) return createLineSeparatorByElement(element)
} }
} }
@@ -121,8 +122,7 @@ class KotlinLineMarkerProvider : LineMarkerProvider {
if (element.isExpectDeclaration()) { if (element.isExpectDeclaration()) {
collectActualMarkers(element, result) collectActualMarkers(element, result)
} } else if (element.isEffectivelyActual()) {
else if (element.isEffectivelyActual()) {
collectExpectedMarkers(element, result) collectExpectedMarkers(element, result)
} }
} }
@@ -135,11 +135,11 @@ private val OVERRIDDEN_MARK: Icon = AllIcons.Gutter.OverridenMethod
private val IMPLEMENTED_MARK: Icon = AllIcons.Gutter.ImplementedMethod private val IMPLEMENTED_MARK: Icon = AllIcons.Gutter.ImplementedMethod
data class NavigationPopupDescriptor( data class NavigationPopupDescriptor(
val targets: Collection<NavigatablePsiElement>, val targets: Collection<NavigatablePsiElement>,
val title: String, val title: String,
val findUsagesTitle: String, val findUsagesTitle: String,
val renderer: ListCellRenderer<*>, val renderer: ListCellRenderer<*>,
val updater: ListBackgroundUpdaterTask? = null val updater: ListBackgroundUpdaterTask? = null
) { ) {
fun showPopup(e: MouseEvent?) { fun showPopup(e: MouseEvent?) {
PsiElementListNavigator.openTargets(e, targets.toTypedArray(), title, findUsagesTitle, renderer, updater) PsiElementListNavigator.openTargets(e, targets.toTypedArray(), title, findUsagesTitle, renderer, updater)
@@ -151,22 +151,22 @@ interface TestableLineMarkerNavigator {
} }
private val SUBCLASSED_CLASS = MarkerType( private val SUBCLASSED_CLASS = MarkerType(
"SUBCLASSED_CLASS", "SUBCLASSED_CLASS",
{ getPsiClass(it)?.let { MarkerType.getSubclassedClassTooltip(it) } }, { getPsiClass(it)?.let { MarkerType.getSubclassedClassTooltip(it) } },
object : LineMarkerNavigator() { object : LineMarkerNavigator() {
override fun browse(e: MouseEvent?, element: PsiElement?) { override fun browse(e: MouseEvent?, element: PsiElement?) {
getPsiClass(element)?.let { MarkerType.navigateToSubclassedClass(e, it) } getPsiClass(element)?.let { MarkerType.navigateToSubclassedClass(e, it) }
} }
}) })
private val OVERRIDDEN_FUNCTION = object : MarkerType( private val OVERRIDDEN_FUNCTION = object : MarkerType(
"OVERRIDDEN_FUNCTION", "OVERRIDDEN_FUNCTION",
{ getPsiMethod(it)?.let(::getOverriddenMethodTooltip) }, { getPsiMethod(it)?.let(::getOverriddenMethodTooltip) },
object : LineMarkerNavigator() { object : LineMarkerNavigator() {
override fun browse(e: MouseEvent?, element: PsiElement?) { override fun browse(e: MouseEvent?, element: PsiElement?) {
buildNavigateToOverriddenMethodPopup(e, element)?.showPopup(e) buildNavigateToOverriddenMethodPopup(e, element)?.showPopup(e)
} }
}) { }) {
override fun getNavigationHandler(): GutterIconNavigationHandler<PsiElement> { override fun getNavigationHandler(): GutterIconNavigationHandler<PsiElement> {
val superHandler = super.getNavigationHandler() val superHandler = super.getNavigationHandler()
@@ -181,13 +181,13 @@ private val OVERRIDDEN_FUNCTION = object : MarkerType(
} }
private val OVERRIDDEN_PROPERTY = object : MarkerType( private val OVERRIDDEN_PROPERTY = object : MarkerType(
"OVERRIDDEN_PROPERTY", "OVERRIDDEN_PROPERTY",
{ it?.let { getOverriddenPropertyTooltip(it.parent as KtNamedDeclaration) } }, { it?.let { getOverriddenPropertyTooltip(it.parent as KtNamedDeclaration) } },
object : LineMarkerNavigator() { object : LineMarkerNavigator() {
override fun browse(e: MouseEvent?, element: PsiElement?) { override fun browse(e: MouseEvent?, element: PsiElement?) {
buildNavigateToPropertyOverriddenDeclarationsPopup(e, element)?.showPopup(e) buildNavigateToPropertyOverriddenDeclarationsPopup(e, element)?.showPopup(e)
} }
}) { }) {
override fun getNavigationHandler(): GutterIconNavigationHandler<PsiElement> { override fun getNavigationHandler(): GutterIconNavigationHandler<PsiElement> {
val superHandler = super.getNavigationHandler() val superHandler = super.getNavigationHandler()
@@ -205,26 +205,29 @@ private val PsiElement.markerDeclaration
get() = (this as? KtDeclaration) ?: (parent as? KtDeclaration) get() = (this as? KtDeclaration) ?: (parent as? KtDeclaration)
private val PLATFORM_ACTUAL = MarkerType( private val PLATFORM_ACTUAL = MarkerType(
"PLATFORM_ACTUAL", "PLATFORM_ACTUAL",
{ it?.let { getPlatformActualTooltip(it.markerDeclaration) } }, { it?.let { getPlatformActualTooltip(it.markerDeclaration) } },
object : LineMarkerNavigator() { object : LineMarkerNavigator() {
override fun browse(e: MouseEvent?, element: PsiElement?) { override fun browse(e: MouseEvent?, element: PsiElement?) {
element?.let { navigateToPlatformActual(e, it.markerDeclaration) } element?.let { navigateToPlatformActual(e, it.markerDeclaration) }
}
} }
}
) )
private val EXPECTED_DECLARATION = MarkerType( private val EXPECTED_DECLARATION = MarkerType(
"EXPECTED_DECLARATION", "EXPECTED_DECLARATION",
{ it?.let { getExpectedDeclarationTooltip(it.markerDeclaration) } }, { it?.let { getExpectedDeclarationTooltip(it.markerDeclaration) } },
object : LineMarkerNavigator() { object : LineMarkerNavigator() {
override fun browse(e: MouseEvent?, element: PsiElement?) { override fun browse(e: MouseEvent?, element: PsiElement?) {
element?.let { navigateToExpectedDeclaration(it.markerDeclaration) } element?.let { navigateToExpectedDeclaration(it.markerDeclaration) }
}
} }
}
) )
private fun isImplementsAndNotOverrides(descriptor: CallableMemberDescriptor, overriddenMembers: Collection<CallableMemberDescriptor>): Boolean { private fun isImplementsAndNotOverrides(
descriptor: CallableMemberDescriptor,
overriddenMembers: Collection<CallableMemberDescriptor>
): Boolean {
return descriptor.modality != Modality.ABSTRACT && overriddenMembers.all { it.modality == Modality.ABSTRACT } return descriptor.modality != Modality.ABSTRACT && overriddenMembers.all { it.modality == Modality.ABSTRACT }
} }
@@ -288,8 +291,10 @@ private fun collectInheritedClassMarker(element: KtClass, result: MutableCollect
result.add(lineMarkerInfo) result.add(lineMarkerInfo)
} }
private fun collectOverriddenPropertyAccessors(properties: Collection<KtNamedDeclaration>, private fun collectOverriddenPropertyAccessors(
result: MutableCollection<LineMarkerInfo<*>>) { properties: Collection<KtNamedDeclaration>,
result: MutableCollection<LineMarkerInfo<*>>
) {
val mappingToJava = HashMap<PsiElement, KtNamedDeclaration>() val mappingToJava = HashMap<PsiElement, KtNamedDeclaration>()
for (property in properties) { for (property in properties) {
if (property.isOverridable()) { if (property.isOverridable()) {
@@ -326,13 +331,15 @@ private fun collectOverriddenPropertyAccessors(properties: Collection<KtNamedDec
private val KtNamedDeclaration.expectOrActualAnchor private val KtNamedDeclaration.expectOrActualAnchor
get() = get() =
nameIdentifier nameIdentifier
?: (this as? KtConstructor<*>)?.let { ?: (this as? KtConstructor<*>)?.let {
it.getConstructorKeyword() ?: it.getValueParameterList()?.leftParenthesis it.getConstructorKeyword() ?: it.getValueParameterList()?.leftParenthesis
} }
?: this ?: this
private fun collectActualMarkers(declaration: KtNamedDeclaration, private fun collectActualMarkers(
result: MutableCollection<LineMarkerInfo<*>>) { declaration: KtNamedDeclaration,
result: MutableCollection<LineMarkerInfo<*>>
) {
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
@@ -358,8 +365,10 @@ private fun collectActualMarkers(declaration: KtNamedDeclaration,
result.add(lineMarkerInfo) result.add(lineMarkerInfo)
} }
private fun collectExpectedMarkers(declaration: KtNamedDeclaration, private fun collectExpectedMarkers(
result: MutableCollection<LineMarkerInfo<*>>) { declaration: KtNamedDeclaration,
result: MutableCollection<LineMarkerInfo<*>>
) {
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
val platformModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() val platformModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
@@ -30,7 +30,6 @@ import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiModifier import com.intellij.psi.PsiModifier
import com.intellij.psi.search.PsiElementProcessor import com.intellij.psi.search.PsiElementProcessor
import com.intellij.psi.search.PsiElementProcessorAdapter import com.intellij.psi.search.PsiElementProcessorAdapter
import com.intellij.psi.search.searches.OverridingMethodsSearch
import com.intellij.util.CommonProcessors import com.intellij.util.CommonProcessors
import gnu.trove.THashSet import gnu.trove.THashSet
import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.elements.KtLightMethod
@@ -91,7 +90,8 @@ fun buildNavigateToOverriddenMethodPopup(e: MouseEvent?, element: PsiElement?):
val method = getPsiMethod(element) ?: return null val method = getPsiMethod(element) ?: return null
if (DumbService.isDumb(method.project)) { if (DumbService.isDumb(method.project)) {
DumbService.getInstance(method.project)?.showDumbModeNotification("Navigation to overriding classes is not possible during index update") DumbService.getInstance(method.project)
?.showDumbModeNotification("Navigation to overriding classes is not possible during index update")
return null return null
} }
@@ -104,7 +104,9 @@ fun buildNavigateToOverriddenMethodPopup(e: MouseEvent?, element: PsiElement?):
} }
} }
}, },
"Searching for overriding declarations", true, method.project, e?.component as JComponent?)) { "Searching for overriding declarations", true, method.project, e?.component as JComponent?
)
) {
return null return null
} }
@@ -115,17 +117,20 @@ fun buildNavigateToOverriddenMethodPopup(e: MouseEvent?, element: PsiElement?):
overridingJavaMethods = overridingJavaMethods.sortedWith(renderer.comparator) overridingJavaMethods = overridingJavaMethods.sortedWith(renderer.comparator)
val methodsUpdater = OverridingMethodsUpdater(method, renderer) val methodsUpdater = OverridingMethodsUpdater(method, renderer)
return NavigationPopupDescriptor(overridingJavaMethods, return NavigationPopupDescriptor(
methodsUpdater.getCaption(overridingJavaMethods.size), overridingJavaMethods,
"Overriding declarations of " + method.name, methodsUpdater.getCaption(overridingJavaMethods.size),
renderer, "Overriding declarations of " + method.name,
methodsUpdater) renderer,
methodsUpdater
)
} }
private class OverridingMethodsUpdater( private class OverridingMethodsUpdater(
private val myMethod: PsiMethod, private val myMethod: PsiMethod,
private val myRenderer: PsiElementListCellRenderer<out PsiElement>) : private val myRenderer: PsiElementListCellRenderer<out PsiElement>
ListBackgroundUpdaterTask(myMethod.project, "Searching for overriding methods") { ) :
ListBackgroundUpdaterTask(myMethod.project, "Searching for overriding methods") {
override fun getCaption(size: Int): String { override fun getCaption(size: Int): String {
return if (myMethod.hasModifierProperty(PsiModifier.ABSTRACT)) return if (myMethod.hasModifierProperty(PsiModifier.ABSTRACT))
DaemonBundle.message("navigation.title.implementation.method", myMethod.name, size)!! DaemonBundle.message("navigation.title.implementation.method", myMethod.name, size)!!
@@ -29,11 +29,9 @@ import com.intellij.psi.PsiMethod
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.PsiElementProcessor import com.intellij.psi.search.PsiElementProcessor
import com.intellij.psi.search.PsiElementProcessorAdapter import com.intellij.psi.search.PsiElementProcessorAdapter
import com.intellij.psi.search.searches.OverridingMethodsSearch
import com.intellij.util.AdapterProcessor import com.intellij.util.AdapterProcessor
import com.intellij.util.CommonProcessors import com.intellij.util.CommonProcessors
import com.intellij.util.Function import com.intellij.util.Function
import org.jetbrains.kotlin.asJava.getAccessorLightMethods
import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod
import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods
@@ -47,8 +45,8 @@ fun getOverriddenPropertyTooltip(property: KtNamedDeclaration): String? {
val overriddenInClassesProcessor = PsiElementProcessor.CollectElementsWithLimit<PsiClass>(5) val overriddenInClassesProcessor = PsiElementProcessor.CollectElementsWithLimit<PsiClass>(5)
val consumer = AdapterProcessor<PsiMethod, PsiClass>( val consumer = AdapterProcessor<PsiMethod, PsiClass>(
CommonProcessors.UniqueProcessor<PsiClass>(PsiElementProcessorAdapter(overriddenInClassesProcessor)), CommonProcessors.UniqueProcessor<PsiClass>(PsiElementProcessorAdapter(overriddenInClassesProcessor)),
Function { method: PsiMethod? -> method?.containingClass } Function { method: PsiMethod? -> method?.containingClass }
) )
for (method in property.toPossiblyFakeLightMethods()) { for (method in property.toPossiblyFakeLightMethods()) {
@@ -90,28 +88,33 @@ fun buildNavigateToPropertyOverriddenDeclarationsPopup(e: MouseEvent?, element:
val elementProcessor = CommonProcessors.CollectUniquesProcessor<PsiElement>() val elementProcessor = CommonProcessors.CollectUniquesProcessor<PsiElement>()
val ktPsiMethodProcessor = Runnable { val ktPsiMethodProcessor = Runnable {
KotlinDefinitionsSearcher.processPropertyImplementationsMethods( KotlinDefinitionsSearcher.processPropertyImplementationsMethods(
psiPropertyMethods, psiPropertyMethods,
GlobalSearchScope.allScope(project), GlobalSearchScope.allScope(project),
elementProcessor) elementProcessor
)
} }
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously( if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(
/* runnable */ ktPsiMethodProcessor, /* runnable */ ktPsiMethodProcessor,
MarkerType.SEARCHING_FOR_OVERRIDING_METHODS, MarkerType.SEARCHING_FOR_OVERRIDING_METHODS,
/* can be canceled */ true, /* can be canceled */ true,
project, project,
e?.component as JComponent?)) { e?.component as JComponent?
)
) {
return null return null
} }
val renderer = DefaultPsiElementCellRenderer() val renderer = DefaultPsiElementCellRenderer()
val navigatingOverrides = elementProcessor.results val navigatingOverrides = elementProcessor.results
.sortedWith(renderer.comparator) .sortedWith(renderer.comparator)
.filterIsInstance<NavigatablePsiElement>() .filterIsInstance<NavigatablePsiElement>()
return NavigationPopupDescriptor(navigatingOverrides, return NavigationPopupDescriptor(
KotlinBundle.message("navigation.title.overriding.property", propertyOrParameter.name), navigatingOverrides,
KotlinBundle.message("navigation.findUsages.title.overriding.property", propertyOrParameter.name), renderer) KotlinBundle.message("navigation.title.overriding.property", propertyOrParameter.name),
KotlinBundle.message("navigation.findUsages.title.overriding.property", propertyOrParameter.name), renderer
)
} }
@@ -38,7 +38,7 @@ import org.jetbrains.kotlin.renderer.RenderingFormat
import java.awt.event.MouseEvent import java.awt.event.MouseEvent
import java.util.* import java.util.*
object SuperDeclarationMarkerTooltip: Function<PsiElement, String> { object SuperDeclarationMarkerTooltip : Function<PsiElement, String> {
override fun `fun`(element: PsiElement): String? { override fun `fun`(element: PsiElement): String? {
val ktDeclaration = element.getParentOfType<KtDeclaration>(false) ?: return null val ktDeclaration = element.getParentOfType<KtDeclaration>(false) ?: return null
val (elementDescriptor, overriddenDescriptors) = resolveDeclarationWithParents(ktDeclaration!!) val (elementDescriptor, overriddenDescriptors) = resolveDeclarationWithParents(ktDeclaration!!)
@@ -83,16 +83,19 @@ class SuperDeclarationMarkerNavigationHandler : GutterIconNavigationHandler<PsiE
} }
val elementName = elementDescriptor!!.name val elementName = elementDescriptor!!.name
return NavigationPopupDescriptor(superDeclarations, return NavigationPopupDescriptor(
KotlinBundle.message("navigation.title.super.declaration", elementName), superDeclarations,
KotlinBundle.message("navigation.findUsages.title.super.declaration", elementName), KotlinBundle.message("navigation.title.super.declaration", elementName),
KtFunctionPsiElementCellRenderer()) KotlinBundle.message("navigation.findUsages.title.super.declaration", elementName),
KtFunctionPsiElementCellRenderer()
)
} }
} }
data class ResolveWithParentsResult( data class ResolveWithParentsResult(
val descriptor: CallableMemberDescriptor?, val descriptor: CallableMemberDescriptor?,
val overriddenDescriptors: Collection<CallableMemberDescriptor>) val overriddenDescriptors: Collection<CallableMemberDescriptor>
)
fun resolveDeclarationWithParents(element: KtDeclaration): ResolveWithParentsResult { fun resolveDeclarationWithParents(element: KtDeclaration): ResolveWithParentsResult {
val descriptor = if (element is KtParameter) val descriptor = if (element is KtParameter)