FIR: allow diagnostic collection on default property accessors
This commit is contained in:
committed by
teamcityserver
parent
39fe457f91
commit
2a9a1dbb86
Vendored
+2
-2
@@ -5,12 +5,12 @@ abstract class A {
|
|||||||
|
|
||||||
class C1 : A() {
|
class C1 : A() {
|
||||||
<!REDUNDANT_VISIBILITY_MODIFIER!>public<!> override var attribute = super.attribute
|
<!REDUNDANT_VISIBILITY_MODIFIER!>public<!> override var attribute = super.attribute
|
||||||
public set
|
<!REDUNDANT_VISIBILITY_MODIFIER!>public<!> set
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class B2 : A() {
|
abstract class B2 : A() {
|
||||||
override var attribute = "b"
|
override var attribute = "b"
|
||||||
public set
|
<!REDUNDANT_VISIBILITY_MODIFIER!>public<!> set
|
||||||
}
|
}
|
||||||
|
|
||||||
class C2 : B2() {
|
class C2 : B2() {
|
||||||
|
|||||||
+1
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
|||||||
|
|
||||||
object FirJvmExternalDeclarationChecker : FirBasicDeclarationChecker() {
|
object FirJvmExternalDeclarationChecker : FirBasicDeclarationChecker() {
|
||||||
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
if (declaration is FirPropertyAccessor) return
|
||||||
checkInternal(declaration, null, null, context, reporter)
|
checkInternal(declaration, null, null, context, reporter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-12
@@ -120,18 +120,20 @@ object FirExposedVisibilityDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declaration.valueParameters.forEachIndexed { i, valueParameter ->
|
if (declaration !is FirPropertyAccessor) {
|
||||||
if (i < declaration.valueParameters.size) {
|
declaration.valueParameters.forEachIndexed { i, valueParameter ->
|
||||||
val (restricting, restrictingVisibility) = valueParameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
if (i < declaration.valueParameters.size) {
|
||||||
?.findVisibilityExposure(context, functionVisibility) ?: return@forEachIndexed
|
val (restricting, restrictingVisibility) = valueParameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||||
reporter.reportOn(
|
?.findVisibilityExposure(context, functionVisibility) ?: return@forEachIndexed
|
||||||
valueParameter.source,
|
reporter.reportOn(
|
||||||
FirErrors.EXPOSED_PARAMETER_TYPE,
|
valueParameter.source,
|
||||||
functionVisibility,
|
FirErrors.EXPOSED_PARAMETER_TYPE,
|
||||||
restricting,
|
functionVisibility,
|
||||||
restrictingVisibility,
|
restricting,
|
||||||
context
|
restrictingVisibility,
|
||||||
)
|
context
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkMemberReceiver(declaration.receiverTypeRef, declaration as? FirCallableDeclaration, reporter, context)
|
checkMemberReceiver(declaration.receiverTypeRef, declaration as? FirCallableDeclaration, reporter, context)
|
||||||
|
|||||||
-12
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
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.declarations.impl.FirPrimaryConstructor
|
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.hasBody
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isInner
|
import org.jetbrains.kotlin.fir.declarations.utils.isInner
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||||
@@ -34,17 +33,6 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
|||||||
val source = declaration.source ?: return
|
val source = declaration.source ?: return
|
||||||
if (source.kind is FirFakeSourceElementKind) return
|
if (source.kind is FirFakeSourceElementKind) return
|
||||||
|
|
||||||
if (declaration is FirProperty) {
|
|
||||||
fun checkPropertyAccessor(propertyAccessor: FirPropertyAccessor?) {
|
|
||||||
if (propertyAccessor != null && !propertyAccessor.hasBody) {
|
|
||||||
check(propertyAccessor, context, reporter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkPropertyAccessor(declaration.getter)
|
|
||||||
checkPropertyAccessor(declaration.setter)
|
|
||||||
}
|
|
||||||
|
|
||||||
source.getModifierList()?.let { checkModifiers(it, declaration, context, reporter) }
|
source.getModifierList()?.let { checkModifiers(it, declaration, context, reporter) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.extended
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.KtNodeTypes
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
||||||
import org.jetbrains.kotlin.fir.FirFakeSourceElement
|
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
import org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirPropertyInitializationChecker
|
import org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirPropertyInitializationChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.cfa.util.PathAwarePropertyInitializationInfo
|
import org.jetbrains.kotlin.fir.analysis.cfa.util.PathAwarePropertyInitializationInfo
|
||||||
@@ -40,7 +40,7 @@ object CanBeValChecker : AbstractFirPropertyInitializationChecker() {
|
|||||||
|
|
||||||
for (property in unprocessedProperties) {
|
for (property in unprocessedProperties) {
|
||||||
val source = property.source
|
val source = property.source
|
||||||
if (source is FirFakeSourceElement) continue
|
if (source?.kind is FirFakeSourceElementKind) continue
|
||||||
if (source?.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION) continue
|
if (source?.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION) continue
|
||||||
propertiesCharacteristics[property] = EventOccurrencesRange.ZERO
|
propertiesCharacteristics[property] = EventOccurrencesRange.ZERO
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.checkers.extended
|
package org.jetbrains.kotlin.fir.analysis.checkers.extended
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirFakeSourceElement
|
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||||
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.expression.FirFunctionCallChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||||
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
|
|||||||
|
|
||||||
object EmptyRangeChecker : FirFunctionCallChecker() {
|
object EmptyRangeChecker : FirFunctionCallChecker() {
|
||||||
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
if (expression.source is FirFakeSourceElement) return
|
if (expression.source?.kind is FirFakeSourceElementKind) return
|
||||||
val left = expression.rangeLeft ?: return
|
val left = expression.rangeLeft ?: return
|
||||||
val right = expression.rangeRight ?: return
|
val right = expression.rangeRight ?: return
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -7,12 +7,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.extended
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.fir.FirFakeSourceElement
|
|
||||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
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.context.findClosest
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isLocalMember
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject
|
import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
|
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.overriddenFunctions
|
import org.jetbrains.kotlin.fir.analysis.checkers.overriddenFunctions
|
||||||
@@ -42,7 +40,7 @@ object RedundantVisibilityModifierSyntaxChecker : FirDeclarationSyntaxChecker<Fi
|
|||||||
reporter: DiagnosticReporter
|
reporter: DiagnosticReporter
|
||||||
) {
|
) {
|
||||||
if (element is FirConstructor && source.kind is FirFakeSourceElementKind) return
|
if (element is FirConstructor && source.kind is FirFakeSourceElementKind) return
|
||||||
if (source is FirFakeSourceElement) return
|
if (source.kind is FirFakeSourceElementKind) return
|
||||||
if (
|
if (
|
||||||
element !is FirMemberDeclaration
|
element !is FirMemberDeclaration
|
||||||
&& !(element is FirPropertyAccessor && element.visibility == context.containingPropertyVisibility)
|
&& !(element is FirPropertyAccessor && element.visibility == context.containingPropertyVisibility)
|
||||||
|
|||||||
+3
-5
@@ -127,11 +127,9 @@ abstract class AbstractDiagnosticCollectorVisitor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: Nothing?) {
|
override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: Nothing?) {
|
||||||
if (propertyAccessor !is FirDefaultPropertyAccessor) {
|
val property = context.containingDeclarations.last() as FirProperty
|
||||||
val property = context.containingDeclarations.last() as FirProperty
|
withAnnotationContainer(propertyAccessor) {
|
||||||
withAnnotationContainer(propertyAccessor) {
|
visitWithDeclarationAndReceiver(propertyAccessor, property.name, property.receiverTypeRef)
|
||||||
visitWithDeclarationAndReceiver(propertyAccessor, property.name, property.receiverTypeRef)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-2
@@ -1142,7 +1142,12 @@ class DeclarationsConverter(
|
|||||||
}
|
}
|
||||||
this.getter = convertedAccessors.find { it.isGetter }
|
this.getter = convertedAccessors.find { it.isGetter }
|
||||||
?: FirDefaultPropertyGetter(
|
?: FirDefaultPropertyGetter(
|
||||||
property.toFirSourceElement(FirFakeSourceElementKind.DefaultAccessor), moduleData, FirDeclarationOrigin.Source, returnType, propertyVisibility, symbol,
|
property.toFirSourceElement(FirFakeSourceElementKind.DefaultAccessor),
|
||||||
|
moduleData,
|
||||||
|
FirDeclarationOrigin.Source,
|
||||||
|
returnType.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor),
|
||||||
|
propertyVisibility,
|
||||||
|
symbol,
|
||||||
).also {
|
).also {
|
||||||
it.status = defaultAccessorStatus()
|
it.status = defaultAccessorStatus()
|
||||||
it.initContainingClassAttr()
|
it.initContainingClassAttr()
|
||||||
@@ -1154,7 +1159,7 @@ class DeclarationsConverter(
|
|||||||
property.toFirSourceElement(FirFakeSourceElementKind.DefaultAccessor),
|
property.toFirSourceElement(FirFakeSourceElementKind.DefaultAccessor),
|
||||||
moduleData,
|
moduleData,
|
||||||
FirDeclarationOrigin.Source,
|
FirDeclarationOrigin.Source,
|
||||||
returnType,
|
returnType.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor),
|
||||||
propertyVisibility, symbol,
|
propertyVisibility, symbol,
|
||||||
).also {
|
).also {
|
||||||
it.status = defaultAccessorStatus()
|
it.status = defaultAccessorStatus()
|
||||||
|
|||||||
@@ -314,6 +314,7 @@ class FirFakeSourceElement(psi: PsiElement, override val kind: FirFakeSourceElem
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun FirSourceElement.fakeElement(newKind: FirFakeSourceElementKind): FirSourceElement {
|
fun FirSourceElement.fakeElement(newKind: FirFakeSourceElementKind): FirSourceElement {
|
||||||
|
if (kind == newKind) return this
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is FirLightSourceElement -> FirLightSourceElement(lighterASTNode, startOffset, endOffset, treeStructure, newKind)
|
is FirLightSourceElement -> FirLightSourceElement(lighterASTNode, startOffset, endOffset, treeStructure, newKind)
|
||||||
is FirPsiSourceElement -> FirFakeSourceElement(psi, newKind)
|
is FirPsiSourceElement -> FirFakeSourceElement(psi, newKind)
|
||||||
|
|||||||
+2
-4
@@ -8,9 +8,7 @@ package org.jetbrains.kotlin.fir.declarations.impl
|
|||||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
|
||||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
|
||||||
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
|
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildDefaultSetterValueParameter
|
import org.jetbrains.kotlin.fir.declarations.builder.buildDefaultSetterValueParameter
|
||||||
@@ -126,7 +124,7 @@ class FirDefaultPropertySetter(
|
|||||||
FirImplicitUnitTypeRef(source),
|
FirImplicitUnitTypeRef(source),
|
||||||
valueParameters = mutableListOf(
|
valueParameters = mutableListOf(
|
||||||
buildDefaultSetterValueParameter builder@{
|
buildDefaultSetterValueParameter builder@{
|
||||||
this@builder.source = source
|
this@builder.source = source?.fakeElement(FirFakeSourceElementKind.DefaultAccessor)
|
||||||
this@builder.moduleData = moduleData
|
this@builder.moduleData = moduleData
|
||||||
this@builder.origin = origin
|
this@builder.origin = origin
|
||||||
this@builder.returnTypeRef = propertyTypeRef
|
this@builder.returnTypeRef = propertyTypeRef
|
||||||
|
|||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
@Target(AnnotationTarget.PROPERTY_GETTER)
|
|
||||||
annotation class smartget
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.PROPERTY_SETTER)
|
|
||||||
annotation class smartset
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.FUNCTION)
|
|
||||||
annotation class base
|
|
||||||
|
|
||||||
class My(x: Int) {
|
|
||||||
<!WRONG_ANNOTATION_TARGET!>@smartget<!> var y = x
|
|
||||||
@base @smartget @smartset get
|
|
||||||
@base @smartget @smartset set
|
|
||||||
|
|
||||||
@base <!WRONG_ANNOTATION_TARGET!>@smartget<!> <!WRONG_ANNOTATION_TARGET!>@smartset<!> fun foo() = y
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
@Target(AnnotationTarget.PROPERTY_GETTER)
|
@Target(AnnotationTarget.PROPERTY_GETTER)
|
||||||
annotation class smartget
|
annotation class smartget
|
||||||
|
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
// FILE: test/AnnotationTargets.java
|
|
||||||
|
|
||||||
package test;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
public class AnnotationTargets {
|
|
||||||
|
|
||||||
public @interface base {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Target(ElementType.ANNOTATION_TYPE)
|
|
||||||
public @interface meta {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Target(ElementType.CONSTRUCTOR)
|
|
||||||
public @interface konstructor {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Target(ElementType.FIELD)
|
|
||||||
public @interface fieldann {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Target(ElementType.LOCAL_VARIABLE)
|
|
||||||
public @interface local {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
public @interface method {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Target(ElementType.PARAMETER)
|
|
||||||
public @interface parameter {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
public @interface type {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
|
|
||||||
public @interface multiple {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: test/AnnotationTargets.kt
|
|
||||||
|
|
||||||
@file:AnnotationTargets.type
|
|
||||||
package test
|
|
||||||
|
|
||||||
import test.AnnotationTargets.*
|
|
||||||
|
|
||||||
@base @meta @type <!WRONG_ANNOTATION_TARGET!>@konstructor<!> annotation class KMeta
|
|
||||||
|
|
||||||
@base <!WRONG_ANNOTATION_TARGET!>@meta<!> @type <!WRONG_ANNOTATION_TARGET!>@method<!> <!WRONG_ANNOTATION_TARGET!>@multiple<!> class KClass(
|
|
||||||
@base @fieldann @parameter val y:
|
|
||||||
<!WRONG_ANNOTATION_TARGET!>@base<!> <!WRONG_ANNOTATION_TARGET!>@type<!> Int) {
|
|
||||||
|
|
||||||
@base @multiple @fieldann <!WRONG_ANNOTATION_TARGET!>@local<!> val x = 0
|
|
||||||
@method @konstructor @type get
|
|
||||||
|
|
||||||
@base @method @multiple <!WRONG_ANNOTATION_TARGET!>@konstructor<!>
|
|
||||||
fun foo(@parameter <!WRONG_ANNOTATION_TARGET!>@type<!> i:
|
|
||||||
<!WRONG_ANNOTATION_TARGET!>@base<!> <!WRONG_ANNOTATION_TARGET!>@multiple<!> Int
|
|
||||||
): <!WRONG_ANNOTATION_TARGET!>@fieldann<!> <!WRONG_ANNOTATION_TARGET!>@parameter<!> Int {
|
|
||||||
|
|
||||||
@local @base <!WRONG_ANNOTATION_TARGET!>@multiple<!> <!WRONG_ANNOTATION_TARGET!>@fieldann<!> val j = i + 1
|
|
||||||
<!WRONG_ANNOTATION_TARGET!>@base<!> <!WRONG_ANNOTATION_TARGET!>@multiple<!> return j
|
|
||||||
}
|
|
||||||
|
|
||||||
@base <!WRONG_ANNOTATION_TARGET!>@method<!> @konstructor constructor(): this(0)
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// FILE: test/AnnotationTargets.java
|
// FILE: test/AnnotationTargets.java
|
||||||
|
|
||||||
package test;
|
package test;
|
||||||
|
|||||||
Reference in New Issue
Block a user