-6
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.*
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -87,11 +86,6 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by warning<KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE) {
|
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by warning<KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE) {
|
||||||
parameter<KtKeywordToken>("valOrVar")
|
parameter<KtKeywordToken>("valOrVar")
|
||||||
}
|
}
|
||||||
val INVISIBLE_SETTER by error<PsiElement>(PositioningStrategy.ASSIGNMENT_LHS) {
|
|
||||||
parameter<FirPropertySymbol>("property")
|
|
||||||
parameter<Visibility>("visibility")
|
|
||||||
parameter<CallableId>("callableId")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val UNRESOLVED by object : DiagnosticGroup("Unresolved") {
|
val UNRESOLVED by object : DiagnosticGroup("Unresolved") {
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
@@ -118,7 +117,6 @@ object FirErrors {
|
|||||||
val VAL_OR_VAR_ON_FUN_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
val VAL_OR_VAR_ON_FUN_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||||
val VAL_OR_VAR_ON_CATCH_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
val VAL_OR_VAR_ON_CATCH_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||||
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||||
val INVISIBLE_SETTER by error3<PsiElement, FirPropertySymbol, Visibility, CallableId>(SourceElementPositioningStrategies.ASSIGNMENT_LHS)
|
|
||||||
|
|
||||||
// Unresolved
|
// Unresolved
|
||||||
val INVISIBLE_REFERENCE by error1<PsiElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val INVISIBLE_REFERENCE by error1<PsiElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
|||||||
|
|
||||||
override val variableAssignmentCheckers: Set<FirVariableAssignmentChecker>
|
override val variableAssignmentCheckers: Set<FirVariableAssignmentChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirReassignmentAndInvisibleSetterChecker,
|
FirValReassignmentChecker,
|
||||||
FirAssignmentTypeMismatchChecker
|
FirAssignmentTypeMismatchChecker
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
-125
@@ -1,125 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
|
||||||
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.toRegularClassSymbol
|
|
||||||
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.declarations.FirPropertyAccessor
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.fir.references.FirBackingFieldReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ExpressionReceiverValue
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.visibilityChecker
|
|
||||||
|
|
||||||
object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker() {
|
|
||||||
override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) {
|
|
||||||
checkInvisibleSetter(expression, context, reporter)
|
|
||||||
checkValReassignmentViaBackingField(expression, context, reporter)
|
|
||||||
checkValReassignmentOnValueParameter(expression, context, reporter)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkInvisibleSetter(
|
|
||||||
expression: FirVariableAssignment,
|
|
||||||
context: CheckerContext,
|
|
||||||
reporter: DiagnosticReporter
|
|
||||||
) {
|
|
||||||
fun shouldInvisibleSetterBeReported(symbol: FirPropertySymbol): Boolean {
|
|
||||||
val setterSymbol = symbol.setterSymbol
|
|
||||||
|
|
||||||
@OptIn(SymbolInternals::class)
|
|
||||||
val setterFir = setterSymbol?.fir
|
|
||||||
if (setterFir != null) {
|
|
||||||
val isVisible = context.session.visibilityChecker.isVisible(
|
|
||||||
setterFir,
|
|
||||||
context.session,
|
|
||||||
context.findClosest()!!,
|
|
||||||
context.containingDeclarations,
|
|
||||||
ExpressionReceiverValue(expression.dispatchReceiver),
|
|
||||||
)
|
|
||||||
if (!isVisible) {
|
|
||||||
// Report SUBCLASS_CANT_CALL_COMPANION_PROTECTED_NON_STATIC in another checker
|
|
||||||
val dispatchReceiverTypeSymbol = symbol.dispatchReceiverType?.toSymbol(context.session)
|
|
||||||
return setterFir.visibility != Visibilities.Protected ||
|
|
||||||
dispatchReceiverTypeSymbol !is FirRegularClassSymbol ||
|
|
||||||
!dispatchReceiverTypeSymbol.isCompanion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val callableSymbol = expression.calleeReference.toResolvedCallableSymbol()
|
|
||||||
if (callableSymbol is FirPropertySymbol && shouldInvisibleSetterBeReported(callableSymbol)) {
|
|
||||||
val explicitReceiver = expression.explicitReceiver
|
|
||||||
// Try to get type from smartcast
|
|
||||||
if (explicitReceiver is FirExpressionWithSmartcast) {
|
|
||||||
val symbol = explicitReceiver.originalType.toRegularClassSymbol(context.session)
|
|
||||||
if (symbol != null) {
|
|
||||||
for (declarationSymbol in symbol.declarationSymbols) {
|
|
||||||
if (declarationSymbol is FirPropertySymbol && declarationSymbol.name == callableSymbol.name) {
|
|
||||||
if (!shouldInvisibleSetterBeReported(declarationSymbol)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reporter.reportOn(
|
|
||||||
expression.source,
|
|
||||||
FirErrors.INVISIBLE_SETTER,
|
|
||||||
callableSymbol,
|
|
||||||
callableSymbol.setterSymbol!!.visibility,
|
|
||||||
callableSymbol.callableId,
|
|
||||||
context
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkValReassignmentViaBackingField(
|
|
||||||
expression: FirVariableAssignment,
|
|
||||||
context: CheckerContext,
|
|
||||||
reporter: DiagnosticReporter
|
|
||||||
) {
|
|
||||||
val backingFieldReference = expression.lValue as? FirBackingFieldReference ?: return
|
|
||||||
val propertySymbol = backingFieldReference.resolvedSymbol
|
|
||||||
if (propertySymbol.isVar) return
|
|
||||||
val closestGetter = context.findClosest<FirPropertyAccessor> { it.isGetter }?.symbol ?: return
|
|
||||||
if (propertySymbol.getterSymbol != closestGetter) return
|
|
||||||
|
|
||||||
backingFieldReference.source?.let {
|
|
||||||
if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.RestrictionOfValReassignmentViaBackingField)) {
|
|
||||||
reporter.reportOn(it, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR, propertySymbol, context)
|
|
||||||
} else {
|
|
||||||
reporter.reportOn(it, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD, propertySymbol, context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkValReassignmentOnValueParameter(
|
|
||||||
expression: FirVariableAssignment,
|
|
||||||
context: CheckerContext,
|
|
||||||
reporter: DiagnosticReporter
|
|
||||||
) {
|
|
||||||
val valueParameter = (expression.lValue as? FirResolvedNamedReference)?.resolvedSymbol as? FirValueParameterSymbol ?: return
|
|
||||||
reporter.reportOn(expression.lValue.source, FirErrors.VAL_REASSIGNMENT, valueParameter, context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+55
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
|
||||||
|
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.declarations.FirPropertyAccessor
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||||
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirBackingFieldReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
||||||
|
|
||||||
|
object FirValReassignmentChecker : FirVariableAssignmentChecker() {
|
||||||
|
override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
checkValReassignmentViaBackingField(expression, context, reporter)
|
||||||
|
checkValReassignmentOnValueParameter(expression, context, reporter)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkValReassignmentViaBackingField(
|
||||||
|
expression: FirVariableAssignment,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter
|
||||||
|
) {
|
||||||
|
val backingFieldReference = expression.lValue as? FirBackingFieldReference ?: return
|
||||||
|
val propertySymbol = backingFieldReference.resolvedSymbol
|
||||||
|
if (propertySymbol.isVar) return
|
||||||
|
val closestGetter = context.findClosest<FirPropertyAccessor> { it.isGetter }?.symbol ?: return
|
||||||
|
if (propertySymbol.getterSymbol != closestGetter) return
|
||||||
|
|
||||||
|
backingFieldReference.source?.let {
|
||||||
|
if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.RestrictionOfValReassignmentViaBackingField)) {
|
||||||
|
reporter.reportOn(it, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR, propertySymbol, context)
|
||||||
|
} else {
|
||||||
|
reporter.reportOn(it, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD, propertySymbol, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkValReassignmentOnValueParameter(
|
||||||
|
expression: FirVariableAssignment,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter
|
||||||
|
) {
|
||||||
|
val valueParameter = (expression.lValue as? FirResolvedNamedReference)?.resolvedSymbol as? FirValueParameterSymbol ?: return
|
||||||
|
reporter.reportOn(expression.lValue.source, FirErrors.VAL_REASSIGNMENT, valueParameter, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
-3
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FQ_N
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.COLLECTION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.COLLECTION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.MODULE_DATA
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.MODULE_DATA
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FUNCTION_PARAMETERS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FUNCTION_PARAMETERS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NAME_OF_CONTAINING_DECLARATION_OR_FILE
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NOT_RENDERED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NOT_RENDERED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT
|
||||||
@@ -233,7 +232,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_CHARACTER
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_IF_AS_EXPRESSION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_IF_AS_EXPRESSION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVISIBLE_REFERENCE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVISIBLE_REFERENCE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVISIBLE_SETTER
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.IS_ENUM_ENTRY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.IS_ENUM_ENTRY
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ITERATOR_AMBIGUITY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ITERATOR_AMBIGUITY
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE
|
||||||
@@ -494,7 +492,6 @@ class FirDefaultErrorMessages {
|
|||||||
|
|
||||||
// Unresolved
|
// Unresolved
|
||||||
map.put(INVISIBLE_REFERENCE, "Symbol {0} is invisible", SYMBOL)
|
map.put(INVISIBLE_REFERENCE, "Symbol {0} is invisible", SYMBOL)
|
||||||
map.put(INVISIBLE_SETTER, "Cannot access ''{0}'': it is {1} in {2}", VARIABLE_NAME, VISIBILITY, NAME_OF_CONTAINING_DECLARATION_OR_FILE)
|
|
||||||
map.put(UNRESOLVED_REFERENCE, "Unresolved reference: {0}", NULLABLE_STRING)
|
map.put(UNRESOLVED_REFERENCE, "Unresolved reference: {0}", NULLABLE_STRING)
|
||||||
map.put(UNRESOLVED_LABEL, "Unresolved label")
|
map.put(UNRESOLVED_LABEL, "Unresolved label")
|
||||||
map.put(DESERIALIZATION_ERROR, "Deserialization error")
|
map.put(DESERIALIZATION_ERROR, "Deserialization error")
|
||||||
|
|||||||
+3
-10
@@ -13,14 +13,16 @@ import org.jetbrains.kotlin.diagnostics.rendering.Renderer
|
|||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
import org.jetbrains.kotlin.fir.FirRenderer
|
import org.jetbrains.kotlin.fir.FirRenderer
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.render
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
|
||||||
|
|
||||||
object FirDiagnosticRenderers {
|
object FirDiagnosticRenderers {
|
||||||
val NULLABLE_STRING = Renderer<String?> { it ?: "null" }
|
val NULLABLE_STRING = Renderer<String?> { it ?: "null" }
|
||||||
@@ -134,15 +136,6 @@ object FirDiagnosticRenderers {
|
|||||||
"Module ${it.name}"
|
"Module ${it.name}"
|
||||||
}
|
}
|
||||||
|
|
||||||
val NAME_OF_CONTAINING_DECLARATION_OR_FILE = Renderer { symbol: CallableId ->
|
|
||||||
val classId = symbol.classId
|
|
||||||
if (classId == null) {
|
|
||||||
"file"
|
|
||||||
} else {
|
|
||||||
"'${classId}'"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("FunctionName")
|
@Suppress("FunctionName")
|
||||||
fun <T> COLLECTION(renderer: ContextIndependentParameterRenderer<T>): ContextIndependentParameterRenderer<Collection<T>> {
|
fun <T> COLLECTION(renderer: ContextIndependentParameterRenderer<T>): ContextIndependentParameterRenderer<Collection<T>> {
|
||||||
return Renderer { list ->
|
return Renderer { list ->
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.descriptors.java.JavaVisibilities
|
|||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue
|
import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
|
|
||||||
@@ -30,13 +29,7 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() {
|
|||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
val ownerId = symbol.getOwnerId()
|
val ownerId = symbol.getOwnerId()
|
||||||
ownerId != null && canSeeProtectedMemberOf(
|
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, dispatchReceiver, ownerId, session)
|
||||||
containingDeclarations,
|
|
||||||
dispatchReceiver,
|
|
||||||
ownerId,
|
|
||||||
symbol.fir is FirSyntheticPropertyAccessor,
|
|
||||||
session
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,23 +5,22 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir
|
package org.jetbrains.kotlin.fir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
|
||||||
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.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
|
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirExplicitSuperReference
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol
|
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue
|
import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
@@ -117,13 +116,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
|
|
||||||
Visibilities.Protected -> {
|
Visibilities.Protected -> {
|
||||||
val ownerId = symbol.getOwnerId()
|
val ownerId = symbol.getOwnerId()
|
||||||
ownerId != null && canSeeProtectedMemberOf(
|
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, dispatchReceiver, ownerId, session)
|
||||||
containingDeclarations,
|
|
||||||
dispatchReceiver,
|
|
||||||
ownerId,
|
|
||||||
symbol.fir is FirSyntheticPropertyAccessor,
|
|
||||||
session
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> platformVisibilityCheck(
|
else -> platformVisibilityCheck(
|
||||||
@@ -178,43 +171,22 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun canSeeProtectedMemberOf(
|
private fun canSeeProtectedMemberOf(
|
||||||
containingUseSiteClassSymbol: FirClassSymbol<*>,
|
containingUseSiteClass: FirClass,
|
||||||
dispatchReceiver: ReceiverValue?,
|
dispatchReceiver: ReceiverValue?,
|
||||||
ownerId: ClassId,
|
ownerId: ClassId, session: FirSession
|
||||||
isSyntheticProperty: Boolean,
|
|
||||||
session: FirSession
|
|
||||||
): Boolean {
|
): Boolean {
|
||||||
dispatchReceiver?.ownerIfCompanion(session)?.let { companionOwnerClassId ->
|
dispatchReceiver?.ownerIfCompanion(session)?.let { companionOwnerClassId ->
|
||||||
if (containingUseSiteClassSymbol.isSubClass(companionOwnerClassId, session)) return true
|
if (containingUseSiteClass.isSubClass(companionOwnerClassId, session)) return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (containingUseSiteClassSymbol.isSubClass(ownerId, session)) {
|
// TODO: Add check for receiver, see org.jetbrains.kotlin.descriptors.Visibility#doesReceiverFitForProtectedVisibility
|
||||||
val receiverExpression = dispatchReceiver?.receiverExpression
|
return containingUseSiteClass.isSubClass(ownerId, session)
|
||||||
if (receiverExpression == null ||
|
|
||||||
receiverExpression is FirThisReceiverExpression ||
|
|
||||||
(receiverExpression is FirQualifiedAccessExpression && receiverExpression.calleeReference is FirExplicitSuperReference) ||
|
|
||||||
dispatchReceiver.type.toSymbol(session).isSubClass(containingUseSiteClassSymbol.classId, session)
|
|
||||||
) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSyntheticProperty) {
|
|
||||||
return if (session.languageVersionSettings.supportsFeature(LanguageFeature.ImproveReportingDiagnosticsOnProtectedMembersOfBaseClass))
|
|
||||||
containingUseSiteClassSymbol.classId.packageFqName == ownerId.packageFqName
|
|
||||||
else
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirBasedSymbol<*>?.isSubClass(ownerId: ClassId, session: FirSession): Boolean {
|
private fun FirClass.isSubClass(ownerId: ClassId, session: FirSession): Boolean {
|
||||||
val classSymbol = this as? FirClassSymbol<*> ?: return false
|
|
||||||
val classId = classSymbol.classId
|
|
||||||
if (classId.isSame(ownerId)) return true
|
if (classId.isSame(ownerId)) return true
|
||||||
|
|
||||||
return lookupSuperTypes(classSymbol, lookupInterfaces = true, deep = true, session).any { superType ->
|
return lookupSuperTypes(this, lookupInterfaces = true, deep = true, session).any { superType ->
|
||||||
(superType as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag?.classId?.isSame(ownerId) == true
|
(superType as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag?.classId?.isSame(ownerId) == true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,16 +207,14 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
protected fun canSeeProtectedMemberOf(
|
protected fun canSeeProtectedMemberOf(
|
||||||
containingDeclarationOfUseSite: List<FirDeclaration>,
|
containingDeclarationOfUseSite: List<FirDeclaration>,
|
||||||
dispatchReceiver: ReceiverValue?,
|
dispatchReceiver: ReceiverValue?,
|
||||||
ownerId: ClassId,
|
ownerId: ClassId, session: FirSession
|
||||||
isSyntheticProperty: Boolean,
|
|
||||||
session: FirSession
|
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (canSeePrivateMemberOf(containingDeclarationOfUseSite, ownerId, session)) return true
|
if (canSeePrivateMemberOf(containingDeclarationOfUseSite, ownerId, session)) return true
|
||||||
|
|
||||||
for (containingDeclaration in containingDeclarationOfUseSite) {
|
for (containingDeclaration in containingDeclarationOfUseSite) {
|
||||||
if (containingDeclaration !is FirClass) continue
|
if (containingDeclaration !is FirClass) continue
|
||||||
val boundSymbol = containingDeclaration.symbol
|
val boundSymbol = containingDeclaration.symbol
|
||||||
if (canSeeProtectedMemberOf(boundSymbol.fir.symbol, dispatchReceiver, ownerId, isSyntheticProperty, session)) return true
|
if (canSeeProtectedMemberOf(boundSymbol.fir, dispatchReceiver, ownerId, session)) return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -49,20 +49,9 @@ fun lookupSuperTypes(
|
|||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
supertypeSupplier: SupertypeSupplier = SupertypeSupplier.Default,
|
supertypeSupplier: SupertypeSupplier = SupertypeSupplier.Default,
|
||||||
substituteTypes: Boolean = false
|
substituteTypes: Boolean = false
|
||||||
): List<ConeClassLikeType> {
|
|
||||||
return lookupSuperTypes(klass.symbol, lookupInterfaces, deep, useSiteSession, supertypeSupplier, substituteTypes)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun lookupSuperTypes(
|
|
||||||
classSymbol: FirClassSymbol<*>,
|
|
||||||
lookupInterfaces: Boolean,
|
|
||||||
deep: Boolean,
|
|
||||||
useSiteSession: FirSession,
|
|
||||||
supertypeSupplier: SupertypeSupplier = SupertypeSupplier.Default,
|
|
||||||
substituteTypes: Boolean = false
|
|
||||||
): List<ConeClassLikeType> {
|
): List<ConeClassLikeType> {
|
||||||
return SmartList<ConeClassLikeType>().also {
|
return SmartList<ConeClassLikeType>().also {
|
||||||
classSymbol.collectSuperTypes(it, SmartSet.create(), deep, lookupInterfaces, substituteTypes, useSiteSession, supertypeSupplier)
|
klass.symbol.collectSuperTypes(it, SmartSet.create(), deep, lookupInterfaces, substituteTypes, useSiteSession, supertypeSupplier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-2
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.fir.references.builder
|
package org.jetbrains.kotlin.fir.references.builder
|
||||||
|
|
||||||
import kotlin.contracts.*
|
import kotlin.contracts.*
|
||||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
|
||||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||||
@@ -25,7 +24,6 @@ class FirExplicitSuperReferenceBuilder {
|
|||||||
var labelName: String? = null
|
var labelName: String? = null
|
||||||
lateinit var superTypeRef: FirTypeRef
|
lateinit var superTypeRef: FirTypeRef
|
||||||
|
|
||||||
@OptIn(FirImplementationDetail::class)
|
|
||||||
fun build(): FirSuperReference {
|
fun build(): FirSuperReference {
|
||||||
return FirExplicitSuperReference(
|
return FirExplicitSuperReference(
|
||||||
source,
|
source,
|
||||||
|
|||||||
+1
-2
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.references.impl
|
package org.jetbrains.kotlin.fir.references.impl
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
|
||||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
@@ -16,7 +15,7 @@ import org.jetbrains.kotlin.fir.visitors.*
|
|||||||
* DO NOT MODIFY IT MANUALLY
|
* DO NOT MODIFY IT MANUALLY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class FirExplicitSuperReference @FirImplementationDetail constructor(
|
internal class FirExplicitSuperReference(
|
||||||
override val source: FirSourceElement?,
|
override val source: FirSourceElement?,
|
||||||
override val labelName: String?,
|
override val labelName: String?,
|
||||||
override var superTypeRef: FirTypeRef,
|
override var superTypeRef: FirTypeRef,
|
||||||
|
|||||||
+1
-3
@@ -401,9 +401,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl(superReference, "FirExplicitSuperReference") {
|
impl(superReference, "FirExplicitSuperReference")
|
||||||
publicImplementation()
|
|
||||||
}
|
|
||||||
|
|
||||||
noImpl(controlFlowGraphReference)
|
noImpl(controlFlowGraphReference)
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class Test: ATest(), ITest {
|
|||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
val test = Test()
|
val test = Test()
|
||||||
<!INVISIBLE_SETTER!>test.prop<!> = 12
|
test.prop = 12
|
||||||
|
|
||||||
val itest: ITest = test
|
val itest: ITest = test
|
||||||
itest.prop = 12 // No error here
|
itest.prop = 12 // No error here
|
||||||
|
|||||||
@@ -23,23 +23,23 @@ class P {
|
|||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val p = P()
|
val p = P()
|
||||||
<!INVISIBLE_SETTER!>p.x<!> = 34 //should be an error here
|
p.x = 34 //should be an error here
|
||||||
p.y = 23
|
p.y = 23
|
||||||
|
|
||||||
fun inner() {
|
fun inner() {
|
||||||
<!INVISIBLE_SETTER!>p.x<!> = 44
|
p.x = 44
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class R {
|
class R {
|
||||||
val p = P();
|
val p = P();
|
||||||
init {
|
init {
|
||||||
<!INVISIBLE_SETTER!>p.x<!> = 42
|
p.x = 42
|
||||||
}
|
}
|
||||||
|
|
||||||
val testInGetterInOtherClass : Int
|
val testInGetterInOtherClass : Int
|
||||||
get() {
|
get() {
|
||||||
<!INVISIBLE_SETTER!>p.x<!> = 33
|
p.x = 33
|
||||||
return 3
|
return 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,4 +50,4 @@ fun test() {
|
|||||||
<!UNRESOLVED_REFERENCE!>p<!>.x = 43
|
<!UNRESOLVED_REFERENCE!>p<!>.x = 43
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
//KT-2960 Perform control flow checks for package property initializers
|
||||||
|
|
||||||
|
package b
|
||||||
|
|
||||||
|
class P {
|
||||||
|
var x : Int = 0
|
||||||
|
private set
|
||||||
|
}
|
||||||
|
|
||||||
|
val p = P()
|
||||||
|
var f = { -> p.x = 32 }
|
||||||
|
|
||||||
|
val o = object {
|
||||||
|
fun run() {
|
||||||
|
p.x = 4
|
||||||
|
|
||||||
|
val z : Int
|
||||||
|
doSmth(<!UNINITIALIZED_VARIABLE!>z<!>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val g = { ->
|
||||||
|
val x: Int
|
||||||
|
doSmth(<!UNINITIALIZED_VARIABLE!>x<!>)
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val a : Int = 1
|
||||||
|
get() {
|
||||||
|
val x : Int
|
||||||
|
doSmth(<!UNINITIALIZED_VARIABLE!>x<!>)
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doSmth(i: Int) = i
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
// FIR_IDENTICAL
|
|
||||||
//KT-2960 Perform control flow checks for package property initializers
|
//KT-2960 Perform control flow checks for package property initializers
|
||||||
|
|
||||||
package b
|
package b
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
open class X(s : String) {
|
||||||
|
public var n: String = s
|
||||||
|
private set
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Z : X("subclass") {
|
||||||
|
fun print(): String {
|
||||||
|
n = n
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
return Z().print() //error
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
// FIR_IDENTICAL
|
|
||||||
open class X(s : String) {
|
open class X(s : String) {
|
||||||
public var n: String = s
|
public var n: String = s
|
||||||
private set
|
private set
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ fun test() {
|
|||||||
val po = <!INVISIBLE_REFERENCE!>PO<!>
|
val po = <!INVISIBLE_REFERENCE!>PO<!>
|
||||||
|
|
||||||
val v = xx
|
val v = xx
|
||||||
<!INVISIBLE_SETTER("xx; private; file")!>xx<!> = 40
|
xx = 40
|
||||||
}
|
}
|
||||||
|
|
||||||
class B : <!EXPOSED_SUPER_CLASS, INVISIBLE_REFERENCE!>A<!>() {}
|
class B : <!EXPOSED_SUPER_CLASS, INVISIBLE_REFERENCE!>A<!>() {}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class A<T> {
|
||||||
|
public var x: Int = 0
|
||||||
|
private set
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
val a = A<Any>()
|
||||||
|
a.x = 1
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
// FIR_IDENTICAL
|
|
||||||
class A<T> {
|
class A<T> {
|
||||||
public var x: Int = 0
|
public var x: Int = 0
|
||||||
private set
|
private set
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ class B: A()
|
|||||||
|
|
||||||
class C: A() {
|
class C: A() {
|
||||||
fun bar() {
|
fun bar() {
|
||||||
A().<!INVISIBLE_REFERENCE!>foo<!>()
|
A().foo()
|
||||||
B().<!INVISIBLE_REFERENCE!>foo<!>()
|
B().foo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -13,6 +13,6 @@ class B {
|
|||||||
|
|
||||||
class C: A() {
|
class C: A() {
|
||||||
init {
|
init {
|
||||||
B.<!INVISIBLE_REFERENCE!>foo<!>() // Error: receiver is not suitable
|
B.foo() // Error: receiver is not suitable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+7
-5
@@ -21,8 +21,9 @@ class B : A() {
|
|||||||
b.foo
|
b.foo
|
||||||
b.bar = b.bar + ""
|
b.bar = b.bar + ""
|
||||||
|
|
||||||
a.<!INVISIBLE_REFERENCE!>foo<!>
|
a.foo
|
||||||
<!INVISIBLE_SETTER!>a.bar<!> = a.bar + ""
|
// TODO: should be INVISIBLE_SETTER
|
||||||
|
a.bar = a.bar + ""
|
||||||
|
|
||||||
if (a is B) {
|
if (a is B) {
|
||||||
a.foo
|
a.foo
|
||||||
@@ -31,13 +32,14 @@ class B : A() {
|
|||||||
|
|
||||||
if (d.x is B) {
|
if (d.x is B) {
|
||||||
d.x.abc // Ok
|
d.x.abc // Ok
|
||||||
d.x.<!INVISIBLE_REFERENCE!>foo<!>
|
d.x.foo
|
||||||
<!INVISIBLE_SETTER!>d.x.bar<!> = d.x.bar + ""
|
// TODO: should be INVISIBLE_SETTER
|
||||||
|
d.x.bar = d.x.bar + ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun baz(a: A) {
|
fun baz(a: A) {
|
||||||
a.<!INVISIBLE_REFERENCE!>foo<!>
|
a.<!INVISIBLE_REFERENCE!>foo<!>
|
||||||
<!INVISIBLE_SETTER!>a.bar<!> = a.bar + ""
|
a.bar = a.bar + ""
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
@@ -22,6 +22,7 @@ class B : A() {
|
|||||||
b.bar = b.bar + ""
|
b.bar = b.bar + ""
|
||||||
|
|
||||||
a.<!INVISIBLE_MEMBER!>foo<!>
|
a.<!INVISIBLE_MEMBER!>foo<!>
|
||||||
|
// TODO: should be INVISIBLE_SETTER
|
||||||
a.<!INVISIBLE_SETTER!>bar<!> = a.bar + ""
|
a.<!INVISIBLE_SETTER!>bar<!> = a.bar + ""
|
||||||
|
|
||||||
if (a is B) {
|
if (a is B) {
|
||||||
@@ -32,6 +33,7 @@ class B : A() {
|
|||||||
if (d.x is B) {
|
if (d.x is B) {
|
||||||
d.x.abc // Ok
|
d.x.abc // Ok
|
||||||
d.x.<!INVISIBLE_MEMBER!>foo<!>
|
d.x.<!INVISIBLE_MEMBER!>foo<!>
|
||||||
|
// TODO: should be INVISIBLE_SETTER
|
||||||
d.x.<!INVISIBLE_SETTER!>bar<!> = d.x.bar + ""
|
d.x.<!INVISIBLE_SETTER!>bar<!> = d.x.bar + ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -11,7 +11,7 @@ class Data(var x: A)
|
|||||||
|
|
||||||
class B : A() {
|
class B : A() {
|
||||||
fun baz(a: A, b: B, d: Data) {
|
fun baz(a: A, b: B, d: Data) {
|
||||||
a.<!INVISIBLE_REFERENCE!>foo<!> { }
|
a.foo { }
|
||||||
|
|
||||||
b.foo { }
|
b.foo { }
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ class B : A() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (d.x is B) {
|
if (d.x is B) {
|
||||||
d.x.<!INVISIBLE_REFERENCE!>foo<!> {}
|
d.x.foo {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -11,8 +11,8 @@ fun BaseOuter.foo(): String = ""
|
|||||||
class Derived : BaseOuter() {
|
class Derived : BaseOuter() {
|
||||||
fun test(foo: Foo) {
|
fun test(foo: Foo) {
|
||||||
if (foo.base is Derived) {
|
if (foo.base is Derived) {
|
||||||
foo.base.foo() checkType { _<String>() } // Resolved to extension
|
foo.base.foo() checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String>() } // Resolved to extension
|
||||||
foo.base.<!INVISIBLE_REFERENCE!>bar<!>()
|
foo.base.bar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -11,11 +11,11 @@ class Derived : Base() {
|
|||||||
override fun bar() { }
|
override fun bar() { }
|
||||||
|
|
||||||
protected fun baz(x: Base) {
|
protected fun baz(x: Base) {
|
||||||
x.<!INVISIBLE_REFERENCE!>foo<!>()
|
x.foo()
|
||||||
x.<!INVISIBLE_REFERENCE!>bar<!>()
|
x.bar()
|
||||||
|
|
||||||
x.<!INVISIBLE_REFERENCE!>x<!> = x.<!INVISIBLE_REFERENCE!>x<!> + 1
|
x.x = x.x + 1
|
||||||
<!INVISIBLE_SETTER!>x.y<!> = x.y + 1
|
x.y = x.y + 1
|
||||||
|
|
||||||
if (x is Derived) {
|
if (x is Derived) {
|
||||||
x.foo()
|
x.foo()
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class E : C() {
|
|||||||
|
|
||||||
class F : C() {
|
class F : C() {
|
||||||
fun test8(c: C) {
|
fun test8(c: C) {
|
||||||
doSmth(c.<!INVISIBLE_REFERENCE!>i<!>)
|
doSmth(c.i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ fun foo(javaClass: JavaClass) {
|
|||||||
javaClass.<!INVISIBLE_REFERENCE!>somethingProtected<!>
|
javaClass.<!INVISIBLE_REFERENCE!>somethingProtected<!>
|
||||||
javaClass.<!INVISIBLE_REFERENCE!>somethingPrivate<!>
|
javaClass.<!INVISIBLE_REFERENCE!>somethingPrivate<!>
|
||||||
javaClass.<!INVISIBLE_REFERENCE!>somethingPackage<!>
|
javaClass.<!INVISIBLE_REFERENCE!>somethingPackage<!>
|
||||||
<!INVISIBLE_SETTER!>javaClass.somethingPublic<!> = 1
|
javaClass.somethingPublic = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// FILE: JavaClass.java
|
// FILE: JavaClass.java
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ fun foo(javaClass: JavaClass) {
|
|||||||
class X : JavaClass() {
|
class X : JavaClass() {
|
||||||
fun foo(other: JavaClass) {
|
fun foo(other: JavaClass) {
|
||||||
doSomething { bar() }
|
doSomething { bar() }
|
||||||
other.<!INVISIBLE_REFERENCE!>doSomething<!> { bar() }
|
other.doSomething { bar() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -18,12 +18,12 @@ class Data(var x: Foo)
|
|||||||
|
|
||||||
class B : Foo() {
|
class B : Foo() {
|
||||||
fun baz(a: Foo, t: Foo, d: Data) {
|
fun baz(a: Foo, t: Foo, d: Data) {
|
||||||
<!INVISIBLE_SETTER!>a.bar<!> = t.bar
|
a.bar = t.bar
|
||||||
<!INVISIBLE_SETTER!>a.foo<!> = t.foo
|
a.foo = t.foo
|
||||||
|
|
||||||
if (d.x is B) {
|
if (d.x is B) {
|
||||||
<!INVISIBLE_SETTER!>d.x.bar<!> = d.x.bar + ""
|
d.x.bar = d.x.bar + ""
|
||||||
<!INVISIBLE_SETTER!>d.x.foo<!> = d.x.foo + ""
|
d.x.foo = d.x.foo + ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -19,11 +19,11 @@ class Data(var x: Foo)
|
|||||||
class B : Foo() {
|
class B : Foo() {
|
||||||
fun baz(a: Foo, t: Foo, d: Data) {
|
fun baz(a: Foo, t: Foo, d: Data) {
|
||||||
a.bar = t.bar
|
a.bar = t.bar
|
||||||
<!INVISIBLE_SETTER!>a.foo<!> = t.foo
|
a.foo = t.foo
|
||||||
|
|
||||||
if (d.x is B) {
|
if (d.x is B) {
|
||||||
d.x.bar = d.x.bar + ""
|
d.x.bar = d.x.bar + ""
|
||||||
<!INVISIBLE_SETTER!>d.x.foo<!> = d.x.foo + ""
|
d.x.foo = d.x.foo + ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -13,11 +13,11 @@ class Data(var x: Foo)
|
|||||||
class B : Foo() {
|
class B : Foo() {
|
||||||
fun baz(a: Foo, t: Foo, d: Data) {
|
fun baz(a: Foo, t: Foo, d: Data) {
|
||||||
a.bar = t.bar
|
a.bar = t.bar
|
||||||
<!INVISIBLE_SETTER!>a.foo<!> = t.foo
|
a.foo = t.foo
|
||||||
|
|
||||||
if (d.x is B) {
|
if (d.x is B) {
|
||||||
d.x.bar = d.x.bar + ""
|
d.x.bar = d.x.bar + ""
|
||||||
<!INVISIBLE_SETTER!>d.x.foo<!> = d.x.foo + ""
|
d.x.foo = d.x.foo + ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-2
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
@@ -301,7 +300,6 @@ private object FirToKtConversionCreator {
|
|||||||
FqName::class,
|
FqName::class,
|
||||||
FirModuleData::class,
|
FirModuleData::class,
|
||||||
ExpectActualCompatibility.Incompatible::class,
|
ExpectActualCompatibility.Incompatible::class,
|
||||||
CallableId::class
|
|
||||||
)
|
)
|
||||||
|
|
||||||
private val KType.kClass: KClass<*>
|
private val KType.kClass: KClass<*>
|
||||||
|
|||||||
-9
@@ -242,15 +242,6 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
add(FirErrors.INVISIBLE_SETTER) { firDiagnostic ->
|
|
||||||
InvisibleSetterImpl(
|
|
||||||
firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firDiagnostic.a.fir),
|
|
||||||
firDiagnostic.b,
|
|
||||||
firDiagnostic.c,
|
|
||||||
firDiagnostic as FirPsiDiagnostic,
|
|
||||||
token,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
add(FirErrors.INVISIBLE_REFERENCE) { firDiagnostic ->
|
add(FirErrors.INVISIBLE_REFERENCE) { firDiagnostic ->
|
||||||
InvisibleReferenceImpl(
|
InvisibleReferenceImpl(
|
||||||
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
|
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
|
||||||
|
|||||||
-8
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableSymbol
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
@@ -199,13 +198,6 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
abstract val valOrVar: KtKeywordToken
|
abstract val valOrVar: KtKeywordToken
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class InvisibleSetter : KtFirDiagnostic<PsiElement>() {
|
|
||||||
override val diagnosticClass get() = InvisibleSetter::class
|
|
||||||
abstract val property: KtVariableSymbol
|
|
||||||
abstract val visibility: Visibility
|
|
||||||
abstract val callableId: CallableId
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class InvisibleReference : KtFirDiagnostic<PsiElement>() {
|
abstract class InvisibleReference : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = InvisibleReference::class
|
override val diagnosticClass get() = InvisibleReference::class
|
||||||
abstract val reference: KtSymbol
|
abstract val reference: KtSymbol
|
||||||
|
|||||||
-11
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
@@ -284,16 +283,6 @@ internal class ValOrVarOnSecondaryConstructorParameterImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class InvisibleSetterImpl(
|
|
||||||
override val property: KtVariableSymbol,
|
|
||||||
override val visibility: Visibility,
|
|
||||||
override val callableId: CallableId,
|
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
|
||||||
override val token: ValidityToken,
|
|
||||||
) : KtFirDiagnostic.InvisibleSetter(), KtAbstractFirDiagnostic<PsiElement> {
|
|
||||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class InvisibleReferenceImpl(
|
internal class InvisibleReferenceImpl(
|
||||||
override val reference: KtSymbol,
|
override val reference: KtSymbol,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
|
|||||||
Reference in New Issue
Block a user