[FIR] Check for setter visibility in resolution stage
This is required for the following commit where candidates from the original scope in presence of smart cast will not be ignored if they're the same symbol.
This commit is contained in:
committed by
Space Team
parent
737b286d5c
commit
5186ba80e2
+1
-1
@@ -149,5 +149,5 @@ FILE: RedundantVisibilityModifierCheckerForInnerComponents.kt
|
|||||||
|
|
||||||
}
|
}
|
||||||
public final fun test5(): R|kotlin/Unit| {
|
public final fun test5(): R|kotlin/Unit| {
|
||||||
R|/B5.B5|().R|/B5.attribute| = String(c)
|
R|/B5.B5|().R|/B5.attribute<HIDDEN SETTER: /B5.attribute is invisible>#| = String(c)
|
||||||
}
|
}
|
||||||
|
|||||||
-56
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.analysis.cfa.evaluatedInPlace
|
import org.jetbrains.kotlin.fir.analysis.cfa.evaluatedInPlace
|
||||||
@@ -15,78 +14,23 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
|
|||||||
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingSymbol
|
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingSymbol
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
|
|
||||||
import org.jetbrains.kotlin.fir.references.*
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph
|
import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnosticWithCandidates
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnosticWithCandidates
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.types.resolvedType
|
|
||||||
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.visibilityChecker
|
|
||||||
|
|
||||||
object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker() {
|
object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker() {
|
||||||
override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
checkInvisibleSetter(expression, context, reporter)
|
|
||||||
checkValReassignmentViaBackingField(expression, context, reporter)
|
checkValReassignmentViaBackingField(expression, context, reporter)
|
||||||
checkValReassignmentOnValueParameter(expression, context, reporter)
|
checkValReassignmentOnValueParameter(expression, context, reporter)
|
||||||
checkVariableExpected(expression, context, reporter)
|
checkVariableExpected(expression, context, reporter)
|
||||||
checkValReassignment(expression, context, reporter)
|
checkValReassignment(expression, context, reporter)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkInvisibleSetter(
|
|
||||||
expression: FirVariableAssignment,
|
|
||||||
context: CheckerContext,
|
|
||||||
reporter: DiagnosticReporter
|
|
||||||
) {
|
|
||||||
fun shouldInvisibleSetterBeReported(symbol: FirPropertySymbol): Boolean {
|
|
||||||
@OptIn(SymbolInternals::class)
|
|
||||||
val setterFir = symbol.setterSymbol?.fir ?: symbol.originalForSubstitutionOverride?.setterSymbol?.fir
|
|
||||||
if (setterFir != null) {
|
|
||||||
return !context.session.visibilityChecker.isVisible(
|
|
||||||
setterFir,
|
|
||||||
context.session,
|
|
||||||
context.findClosest()!!,
|
|
||||||
context.containingDeclarations,
|
|
||||||
expression.dispatchReceiver,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
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 FirSmartCastExpression) {
|
|
||||||
val symbol = explicitReceiver.originalExpression.resolvedType.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.lValue.source,
|
|
||||||
FirErrors.INVISIBLE_SETTER,
|
|
||||||
callableSymbol,
|
|
||||||
callableSymbol.setterSymbol?.visibility ?: Visibilities.Private,
|
|
||||||
callableSymbol.callableId,
|
|
||||||
context
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkValReassignmentViaBackingField(
|
private fun checkValReassignmentViaBackingField(
|
||||||
expression: FirVariableAssignment,
|
expression: FirVariableAssignment,
|
||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
|
|||||||
+6
@@ -96,6 +96,12 @@ private fun ConeDiagnostic.toKtDiagnostic(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is ConeTypeVisibilityError -> symbol.toInvisibleReferenceDiagnostic(smallestUnresolvablePrefix.last().source)
|
is ConeTypeVisibilityError -> symbol.toInvisibleReferenceDiagnostic(smallestUnresolvablePrefix.last().source)
|
||||||
|
is ConeSetterVisibilityError -> FirErrors.INVISIBLE_SETTER.createOn(
|
||||||
|
source,
|
||||||
|
symbol,
|
||||||
|
symbol.setterSymbol?.visibility ?: symbol.visibility,
|
||||||
|
symbol.callableId
|
||||||
|
)
|
||||||
is ConeVisibilityError -> symbol.toInvisibleReferenceDiagnostic(source)
|
is ConeVisibilityError -> symbol.toInvisibleReferenceDiagnostic(source)
|
||||||
is ConeInapplicableWrongReceiver -> when (val diagnostic = primaryDiagnostic) {
|
is ConeInapplicableWrongReceiver -> when (val diagnostic = primaryDiagnostic) {
|
||||||
is DynamicReceiverExpectedButWasNonDynamic ->
|
is DynamicReceiverExpectedButWasNonDynamic ->
|
||||||
|
|||||||
@@ -578,11 +578,12 @@ fun createConeDiagnosticForCandidateWithError(
|
|||||||
applicability: CandidateApplicability,
|
applicability: CandidateApplicability,
|
||||||
candidate: Candidate,
|
candidate: Candidate,
|
||||||
): ConeDiagnostic {
|
): ConeDiagnostic {
|
||||||
|
val symbol = candidate.symbol
|
||||||
return when (applicability) {
|
return when (applicability) {
|
||||||
CandidateApplicability.HIDDEN -> ConeHiddenCandidateError(candidate)
|
CandidateApplicability.HIDDEN -> ConeHiddenCandidateError(candidate)
|
||||||
CandidateApplicability.K2_VISIBILITY_ERROR -> {
|
CandidateApplicability.K2_VISIBILITY_ERROR -> {
|
||||||
val session = candidate.callInfo.session
|
val session = candidate.callInfo.session
|
||||||
val declaration = candidate.symbol.fir
|
val declaration = symbol.fir
|
||||||
if (declaration is FirMemberDeclaration &&
|
if (declaration is FirMemberDeclaration &&
|
||||||
session.visibilityChecker.isVisible(declaration, candidate, skipCheckForContainingClassVisibility = true)
|
session.visibilityChecker.isVisible(declaration, candidate, skipCheckForContainingClassVisibility = true)
|
||||||
) {
|
) {
|
||||||
@@ -604,13 +605,17 @@ fun createConeDiagnosticForCandidateWithError(
|
|||||||
return ConeVisibilityError(it.symbol)
|
return ConeVisibilityError(it.symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConeVisibilityError(candidate.symbol)
|
if (symbol is FirPropertySymbol && SetterVisibilityError in candidate.diagnostics) {
|
||||||
|
ConeSetterVisibilityError(symbol)
|
||||||
|
} else {
|
||||||
|
ConeVisibilityError(symbol)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CandidateApplicability.INAPPLICABLE_WRONG_RECEIVER -> ConeInapplicableWrongReceiver(listOf(candidate))
|
CandidateApplicability.INAPPLICABLE_WRONG_RECEIVER -> ConeInapplicableWrongReceiver(listOf(candidate))
|
||||||
CandidateApplicability.K2_NO_COMPANION_OBJECT -> ConeNoCompanionObject(candidate)
|
CandidateApplicability.K2_NO_COMPANION_OBJECT -> ConeNoCompanionObject(candidate)
|
||||||
else -> {
|
else -> {
|
||||||
if (TypeParameterAsExpression in candidate.diagnostics) {
|
if (TypeParameterAsExpression in candidate.diagnostics) {
|
||||||
ConeTypeParameterInQualifiedAccess(candidate.symbol as FirTypeParameterSymbol)
|
ConeTypeParameterInQualifiedAccess(symbol as FirTypeParameterSymbol)
|
||||||
} else {
|
} else {
|
||||||
ConeInapplicableCandidateError(applicability, candidate)
|
ConeInapplicableCandidateError(applicability, candidate)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,10 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
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.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.fir.matchingParameterFunctionType
|
|
||||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirThisReference
|
import org.jetbrains.kotlin.fir.references.FirThisReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
@@ -33,7 +31,6 @@ import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.visibilityChecker
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.isSubtypeConstraintCompatible
|
import org.jetbrains.kotlin.resolve.calls.inference.isSubtypeConstraintCompatible
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
||||||
@@ -611,6 +608,14 @@ internal object CheckVisibility : CheckerStage() {
|
|||||||
sink.yieldDiagnostic(VisibilityError)
|
sink.yieldDiagnostic(VisibilityError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (symbol is FirPropertySymbol && callInfo.callSite is FirVariableAssignment) {
|
||||||
|
val setterFir = symbol.setterSymbol?.fir ?: symbol.originalForSubstitutionOverride?.setterSymbol?.fir
|
||||||
|
if (setterFir != null && !visibilityChecker.isVisible(setterFir, candidate)) {
|
||||||
|
sink.yieldDiagnostic(SetterVisibilityError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (declaration is FirConstructor) {
|
if (declaration is FirConstructor) {
|
||||||
|
|||||||
+2
@@ -86,6 +86,8 @@ object HiddenCandidate : ResolutionDiagnostic(HIDDEN)
|
|||||||
|
|
||||||
object VisibilityError : ResolutionDiagnostic(K2_VISIBILITY_ERROR)
|
object VisibilityError : ResolutionDiagnostic(K2_VISIBILITY_ERROR)
|
||||||
|
|
||||||
|
object SetterVisibilityError : ResolutionDiagnostic(K2_VISIBILITY_ERROR)
|
||||||
|
|
||||||
object ResolvedWithLowPriority : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
object ResolvedWithLowPriority : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
||||||
|
|
||||||
object ResolvedWithSynthetic : ResolutionDiagnostic(K2_SYNTHETIC_RESOLVED)
|
object ResolvedWithSynthetic : ResolutionDiagnostic(K2_SYNTHETIC_RESOLVED)
|
||||||
|
|||||||
+6
@@ -111,6 +111,12 @@ open class ConeVisibilityError(
|
|||||||
override val reason: String get() = "HIDDEN: ${describeSymbol(symbol)} is invisible"
|
override val reason: String get() = "HIDDEN: ${describeSymbol(symbol)} is invisible"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open class ConeSetterVisibilityError(
|
||||||
|
override val symbol: FirPropertySymbol
|
||||||
|
) : ConeDiagnosticWithSymbol<FirBasedSymbol<*>> {
|
||||||
|
override val reason: String get() = "HIDDEN SETTER: ${describeSymbol(symbol)} is invisible"
|
||||||
|
}
|
||||||
|
|
||||||
class ConeTypeVisibilityError(
|
class ConeTypeVisibilityError(
|
||||||
symbol: FirBasedSymbol<*>,
|
symbol: FirBasedSymbol<*>,
|
||||||
val smallestUnresolvablePrefix: List<FirQualifierPart>,
|
val smallestUnresolvablePrefix: List<FirQualifierPart>,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ fun test() {
|
|||||||
val u : <!INVISIBLE_REFERENCE!>A<!> = <!INVISIBLE_REFERENCE!>A<!>()
|
val u : <!INVISIBLE_REFERENCE!>A<!> = <!INVISIBLE_REFERENCE!>A<!>()
|
||||||
|
|
||||||
val z = <!INVISIBLE_REFERENCE!>x<!>
|
val z = <!INVISIBLE_REFERENCE!>x<!>
|
||||||
<!INVISIBLE_REFERENCE, INVISIBLE_SETTER!>x<!> = 30
|
<!INVISIBLE_REFERENCE!>x<!> = 30
|
||||||
|
|
||||||
val po = <!INVISIBLE_REFERENCE!>PO<!>
|
val po = <!INVISIBLE_REFERENCE!>PO<!>
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ package foo
|
|||||||
|
|
||||||
fun test(s: bar.Sub<String>) {
|
fun test(s: bar.Sub<String>) {
|
||||||
s.<!INVISIBLE_REFERENCE!>name<!>
|
s.<!INVISIBLE_REFERENCE!>name<!>
|
||||||
s.<!INVISIBLE_REFERENCE, INVISIBLE_SETTER!>name<!> = ""
|
s.<!INVISIBLE_REFERENCE!>name<!> = ""
|
||||||
s.name2
|
s.name2
|
||||||
s.name2 = ""
|
s.name2 = ""
|
||||||
s.<!INVISIBLE_REFERENCE!>doSomething<!>()
|
s.<!INVISIBLE_REFERENCE!>doSomething<!>()
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ class A {
|
|||||||
|
|
||||||
class B() {
|
class B() {
|
||||||
init {
|
init {
|
||||||
A().<!INVISIBLE_REFERENCE, INVISIBLE_SETTER!>a<!> = "Hello"
|
A().<!INVISIBLE_REFERENCE!>a<!> = "Hello"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ class A(private var i: Int, var j: Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test(a: A) {
|
fun test(a: A) {
|
||||||
a.<!INVISIBLE_REFERENCE, INVISIBLE_SETTER!>i<!>++
|
a.<!INVISIBLE_REFERENCE!>i<!>++
|
||||||
a.j++
|
a.j++
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ class Derived : Base() {
|
|||||||
x.<!INVISIBLE_REFERENCE!>foo<!>()
|
x.<!INVISIBLE_REFERENCE!>foo<!>()
|
||||||
x.<!INVISIBLE_REFERENCE!>bar<!>()
|
x.<!INVISIBLE_REFERENCE!>bar<!>()
|
||||||
|
|
||||||
x.<!INVISIBLE_REFERENCE, INVISIBLE_SETTER!>x<!> = x.<!INVISIBLE_REFERENCE!>x<!> + 1
|
x.<!INVISIBLE_REFERENCE!>x<!> = x.<!INVISIBLE_REFERENCE!>x<!> + 1
|
||||||
x.<!INVISIBLE_SETTER!>y<!> = x.y + 1
|
x.<!INVISIBLE_SETTER!>y<!> = x.y + 1
|
||||||
|
|
||||||
if (x is Derived) {
|
if (x is Derived) {
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ open class C : T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test4(c: C) {
|
fun test4(c: C) {
|
||||||
c.<!INVISIBLE_REFERENCE, INVISIBLE_SETTER!>i<!>++
|
c.<!INVISIBLE_REFERENCE!>i<!>++
|
||||||
}
|
}
|
||||||
|
|
||||||
class D : C() {
|
class D : C() {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ fun test() {
|
|||||||
val u : <!INVISIBLE_REFERENCE!>A<!> = <!INVISIBLE_REFERENCE!>A<!>()
|
val u : <!INVISIBLE_REFERENCE!>A<!> = <!INVISIBLE_REFERENCE!>A<!>()
|
||||||
|
|
||||||
val z = <!INVISIBLE_REFERENCE!>x<!>
|
val z = <!INVISIBLE_REFERENCE!>x<!>
|
||||||
<!INVISIBLE_REFERENCE, INVISIBLE_SETTER!>x<!> = 30
|
<!INVISIBLE_REFERENCE!>x<!> = 30
|
||||||
|
|
||||||
val po = <!INVISIBLE_REFERENCE!>PO<!>
|
val po = <!INVISIBLE_REFERENCE!>PO<!>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,23 +15,23 @@ class Test<in I, out O> {
|
|||||||
this.i = getT()
|
this.i = getT()
|
||||||
with(Test<I, O>()) {
|
with(Test<I, O>()) {
|
||||||
i = getT() // resolved to this@Test.i
|
i = getT() // resolved to this@Test.i
|
||||||
this.<!INVISIBLE_REFERENCE, INVISIBLE_SETTER!>i<!> = getT()
|
this.<!INVISIBLE_REFERENCE!>i<!> = getT()
|
||||||
this@with.<!INVISIBLE_REFERENCE, INVISIBLE_SETTER!>i<!> = getT()
|
this@with.<!INVISIBLE_REFERENCE!>i<!> = getT()
|
||||||
this@Test.i = getT()
|
this@Test.i = getT()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <I, O> test(t: Test<I, O>) {
|
fun <I, O> test(t: Test<I, O>) {
|
||||||
t.<!INVISIBLE_REFERENCE, INVISIBLE_SETTER!>i<!> = getT()
|
t.<!INVISIBLE_REFERENCE!>i<!> = getT()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun <I, O> test(t: Test<I, O>) {
|
fun <I, O> test(t: Test<I, O>) {
|
||||||
t.<!INVISIBLE_REFERENCE, INVISIBLE_SETTER!>i<!> = getT()
|
t.<!INVISIBLE_REFERENCE!>i<!> = getT()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <I, O> test(t: Test<I, O>) {
|
fun <I, O> test(t: Test<I, O>) {
|
||||||
t.<!INVISIBLE_REFERENCE, INVISIBLE_SETTER!>i<!> = getT()
|
t.<!INVISIBLE_REFERENCE!>i<!> = getT()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user