Fix parsing of generic extension functions

This commit is contained in:
Sergey Chernov 2026-04-06 19:29:06 +03:00
parent 35628c8453
commit 1fca2b112f
2 changed files with 47 additions and 1 deletions

View File

@ -1449,6 +1449,13 @@ class Compiler(
}
cc.nextNonWhitespace()
val afterSegment = cc.peekNextNonWhitespace()
if (afterSegment.type == Token.Type.LT) {
val nextAfterSuffix = peekTokenAfterExtensionReceiverSegmentSuffix()
if (nextAfterSuffix != Token.Type.DOT) {
cc.restorePos(dotPos)
break
}
}
if (afterSegment.type != Token.Type.DOT &&
afterSegment.type != Token.Type.LT &&
afterSegment.type != Token.Type.QUESTION &&
@ -1496,6 +1503,38 @@ class Compiler(
}
}
private fun peekTokenAfterExtensionReceiverSegmentSuffix(): Token.Type {
val saved = cc.savePos()
try {
if (cc.peekNextNonWhitespace().type == Token.Type.LT) {
var depth = 0
while (true) {
when (val tok = cc.nextNonWhitespace().type) {
Token.Type.LT -> depth += 1
Token.Type.GT -> {
depth -= 1
if (depth <= 0) break
}
Token.Type.SHR -> {
depth -= 2
if (depth <= 0) break
}
Token.Type.EOF -> return Token.Type.EOF
else -> {}
}
}
}
if (cc.peekNextNonWhitespace().type == Token.Type.QUESTION ||
cc.peekNextNonWhitespace().type == Token.Type.IFNULLASSIGN
) {
cc.nextNonWhitespace()
}
return cc.peekNextNonWhitespace().type
} finally {
cc.restorePos(saved)
}
}
private fun shouldImplicitTypeVar(name: String, explicit: Set<String>): Boolean {
if (explicit.contains(name)) return true
if (name.contains('.')) return false
@ -4253,6 +4292,13 @@ class Compiler(
}
cc.nextNonWhitespace()
val afterSegment = cc.peekNextNonWhitespace()
if (afterSegment.type == Token.Type.LT) {
val nextAfterSuffix = peekTokenAfterExtensionReceiverSegmentSuffix()
if (nextAfterSuffix != Token.Type.DOT) {
cc.restorePos(dotPos)
break
}
}
if (afterSegment.type != Token.Type.DOT &&
afterSegment.type != Token.Type.LT &&
afterSegment.type != Token.Type.QUESTION &&

View File

@ -393,7 +393,7 @@ class OOTest {
fun base() = "base"
}
fun X.decorate(value): String {
fun X.decorate<T>(value: T): String {
this.base() + ":" + value.toString()
}
val X.tag get() = this.base() + ":tag"