Skip to content

Commit

Permalink
Create secondary constructor: fill 'this()' arguments
Browse files Browse the repository at this point in the history
#KT-11865 Fixed
  • Loading branch information
t-kameyama authored and vladimirdolzhenko committed Apr 16, 2020
1 parent e271015 commit eff5700
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.types.typeUtil.isUnit
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
Expand Down Expand Up @@ -582,13 +583,28 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {

if (declarationInPlace is KtSecondaryConstructor) {
val containingClass = declarationInPlace.containingClassOrObject!!
if (containingClass.primaryConstructorParameters.isNotEmpty()) {
val primaryConstructorParameters = containingClass.primaryConstructorParameters
if (primaryConstructorParameters.isNotEmpty()) {
declarationInPlace.replaceImplicitDelegationCallWithExplicit(true)
} else if ((receiverClassDescriptor as ClassDescriptor).getSuperClassOrAny().constructors
.all { it.valueParameters.isNotEmpty() }
) {
declarationInPlace.replaceImplicitDelegationCallWithExplicit(false)
}
if (declarationInPlace.valueParameters.size > primaryConstructorParameters.size) {
val hasCompatibleTypes = primaryConstructorParameters.zip(callableInfo.parameterInfos).all { (primary, secondary) ->
val primaryType = currentFileContext[BindingContext.TYPE, primary.typeReference] ?: return@all false
val secondaryType = computeTypeCandidates(secondary.typeInfo).firstOrNull()?.theType ?: return@all false
secondaryType.isSubtypeOf(primaryType)
}
if (hasCompatibleTypes) {
val delegationCallArgumentList = declarationInPlace.getDelegationCall().valueArgumentList
primaryConstructorParameters.forEach {
val name = it.name
if (name != null) delegationCallArgumentList?.addArgument(psiFactory.createArgument(name))
}
}
}
}

return declarationInPlace
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// "Create secondary constructor" "true"

class CtorPrimary(val f1: Int, val f2: Int?)

fun construct() {
val v6 = CtorPrimary(1, 2, 3<caret>)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// "Create secondary constructor" "true"

class CtorPrimary(val f1: Int, val f2: Int?) {
constructor(f1: Int, f2: Int, i: Int) : this(f1, f2)
}

fun construct() {
val v6 = CtorPrimary(1, 2, 3)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// "Create secondary constructor" "true"
// DISABLE-ERRORS

class CtorPrimary(val f1: Int, val f2: String)

fun construct() {
val v6 = CtorPrimary(1, 2, 3<caret>)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// "Create secondary constructor" "true"
// DISABLE-ERRORS

class CtorPrimary(val f1: Int, val f2: String) {
constructor(f1: Int, f2: Int, i: Int) : this()
}

fun construct() {
val v6 = CtorPrimary(1, 2, 3)
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit eff5700

Please sign in to comment.