[FIR] Implement UNDERSCORE_IS_RESERVED, UNDERSCORE_USAGE_WITHOUT_BACKTICKS diagnostics (lighttree)
This commit is contained in:
committed by
TeamCityServer
parent
ea2d9f7c0c
commit
704b5a0e13
+123
-40
@@ -5,55 +5,106 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||
|
||||
import com.intellij.lang.LighterASTNode
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiNameIdentifierOwner
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getChildren
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtDotQualifiedExpressionElementType
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtNameReferenceExpressionElementType
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtParameterElementType
|
||||
|
||||
object FirReservedUnderscoreExpressionChecker : FirBasicExpressionChecker() {
|
||||
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val source = expression.source
|
||||
|
||||
if (expression is FirFunctionCall) {
|
||||
val calleeReferenceSource = expression.calleeReference.source
|
||||
if (calleeReferenceSource is FirLightSourceElement && calleeReferenceSource.lighterASTNode.tokenType == KtNodeTypes.OPERATION_REFERENCE) {
|
||||
return
|
||||
}
|
||||
|
||||
reportIfUnderscore(
|
||||
expression.calleeReference.psi?.text, expression.source, context, reporter,
|
||||
expression.calleeReference.source.text, expression.calleeReference.source, context, reporter,
|
||||
isExpression = true
|
||||
)
|
||||
|
||||
for (argument in expression.arguments) {
|
||||
if (argument is FirNamedArgumentExpression) {
|
||||
reportIfUnderscore(argument.psi?.firstChild?.text, argument.source, context, reporter)
|
||||
}
|
||||
}
|
||||
} else if (expression is FirQualifiedAccess) {
|
||||
fun processQualifiedAccess(psi: PsiElement?) {
|
||||
if (psi is KtNameReferenceExpression) {
|
||||
reportIfUnderscore(psi.text, expression.source, context, reporter, isExpression = true)
|
||||
} else if (psi is KtDotQualifiedExpression || psi is KtCallableReferenceExpression) {
|
||||
processQualifiedAccess(psi.firstChild)
|
||||
processQualifiedAccess(psi.lastChild)
|
||||
}
|
||||
}
|
||||
|
||||
val psi = expression.psi
|
||||
if (psi != null && psi.parent !is KtDotQualifiedExpression && psi.parent !is KtCallableReferenceExpression) {
|
||||
processQualifiedAccess(psi)
|
||||
if (source is FirPsiSourceElement<*>) {
|
||||
reportIfUnderscoreInQualifiedAccess(source, expression, context, reporter)
|
||||
} else if (source is FirLightSourceElement) {
|
||||
reportIfUnderscoreInQualifiedAccess(source, expression, context, reporter)
|
||||
}
|
||||
} else if (expression is FirGetClassCall) {
|
||||
for (argument in expression.argumentList.arguments) {
|
||||
reportIfUnderscore(argument.psi?.text, expression.source, context, reporter, isExpression = true)
|
||||
reportIfUnderscore(argument.source.text, expression.source, context, reporter, isExpression = true)
|
||||
}
|
||||
} else if (expression is FirReturnExpression) {
|
||||
reportIfUnderscore(expression.target.labelName, expression.source, context, reporter)
|
||||
var labelName: String? = null
|
||||
if (source is FirPsiSourceElement<*>) {
|
||||
labelName = (source.psi.parent as? KtLabeledExpression)?.getLabelName()
|
||||
} else if (source is FirLightSourceElement) {
|
||||
val parent = source.treeStructure.getParent(source.lighterASTNode)
|
||||
if (parent != null && parent.tokenType == KtNodeTypes.LABELED_EXPRESSION) {
|
||||
labelName = source.treeStructure.findDescendantByType(parent, KtNodeTypes.LABEL).toString()
|
||||
labelName = labelName.substring(0, labelName.length - 1)
|
||||
}
|
||||
}
|
||||
|
||||
reportIfUnderscore(labelName, expression.source, context, reporter)
|
||||
}
|
||||
}
|
||||
|
||||
private fun reportIfUnderscoreInQualifiedAccess(
|
||||
source: FirPsiSourceElement<*>,
|
||||
expression: FirStatement,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
fun processQualifiedAccess(psi: PsiElement?) {
|
||||
if (psi is KtNameReferenceExpression) {
|
||||
reportIfUnderscore(psi.text, expression.source, context, reporter, isExpression = true)
|
||||
} else if (psi is KtDotQualifiedExpression || psi is KtCallableReferenceExpression) {
|
||||
processQualifiedAccess(psi.firstChild)
|
||||
processQualifiedAccess(psi.lastChild)
|
||||
}
|
||||
}
|
||||
|
||||
val psi = source.psi
|
||||
if (psi.parent !is KtDotQualifiedExpression && psi.parent !is KtCallableReferenceExpression) {
|
||||
processQualifiedAccess(psi)
|
||||
}
|
||||
}
|
||||
|
||||
private fun reportIfUnderscoreInQualifiedAccess(
|
||||
source: FirLightSourceElement,
|
||||
expression: FirStatement,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
fun processQualifiedAccess(lightSourceElement: LighterASTNode?) {
|
||||
val tokenType = lightSourceElement?.tokenType
|
||||
if (tokenType is KtNameReferenceExpressionElementType) {
|
||||
reportIfUnderscore(lightSourceElement.toString(), expression.source, context, reporter, isExpression = true)
|
||||
} else if (lightSourceElement != null && (tokenType is KtDotQualifiedExpressionElementType || tokenType == KtNodeTypes.CALLABLE_REFERENCE_EXPRESSION)) {
|
||||
val children = lightSourceElement.getChildren(source.treeStructure)
|
||||
processQualifiedAccess(children.first())
|
||||
processQualifiedAccess(children.last())
|
||||
}
|
||||
}
|
||||
|
||||
val astNode = source.lighterASTNode
|
||||
val parent = source.treeStructure.getParent(astNode)
|
||||
if (parent?.tokenType !is KtDotQualifiedExpressionElementType && parent?.tokenType != KtNodeTypes.CALLABLE_REFERENCE_EXPRESSION) {
|
||||
processQualifiedAccess(astNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +118,6 @@ object FirReservedUnderscoreDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
declaration is FirProperty ||
|
||||
declaration is FirTypeAlias
|
||||
) {
|
||||
|
||||
reportIfUnderscore(declaration, context, reporter)
|
||||
|
||||
if (declaration is FirFunction<*>) {
|
||||
@@ -94,15 +144,35 @@ private fun reportIfUnderscore(
|
||||
reporter: DiagnosticReporter,
|
||||
isSingleUnderscoreAllowed: Boolean = false
|
||||
) {
|
||||
val rawIdentifier = (declaration.psi as? PsiNameIdentifierOwner)?.nameIdentifier?.text ?: return
|
||||
reportIfUnderscore(rawIdentifier, declaration.source, context, reporter, isSingleUnderscoreAllowed)
|
||||
val source = declaration.source
|
||||
val rawIdentifier = when (source) {
|
||||
is FirPsiSourceElement<*> ->
|
||||
(source.psi as? PsiNameIdentifierOwner)?.nameIdentifier?.text
|
||||
is FirLightSourceElement ->
|
||||
source.treeStructure.nameIdentifier(source.lighterASTNode)?.toString()
|
||||
else ->
|
||||
null
|
||||
}
|
||||
|
||||
fun reportIfAnyDescendantIfUnderscore(typeRef: FirTypeRef?) {
|
||||
if (typeRef == null) return
|
||||
reportIfUnderscore(rawIdentifier, source, context, reporter, isSingleUnderscoreAllowed)
|
||||
|
||||
if (typeRef.psi?.anyDescendantOfType<LeafPsiElement> { isUnderscore(it.text) } == true) {
|
||||
fun reportIfAnyDescendantIsUnderscore(typeRefSource: FirSourceElement?) {
|
||||
if (typeRefSource == null) return
|
||||
|
||||
val isReport = when (typeRefSource) {
|
||||
is FirPsiSourceElement<*> -> {
|
||||
val psi = typeRefSource.psi
|
||||
psi !is KtFunctionLiteral && psi.anyDescendantOfType<LeafPsiElement> { isUnderscore(it.text) }
|
||||
}
|
||||
is FirLightSourceElement ->
|
||||
source?.treeStructure?.findFirstDescendant(typeRefSource.lighterASTNode) { node -> isUnderscore(node.toString()) } != null
|
||||
else ->
|
||||
false
|
||||
}
|
||||
|
||||
if (isReport) {
|
||||
reporter.reportOn(
|
||||
typeRef.source,
|
||||
typeRefSource,
|
||||
FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS,
|
||||
context
|
||||
)
|
||||
@@ -110,17 +180,30 @@ private fun reportIfUnderscore(
|
||||
}
|
||||
|
||||
if (declaration is FirValueParameter) {
|
||||
val psi = declaration.returnTypeRef.psi
|
||||
if (psi !is KtFunctionLiteral && psi !is KtParameter) {
|
||||
reportIfAnyDescendantIfUnderscore(declaration.returnTypeRef)
|
||||
val isReport = when (val returnTypeRefSource = declaration.returnTypeRef.source) {
|
||||
is FirPsiSourceElement<*> -> {
|
||||
val psi = returnTypeRefSource.psi
|
||||
psi !is KtFunctionLiteral && psi !is KtParameter
|
||||
}
|
||||
is FirLightSourceElement -> {
|
||||
val tokenType = returnTypeRefSource.lighterASTNode.tokenType
|
||||
tokenType !is KtParameterElementType && tokenType != KtNodeTypes.CLASS
|
||||
}
|
||||
else -> {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
if (isReport) {
|
||||
reportIfAnyDescendantIsUnderscore(declaration.returnTypeRef.source)
|
||||
}
|
||||
} else if (declaration is FirFunction<*>) {
|
||||
reportIfAnyDescendantIfUnderscore(declaration.receiverTypeRef)
|
||||
reportIfAnyDescendantIsUnderscore(declaration.receiverTypeRef?.source)
|
||||
}
|
||||
}
|
||||
|
||||
private fun reportIfUnderscore(
|
||||
text: String?,
|
||||
text: CharSequence?,
|
||||
source: FirSourceElement?,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter,
|
||||
@@ -140,4 +223,4 @@ private fun reportIfUnderscore(
|
||||
}
|
||||
}
|
||||
|
||||
private fun isUnderscore(text: String) = text.all { it == '_' }
|
||||
private fun isUnderscore(text: CharSequence) = text.all { it == '_' }
|
||||
+51
@@ -644,6 +644,28 @@ object LightTreePositioningStrategies {
|
||||
}
|
||||
|
||||
val RESERVED_UNDERSCORE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>
|
||||
): List<TextRange> {
|
||||
if (node.tokenType == KtNodeTypes.RETURN) {
|
||||
val parent = tree.getParent(node)
|
||||
if (parent != null) {
|
||||
val label = tree.findDescendantByType(parent, KtNodeTypes.LABEL)
|
||||
if (label != null) {
|
||||
return markElement(label, startOffset, endOffset - 1, tree, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val descendants =
|
||||
tree.collectDescendantsOfType(node, KtTokens.IDENTIFIER) { descendant -> descendant.toString().all { it == '_' } };
|
||||
if (descendants.isNotEmpty())
|
||||
return descendants.map { markSingleElement(it, it, startOffset, endOffset, tree, node) }
|
||||
return super.mark(node, startOffset, endOffset, tree)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -858,6 +880,35 @@ fun FlyweightCapableTreeStructure<LighterASTNode>.findFirstDescendant(
|
||||
?: childrenRef.get()?.firstNotNullResult { child -> child?.let { findFirstDescendant(it, predicate) } }
|
||||
}
|
||||
|
||||
fun FlyweightCapableTreeStructure<LighterASTNode>.collectDescendantsOfType(
|
||||
node: LighterASTNode, type: IElementType,
|
||||
predicate: (LighterASTNode) -> Boolean = { true }
|
||||
): List<LighterASTNode> {
|
||||
val result = mutableListOf<LighterASTNode>()
|
||||
|
||||
fun FlyweightCapableTreeStructure<LighterASTNode>.collectDescendantByType(node: LighterASTNode) {
|
||||
val childrenRef = Ref<Array<LighterASTNode?>>()
|
||||
getChildren(node, childrenRef)
|
||||
|
||||
val childrenRefGet = childrenRef.get()
|
||||
if (childrenRefGet != null) {
|
||||
for (child in childrenRefGet) {
|
||||
if (child?.tokenType == type && predicate(child)) {
|
||||
result.add(child)
|
||||
}
|
||||
|
||||
if (child != null) {
|
||||
collectDescendantByType(child)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collectDescendantByType(node)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun FlyweightCapableTreeStructure<LighterASTNode>.findChildByType(node: LighterASTNode, type: TokenSet): LighterASTNode? {
|
||||
val childrenRef = Ref<Array<LighterASTNode?>>()
|
||||
getChildren(node, childrenRef)
|
||||
|
||||
+12
-1
@@ -46,11 +46,22 @@ fun markRange(
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||
originalNode: LighterASTNode
|
||||
): List<TextRange> {
|
||||
return listOf(markSingleElement(from, to, startOffset, endOffset, tree, originalNode))
|
||||
}
|
||||
|
||||
fun markSingleElement(
|
||||
from: LighterASTNode,
|
||||
to: LighterASTNode,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||
originalNode: LighterASTNode
|
||||
): TextRange {
|
||||
val betterFrom = from.nonFillerFirstChildOrSelf(tree)
|
||||
val betterTo = to.nonFillerLastChildOrSelf(tree)
|
||||
val startDelta = tree.getStartOffset(betterFrom) - tree.getStartOffset(originalNode)
|
||||
val endDelta = tree.getEndOffset(betterTo) - tree.getEndOffset(originalNode)
|
||||
return listOf(TextRange(startDelta + startOffset, endDelta + endOffset))
|
||||
return TextRange(startDelta + startOffset, endDelta + endOffset)
|
||||
}
|
||||
|
||||
private val DOC_AND_COMMENT_TOKENS = setOf(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package
|
||||
|
||||
public val ______: _<kotlin.Int>
|
||||
public var p: kotlin.Int?
|
||||
public val something: kotlin.Any?
|
||||
public val something2: kotlin.Any?
|
||||
public fun __(/*0*/ ___: kotlin.Int, /*1*/ y: _<kotlin.Int>?): kotlin.Int
|
||||
@@ -51,3 +52,4 @@ public final class _</*0*/ ________> {
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
||||
val firFile = info.firFiles[file] ?: continue
|
||||
var diagnostics = diagnosticsPerFile[firFile] ?: continue
|
||||
if (AdditionalFilesDirectives.CHECK_TYPE in module.directives) {
|
||||
diagnostics = diagnostics.filter { it.factory.name != Errors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS.name }
|
||||
diagnostics = diagnostics.filter { it.factory.name != FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS.name }
|
||||
}
|
||||
val diagnosticsMetadataInfos = diagnostics.mapNotNull { diagnostic ->
|
||||
if (!diagnosticsService.shouldRenderDiagnostic(module, diagnostic.factory.name)) return@mapNotNull null
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-100
|
||||
* MAIN LINK: expressions, constant-literals, integer-literals, decimal-integer-literals -> paragraph 1 -> sentence 2
|
||||
* NUMBER: 1
|
||||
* DESCRIPTION: Integer literals with an underscore in the first position (it's considered as identifiers).
|
||||
*/
|
||||
|
||||
// TESTCASE NUMBER: 1
|
||||
val value_1 = <!UNRESOLVED_REFERENCE!>_5678_90<!>
|
||||
|
||||
// TESTCASE NUMBER: 2
|
||||
val value_2 = <!UNRESOLVED_REFERENCE!>_2_3_4_5_6_7_8_9_<!>
|
||||
|
||||
// TESTCASE NUMBER: 3
|
||||
val value_3 = <!UNRESOLVED_REFERENCE!>_____________0000<!>
|
||||
|
||||
// TESTCASE NUMBER: 4
|
||||
val value_4 = <!UNRESOLVED_REFERENCE!>_______________________________________________________________________________________________________________________________________________________0<!>
|
||||
|
||||
// TESTCASE NUMBER: 5
|
||||
val value_5 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
||||
|
||||
// TESTCASE NUMBER: 6
|
||||
val value_6 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>_<!>
|
||||
|
||||
// TESTCASE NUMBER: 7
|
||||
val value_7 = <!UNRESOLVED_REFERENCE!>_0_<!>
|
||||
|
||||
// TESTCASE NUMBER: 8
|
||||
val value_8 = <!UNRESOLVED_REFERENCE!>_9_<!>
|
||||
+2
-3
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
@@ -21,10 +20,10 @@ val value_3 = <!UNRESOLVED_REFERENCE!>_____________0000<!>
|
||||
val value_4 = <!UNRESOLVED_REFERENCE!>_______________________________________________________________________________________________________________________________________________________0<!>
|
||||
|
||||
// TESTCASE NUMBER: 5
|
||||
val value_5 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
||||
val value_5 = <!UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
||||
|
||||
// TESTCASE NUMBER: 6
|
||||
val value_6 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>_<!>
|
||||
val value_6 = <!UNRESOLVED_REFERENCE!>_<!>
|
||||
|
||||
// TESTCASE NUMBER: 7
|
||||
val value_7 = <!UNRESOLVED_REFERENCE!>_0_<!>
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-100
|
||||
* MAIN LINK: expressions, constant-literals, integer-literals, decimal-integer-literals -> paragraph 1 -> sentence 2
|
||||
* NUMBER: 2
|
||||
* DESCRIPTION: Integer literals with an underscore in the first position (it's considered as identifiers).
|
||||
*/
|
||||
|
||||
// TESTCASE NUMBER: 1
|
||||
val value_1 = <!UNRESOLVED_REFERENCE!>_5678_90<!>
|
||||
|
||||
// TESTCASE NUMBER: 2
|
||||
val value_2 = <!UNRESOLVED_REFERENCE!>_2_3_4_5_6_7_8_9_<!>
|
||||
|
||||
// TESTCASE NUMBER: 3
|
||||
val value_3 = <!UNRESOLVED_REFERENCE!>_____________0000<!>
|
||||
|
||||
// TESTCASE NUMBER: 4
|
||||
val value_4 = <!UNRESOLVED_REFERENCE!>_______________________________________________________________________________________________________________________________________________________0<!>
|
||||
|
||||
// TESTCASE NUMBER: 5
|
||||
val value_5 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
||||
|
||||
// TESTCASE NUMBER: 6
|
||||
val value_6 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>_<!>
|
||||
|
||||
// TESTCASE NUMBER: 7
|
||||
val value_7 = <!UNRESOLVED_REFERENCE!>_0_<!>
|
||||
|
||||
// TESTCASE NUMBER: 8
|
||||
val value_8 = <!UNRESOLVED_REFERENCE!>_9_<!>
|
||||
+2
-3
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
@@ -21,10 +20,10 @@ val value_3 = <!UNRESOLVED_REFERENCE!>_____________0000<!>
|
||||
val value_4 = <!UNRESOLVED_REFERENCE!>_______________________________________________________________________________________________________________________________________________________0<!>
|
||||
|
||||
// TESTCASE NUMBER: 5
|
||||
val value_5 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
||||
val value_5 = <!UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
||||
|
||||
// TESTCASE NUMBER: 6
|
||||
val value_6 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>_<!>
|
||||
val value_6 = <!UNRESOLVED_REFERENCE!>_<!>
|
||||
|
||||
// TESTCASE NUMBER: 7
|
||||
val value_7 = <!UNRESOLVED_REFERENCE!>_0_<!>
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-100
|
||||
* MAIN LINK: expressions, constant-literals, integer-literals, decimal-integer-literals -> paragraph 1 -> sentence 2
|
||||
* NUMBER: 3
|
||||
* DESCRIPTION: Integer literals with an underscore in the first position (it's considered as identifiers).
|
||||
*/
|
||||
|
||||
// TESTCASE NUMBER: 1
|
||||
val value_1 = <!UNRESOLVED_REFERENCE!>_5678_90<!>
|
||||
|
||||
// TESTCASE NUMBER: 2
|
||||
val value_2 = <!UNRESOLVED_REFERENCE!>_2_3_4_5_6_7_8_9_<!>
|
||||
|
||||
// TESTCASE NUMBER: 3
|
||||
val value_3 = <!UNRESOLVED_REFERENCE!>_____________0000<!>
|
||||
|
||||
// TESTCASE NUMBER: 4
|
||||
val value_4 = <!UNRESOLVED_REFERENCE!>_______________________________________________________________________________________________________________________________________________________0<!>
|
||||
|
||||
// TESTCASE NUMBER: 5
|
||||
val value_5 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
||||
|
||||
// TESTCASE NUMBER: 6
|
||||
val value_6 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>_<!>
|
||||
|
||||
// TESTCASE NUMBER: 7
|
||||
val value_7 = <!UNRESOLVED_REFERENCE!>_0_<!>
|
||||
|
||||
// TESTCASE NUMBER: 8
|
||||
val value_8 = <!UNRESOLVED_REFERENCE!>_9_<!>
|
||||
+2
-3
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
@@ -21,10 +20,10 @@ val value_3 = <!UNRESOLVED_REFERENCE!>_____________0000<!>
|
||||
val value_4 = <!UNRESOLVED_REFERENCE!>_______________________________________________________________________________________________________________________________________________________0<!>
|
||||
|
||||
// TESTCASE NUMBER: 5
|
||||
val value_5 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
||||
val value_5 = <!UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
||||
|
||||
// TESTCASE NUMBER: 6
|
||||
val value_6 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>_<!>
|
||||
val value_6 = <!UNRESOLVED_REFERENCE!>_<!>
|
||||
|
||||
// TESTCASE NUMBER: 7
|
||||
val value_7 = <!UNRESOLVED_REFERENCE!>_0_<!>
|
||||
|
||||
Reference in New Issue
Block a user