[FIR] Fix generating properties for varargs in primary constructors

This commit is contained in:
Dmitriy Novozhilov
2020-01-23 18:22:23 +03:00
parent 69927409fc
commit 3dfad4f0c3
12 changed files with 68 additions and 50 deletions
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.lightTree.fir
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.builder.convertToArrayType
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
@@ -36,6 +37,9 @@ class ValueParameter(
fun toFirProperty(session: FirSession, callableId: CallableId): FirProperty {
val name = this.firValueParameter.name
var type = this.firValueParameter.returnTypeRef
if (this.firValueParameter.isVararg) {
type = type.convertToArrayType()
}
if (type is FirImplicitTypeRef) {
type = FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Incomplete code", DiagnosticKind.Syntax))
}
@@ -26,11 +26,12 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.ConeStarProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitKPropertyTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
import org.jetbrains.kotlin.fir.types.FirUserTypeRef
import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -395,6 +396,14 @@ fun FirModifiableVariable<*>.generateAccessorsByDelegate(session: FirSession, me
}
}
fun FirTypeRef.convertToArrayType(): FirUserTypeRef = FirUserTypeRefImpl(source, isMarkedNullable = false).apply {
qualifier += FirQualifierPartImpl(ARRAY_TYPE_NAME).apply {
typeArguments += FirTypeProjectionWithVarianceImpl(
source, this@convertToArrayType, Variance.OUT_VARIANCE
)
}
}
private val GET_VALUE = Name.identifier("getValue")
private val SET_VALUE = Name.identifier("setValue")
private val PROVIDE_DELEGATE = Name.identifier("provideDelegate")
@@ -22,9 +22,9 @@ import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement
import org.jetbrains.kotlin.fir.impl.FirLabelImpl
import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.impl.*
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.lexer.KtTokens.*
import org.jetbrains.kotlin.name.ClassId
@@ -270,7 +270,10 @@ class RawFirBuilder(session: FirSession, val scopeProvider: FirScopeProvider, va
private fun KtParameter.toFirProperty(firParameter: FirValueParameter): FirProperty {
require(hasValOrVar())
val type = typeReference.toFirOrErrorType()
var type = typeReference.toFirOrErrorType()
if (firParameter.isVararg) {
type = type.convertToArrayType()
}
val status = FirDeclarationStatusImpl(visibility, modality).apply {
isExpect = hasExpectModifier()
isActual = hasActualModifier()
@@ -1,9 +1,9 @@
class Foo(vararg val strings: String)
fun test_1(foo: Foo) {
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for (s in foo.strings) {
s.<!UNRESOLVED_REFERENCE!>length<!>
}<!>
for (s in foo.strings) {
s.length
}
}
fun test_2(vararg strings: String) {
@@ -1,19 +1,19 @@
FILE: iteratorOfVararg.kt
FILE: varargInPrimaryConstructor.kt
public final class Foo : R|kotlin/Any| {
public constructor(vararg strings: R|kotlin/Array<kotlin/String>|): R|Foo| {
super<R|kotlin/Any|>()
}
public final val strings: R|kotlin/String| = R|<local>/strings|
public get(): R|kotlin/String|
public final val strings: R|kotlin/Array<out kotlin/String>| = R|<local>/strings|
public get(): R|kotlin/Array<out kotlin/String>|
}
public final fun test_1(foo: R|Foo|): R|kotlin/Unit| {
lval <range>: R|kotlin/String| = R|<local>/foo|.R|/Foo.strings|
lval <iterator>: <ERROR TYPE REF: Unresolved name: iterator> = R|<local>/<range>|.<Unresolved name: iterator>#()
while(R|<local>/<iterator>|.<Unresolved name: hasNext>#()) {
lval s: <ERROR TYPE REF: Unresolved name: next> = R|<local>/<iterator>|.<Unresolved name: next>#()
R|<local>/s|.<Unresolved name: length>#
lval <range>: R|kotlin/Array<out kotlin/String>| = R|<local>/foo|.R|/Foo.strings|
lval <iterator>: R|kotlin/collections/Iterator<kotlin/String>| = R|<local>/<range>|.R|FakeOverride<kotlin/Array.iterator: R|kotlin/collections/Iterator<kotlin/String>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
lval s: R|kotlin/String| = R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|kotlin/String|>|()
R|<local>/s|.R|kotlin/String.length|
}
}
@@ -243,6 +243,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/resolve/testData/resolve/typeParameterVsNested.kt");
}
@TestMetadata("varargInPrimaryConstructor.kt")
public void testVarargInPrimaryConstructor() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/varargInPrimaryConstructor.kt");
}
@TestMetadata("whenAsReceiver.kt")
public void testWhenAsReceiver() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/whenAsReceiver.kt");
@@ -1051,11 +1056,6 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/resolve/testData/resolve/problems/invokeOfLambdaWithReceiver.kt");
}
@TestMetadata("iteratorOfVararg.kt")
public void testIteratorOfVararg() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/problems/iteratorOfVararg.kt");
}
@TestMetadata("javaAccessorConversion.kt")
public void testJavaAccessorConversion() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/problems/javaAccessorConversion.kt");
@@ -243,6 +243,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/resolve/testData/resolve/typeParameterVsNested.kt");
}
@TestMetadata("varargInPrimaryConstructor.kt")
public void testVarargInPrimaryConstructor() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/varargInPrimaryConstructor.kt");
}
@TestMetadata("whenAsReceiver.kt")
public void testWhenAsReceiver() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/whenAsReceiver.kt");
@@ -1051,11 +1056,6 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/resolve/testData/resolve/problems/invokeOfLambdaWithReceiver.kt");
}
@TestMetadata("iteratorOfVararg.kt")
public void testIteratorOfVararg() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/problems/iteratorOfVararg.kt");
}
@TestMetadata("javaAccessorConversion.kt")
public void testJavaAccessorConversion() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/problems/javaAccessorConversion.kt");
@@ -9,4 +9,6 @@ import org.jetbrains.kotlin.name.Name
val NAME_FOR_BACKING_FIELD = Name.identifier("field")
val NAME_FOR_DEFAULT_VALUE_PARAMETER = Name.identifier("value")
val CONSTRUCTOR_NAME = Name.special("<init>")
val CONSTRUCTOR_NAME = Name.special("<init>")
val ARRAY_TYPE_NAME = Name.identifier("Array")
@@ -90,15 +90,15 @@ FILE fqName:<root> fileName:/annotationClasses.kt
CONSTRUCTOR visibility:public <> (xs:kotlin.IntArray) returnType:<root>.Test4 [primary]
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray
PROPERTY name:xs visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Int visibility:private [final]
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.Int> visibility:private [final]
EXPRESSION_BODY
GET_VAR 'xs: kotlin.IntArray declared in <root>.Test4.<init>' type=kotlin.IntArray origin=INITIALIZE_PROPERTY_FROM_PARAMETER
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.Test4) returnType:kotlin.Int
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.Test4) returnType:kotlin.Array<out kotlin.Int>
correspondingProperty: PROPERTY name:xs visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.Test4
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.Int declared in <root>.Test4'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.Array<out kotlin.Int> declared in <root>.Test4'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.Int> visibility:private [final]' type=kotlin.Array<out kotlin.Int> origin=null
receiver: GET_VAR '<this>: <root>.Test4 declared in <root>.Test4.<get-xs>' type=<root>.Test4 origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
@@ -4,15 +4,15 @@ FILE fqName:<root> fileName:/annotationsWithVarargParameters.kt
CONSTRUCTOR visibility:public <> (xs:kotlin.Array<kotlin.String>) returnType:<root>.A [primary]
VALUE_PARAMETER name:xs index:0 type:kotlin.Array<kotlin.String>
PROPERTY name:xs visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.String visibility:private [final]
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.String> visibility:private [final]
EXPRESSION_BODY
GET_VAR 'xs: kotlin.Array<kotlin.String> declared in <root>.A.<init>' type=kotlin.Array<kotlin.String> origin=INITIALIZE_PROPERTY_FROM_PARAMETER
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.A) returnType:kotlin.String
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.A) returnType:kotlin.Array<out kotlin.String>
correspondingProperty: PROPERTY name:xs visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.A
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.String declared in <root>.A'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.String visibility:private [final]' type=kotlin.String origin=null
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.Array<out kotlin.String> declared in <root>.A'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.String> visibility:private [final]' type=kotlin.Array<out kotlin.String> origin=null
receiver: GET_VAR '<this>: <root>.A declared in <root>.A.<get-xs>' type=<root>.A origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
@@ -4,15 +4,15 @@ FILE fqName:<root> fileName:/spreadOperatorInAnnotationArguments.kt
CONSTRUCTOR visibility:public <> (xs:kotlin.Array<kotlin.String>) returnType:<root>.A [primary]
VALUE_PARAMETER name:xs index:0 type:kotlin.Array<kotlin.String>
PROPERTY name:xs visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.String visibility:private [final]
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.String> visibility:private [final]
EXPRESSION_BODY
GET_VAR 'xs: kotlin.Array<kotlin.String> declared in <root>.A.<init>' type=kotlin.Array<kotlin.String> origin=INITIALIZE_PROPERTY_FROM_PARAMETER
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.A) returnType:kotlin.String
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.A) returnType:kotlin.Array<out kotlin.String>
correspondingProperty: PROPERTY name:xs visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.A
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.String declared in <root>.A'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.String visibility:private [final]' type=kotlin.String origin=null
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.Array<out kotlin.String> declared in <root>.A'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.String> visibility:private [final]' type=kotlin.Array<out kotlin.String> origin=null
receiver: GET_VAR '<this>: <root>.A declared in <root>.A.<get-xs>' type=<root>.A origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
@@ -4,15 +4,15 @@ FILE fqName:<root> fileName:/varargsInAnnotationArguments.kt
CONSTRUCTOR visibility:public <> (xs:kotlin.IntArray) returnType:<root>.A1 [primary]
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray
PROPERTY name:xs visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Int visibility:private [final]
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.Int> visibility:private [final]
EXPRESSION_BODY
GET_VAR 'xs: kotlin.IntArray declared in <root>.A1.<init>' type=kotlin.IntArray origin=INITIALIZE_PROPERTY_FROM_PARAMETER
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.A1) returnType:kotlin.Int
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.A1) returnType:kotlin.Array<out kotlin.Int>
correspondingProperty: PROPERTY name:xs visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.A1
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.Int declared in <root>.A1'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.Array<out kotlin.Int> declared in <root>.A1'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.Int> visibility:private [final]' type=kotlin.Array<out kotlin.Int> origin=null
receiver: GET_VAR '<this>: <root>.A1 declared in <root>.A1.<get-xs>' type=<root>.A1 origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
@@ -32,15 +32,15 @@ FILE fqName:<root> fileName:/varargsInAnnotationArguments.kt
CONSTRUCTOR visibility:public <> (xs:kotlin.Array<kotlin.String>) returnType:<root>.A2 [primary]
VALUE_PARAMETER name:xs index:0 type:kotlin.Array<kotlin.String>
PROPERTY name:xs visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.String visibility:private [final]
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.String> visibility:private [final]
EXPRESSION_BODY
GET_VAR 'xs: kotlin.Array<kotlin.String> declared in <root>.A2.<init>' type=kotlin.Array<kotlin.String> origin=INITIALIZE_PROPERTY_FROM_PARAMETER
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.A2) returnType:kotlin.String
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.A2) returnType:kotlin.Array<out kotlin.String>
correspondingProperty: PROPERTY name:xs visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.A2
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.String declared in <root>.A2'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.String visibility:private [final]' type=kotlin.String origin=null
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.Array<out kotlin.String> declared in <root>.A2'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.String> visibility:private [final]' type=kotlin.Array<out kotlin.String> origin=null
receiver: GET_VAR '<this>: <root>.A2 declared in <root>.A2.<get-xs>' type=<root>.A2 origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
@@ -60,15 +60,15 @@ FILE fqName:<root> fileName:/varargsInAnnotationArguments.kt
CONSTRUCTOR visibility:public <> (xs:kotlin.Array<<root>.A1>) returnType:<root>.AA [primary]
VALUE_PARAMETER name:xs index:0 type:kotlin.Array<<root>.A1>
PROPERTY name:xs visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:xs type:<root>.A1 visibility:private [final]
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out <root>.A1> visibility:private [final]
EXPRESSION_BODY
GET_VAR 'xs: kotlin.Array<<root>.A1> declared in <root>.AA.<init>' type=kotlin.Array<<root>.A1> origin=INITIALIZE_PROPERTY_FROM_PARAMETER
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.AA) returnType:<root>.A1
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.AA) returnType:kotlin.Array<out <root>.A1>
correspondingProperty: PROPERTY name:xs visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.AA
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): <root>.A1 declared in <root>.AA'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:<root>.A1 visibility:private [final]' type=<root>.A1 origin=null
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.Array<out <root>.A1> declared in <root>.AA'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out <root>.A1> visibility:private [final]' type=kotlin.Array<out <root>.A1> origin=null
receiver: GET_VAR '<this>: <root>.AA declared in <root>.AA.<get-xs>' type=<root>.AA origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden: