[FIR] Implement INCORRECT_CHARACTER_LITERAL, EMPTY_CHARACTER_LITERAL, TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL, ILLEGAL_ESCAPE, ILLEGAL_ESCAPE_SEQUENCE diagnostics, fix tests
This commit is contained in:
committed by
TeamCityServer
parent
91d42fe345
commit
404c69ded7
+1
-1
@@ -7,7 +7,7 @@ class B: A() {
|
|||||||
<!UNRESOLVED_REFERENCE!>invoke<!>()
|
<!UNRESOLVED_REFERENCE!>invoke<!>()
|
||||||
|
|
||||||
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!> {
|
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!> {
|
||||||
<!UNRESOLVED_REFERENCE!>println<!>(<!ILLEGAL_CONST_EXPRESSION!>'weird'<!>)
|
<!UNRESOLVED_REFERENCE!>println<!>(<!TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL!>'weird'<!>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -63,6 +63,10 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
|||||||
val NESTED_CLASS_NOT_ALLOWED by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME) {
|
val NESTED_CLASS_NOT_ALLOWED by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME) {
|
||||||
parameter<String>("declaration")
|
parameter<String>("declaration")
|
||||||
}
|
}
|
||||||
|
val INCORRECT_CHARACTER_LITERAL by error<FirSourceElement, PsiElement>()
|
||||||
|
val EMPTY_CHARACTER_LITERAL by error<FirSourceElement, PsiElement>()
|
||||||
|
val TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL by error<FirSourceElement, PsiElement>()
|
||||||
|
val ILLEGAL_ESCAPE by error<FirSourceElement, PsiElement>()
|
||||||
}
|
}
|
||||||
|
|
||||||
val UNRESOLVED by object : DiagnosticGroup("Unresolved") {
|
val UNRESOLVED by object : DiagnosticGroup("Unresolved") {
|
||||||
|
|||||||
@@ -79,6 +79,10 @@ object FirErrors {
|
|||||||
val VARIABLE_EXPECTED by error0<FirSourceElement, PsiElement>()
|
val VARIABLE_EXPECTED by error0<FirSourceElement, PsiElement>()
|
||||||
val DELEGATION_IN_INTERFACE by error0<FirSourceElement, PsiElement>()
|
val DELEGATION_IN_INTERFACE by error0<FirSourceElement, PsiElement>()
|
||||||
val NESTED_CLASS_NOT_ALLOWED by error1<FirSourceElement, KtNamedDeclaration, String>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
val NESTED_CLASS_NOT_ALLOWED by error1<FirSourceElement, KtNamedDeclaration, String>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||||
|
val INCORRECT_CHARACTER_LITERAL by error0<FirSourceElement, PsiElement>()
|
||||||
|
val EMPTY_CHARACTER_LITERAL by error0<FirSourceElement, PsiElement>()
|
||||||
|
val TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL by error0<FirSourceElement, PsiElement>()
|
||||||
|
val ILLEGAL_ESCAPE by error0<FirSourceElement, PsiElement>()
|
||||||
|
|
||||||
// Unresolved
|
// Unresolved
|
||||||
val HIDDEN by error1<FirSourceElement, PsiElement, AbstractFirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val HIDDEN by error1<FirSourceElement, PsiElement, AbstractFirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
|
|||||||
+4
@@ -175,6 +175,10 @@ private fun ConeSimpleDiagnostic.getFactory(): FirDiagnosticFactory0<FirSourceEl
|
|||||||
DiagnosticKind.IllegalProjectionUsage -> FirErrors.ILLEGAL_PROJECTION_USAGE
|
DiagnosticKind.IllegalProjectionUsage -> FirErrors.ILLEGAL_PROJECTION_USAGE
|
||||||
DiagnosticKind.MissingStdlibClass -> FirErrors.MISSING_STDLIB_CLASS
|
DiagnosticKind.MissingStdlibClass -> FirErrors.MISSING_STDLIB_CLASS
|
||||||
DiagnosticKind.Other -> FirErrors.OTHER_ERROR
|
DiagnosticKind.Other -> FirErrors.OTHER_ERROR
|
||||||
|
DiagnosticKind.IncorrectCharacterLiteral -> FirErrors.INCORRECT_CHARACTER_LITERAL
|
||||||
|
DiagnosticKind.EmptyCharacterLiteral -> FirErrors.EMPTY_CHARACTER_LITERAL
|
||||||
|
DiagnosticKind.TooManyCharactersInCharacterLiteral -> FirErrors.TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL
|
||||||
|
DiagnosticKind.IllegalEscape -> FirErrors.ILLEGAL_ESCAPE
|
||||||
else -> throw IllegalArgumentException("Unsupported diagnostic kind: $kind at $javaClass")
|
else -> throw IllegalArgumentException("Unsupported diagnostic kind: $kind at $javaClass")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -46,7 +46,7 @@ abstract class BaseConverter(
|
|||||||
override val LighterASTNode.unescapedValue: String
|
override val LighterASTNode.unescapedValue: String
|
||||||
get() {
|
get() {
|
||||||
val escape = this.asText
|
val escape = this.asText
|
||||||
return escapedStringToCharacter(escape)?.toString()
|
return escapedStringToCharacter(escape).value?.toString()
|
||||||
?: escape.replace("\\", "").replace("u", "\\u")
|
?: escape.replace("\\", "").replace("u", "\\u")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-3
@@ -332,13 +332,18 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
ConeSimpleDiagnostic("Incorrect double: $text", DiagnosticKind.IllegalConstExpression)
|
ConeSimpleDiagnostic("Incorrect double: $text", DiagnosticKind.IllegalConstExpression)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
CHARACTER_CONSTANT ->
|
CHARACTER_CONSTANT -> {
|
||||||
|
val characterWithDiagnostic = text.parseCharacter()
|
||||||
buildConstOrErrorExpression(
|
buildConstOrErrorExpression(
|
||||||
sourceElement,
|
sourceElement,
|
||||||
ConstantValueKind.Char,
|
ConstantValueKind.Char,
|
||||||
text.parseCharacter(),
|
characterWithDiagnostic.value,
|
||||||
ConeSimpleDiagnostic("Incorrect character: $text", DiagnosticKind.IllegalConstExpression)
|
ConeSimpleDiagnostic(
|
||||||
|
"Incorrect character: $text",
|
||||||
|
characterWithDiagnostic.getDiagnostic() ?: DiagnosticKind.IllegalConstExpression
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
BOOLEAN_CONSTANT ->
|
BOOLEAN_CONSTANT ->
|
||||||
buildConstExpression(
|
buildConstExpression(
|
||||||
sourceElement,
|
sourceElement,
|
||||||
|
|||||||
+41
-21
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.declarations.FirVariable
|
|||||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
||||||
@@ -40,30 +41,30 @@ import org.jetbrains.kotlin.types.ConstantValueKind
|
|||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
fun String.parseCharacter(): Char? {
|
fun String.parseCharacter(): CharacterWithDiagnostic {
|
||||||
// Strip the quotes
|
// Strip the quotes
|
||||||
if (length < 2 || this[0] != '\'' || this[length - 1] != '\'') {
|
if (length < 2 || this[0] != '\'' || this[length - 1] != '\'') {
|
||||||
return null
|
return CharacterWithDiagnostic(DiagnosticKind.IncorrectCharacterLiteral)
|
||||||
}
|
}
|
||||||
val text = substring(1, length - 1) // now there're no quotes
|
val text = substring(1, length - 1) // now there is no quotes
|
||||||
|
|
||||||
if (text.isEmpty()) {
|
if (text.isEmpty()) {
|
||||||
return null
|
return CharacterWithDiagnostic(DiagnosticKind.EmptyCharacterLiteral)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (text[0] != '\\') {
|
return if (text[0] != '\\') {
|
||||||
// No escape
|
// No escape
|
||||||
if (text.length == 1) {
|
if (text.length == 1) {
|
||||||
text[0]
|
CharacterWithDiagnostic(text[0])
|
||||||
} else {
|
} else {
|
||||||
null
|
CharacterWithDiagnostic(DiagnosticKind.TooManyCharactersInCharacterLiteral)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
escapedStringToCharacter(text)
|
escapedStringToCharacter(text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun escapedStringToCharacter(text: String): Char? {
|
fun escapedStringToCharacter(text: String): CharacterWithDiagnostic {
|
||||||
assert(text.isNotEmpty() && text[0] == '\\') {
|
assert(text.isNotEmpty() && text[0] == '\\') {
|
||||||
"Only escaped sequences must be passed to this routine: $text"
|
"Only escaped sequences must be passed to this routine: $text"
|
||||||
}
|
}
|
||||||
@@ -73,40 +74,59 @@ fun escapedStringToCharacter(text: String): Char? {
|
|||||||
when (escape.length) {
|
when (escape.length) {
|
||||||
0 -> {
|
0 -> {
|
||||||
// bare slash
|
// bare slash
|
||||||
return null
|
return CharacterWithDiagnostic(DiagnosticKind.IllegalEscape)
|
||||||
}
|
}
|
||||||
1 -> {
|
1 -> {
|
||||||
// one-char escape
|
// one-char escape
|
||||||
return translateEscape(escape[0]) ?: return null
|
return translateEscape(escape[0])
|
||||||
}
|
}
|
||||||
5 -> {
|
5 -> {
|
||||||
// unicode escape
|
// unicode escape
|
||||||
if (escape[0] == 'u') {
|
if (escape[0] == 'u') {
|
||||||
try {
|
try {
|
||||||
val intValue = Integer.valueOf(escape.substring(1), 16)
|
val intValue = Integer.valueOf(escape.substring(1), 16)
|
||||||
return intValue.toInt().toChar()
|
return CharacterWithDiagnostic(intValue.toInt().toChar())
|
||||||
} catch (e: NumberFormatException) {
|
} catch (e: NumberFormatException) {
|
||||||
// Will be reported below
|
// Will be reported below
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return CharacterWithDiagnostic(DiagnosticKind.IllegalEscape)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun translateEscape(c: Char): Char? =
|
internal fun translateEscape(c: Char): CharacterWithDiagnostic =
|
||||||
when (c) {
|
when (c) {
|
||||||
't' -> '\t'
|
't' -> CharacterWithDiagnostic('\t')
|
||||||
'b' -> '\b'
|
'b' -> CharacterWithDiagnostic('\b')
|
||||||
'n' -> '\n'
|
'n' -> CharacterWithDiagnostic('\n')
|
||||||
'r' -> '\r'
|
'r' -> CharacterWithDiagnostic('\r')
|
||||||
'\'' -> '\''
|
'\'' -> CharacterWithDiagnostic('\'')
|
||||||
'\"' -> '\"'
|
'\"' -> CharacterWithDiagnostic('\"')
|
||||||
'\\' -> '\\'
|
'\\' -> CharacterWithDiagnostic('\\')
|
||||||
'$' -> '$'
|
'$' -> CharacterWithDiagnostic('$')
|
||||||
else -> null
|
else -> CharacterWithDiagnostic(DiagnosticKind.IllegalEscape)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CharacterWithDiagnostic {
|
||||||
|
private val diagnostic: DiagnosticKind?
|
||||||
|
val value: Char?
|
||||||
|
|
||||||
|
constructor(diagnostic: DiagnosticKind) {
|
||||||
|
this.diagnostic = diagnostic
|
||||||
|
this.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(value: Char) {
|
||||||
|
this.diagnostic = null
|
||||||
|
this.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDiagnostic(): DiagnosticKind? {
|
||||||
|
return diagnostic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun IElementType.toBinaryName(): Name? {
|
fun IElementType.toBinaryName(): Name? {
|
||||||
return OperatorConventions.BINARY_OPERATION_NAMES[this]
|
return OperatorConventions.BINARY_OPERATION_NAMES[this]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,5 +30,11 @@ enum class DiagnosticKind {
|
|||||||
UnknownCallableKind,
|
UnknownCallableKind,
|
||||||
IllegalProjectionUsage,
|
IllegalProjectionUsage,
|
||||||
MissingStdlibClass,
|
MissingStdlibClass,
|
||||||
|
|
||||||
|
IncorrectCharacterLiteral,
|
||||||
|
EmptyCharacterLiteral,
|
||||||
|
TooManyCharactersInCharacterLiteral,
|
||||||
|
IllegalEscape,
|
||||||
|
|
||||||
Other
|
Other
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
fun test(c : Char) {
|
fun test(c : Char) {
|
||||||
test(<!ILLEGAL_CONST_EXPRESSION!>''<!>)
|
test(<!EMPTY_CHARACTER_LITERAL!>''<!>)
|
||||||
test('a')
|
test('a')
|
||||||
test(<!ILLEGAL_CONST_EXPRESSION!>'aa'<!>)
|
test(<!TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL!>'aa'<!>)
|
||||||
test(<!ILLEGAL_CONST_EXPRESSION!>'a)<!>
|
test(<!INCORRECT_CHARACTER_LITERAL!>'a)<!>
|
||||||
<!UNRESOLVED_REFERENCE!>test<!>(<!ILLEGAL_CONST_EXPRESSION!>'<!>
|
<!UNRESOLVED_REFERENCE!>test<!>(<!INCORRECT_CHARACTER_LITERAL!>'<!>
|
||||||
<!UNRESOLVED_REFERENCE!>test<!>(0<!ILLEGAL_CONST_EXPRESSION!><!SYNTAX!><!>'<!>
|
<!UNRESOLVED_REFERENCE!>test<!>(0<!INCORRECT_CHARACTER_LITERAL!><!SYNTAX!><!>'<!>
|
||||||
<!UNRESOLVED_REFERENCE!>test<!>('\n')
|
<!UNRESOLVED_REFERENCE!>test<!>('\n')
|
||||||
test('\\')
|
test('\\')
|
||||||
test(<!ILLEGAL_CONST_EXPRESSION!>''<!><!ILLEGAL_CONST_EXPRESSION, TOO_MANY_ARGUMENTS!><!SYNTAX!><!>''<!>)
|
test(<!EMPTY_CHARACTER_LITERAL!>''<!><!EMPTY_CHARACTER_LITERAL, TOO_MANY_ARGUMENTS!><!SYNTAX!><!>''<!>)
|
||||||
test('\'')
|
test('\'')
|
||||||
test('\"')
|
test('\"')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
// KT-451 Incorrect character literals cause assertion failures
|
// KT-451 Incorrect character literals cause assertion failures
|
||||||
|
|
||||||
fun ff() {
|
fun ff() {
|
||||||
val b = <!ILLEGAL_CONST_EXPRESSION!>''<!>
|
val b = <!EMPTY_CHARACTER_LITERAL!>''<!>
|
||||||
val c = <!ILLEGAL_CONST_EXPRESSION!>'23'<!>
|
val c = <!TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL!>'23'<!>
|
||||||
val d = <!ILLEGAL_CONST_EXPRESSION!>'a<!>
|
val d = <!INCORRECT_CHARACTER_LITERAL!>'a<!>
|
||||||
val e = <!ILLEGAL_CONST_EXPRESSION!>'ab<!>
|
val e = <!INCORRECT_CHARACTER_LITERAL!>'ab<!>
|
||||||
val f = <!ILLEGAL_CONST_EXPRESSION!>'\'<!>
|
val f = <!ILLEGAL_ESCAPE!>'\'<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
@@ -19,19 +19,19 @@ fun test() {
|
|||||||
'\''
|
'\''
|
||||||
'\\'
|
'\\'
|
||||||
'\$'
|
'\$'
|
||||||
<!ILLEGAL_CONST_EXPRESSION!>'\x'<!>
|
<!ILLEGAL_ESCAPE!>'\x'<!>
|
||||||
<!ILLEGAL_CONST_EXPRESSION!>'\123'<!>
|
<!ILLEGAL_ESCAPE!>'\123'<!>
|
||||||
<!ILLEGAL_CONST_EXPRESSION!>'\ra'<!>
|
<!ILLEGAL_ESCAPE!>'\ra'<!>
|
||||||
<!ILLEGAL_CONST_EXPRESSION!>'\000'<!>
|
<!ILLEGAL_ESCAPE!>'\000'<!>
|
||||||
<!ILLEGAL_CONST_EXPRESSION!>'\000'<!>
|
<!ILLEGAL_ESCAPE!>'\000'<!>
|
||||||
'\u0000'
|
'\u0000'
|
||||||
'\u000a'
|
'\u000a'
|
||||||
'\u000A'
|
'\u000A'
|
||||||
<!ILLEGAL_CONST_EXPRESSION!>'\u'<!>
|
<!ILLEGAL_ESCAPE!>'\u'<!>
|
||||||
<!ILLEGAL_CONST_EXPRESSION!>'\u0'<!>
|
<!ILLEGAL_ESCAPE!>'\u0'<!>
|
||||||
<!ILLEGAL_CONST_EXPRESSION!>'\u00'<!>
|
<!ILLEGAL_ESCAPE!>'\u00'<!>
|
||||||
<!ILLEGAL_CONST_EXPRESSION!>'\u000'<!>
|
<!ILLEGAL_ESCAPE!>'\u000'<!>
|
||||||
<!ILLEGAL_CONST_EXPRESSION!>'\u000z'<!>
|
<!ILLEGAL_ESCAPE!>'\u000z'<!>
|
||||||
<!ILLEGAL_CONST_EXPRESSION!>'\\u000'<!>
|
<!ILLEGAL_ESCAPE!>'\\u000'<!>
|
||||||
<!ILLEGAL_CONST_EXPRESSION!>'\'<!>
|
<!ILLEGAL_ESCAPE!>'\'<!>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ fun test(a: Any) {
|
|||||||
a foo"asd${a}sfsa"
|
a foo"asd${a}sfsa"
|
||||||
a foo"""sdf"""
|
a foo"""sdf"""
|
||||||
a foo'd'
|
a foo'd'
|
||||||
a foo<!ILLEGAL_CONST_EXPRESSION!>''<!>
|
a foo<!EMPTY_CHARACTER_LITERAL!>''<!>
|
||||||
|
|
||||||
a foo""foo a
|
a foo""foo a
|
||||||
a foo"asd"foo a
|
a foo"asd"foo a
|
||||||
@@ -19,17 +19,17 @@ fun test(a: Any) {
|
|||||||
a foo"asd${a}sfsa"foo a
|
a foo"asd${a}sfsa"foo a
|
||||||
a foo"""sdf"""foo a
|
a foo"""sdf"""foo a
|
||||||
a foo'd'foo a
|
a foo'd'foo a
|
||||||
a foo<!ILLEGAL_CONST_EXPRESSION!>''<!>foo a
|
a foo<!EMPTY_CHARACTER_LITERAL!>''<!>foo a
|
||||||
|
|
||||||
a in"foo"
|
a in"foo"
|
||||||
a in"""foo"""
|
a in"""foo"""
|
||||||
a in's'
|
a in's'
|
||||||
a in<!ILLEGAL_CONST_EXPRESSION!>''<!>
|
a in<!EMPTY_CHARACTER_LITERAL!>''<!>
|
||||||
|
|
||||||
a !in"foo"
|
a !in"foo"
|
||||||
a !in"""foo"""
|
a !in"""foo"""
|
||||||
a !in's'
|
a !in's'
|
||||||
a !in<!ILLEGAL_CONST_EXPRESSION!>''<!>
|
a !in<!EMPTY_CHARACTER_LITERAL!>''<!>
|
||||||
|
|
||||||
if("s"is Any) {}
|
if("s"is Any) {}
|
||||||
if("s"is Any) {}
|
if("s"is Any) {}
|
||||||
@@ -37,4 +37,4 @@ fun test(a: Any) {
|
|||||||
|
|
||||||
a foo""<!SYNTAX!>1<!>
|
a foo""<!SYNTAX!>1<!>
|
||||||
a foo""<!SYNTAX!>1.0<!>
|
a foo""<!SYNTAX!>1.0<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ annotation class Foo(
|
|||||||
|
|
||||||
annotation class Bar(
|
annotation class Bar(
|
||||||
val a: Array<String> = [' '],
|
val a: Array<String> = [' '],
|
||||||
val b: Array<String> = ["", <!ILLEGAL_CONST_EXPRESSION!>''<!>],
|
val b: Array<String> = ["", <!EMPTY_CHARACTER_LITERAL!>''<!>],
|
||||||
val c: Array<String> = [1]
|
val c: Array<String> = [1]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -4,28 +4,28 @@
|
|||||||
|
|
||||||
// TESTCASE NUMBER: 1
|
// TESTCASE NUMBER: 1
|
||||||
fun case1() {
|
fun case1() {
|
||||||
val c = <!ILLEGAL_CONST_EXPRESSION!>''<!>
|
val c = <!EMPTY_CHARACTER_LITERAL!>''<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 2
|
// TESTCASE NUMBER: 2
|
||||||
|
|
||||||
fun case2() {
|
fun case2() {
|
||||||
val c2: Char = <!ILLEGAL_CONST_EXPRESSION!>''<!><!SYNTAX!>'<!>
|
val c2: Char = <!EMPTY_CHARACTER_LITERAL!>''<!><!SYNTAX!>'<!>
|
||||||
val c3: Char = <!ILLEGAL_CONST_EXPRESSION!>'\'<!>
|
val c3: Char = <!ILLEGAL_ESCAPE!>'\'<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 3
|
// TESTCASE NUMBER: 3
|
||||||
|
|
||||||
fun case3() {
|
fun case3() {
|
||||||
val c1: Char = <!ILLEGAL_CONST_EXPRESSION!>'B a'<!>
|
val c1: Char = <!TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL!>'B a'<!>
|
||||||
val c2: Char = <!ILLEGAL_CONST_EXPRESSION!>' '<!>
|
val c2: Char = <!TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL!>' '<!>
|
||||||
val c3: Char = <!ILLEGAL_CONST_EXPRESSION!>'Ba'<!>
|
val c3: Char = <!TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL!>'Ba'<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 4
|
// TESTCASE NUMBER: 4
|
||||||
|
|
||||||
fun case4() {
|
fun case4() {
|
||||||
val cOutOfRaneMin = <!ILLEGAL_CONST_EXPRESSION!>'𐀀'<!> //u+10000
|
val cOutOfRaneMin = <!TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL!>'𐀀'<!> //u+10000
|
||||||
|
|
||||||
val cOutOfRangeAroundMax = <!ILLEGAL_CONST_EXPRESSION!>''<!> //u+Dfffff
|
val cOutOfRangeAroundMax = <!TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL!>''<!> //u+Dfffff
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -6,19 +6,19 @@
|
|||||||
|
|
||||||
fun case1() {
|
fun case1() {
|
||||||
//less then four hex digits
|
//less then four hex digits
|
||||||
val c0 = <!ILLEGAL_CONST_EXPRESSION!>'\u'<!>
|
val c0 = <!ILLEGAL_ESCAPE!>'\u'<!>
|
||||||
val c1 = <!ILLEGAL_CONST_EXPRESSION!>'\uf'<!>
|
val c1 = <!ILLEGAL_ESCAPE!>'\uf'<!>
|
||||||
val c2 = <!ILLEGAL_CONST_EXPRESSION!>'\u1f'<!>
|
val c2 = <!ILLEGAL_ESCAPE!>'\u1f'<!>
|
||||||
val c3 = <!ILLEGAL_CONST_EXPRESSION!>'\u1wf'<!>
|
val c3 = <!ILLEGAL_ESCAPE!>'\u1wf'<!>
|
||||||
|
|
||||||
//more then four hex digits
|
//more then four hex digits
|
||||||
val c4 = <!ILLEGAL_CONST_EXPRESSION!>'\u1wF2f'<!>
|
val c4 = <!ILLEGAL_ESCAPE!>'\u1wF2f'<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 2
|
// TESTCASE NUMBER: 2
|
||||||
|
|
||||||
fun case2() {
|
fun case2() {
|
||||||
//not hex
|
//not hex
|
||||||
val c1 = <!ILLEGAL_CONST_EXPRESSION!>'\u000g'<!>
|
val c1 = <!ILLEGAL_ESCAPE!>'\u000g'<!>
|
||||||
val c2 = <!ILLEGAL_CONST_EXPRESSION!>'\u000G'<!>
|
val c2 = <!ILLEGAL_ESCAPE!>'\u000G'<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+24
@@ -124,6 +124,30 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.INCORRECT_CHARACTER_LITERAL) { firDiagnostic ->
|
||||||
|
IncorrectCharacterLiteralImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.EMPTY_CHARACTER_LITERAL) { firDiagnostic ->
|
||||||
|
EmptyCharacterLiteralImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL) { firDiagnostic ->
|
||||||
|
TooManyCharactersInCharacterLiteralImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.ILLEGAL_ESCAPE) { firDiagnostic ->
|
||||||
|
IllegalEscapeImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.HIDDEN) { firDiagnostic ->
|
add(FirErrors.HIDDEN) { firDiagnostic ->
|
||||||
HiddenImpl(
|
HiddenImpl(
|
||||||
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration),
|
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration),
|
||||||
|
|||||||
+16
@@ -108,6 +108,22 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
abstract val declaration: String
|
abstract val declaration: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class IncorrectCharacterLiteral : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = IncorrectCharacterLiteral::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class EmptyCharacterLiteral : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = EmptyCharacterLiteral::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class TooManyCharactersInCharacterLiteral : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = TooManyCharactersInCharacterLiteral::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class IllegalEscape : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = IllegalEscape::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class Hidden : KtFirDiagnostic<PsiElement>() {
|
abstract class Hidden : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = Hidden::class
|
override val diagnosticClass get() = Hidden::class
|
||||||
abstract val hidden: KtSymbol
|
abstract val hidden: KtSymbol
|
||||||
|
|||||||
+28
@@ -145,6 +145,34 @@ internal class NestedClassNotAllowedImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class IncorrectCharacterLiteralImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.IncorrectCharacterLiteral(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class EmptyCharacterLiteralImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.EmptyCharacterLiteral(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class TooManyCharactersInCharacterLiteralImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.TooManyCharactersInCharacterLiteral(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class IllegalEscapeImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.IllegalEscape(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class HiddenImpl(
|
internal class HiddenImpl(
|
||||||
override val hidden: KtSymbol,
|
override val hidden: KtSymbol,
|
||||||
firDiagnostic: FirPsiDiagnostic<*>,
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
|||||||
Reference in New Issue
Block a user