[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
|
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||||
|
|
||||||
|
import com.intellij.lang.LighterASTNode
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiNameIdentifierOwner
|
import com.intellij.psi.PsiNameIdentifierOwner
|
||||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
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.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.fir.analysis.checkers.getChildren
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
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.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
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() {
|
object FirReservedUnderscoreExpressionChecker : FirBasicExpressionChecker() {
|
||||||
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
val source = expression.source
|
||||||
|
|
||||||
if (expression is FirFunctionCall) {
|
if (expression is FirFunctionCall) {
|
||||||
|
val calleeReferenceSource = expression.calleeReference.source
|
||||||
|
if (calleeReferenceSource is FirLightSourceElement && calleeReferenceSource.lighterASTNode.tokenType == KtNodeTypes.OPERATION_REFERENCE) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
reportIfUnderscore(
|
reportIfUnderscore(
|
||||||
expression.calleeReference.psi?.text, expression.source, context, reporter,
|
expression.calleeReference.source.text, expression.calleeReference.source, context, reporter,
|
||||||
isExpression = true
|
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) {
|
} else if (expression is FirQualifiedAccess) {
|
||||||
fun processQualifiedAccess(psi: PsiElement?) {
|
if (source is FirPsiSourceElement<*>) {
|
||||||
if (psi is KtNameReferenceExpression) {
|
reportIfUnderscoreInQualifiedAccess(source, expression, context, reporter)
|
||||||
reportIfUnderscore(psi.text, expression.source, context, reporter, isExpression = true)
|
} else if (source is FirLightSourceElement) {
|
||||||
} else if (psi is KtDotQualifiedExpression || psi is KtCallableReferenceExpression) {
|
reportIfUnderscoreInQualifiedAccess(source, expression, context, reporter)
|
||||||
processQualifiedAccess(psi.firstChild)
|
|
||||||
processQualifiedAccess(psi.lastChild)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val psi = expression.psi
|
|
||||||
if (psi != null && psi.parent !is KtDotQualifiedExpression && psi.parent !is KtCallableReferenceExpression) {
|
|
||||||
processQualifiedAccess(psi)
|
|
||||||
}
|
}
|
||||||
} else if (expression is FirGetClassCall) {
|
} else if (expression is FirGetClassCall) {
|
||||||
for (argument in expression.argumentList.arguments) {
|
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) {
|
} 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 FirProperty ||
|
||||||
declaration is FirTypeAlias
|
declaration is FirTypeAlias
|
||||||
) {
|
) {
|
||||||
|
|
||||||
reportIfUnderscore(declaration, context, reporter)
|
reportIfUnderscore(declaration, context, reporter)
|
||||||
|
|
||||||
if (declaration is FirFunction<*>) {
|
if (declaration is FirFunction<*>) {
|
||||||
@@ -94,15 +144,35 @@ private fun reportIfUnderscore(
|
|||||||
reporter: DiagnosticReporter,
|
reporter: DiagnosticReporter,
|
||||||
isSingleUnderscoreAllowed: Boolean = false
|
isSingleUnderscoreAllowed: Boolean = false
|
||||||
) {
|
) {
|
||||||
val rawIdentifier = (declaration.psi as? PsiNameIdentifierOwner)?.nameIdentifier?.text ?: return
|
val source = declaration.source
|
||||||
reportIfUnderscore(rawIdentifier, declaration.source, context, reporter, isSingleUnderscoreAllowed)
|
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?) {
|
reportIfUnderscore(rawIdentifier, source, context, reporter, isSingleUnderscoreAllowed)
|
||||||
if (typeRef == null) return
|
|
||||||
|
|
||||||
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(
|
reporter.reportOn(
|
||||||
typeRef.source,
|
typeRefSource,
|
||||||
FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS,
|
FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
@@ -110,17 +180,30 @@ private fun reportIfUnderscore(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (declaration is FirValueParameter) {
|
if (declaration is FirValueParameter) {
|
||||||
val psi = declaration.returnTypeRef.psi
|
val isReport = when (val returnTypeRefSource = declaration.returnTypeRef.source) {
|
||||||
if (psi !is KtFunctionLiteral && psi !is KtParameter) {
|
is FirPsiSourceElement<*> -> {
|
||||||
reportIfAnyDescendantIfUnderscore(declaration.returnTypeRef)
|
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<*>) {
|
} else if (declaration is FirFunction<*>) {
|
||||||
reportIfAnyDescendantIfUnderscore(declaration.receiverTypeRef)
|
reportIfAnyDescendantIsUnderscore(declaration.receiverTypeRef?.source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reportIfUnderscore(
|
private fun reportIfUnderscore(
|
||||||
text: String?,
|
text: CharSequence?,
|
||||||
source: FirSourceElement?,
|
source: FirSourceElement?,
|
||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
reporter: DiagnosticReporter,
|
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() {
|
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) } }
|
?: 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? {
|
private fun FlyweightCapableTreeStructure<LighterASTNode>.findChildByType(node: LighterASTNode, type: TokenSet): LighterASTNode? {
|
||||||
val childrenRef = Ref<Array<LighterASTNode?>>()
|
val childrenRef = Ref<Array<LighterASTNode?>>()
|
||||||
getChildren(node, childrenRef)
|
getChildren(node, childrenRef)
|
||||||
|
|||||||
+12
-1
@@ -46,11 +46,22 @@ fun markRange(
|
|||||||
tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||||
originalNode: LighterASTNode
|
originalNode: LighterASTNode
|
||||||
): List<TextRange> {
|
): 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 betterFrom = from.nonFillerFirstChildOrSelf(tree)
|
||||||
val betterTo = to.nonFillerLastChildOrSelf(tree)
|
val betterTo = to.nonFillerLastChildOrSelf(tree)
|
||||||
val startDelta = tree.getStartOffset(betterFrom) - tree.getStartOffset(originalNode)
|
val startDelta = tree.getStartOffset(betterFrom) - tree.getStartOffset(originalNode)
|
||||||
val endDelta = tree.getEndOffset(betterTo) - tree.getEndOffset(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(
|
private val DOC_AND_COMMENT_TOKENS = setOf(
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
public val ______: _<kotlin.Int>
|
public val ______: _<kotlin.Int>
|
||||||
|
public var p: kotlin.Int?
|
||||||
public val something: kotlin.Any?
|
public val something: kotlin.Any?
|
||||||
public val something2: kotlin.Any?
|
public val something2: kotlin.Any?
|
||||||
public fun __(/*0*/ ___: kotlin.Int, /*1*/ y: _<kotlin.Int>?): kotlin.Int
|
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 hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
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
|
val firFile = info.firFiles[file] ?: continue
|
||||||
var diagnostics = diagnosticsPerFile[firFile] ?: continue
|
var diagnostics = diagnosticsPerFile[firFile] ?: continue
|
||||||
if (AdditionalFilesDirectives.CHECK_TYPE in module.directives) {
|
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 ->
|
val diagnosticsMetadataInfos = diagnostics.mapNotNull { diagnostic ->
|
||||||
if (!diagnosticsService.shouldRenderDiagnostic(module, diagnostic.factory.name)) return@mapNotNull null
|
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)
|
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||||
*
|
*
|
||||||
@@ -21,10 +20,10 @@ val value_3 = <!UNRESOLVED_REFERENCE!>_____________0000<!>
|
|||||||
val value_4 = <!UNRESOLVED_REFERENCE!>_______________________________________________________________________________________________________________________________________________________0<!>
|
val value_4 = <!UNRESOLVED_REFERENCE!>_______________________________________________________________________________________________________________________________________________________0<!>
|
||||||
|
|
||||||
// TESTCASE NUMBER: 5
|
// TESTCASE NUMBER: 5
|
||||||
val value_5 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
val value_5 = <!UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
||||||
|
|
||||||
// TESTCASE NUMBER: 6
|
// TESTCASE NUMBER: 6
|
||||||
val value_6 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>_<!>
|
val value_6 = <!UNRESOLVED_REFERENCE!>_<!>
|
||||||
|
|
||||||
// TESTCASE NUMBER: 7
|
// TESTCASE NUMBER: 7
|
||||||
val value_7 = <!UNRESOLVED_REFERENCE!>_0_<!>
|
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)
|
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||||
*
|
*
|
||||||
@@ -21,10 +20,10 @@ val value_3 = <!UNRESOLVED_REFERENCE!>_____________0000<!>
|
|||||||
val value_4 = <!UNRESOLVED_REFERENCE!>_______________________________________________________________________________________________________________________________________________________0<!>
|
val value_4 = <!UNRESOLVED_REFERENCE!>_______________________________________________________________________________________________________________________________________________________0<!>
|
||||||
|
|
||||||
// TESTCASE NUMBER: 5
|
// TESTCASE NUMBER: 5
|
||||||
val value_5 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
val value_5 = <!UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
||||||
|
|
||||||
// TESTCASE NUMBER: 6
|
// TESTCASE NUMBER: 6
|
||||||
val value_6 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>_<!>
|
val value_6 = <!UNRESOLVED_REFERENCE!>_<!>
|
||||||
|
|
||||||
// TESTCASE NUMBER: 7
|
// TESTCASE NUMBER: 7
|
||||||
val value_7 = <!UNRESOLVED_REFERENCE!>_0_<!>
|
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)
|
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||||
*
|
*
|
||||||
@@ -21,10 +20,10 @@ val value_3 = <!UNRESOLVED_REFERENCE!>_____________0000<!>
|
|||||||
val value_4 = <!UNRESOLVED_REFERENCE!>_______________________________________________________________________________________________________________________________________________________0<!>
|
val value_4 = <!UNRESOLVED_REFERENCE!>_______________________________________________________________________________________________________________________________________________________0<!>
|
||||||
|
|
||||||
// TESTCASE NUMBER: 5
|
// TESTCASE NUMBER: 5
|
||||||
val value_5 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
val value_5 = <!UNRESOLVED_REFERENCE!>____________________________________________________<!>
|
||||||
|
|
||||||
// TESTCASE NUMBER: 6
|
// TESTCASE NUMBER: 6
|
||||||
val value_6 = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>_<!>
|
val value_6 = <!UNRESOLVED_REFERENCE!>_<!>
|
||||||
|
|
||||||
// TESTCASE NUMBER: 7
|
// TESTCASE NUMBER: 7
|
||||||
val value_7 = <!UNRESOLVED_REFERENCE!>_0_<!>
|
val value_7 = <!UNRESOLVED_REFERENCE!>_0_<!>
|
||||||
|
|||||||
Reference in New Issue
Block a user