Don't highlight declaration with WRAPPED_INTO_REF
Leave highlighting only for usage. This may allow to make highlighting more local and lazy. Java follows the same rules for "Implicit anonymous class parameter".
This commit is contained in:
@@ -105,6 +105,7 @@ These artifacts include extensions for the types available in the latter JDKs, s
|
|||||||
- [`KT-13630`](https://youtrack.jetbrains.com/issue/KT-13630) Do not show Change Signature dialog when applying "Remove parameter" quick-fix
|
- [`KT-13630`](https://youtrack.jetbrains.com/issue/KT-13630) Do not show Change Signature dialog when applying "Remove parameter" quick-fix
|
||||||
- Re-highlight only single function after local modifications
|
- Re-highlight only single function after local modifications
|
||||||
- [`KT-13474`](https://youtrack.jetbrains.com/issue/KT-13474) Fix performance of typing super call lambda
|
- [`KT-13474`](https://youtrack.jetbrains.com/issue/KT-13474) Fix performance of typing super call lambda
|
||||||
|
- Show "Variables and values captured in a closure" highlighting only for usages
|
||||||
|
|
||||||
#### Intention actions, inspections and quickfixes
|
#### Intention actions, inspections and quickfixes
|
||||||
|
|
||||||
|
|||||||
-2
@@ -25,8 +25,6 @@ class KotlinChangeLocalityDetector : ChangeLocalityDetector {
|
|||||||
override fun getChangeHighlightingDirtyScopeFor(element: PsiElement): PsiElement? {
|
override fun getChangeHighlightingDirtyScopeFor(element: PsiElement): PsiElement? {
|
||||||
val parent = element.parent
|
val parent = element.parent
|
||||||
if (element is KtBlockExpression && parent is KtNamedFunction && parent.name != null) {
|
if (element is KtBlockExpression && parent is KtNamedFunction && parent.name != null) {
|
||||||
// Do nothing for local functions because of at least WRAPPED_INTO_REF highlighting
|
|
||||||
|
|
||||||
if (parent.parents.all { it is KtClassBody || it is KtClassOrObject || it is KtFile || it is KtScript }) {
|
if (parent.parents.all { it is KtClassBody || it is KtClassOrObject || it is KtFile || it is KtScript }) {
|
||||||
return parent
|
return parent
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.highlighter
|
|||||||
|
|
||||||
import com.intellij.lang.annotation.AnnotationHolder
|
import com.intellij.lang.annotation.AnnotationHolder
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiNameIdentifierOwner
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||||
@@ -145,7 +146,11 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
|
|||||||
"Wrapped into a reference object to be modified when captured in a closure"
|
"Wrapped into a reference object to be modified when captured in a closure"
|
||||||
else
|
else
|
||||||
"Value captured in a closure"
|
"Value captured in a closure"
|
||||||
holder.createInfoAnnotation(elementToHighlight, msg).textAttributes = WRAPPED_INTO_REF
|
|
||||||
|
val parent = elementToHighlight.parent
|
||||||
|
if (!(parent is PsiNameIdentifierOwner && parent.nameIdentifier == elementToHighlight)) {
|
||||||
|
holder.createInfoAnnotation(elementToHighlight, msg).textAttributes = WRAPPED_INTO_REF
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor is LocalVariableDescriptor && descriptor !is SyntheticFieldDescriptor) {
|
if (descriptor is LocalVariableDescriptor && descriptor !is SyntheticFieldDescriptor) {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class KotlinColorSettingsPage : ColorSettingsPage {
|
|||||||
val <LOCAL_VARIABLE>ints</LOCAL_VARIABLE> = java.util.<CONSTRUCTOR_CALL>ArrayList</CONSTRUCTOR_CALL><Int?>(2)
|
val <LOCAL_VARIABLE>ints</LOCAL_VARIABLE> = java.util.<CONSTRUCTOR_CALL>ArrayList</CONSTRUCTOR_CALL><Int?>(2)
|
||||||
<LOCAL_VARIABLE>ints</LOCAL_VARIABLE>[0] = 102 + <PARAMETER><VARIABLE_AS_FUNCTION_CALL>f</VARIABLE_AS_FUNCTION_CALL></PARAMETER>() + <PARAMETER><VARIABLE_AS_FUNCTION_LIKE_CALL>fl</VARIABLE_AS_FUNCTION_LIKE_CALL></PARAMETER>()
|
<LOCAL_VARIABLE>ints</LOCAL_VARIABLE>[0] = 102 + <PARAMETER><VARIABLE_AS_FUNCTION_CALL>f</VARIABLE_AS_FUNCTION_CALL></PARAMETER>() + <PARAMETER><VARIABLE_AS_FUNCTION_LIKE_CALL>fl</VARIABLE_AS_FUNCTION_LIKE_CALL></PARAMETER>()
|
||||||
val <LOCAL_VARIABLE>myFun</LOCAL_VARIABLE> = <FUNCTION_LITERAL_BRACES_AND_ARROW>{</FUNCTION_LITERAL_BRACES_AND_ARROW> <FUNCTION_LITERAL_BRACES_AND_ARROW>-></FUNCTION_LITERAL_BRACES_AND_ARROW> "" <FUNCTION_LITERAL_BRACES_AND_ARROW>}</FUNCTION_LITERAL_BRACES_AND_ARROW>;
|
val <LOCAL_VARIABLE>myFun</LOCAL_VARIABLE> = <FUNCTION_LITERAL_BRACES_AND_ARROW>{</FUNCTION_LITERAL_BRACES_AND_ARROW> <FUNCTION_LITERAL_BRACES_AND_ARROW>-></FUNCTION_LITERAL_BRACES_AND_ARROW> "" <FUNCTION_LITERAL_BRACES_AND_ARROW>}</FUNCTION_LITERAL_BRACES_AND_ARROW>;
|
||||||
var <LOCAL_VARIABLE><MUTABLE_VARIABLE><WRAPPED_INTO_REF>ref</WRAPPED_INTO_REF></MUTABLE_VARIABLE></LOCAL_VARIABLE> = <LOCAL_VARIABLE>ints</LOCAL_VARIABLE>.<INSTANCE_PROPERTY>size</INSTANCE_PROPERTY>
|
var <LOCAL_VARIABLE><MUTABLE_VARIABLE>ref</MUTABLE_VARIABLE></LOCAL_VARIABLE> = <LOCAL_VARIABLE>ints</LOCAL_VARIABLE>.<INSTANCE_PROPERTY>size</INSTANCE_PROPERTY>
|
||||||
ints.<EXTENSION_PROPERTY>lastIndex</EXTENSION_PROPERTY> + <PACKAGE_PROPERTY>globalCounter</PACKAGE_PROPERTY>
|
ints.<EXTENSION_PROPERTY>lastIndex</EXTENSION_PROPERTY> + <PACKAGE_PROPERTY>globalCounter</PACKAGE_PROPERTY>
|
||||||
<LOCAL_VARIABLE>ints</LOCAL_VARIABLE>.<EXTENSION_FUNCTION_CALL>forEach</EXTENSION_FUNCTION_CALL> <LABEL>lit@</LABEL> <FUNCTION_LITERAL_BRACES_AND_ARROW>{</FUNCTION_LITERAL_BRACES_AND_ARROW>
|
<LOCAL_VARIABLE>ints</LOCAL_VARIABLE>.<EXTENSION_FUNCTION_CALL>forEach</EXTENSION_FUNCTION_CALL> <LABEL>lit@</LABEL> <FUNCTION_LITERAL_BRACES_AND_ARROW>{</FUNCTION_LITERAL_BRACES_AND_ARROW>
|
||||||
if (<FUNCTION_LITERAL_DEFAULT_PARAMETER>it</FUNCTION_LITERAL_DEFAULT_PARAMETER> == null) return<LABEL>@lit</LABEL>
|
if (<FUNCTION_LITERAL_DEFAULT_PARAMETER>it</FUNCTION_LITERAL_DEFAULT_PARAMETER> == null) return<LABEL>@lit</LABEL>
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ class A2<T>(x: Int, y: Int, t: T) {
|
|||||||
//captured
|
//captured
|
||||||
|
|
||||||
class B(
|
class B(
|
||||||
<info descr="Value captured in a closure">x</info>: Int,
|
x: Int,
|
||||||
<info descr="Value captured in a closure">y</info>: Int,
|
y: Int,
|
||||||
<info descr="Value captured in a closure">t</info>: Int,
|
t: Int,
|
||||||
<info descr="Value captured in a closure">d</info>: Int
|
d: Int
|
||||||
) {
|
) {
|
||||||
<info>init</info> {
|
<info>init</info> {
|
||||||
class C(<warning>a</warning>: Int = <info>x</info>): T <info>by</info> T1(<info>t</info>) {
|
class C(<warning>a</warning>: Int = <info>x</info>): T <info>by</info> T1(<info>t</info>) {
|
||||||
@@ -43,7 +43,7 @@ class B(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class B2(<info descr="Value captured in a closure">x</info>: Int, <info descr="Value captured in a closure">y</info>: Int) {
|
class B2(x: Int, y: Int) {
|
||||||
|
|
||||||
val x1 = { <info>x</info> }()
|
val x1 = { <info>x</info> }()
|
||||||
<info>init</info> {
|
<info>init</info> {
|
||||||
|
|||||||
+12
-12
@@ -20,45 +20,45 @@ fun inline() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun notInline() {
|
fun notInline() {
|
||||||
val <info descr="Value captured in a closure">y2</info> = 1
|
val y2 = 1
|
||||||
run { <info descr="Value captured in a closure">y2</info> }
|
run { <info descr="Value captured in a closure">y2</info> }
|
||||||
run2 { <warning><info descr="Value captured in a closure">y2</info></warning> }
|
run2 { <warning><info descr="Value captured in a closure">y2</info></warning> }
|
||||||
|
|
||||||
val <info descr="Value captured in a closure">y3</info> = 1
|
val y3 = 1
|
||||||
run2 { <warning><info descr="Value captured in a closure">y3</info></warning> }
|
run2 { <warning><info descr="Value captured in a closure">y3</info></warning> }
|
||||||
run { <info descr="Value captured in a closure">y3</info> }
|
run { <info descr="Value captured in a closure">y3</info> }
|
||||||
|
|
||||||
// wrapped, using in not inline
|
// wrapped, using in not inline
|
||||||
val <info descr="Value captured in a closure">z</info> = 2
|
val z = 2
|
||||||
{ <info descr="Value captured in a closure">z</info> }()
|
{ <info descr="Value captured in a closure">z</info> }()
|
||||||
|
|
||||||
val <info descr="Value captured in a closure">z1</info> = 3
|
val z1 = 3
|
||||||
run2 { <warning><info descr="Value captured in a closure">z1</info></warning> }
|
run2 { <warning><info descr="Value captured in a closure">z1</info></warning> }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun nestedDifferent() { // inline within non-inline and vice-versa
|
fun nestedDifferent() { // inline within non-inline and vice-versa
|
||||||
val <info descr="Value captured in a closure">y</info> = 1
|
val y = 1
|
||||||
{
|
{
|
||||||
run {
|
run {
|
||||||
<info descr="Value captured in a closure">y</info>
|
<info descr="Value captured in a closure">y</info>
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
val <info descr="Value captured in a closure">y1</info> = 1
|
val y1 = 1
|
||||||
run {
|
run {
|
||||||
{ <info descr="Value captured in a closure">y1</info> }()
|
{ <info descr="Value captured in a closure">y1</info> }()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun localFunctionAndClass() {
|
fun localFunctionAndClass() {
|
||||||
val <info descr="Value captured in a closure">u</info> = 1
|
val u = 1
|
||||||
fun localFun() {
|
fun localFun() {
|
||||||
run {
|
run {
|
||||||
<info descr="Value captured in a closure">u</info>
|
<info descr="Value captured in a closure">u</info>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val <info descr="Value captured in a closure">v</info> = 1
|
val v = 1
|
||||||
class LocalClass {
|
class LocalClass {
|
||||||
fun f() {
|
fun f() {
|
||||||
run {
|
run {
|
||||||
@@ -69,7 +69,7 @@ fun localFunctionAndClass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun objectExpression() {
|
fun objectExpression() {
|
||||||
val <info descr="Value captured in a closure">u1</info> = 1
|
val u1 = 1
|
||||||
object : Any() {
|
object : Any() {
|
||||||
fun f() {
|
fun f() {
|
||||||
run {
|
run {
|
||||||
@@ -78,14 +78,14 @@ fun objectExpression() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val <info descr="Value captured in a closure">u2</info> = 1
|
val u2 = 1
|
||||||
object : Any() {
|
object : Any() {
|
||||||
val prop = run {
|
val prop = run {
|
||||||
<info descr="Value captured in a closure">u2</info>
|
<info descr="Value captured in a closure">u2</info>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val <info descr="Value captured in a closure">u3</info> = ""
|
val u3 = ""
|
||||||
object : Throwable(run { <info descr="Value captured in a closure">u3</info> }) {
|
object : Throwable(run { <info descr="Value captured in a closure">u3</info> }) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,7 @@ fun objectExpression() {
|
|||||||
task2()
|
task2()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun usage(<info descr="Value captured in a closure">param1</info>: Int, param2: Int) {
|
fun usage(param1: Int, param2: Int) {
|
||||||
withNoInlineParam({ println(<info descr="Value captured in a closure">param1</info>) }, { println(param2) })
|
withNoInlineParam({ println(<info descr="Value captured in a closure">param1</info>) }, { println(param2) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -184,11 +184,11 @@ fun vars(a: Any?) {
|
|||||||
<warning>b =</warning> <info descr="Smart cast to kotlin.Int">a</info>
|
<warning>b =</warning> <info descr="Smart cast to kotlin.Int">a</info>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun returnFunctionLiteralBlock(<info>a</info>: Any?): Function0<Int> {
|
fun returnFunctionLiteralBlock(a: Any?): Function0<Int> {
|
||||||
if (<info>a</info> is Int) return { <info descr="Smart cast to kotlin.Int"><info>a</info></info> }
|
if (<info>a</info> is Int) return { <info descr="Smart cast to kotlin.Int"><info>a</info></info> }
|
||||||
else return { 1 }
|
else return { 1 }
|
||||||
}
|
}
|
||||||
fun returnFunctionLiteral(<info>a</info>: Any?): Function0<Int> =
|
fun returnFunctionLiteral(a: Any?): Function0<Int> =
|
||||||
if (<info>a</info> is Int) (fun (): Int = <info descr="Smart cast to kotlin.Int"><info>a</info></info>)
|
if (<info>a</info> is Int) (fun (): Int = <info descr="Smart cast to kotlin.Int"><info>a</info></info>)
|
||||||
else { -> 1 }
|
else { -> 1 }
|
||||||
|
|
||||||
@@ -212,7 +212,7 @@ fun mergeSmartCasts(a: Any?) {
|
|||||||
|
|
||||||
//mutability
|
//mutability
|
||||||
fun f(): String {
|
fun f(): String {
|
||||||
var <info>a</info>: Any = 11
|
var a: Any = 11
|
||||||
if (<info>a</info> is String) {
|
if (<info>a</info> is String) {
|
||||||
val <warning>i</warning>: String = <info descr="Smart cast to kotlin.String"><info descr="Wrapped into a reference object to be modified when captured in a closure">a</info></info>
|
val <warning>i</warning>: String = <info descr="Smart cast to kotlin.String"><info descr="Wrapped into a reference object to be modified when captured in a closure">a</info></info>
|
||||||
<info descr="Smart cast to kotlin.String"><info descr="Wrapped into a reference object to be modified when captured in a closure">a</info></info>.compareTo("f")
|
<info descr="Smart cast to kotlin.String"><info descr="Wrapped into a reference object to be modified when captured in a closure">a</info></info>.compareTo("f")
|
||||||
|
|||||||
+6
-6
@@ -1,36 +1,36 @@
|
|||||||
fun refs() {
|
fun refs() {
|
||||||
var <info><warning>a</warning></info> = 1
|
var <warning>a</warning> = 1
|
||||||
val <warning>v</warning> = {
|
val <warning>v</warning> = {
|
||||||
<info>a</info> = 2
|
<info>a</info> = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
var <info><warning>x</warning></info> = 1
|
var <warning>x</warning> = 1
|
||||||
val <warning>b</warning> = object {
|
val <warning>b</warning> = object {
|
||||||
fun foo() {
|
fun foo() {
|
||||||
<info>x</info> = 2
|
<info>x</info> = 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var <info><warning>y</warning></info> = 1
|
var <warning>y</warning> = 1
|
||||||
fun foo() {
|
fun foo() {
|
||||||
<info>y</info> = 1
|
<info>y</info> = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refsPlusAssign() {
|
fun refsPlusAssign() {
|
||||||
var <info>a</info> = 1
|
var a = 1
|
||||||
val <warning>v</warning> = {
|
val <warning>v</warning> = {
|
||||||
<info>a</info> += 2
|
<info>a</info> += 2
|
||||||
}
|
}
|
||||||
|
|
||||||
var <info>x</info> = 1
|
var x = 1
|
||||||
val <warning>b</warning> = object {
|
val <warning>b</warning> = object {
|
||||||
fun foo() {
|
fun foo() {
|
||||||
<info>x</info> += 2
|
<info>x</info> += 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var <info>y</info> = 1
|
var y = 1
|
||||||
fun foo() {
|
fun foo() {
|
||||||
<info>y</info> += 1
|
<info>y</info> += 1
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user