Refactor nullable suffix handling in compiler (nullable declaration bug fixed)
This commit is contained in:
parent
017111827d
commit
80933c287d
@ -1048,7 +1048,12 @@ class Compiler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Nullable suffix after base or generic
|
// Nullable suffix after base or generic
|
||||||
val isNullable = cc.skipTokenOfType(Token.Type.QUESTION, isOptional = true)
|
val isNullable = if (cc.skipTokenOfType(Token.Type.QUESTION, isOptional = true)) {
|
||||||
|
true
|
||||||
|
} else if (cc.skipTokenOfType(Token.Type.IFNULLASSIGN, isOptional = true)) {
|
||||||
|
cc.pushPendingAssign()
|
||||||
|
true
|
||||||
|
} else false
|
||||||
val endPos = cc.currentPos()
|
val endPos = cc.currentPos()
|
||||||
|
|
||||||
val miniRef = buildBaseRef(if (miniArgs != null) endPos else lastEnd, miniArgs, isNullable)
|
val miniRef = buildBaseRef(if (miniArgs != null) endPos else lastEnd, miniArgs, isNullable)
|
||||||
|
|||||||
@ -35,8 +35,9 @@ class CompilerContext(val tokens: List<Token>) {
|
|||||||
|
|
||||||
var currentIndex = 0
|
var currentIndex = 0
|
||||||
private var pendingGT = 0
|
private var pendingGT = 0
|
||||||
|
private var pendingAssign = false
|
||||||
|
|
||||||
fun hasNext() = currentIndex < tokens.size || pendingGT > 0
|
fun hasNext() = currentIndex < tokens.size || pendingGT > 0 || pendingAssign
|
||||||
fun hasPrevious() = currentIndex > 0
|
fun hasPrevious() = currentIndex > 0
|
||||||
fun next(): Token {
|
fun next(): Token {
|
||||||
if (pendingGT > 0) {
|
if (pendingGT > 0) {
|
||||||
@ -44,6 +45,11 @@ class CompilerContext(val tokens: List<Token>) {
|
|||||||
val last = tokens[currentIndex - 1]
|
val last = tokens[currentIndex - 1]
|
||||||
return Token(">", last.pos.copy(column = last.pos.column + 1), Token.Type.GT)
|
return Token(">", last.pos.copy(column = last.pos.column + 1), Token.Type.GT)
|
||||||
}
|
}
|
||||||
|
if (pendingAssign) {
|
||||||
|
pendingAssign = false
|
||||||
|
val last = tokens[currentIndex - 1]
|
||||||
|
return Token("=", last.pos.copy(column = last.pos.column + 1), Token.Type.ASSIGN)
|
||||||
|
}
|
||||||
return if (currentIndex < tokens.size) tokens[currentIndex++]
|
return if (currentIndex < tokens.size) tokens[currentIndex++]
|
||||||
else Token("", tokens.last().pos, Token.Type.EOF)
|
else Token("", tokens.last().pos, Token.Type.EOF)
|
||||||
}
|
}
|
||||||
@ -52,16 +58,19 @@ class CompilerContext(val tokens: List<Token>) {
|
|||||||
pendingGT++
|
pendingGT++
|
||||||
}
|
}
|
||||||
|
|
||||||
fun previous() = if (pendingGT > 0) {
|
fun pushPendingAssign() {
|
||||||
pendingGT-- // This is wrong, previous should go back.
|
pendingAssign = true
|
||||||
// But we don't really use previous() in generics parser after splitting.
|
}
|
||||||
throw IllegalStateException("previous() not supported after pushPendingGT")
|
|
||||||
|
fun previous() = if (pendingGT > 0 || pendingAssign) {
|
||||||
|
throw IllegalStateException("previous() not supported after pushPending tokens")
|
||||||
} else if (!hasPrevious()) throw IllegalStateException("No previous token") else tokens[--currentIndex]
|
} else if (!hasPrevious()) throw IllegalStateException("No previous token") else tokens[--currentIndex]
|
||||||
|
|
||||||
fun savePos() = (currentIndex shl 2) or (pendingGT and 3)
|
fun savePos() = (currentIndex shl 3) or (pendingGT and 3) or (if (pendingAssign) 4 else 0)
|
||||||
fun restorePos(pos: Int) {
|
fun restorePos(pos: Int) {
|
||||||
currentIndex = pos shr 2
|
currentIndex = pos shr 3
|
||||||
pendingGT = pos and 3
|
pendingGT = pos and 3
|
||||||
|
pendingAssign = (pos and 4) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ensureLabelIsValid(pos: Pos, label: String) {
|
fun ensureLabelIsValid(pos: Pos, label: String) {
|
||||||
|
|||||||
@ -4803,7 +4803,7 @@ class ScriptTest {
|
|||||||
fun f(a: String = "foo") = a + "!"
|
fun f(a: String = "foo") = a + "!"
|
||||||
fun g(a: String? = null) = a ?: "!!"
|
fun g(a: String? = null) = a ?: "!!"
|
||||||
assertEquals(f(), "foo!")
|
assertEquals(f(), "foo!")
|
||||||
assertEquals(f(), "!!")
|
assertEquals(g(), "!!")
|
||||||
assertEquals(f("bar"), "bar!")
|
assertEquals(f("bar"), "bar!")
|
||||||
class T(b: Int=42,c: String?=null)
|
class T(b: Int=42,c: String?=null)
|
||||||
assertEquals(42, T().b)
|
assertEquals(42, T().b)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user