[FIR] Optimize performance and fix UNDERSCORE_IS_RESERVED, simplify code

This commit is contained in:
Ivan Kochurkin
2021-07-22 01:47:22 +03:00
committed by Space
parent 2fbb700ec6
commit 63fc3645ab
16 changed files with 190 additions and 182 deletions
@@ -1068,8 +1068,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<ConeKotlinType>("actualType")
}
val UNDERSCORE_IS_RESERVED by error<KtElement>(PositioningStrategy.RESERVED_UNDERSCORE)
val UNDERSCORE_USAGE_WITHOUT_BACKTICKS by error<KtElement>(PositioningStrategy.RESERVED_UNDERSCORE)
val UNDERSCORE_IS_RESERVED by error<PsiElement>(PositioningStrategy.RESERVED_UNDERSCORE)
val UNDERSCORE_USAGE_WITHOUT_BACKTICKS by error<PsiElement>(PositioningStrategy.RESERVED_UNDERSCORE)
val EQUALITY_NOT_APPLICABLE by error<KtBinaryExpression> {
parameter<String>("operator")
@@ -554,8 +554,8 @@ object FirErrors {
val DELEGATE_SPECIAL_FUNCTION_AMBIGUITY by error2<KtExpression, String, Collection<FirBasedSymbol<*>>>()
val DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE by error2<KtExpression, String, Collection<FirBasedSymbol<*>>>()
val DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH by error3<KtExpression, String, ConeKotlinType, ConeKotlinType>()
val UNDERSCORE_IS_RESERVED by error0<KtElement>(SourceElementPositioningStrategies.RESERVED_UNDERSCORE)
val UNDERSCORE_USAGE_WITHOUT_BACKTICKS by error0<KtElement>(SourceElementPositioningStrategies.RESERVED_UNDERSCORE)
val UNDERSCORE_IS_RESERVED by error0<PsiElement>(SourceElementPositioningStrategies.RESERVED_UNDERSCORE)
val UNDERSCORE_USAGE_WITHOUT_BACKTICKS by error0<PsiElement>(SourceElementPositioningStrategies.RESERVED_UNDERSCORE)
val EQUALITY_NOT_APPLICABLE by error3<KtBinaryExpression, String, ConeKotlinType, ConeKotlinType>()
val EQUALITY_NOT_APPLICABLE_WARNING by warning3<KtBinaryExpression, String, ConeKotlinType, ConeKotlinType>()
val INCOMPATIBLE_ENUM_COMPARISON_ERROR by error2<KtElement, ConeKotlinType, ConeKotlinType>()
@@ -5,108 +5,34 @@
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.KtNodeTypes
import org.jetbrains.kotlin.fir.FirLightSourceElement
import org.jetbrains.kotlin.fir.FirPsiSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement
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.checkers.getChildren
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.diagnostics.ConeUnderscoreUsageWithoutBackticks
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.text
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
import org.jetbrains.kotlin.psi.stubs.elements.KtDotQualifiedExpressionElementType
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.KtTypeProjection
import org.jetbrains.kotlin.psi.stubs.elements.KtNameReferenceExpressionElementType
import org.jetbrains.kotlin.psi.stubs.elements.KtTypeProjectionElementType
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
when (expression) {
is FirResolvable -> {
reportIfUnderscore(expression.calleeReference.source, context, reporter, isExpression = true)
}
reportIfUnderscore(
expression.calleeReference.source.text, expression.calleeReference.source, context, reporter,
isExpression = true
)
} else if (expression is FirQualifiedAccess) {
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.source.text, expression.source, context, reporter, isExpression = true)
}
} else if (expression is FirReturnExpression) {
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)
is FirResolvedQualifier -> {
for (reservedUnderscoreDiagnostic in expression.nonFatalDiagnostics.filterIsInstance<ConeUnderscoreUsageWithoutBackticks>()) {
reporter.reportOn(reservedUnderscoreDiagnostic.source, FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS, context)
}
}
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)
}
}
}
@@ -114,27 +40,29 @@ object FirReservedUnderscoreExpressionChecker : FirBasicExpressionChecker() {
object FirReservedUnderscoreDeclarationChecker : FirBasicDeclarationChecker() {
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (
declaration is FirClass ||
declaration is FirFunction ||
declaration is FirRegularClass ||
declaration is FirTypeParameter ||
declaration is FirProperty ||
declaration is FirTypeAlias
) {
reportIfUnderscore(declaration, context, reporter)
} else if (declaration is FirFunction) {
if (declaration is FirSimpleFunction) {
reportIfUnderscore(declaration, context, reporter)
}
if (declaration is FirFunction) {
for (parameter in declaration.valueParameters) {
reportIfUnderscore(
parameter,
context,
reporter,
isSingleUnderscoreAllowed = declaration is FirAnonymousFunction || declaration is FirPropertyAccessor
)
}
val isSingleUnderscoreAllowed = declaration is FirAnonymousFunction || declaration is FirPropertyAccessor
for (parameter in declaration.valueParameters) {
reportIfUnderscore(
parameter,
context,
reporter,
isSingleUnderscoreAllowed = isSingleUnderscoreAllowed
)
}
} else if (declaration is FirFile) {
for (import in declaration.imports) {
reportIfUnderscore(import.aliasName?.asString(), import.source, context, reporter)
reportIfUnderscore(import.aliasSource, context, reporter, isExpression = false)
}
}
}
@@ -146,64 +74,98 @@ private fun reportIfUnderscore(
reporter: DiagnosticReporter,
isSingleUnderscoreAllowed: Boolean = false
) {
val source = declaration.source
val rawIdentifier = when (source) {
val declarationSource = declaration.source
val rawName = when (declarationSource) {
is FirPsiSourceElement ->
(source.psi as? PsiNameIdentifierOwner)?.nameIdentifier?.text
(declarationSource.psi as? PsiNameIdentifierOwner)?.nameIdentifier?.text
is FirLightSourceElement ->
source.treeStructure.nameIdentifier(source.lighterASTNode)?.toString()
declarationSource.treeStructure.nameIdentifier(declarationSource.lighterASTNode)?.toString()
else ->
null
}
reportIfUnderscore(rawIdentifier, source, context, reporter, isSingleUnderscoreAllowed)
reportIfUnderscore(rawName, declarationSource, context, reporter, isSingleUnderscoreAllowed)
val returnOrReceiverTypeRef = when (declaration) {
is FirValueParameter -> declaration.returnTypeRef.source
is FirFunction -> declaration.receiverTypeRef?.source
is FirValueParameter -> declaration.returnTypeRef
is FirFunction -> declaration.receiverTypeRef
else -> null
}
val isReportUnderscoreInReturnOrReceiverTypeRef = when (returnOrReceiverTypeRef) {
is FirPsiSourceElement -> {
val psi = returnOrReceiverTypeRef.psi
psi is KtTypeReference && psi.anyDescendantOfType<LeafPsiElement> { isUnderscore(it.text) }
}
is FirLightSourceElement -> {
val lighterASTNode = returnOrReceiverTypeRef.lighterASTNode
lighterASTNode.tokenType == KtNodeTypes.TYPE_REFERENCE &&
source?.treeStructure?.findFirstDescendant(lighterASTNode)
{ it.tokenType == KtNodeTypes.REFERENCE_EXPRESSION && isUnderscore(it.toString()) } != null
}
else -> {
false
}
}
if (returnOrReceiverTypeRef is FirResolvedTypeRef) {
val delegatedTypeRef = returnOrReceiverTypeRef.delegatedTypeRef
if (delegatedTypeRef is FirUserTypeRef) {
for (qualifierPart in delegatedTypeRef.qualifier) {
reportIfUnderscore(qualifierPart.source, context, reporter, isExpression = true)
if (isReportUnderscoreInReturnOrReceiverTypeRef) {
reporter.reportOn(returnOrReceiverTypeRef, FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS, context)
for (typeArgument in qualifierPart.typeArgumentList.typeArguments) {
reportIfUnderscore(typeArgument.source, context, reporter, isExpression = true)
}
}
}
}
}
private fun reportIfUnderscore(
text: CharSequence?,
source: FirSourceElement?,
context: CheckerContext,
reporter: DiagnosticReporter,
isSingleUnderscoreAllowed: Boolean = false,
isExpression: Boolean = false
isExpression: Boolean
) {
if (text == null || isSingleUnderscoreAllowed && text == "_") {
if (source != null && source.kind !is FirFakeSourceElementKind) {
var rawName: String? = null
if (source is FirPsiSourceElement) {
val psi = source.psi
rawName = if (psi is KtNameReferenceExpression) {
psi.getReferencedNameElement().node.text
} else if (psi is KtTypeProjection) {
psi.typeReference?.typeElement?.text
} else if (psi is LeafPsiElement && psi.elementType == KtTokens.IDENTIFIER) {
psi.text
} else {
null
}
} else if (source is FirLightSourceElement) {
val tokenType = source.elementType
rawName = if (tokenType is KtNameReferenceExpressionElementType || tokenType == KtTokens.IDENTIFIER) {
source.lighterASTNode.toString()
} else if (tokenType is KtTypeProjectionElementType) {
source.lighterASTNode.getChildren(source.treeStructure).last().toString()
} else {
null
}
}
if (rawName?.isUnderscore == true) {
reporter.reportOn(
source,
if (isExpression) FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS else FirErrors.UNDERSCORE_IS_RESERVED,
context
)
}
}
}
private fun reportIfUnderscore(
rawName: CharSequence?,
source: FirSourceElement?,
context: CheckerContext,
reporter: DiagnosticReporter,
isSingleUnderscoreAllowed: Boolean
) {
if (source == null || rawName == null || isSingleUnderscoreAllowed && rawName == "_") {
return
}
if (isUnderscore(text)) {
if (rawName.isUnderscore && source.kind !is FirFakeSourceElementKind) {
reporter.reportOn(
source,
if (isExpression) FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS else FirErrors.UNDERSCORE_IS_RESERVED,
FirErrors.UNDERSCORE_IS_RESERVED,
context
)
}
}
private fun isUnderscore(text: CharSequence) = text.all { it == '_' }
val CharSequence.isUnderscore: Boolean
get() = all { it == '_' }
@@ -387,6 +387,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_OF
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_ON_LHS_OF_DOT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_VARIANCE_CONFLICT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNDERSCORE_IS_RESERVED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNEXPECTED_SAFE_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_ENUM_COMPANION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_ENUM_ENTRY
@@ -1388,6 +1390,14 @@ class FirDefaultErrorMessages {
RENDER_TYPE,
RENDER_TYPE,
)
map.put(
UNDERSCORE_IS_RESERVED,
"Names _, __, ___, ..., are reserved in Kotlin"
)
map.put(
UNDERSCORE_USAGE_WITHOUT_BACKTICKS,
"Names _, __, ___, ... can be used only in back-ticks (`_`, `__`, `___`, ...)"
)
map.put(
EQUALITY_NOT_APPLICABLE,
"Operator ''{0}'' cannot be applied to ''{1}'' and ''{2}''",
@@ -715,20 +715,13 @@ object LightTreePositioningStrategies {
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 nameIdentifier = tree.nameIdentifier(node)
if (nameIdentifier != null) {
return markElement(nameIdentifier, startOffset, endOffset, tree, node)
}
if (node.tokenType == KtNodeTypes.LABEL_QUALIFIER) {
return super.mark(node, startOffset, endOffset - 1, tree)
}
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)
}
}
@@ -19,10 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildAnonymousFunction
import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.diagnostics.ConeNotAnnotationContainer
import org.jetbrains.kotlin.fir.diagnostics.ConeUnderscoreIsReserved
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.*
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.*
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
@@ -969,9 +966,16 @@ class ExpressionsConverter(
private fun convertSimpleNameExpression(referenceExpression: LighterASTNode): FirQualifiedAccessExpression {
return buildQualifiedAccessExpression {
source = referenceExpression.toFirSourceElement()
val nameSource = this@buildQualifiedAccessExpression.source
val rawText = referenceExpression.asText
if (nameSource != null && rawText.isUnderscore) {
nonFatalDiagnostics.add(ConeUnderscoreUsageWithoutBackticks(nameSource))
}
calleeReference = buildSimpleNamedReference {
source = this@buildQualifiedAccessExpression.source
name = referenceExpression.asText.nameAsSafeName()
source = nameSource
name = rawText.nameAsSafeName()
}
}
}
@@ -1054,7 +1054,7 @@ open class RawFirBuilder(
null,
ClassKind.CLASS,
containerTypeParameters = emptyList(),
containingClassIsExpectClass = false
containingClassIsExpectClass = false
)
for (declaration in objectDeclaration.declarations) {
@@ -1667,7 +1667,20 @@ open class RawFirBuilder(
expression.getQualifiedExpressionForSelector() != null -> expression.parent
else -> expression
}.toFirSourceElement()
return generateAccessExpression(qualifiedSource, expression.toFirSourceElement(), expression.getReferencedNameAsName())
val expressionSource = expression.toFirSourceElement()
var diagnostic: ConeDiagnostic? = null
val rawText = expression.getReferencedNameElement().node.text
if (rawText.isUnderscore) {
diagnostic = ConeUnderscoreUsageWithoutBackticks(expressionSource)
}
return generateAccessExpression(
qualifiedSource,
expressionSource,
expression.getReferencedNameAsName(),
diagnostic
)
}
override fun visitConstantExpression(expression: KtConstantExpression, data: Unit): FirElement =
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.FirVariable
import org.jetbrains.kotlin.fir.declarations.builder.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.*
@@ -250,7 +251,8 @@ private fun FirExpression.createConventionCall(
fun generateAccessExpression(
qualifiedSource: FirSourceElement?,
calleeReferenceSource: FirSourceElement?,
name: Name
name: Name,
diagnostic: ConeDiagnostic? = null
): FirQualifiedAccessExpression =
buildQualifiedAccessExpression {
this.source = qualifiedSource
@@ -258,6 +260,9 @@ fun generateAccessExpression(
this.source = calleeReferenceSource
this.name = name
}
if (diagnostic != null) {
this.nonFatalDiagnostics.add(diagnostic)
}
}
fun generateResolvedAccessExpression(source: FirSourceElement?, variable: FirVariable): FirQualifiedAccessExpression =
@@ -844,20 +844,10 @@ object PositioningStrategies {
if (nameIdentifier != null) {
return super.mark(nameIdentifier)
}
} else if (element is KtImportDirective) {
return super.mark(element.alias?.nameIdentifier ?: element)
} else if (element is KtReturnExpression) {
val prevSibling = element.getPrevSiblingIgnoringWhitespace()
if (prevSibling is KtContainerNode) {
return mark(prevSibling)
}
} else if (element !is LeafPsiElement) {
val ranges = element.collectDescendantsOfType<LeafPsiElement> { descendant -> descendant.text.all { it == '_' } }
.map { markSingleElement(it) }
if (ranges.isNotEmpty()) {
return ranges
}
} else if (element is KtLabelReferenceExpression) {
return super.mark(element.getReferencedNameElement())
}
return super.mark(element)
}
}
+13 -3
View File
@@ -2,9 +2,9 @@
import kotlin.Deprecated as <!UNDERSCORE_IS_RESERVED!>___<!>
@___("") data class Pair(val x: Int, val y: Int)
@<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>___<!>("") data class Pair(val x: Int, val y: Int)
class <!UNDERSCORE_IS_RESERVED, UNDERSCORE_IS_RESERVED!>_<!><<!UNDERSCORE_IS_RESERVED!>________<!>>
class <!UNDERSCORE_IS_RESERVED!>_<!><<!UNDERSCORE_IS_RESERVED!>________<!>>
val <!UNDERSCORE_IS_RESERVED!>______<!> = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>_<!><Int>()
fun <!UNDERSCORE_IS_RESERVED!>__<!>(<!UNDERSCORE_IS_RESERVED!>___<!>: Int, y: <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>_<!><Int>?): Int {
@@ -25,7 +25,7 @@ fun <!UNDERSCORE_IS_RESERVED!>__<!>(<!UNDERSCORE_IS_RESERVED!>___<!>: Int, y: <!
}
class A1(val <!UNDERSCORE_IS_RESERVED, UNDERSCORE_IS_RESERVED!>_<!>: String)
class A1(val <!UNDERSCORE_IS_RESERVED!>_<!>: String)
class A2(<!UNDERSCORE_IS_RESERVED!>_<!>: String) {
class B {
typealias <!UNDERSCORE_IS_RESERVED!>_<!> = CharSequence
@@ -48,3 +48,13 @@ val something2 = doIt { _ -> 1 }
var p: Int?
get() = null
set(_) {}
object `____` {
object Nested {
fun method() {}
}
}
fun test() {
<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>____<!>.Nested.method()
}
+10
View File
@@ -48,3 +48,13 @@ val something2 = doIt { _ -> 1 }
var p: Int?
get() = null
set(_) {}
object `____` {
object Nested {
fun method() {}
}
}
fun test() {
<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>____<!>.Nested.method()
}
+16
View File
@@ -7,6 +7,7 @@ public val something2: kotlin.Any?
public fun __(/*0*/ ___: kotlin.Int, /*1*/ y: _<kotlin.Int>?): kotlin.Int
public fun doIt(/*0*/ f: (kotlin.Any?) -> kotlin.Any?): kotlin.Any?
public fun oneUnderscore(/*0*/ <anonymous parameter 0>: kotlin.Int): kotlin.Unit
public fun test(): kotlin.Unit
public final class A1 {
public constructor A1(/*0*/ _: kotlin.String)
@@ -53,3 +54,18 @@ public final class _</*0*/ ________> {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object ____ {
private constructor ____()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public object Nested {
private constructor Nested()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun method(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -1,6 +0,0 @@
package test
annotation class `__`(val value: String)
@__("") class TestAnn
@`__`("") class TestAnn2
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
package test
annotation class `__`(val value: String)
@@ -2003,11 +2003,11 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val actualType: KtType
}
abstract class UnderscoreIsReserved : KtFirDiagnostic<KtElement>() {
abstract class UnderscoreIsReserved : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = UnderscoreIsReserved::class
}
abstract class UnderscoreUsageWithoutBackticks : KtFirDiagnostic<KtElement>() {
abstract class UnderscoreUsageWithoutBackticks : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = UnderscoreUsageWithoutBackticks::class
}
@@ -3228,14 +3228,14 @@ internal class DelegateSpecialFunctionReturnTypeMismatchImpl(
internal class UnderscoreIsReservedImpl(
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.UnderscoreIsReserved(), KtAbstractFirDiagnostic<KtElement> {
) : KtFirDiagnostic.UnderscoreIsReserved(), KtAbstractFirDiagnostic<PsiElement> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class UnderscoreUsageWithoutBackticksImpl(
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.UnderscoreUsageWithoutBackticks(), KtAbstractFirDiagnostic<KtElement> {
) : KtFirDiagnostic.UnderscoreUsageWithoutBackticks(), KtAbstractFirDiagnostic<PsiElement> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}