[FIR][LightTree] More fixes in diagnostic positioning
Keep tree padding for modifiers More REFERENCE_EXPRESSIONS kinds Fix source for some call expressions
This commit is contained in:
committed by
TeamCityServer
parent
f3dc8dfb21
commit
0a68edf3bd
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis
|
package org.jetbrains.kotlin.fir.analysis
|
||||||
|
|
||||||
|
import com.intellij.lang.LighterASTNode
|
||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import com.intellij.psi.tree.TokenSet
|
import com.intellij.psi.tree.TokenSet
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
@@ -37,7 +38,13 @@ private fun FirPsiSourceElement<*>.getChild(types: Set<IElementType>, index: Int
|
|||||||
private fun FirLightSourceElement.getChild(types: Set<IElementType>, index: Int, depth: Int): FirSourceElement? {
|
private fun FirLightSourceElement.getChild(types: Set<IElementType>, index: Int, depth: Int): FirSourceElement? {
|
||||||
val visitor = LighterTreeElementFinderByType(treeStructure, types, index, depth)
|
val visitor = LighterTreeElementFinderByType(treeStructure, types, index, depth)
|
||||||
val childNode = visitor.find(lighterASTNode) ?: return null
|
val childNode = visitor.find(lighterASTNode) ?: return null
|
||||||
//we need to keep 'padding' of parent node in child node
|
return buildChildSourceElement(childNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps 'padding' of parent node in child node
|
||||||
|
*/
|
||||||
|
internal fun FirLightSourceElement.buildChildSourceElement(childNode: LighterASTNode): FirLightSourceElement {
|
||||||
val offsetDelta = startOffset - lighterASTNode.startOffset
|
val offsetDelta = startOffset - lighterASTNode.startOffset
|
||||||
return childNode.toFirLightSourceElement(
|
return childNode.toFirLightSourceElement(
|
||||||
treeStructure,
|
treeStructure,
|
||||||
|
|||||||
+12
-5
@@ -34,14 +34,15 @@ internal sealed class FirModifierList {
|
|||||||
|
|
||||||
class FirLightModifierList(
|
class FirLightModifierList(
|
||||||
val modifierList: LighterASTNode,
|
val modifierList: LighterASTNode,
|
||||||
val tree: FlyweightCapableTreeStructure<LighterASTNode>
|
val tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||||
|
private val offsetDelta: Int
|
||||||
) : FirModifierList() {
|
) : FirModifierList() {
|
||||||
override val modifiers: List<FirModifier.FirLightModifier>
|
override val modifiers: List<FirModifier.FirLightModifier>
|
||||||
get() {
|
get() {
|
||||||
val modifierNodes = modifierList.getChildren(tree)
|
val modifierNodes = modifierList.getChildren(tree)
|
||||||
return modifierNodes.filterNotNull()
|
return modifierNodes.filterNotNull()
|
||||||
.filter { it.tokenType is KtModifierKeywordToken }
|
.filter { it.tokenType is KtModifierKeywordToken }
|
||||||
.map { FirModifier.FirLightModifier(it, it.tokenType as KtModifierKeywordToken, tree) }
|
.map { FirModifier.FirLightModifier(it, it.tokenType as KtModifierKeywordToken, tree, offsetDelta) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,10 +66,15 @@ internal sealed class FirModifier<Node : Any>(val node: Node, val token: KtModif
|
|||||||
class FirLightModifier(
|
class FirLightModifier(
|
||||||
node: LighterASTNode,
|
node: LighterASTNode,
|
||||||
token: KtModifierKeywordToken,
|
token: KtModifierKeywordToken,
|
||||||
val tree: FlyweightCapableTreeStructure<LighterASTNode>
|
val tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||||
|
private val offsetDelta: Int
|
||||||
) : FirModifier<LighterASTNode>(node, token) {
|
) : FirModifier<LighterASTNode>(node, token) {
|
||||||
override val source: FirSourceElement
|
override val source: FirSourceElement
|
||||||
get() = node.toFirLightSourceElement(tree)
|
get() = node.toFirLightSourceElement(
|
||||||
|
tree,
|
||||||
|
startOffset = node.startOffset + offsetDelta,
|
||||||
|
endOffset = node.endOffset + offsetDelta
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract val source: FirSourceElement
|
abstract val source: FirSourceElement
|
||||||
@@ -81,7 +87,8 @@ internal fun FirSourceElement?.getModifierList(): FirModifierList? {
|
|||||||
is FirLightSourceElement -> {
|
is FirLightSourceElement -> {
|
||||||
val modifierListNode = lighterASTNode.getChildren(treeStructure).find { it?.tokenType == KtNodeTypes.MODIFIER_LIST }
|
val modifierListNode = lighterASTNode.getChildren(treeStructure).find { it?.tokenType == KtNodeTypes.MODIFIER_LIST }
|
||||||
?: return null
|
?: return null
|
||||||
FirModifierList.FirLightModifierList(modifierListNode, treeStructure)
|
val offsetDelta = startOffset - lighterASTNode.startOffset
|
||||||
|
FirModifierList.FirLightModifierList(modifierListNode, treeStructure, offsetDelta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-1
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
|||||||
import org.jetbrains.kotlin.lexer.KtTokens.MODALITY_MODIFIERS
|
import org.jetbrains.kotlin.lexer.KtTokens.MODALITY_MODIFIERS
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens.VISIBILITY_MODIFIERS
|
import org.jetbrains.kotlin.lexer.KtTokens.VISIBILITY_MODIFIERS
|
||||||
import org.jetbrains.kotlin.psi.KtParameter.VAL_VAR_TOKEN_SET
|
import org.jetbrains.kotlin.psi.KtParameter.VAL_VAR_TOKEN_SET
|
||||||
|
import org.jetbrains.kotlin.psi.stubs.elements.KtConstantExpressionElementType
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
|
|
||||||
object LightTreePositioningStrategies {
|
object LightTreePositioningStrategies {
|
||||||
@@ -625,6 +626,9 @@ private val REFERENCE_EXPRESSIONS = setOf(
|
|||||||
KtNodeTypes.CONSTRUCTOR_DELEGATION_REFERENCE,
|
KtNodeTypes.CONSTRUCTOR_DELEGATION_REFERENCE,
|
||||||
KtNodeTypes.SUPER_EXPRESSION,
|
KtNodeTypes.SUPER_EXPRESSION,
|
||||||
KtNodeTypes.ARRAY_ACCESS_EXPRESSION,
|
KtNodeTypes.ARRAY_ACCESS_EXPRESSION,
|
||||||
|
KtNodeTypes.CALL_EXPRESSION,
|
||||||
|
KtNodeTypes.LABELED_EXPRESSION,
|
||||||
|
KtNodeTypes.DOT_QUALIFIED_EXPRESSION,
|
||||||
KtNodeTypes.FUN,
|
KtNodeTypes.FUN,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -648,7 +652,9 @@ private fun FlyweightCapableTreeStructure<LighterASTNode>.referenceExpression(
|
|||||||
val childrenRef = Ref<Array<LighterASTNode?>>()
|
val childrenRef = Ref<Array<LighterASTNode?>>()
|
||||||
getChildren(node, childrenRef)
|
getChildren(node, childrenRef)
|
||||||
var result = childrenRef.get()?.firstOrNull {
|
var result = childrenRef.get()?.firstOrNull {
|
||||||
it?.tokenType in REFERENCE_EXPRESSIONS || it?.tokenType == KtNodeTypes.PARENTHESIZED
|
it?.tokenType in REFERENCE_EXPRESSIONS ||
|
||||||
|
it?.tokenType is KtConstantExpressionElementType ||
|
||||||
|
it?.tokenType == KtNodeTypes.PARENTHESIZED
|
||||||
}
|
}
|
||||||
while (locateReferencedName && result != null && result.tokenType == KtNodeTypes.PARENTHESIZED) {
|
while (locateReferencedName && result != null && result.tokenType == KtNodeTypes.PARENTHESIZED) {
|
||||||
result = referenceExpression(result, locateReferencedName = true)
|
result = referenceExpression(result, locateReferencedName = true)
|
||||||
|
|||||||
+9
-1
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
|
|||||||
import org.jetbrains.kotlin.lexer.KtToken
|
import org.jetbrains.kotlin.lexer.KtToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.stubs.elements.KtFunctionElementType
|
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
|
|
||||||
abstract class BaseConverter(
|
abstract class BaseConverter(
|
||||||
@@ -81,6 +80,15 @@ abstract class BaseConverter(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun LighterASTNode.getFirstChildExpressionUnwrapped(): LighterASTNode? {
|
||||||
|
val expression = getFirstChildExpression() ?: return null
|
||||||
|
return if (expression.tokenType == KtNodeTypes.PARENTHESIZED) {
|
||||||
|
expression.getFirstChildExpressionUnwrapped()
|
||||||
|
} else {
|
||||||
|
expression
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun LighterASTNode.getLastChildExpression(): LighterASTNode? {
|
private fun LighterASTNode.getLastChildExpression(): LighterASTNode? {
|
||||||
var result: LighterASTNode? = null
|
var result: LighterASTNode? = null
|
||||||
forEachChildren {
|
forEachChildren {
|
||||||
|
|||||||
+1
-1
@@ -548,7 +548,7 @@ class ExpressionsConverter(
|
|||||||
val (calleeReference, explicitReceiver, isImplicitInvoke) = when {
|
val (calleeReference, explicitReceiver, isImplicitInvoke) = when {
|
||||||
name != null -> CalleeAndReceiver(
|
name != null -> CalleeAndReceiver(
|
||||||
buildSimpleNamedReference {
|
buildSimpleNamedReference {
|
||||||
this.source = source
|
this.source = callSuffix.getFirstChildExpressionUnwrapped()?.toFirSourceElement() ?: source
|
||||||
this.name = name.nameAsSafeName()
|
this.name = name.nameAsSafeName()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-1
@@ -4,7 +4,8 @@ package h
|
|||||||
class Square() {
|
class Square() {
|
||||||
var size : Double =
|
var size : Double =
|
||||||
<!UNRESOLVED_REFERENCE!>set<!>(<!UNRESOLVED_REFERENCE!>value<!>) {
|
<!UNRESOLVED_REFERENCE!>set<!>(<!UNRESOLVED_REFERENCE!>value<!>) {
|
||||||
<!SYNTAX!>$area<!> <!SYNTAX!>= size * size<!>
|
//in LT this LAMBDA_EXPRESSION get parsed lazyly, but doesn't got anywhere in FIR tree (as property doesn't have place for it)
|
||||||
|
<!SYNTAX{PSI}!>$area<!> <!SYNTAX{PSI}!>= size * size<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>var area : Double<!>
|
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>var area : Double<!>
|
||||||
|
|||||||
+2
-2
@@ -6,9 +6,9 @@ enum class Enum {
|
|||||||
|
|
||||||
<!NESTED_CLASS_NOT_ALLOWED!>class TestNested<!>
|
<!NESTED_CLASS_NOT_ALLOWED!>class TestNested<!>
|
||||||
|
|
||||||
<!NESTED_CLASS_NOT_ALLOWED!>interface TestInterface<!>
|
<!LOCAL_INTERFACE_NOT_ALLOWED, NESTED_CLASS_NOT_ALLOWED!>interface TestInterface<!>
|
||||||
|
|
||||||
object TestObject
|
<!LOCAL_OBJECT_NOT_ALLOWED!>object TestObject<!>
|
||||||
|
|
||||||
enum class TestEnumClass {
|
enum class TestEnumClass {
|
||||||
OTHER_ENTRY
|
OTHER_ENTRY
|
||||||
|
|||||||
+2
-2
@@ -6,9 +6,9 @@ enum class Enum {
|
|||||||
|
|
||||||
<!NESTED_CLASS_NOT_ALLOWED!>class TestNested<!>
|
<!NESTED_CLASS_NOT_ALLOWED!>class TestNested<!>
|
||||||
|
|
||||||
<!NESTED_CLASS_NOT_ALLOWED!>interface TestInterface<!>
|
<!LOCAL_INTERFACE_NOT_ALLOWED, NESTED_CLASS_NOT_ALLOWED!>interface TestInterface<!>
|
||||||
|
|
||||||
object TestObject
|
<!LOCAL_OBJECT_NOT_ALLOWED!>object TestObject<!>
|
||||||
|
|
||||||
enum class TestEnumClass {
|
enum class TestEnumClass {
|
||||||
OTHER_ENTRY
|
OTHER_ENTRY
|
||||||
|
|||||||
+2
-2
@@ -6,9 +6,9 @@ enum class Enum {
|
|||||||
|
|
||||||
<!NESTED_CLASS_NOT_ALLOWED!>class TestNested<!>
|
<!NESTED_CLASS_NOT_ALLOWED!>class TestNested<!>
|
||||||
|
|
||||||
<!NESTED_CLASS_NOT_ALLOWED!>interface TestInterface<!>
|
<!LOCAL_INTERFACE_NOT_ALLOWED, NESTED_CLASS_NOT_ALLOWED!>interface TestInterface<!>
|
||||||
|
|
||||||
object TestObject
|
<!LOCAL_OBJECT_NOT_ALLOWED!>object TestObject<!>
|
||||||
|
|
||||||
enum class TestEnumClass {
|
enum class TestEnumClass {
|
||||||
OTHER_ENTRY
|
OTHER_ENTRY
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ package toplevelObjectDeclarations
|
|||||||
|
|
||||||
<!NO_VALUE_FOR_PARAMETER!>class T : <!SUPERTYPE_NOT_INITIALIZED!>Foo<!> {}<!>
|
<!NO_VALUE_FOR_PARAMETER!>class T : <!SUPERTYPE_NOT_INITIALIZED!>Foo<!> {}<!>
|
||||||
|
|
||||||
object A : <!SUPERTYPE_NOT_INITIALIZED!>Foo<!> {
|
<!NO_VALUE_FOR_PARAMETER{LT}!>object A : <!SUPERTYPE_NOT_INITIALIZED!>Foo<!> {
|
||||||
val x : Int = 2
|
val x : Int = 2
|
||||||
|
|
||||||
fun test() : Int {
|
fun test() : Int {
|
||||||
return x + foo(<!NO_VALUE_FOR_PARAMETER!>)<!>
|
return x + foo(<!NO_VALUE_FOR_PARAMETER{PSI}!>)<!>
|
||||||
}
|
}
|
||||||
}
|
}<!>
|
||||||
|
|
||||||
object B : A {}
|
object B : A {}
|
||||||
|
|
||||||
|
|||||||
@@ -25,5 +25,5 @@ val z = z
|
|||||||
fun block(f : () -> Unit) = f()
|
fun block(f : () -> Unit) = f()
|
||||||
|
|
||||||
fun bar3() = block{ <!UNRESOLVED_REFERENCE!>foo3<!>() // <-- missing closing curly bracket
|
fun bar3() = block{ <!UNRESOLVED_REFERENCE!>foo3<!>() // <-- missing closing curly bracket
|
||||||
fun foo3() = block{ bar3() }<!SYNTAX!><!>
|
fun foo3() = block{ bar3() }<!SYNTAX{PSI}!><!>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user