From 569e4a68ae44a9e6e4217f004842ecb26f87b128 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 6 Mar 2015 19:21:30 +0100 Subject: [PATCH] Support for secondary constructors in j2k --- .../kotlin/j2k/ClassBodyConverter.kt | 25 +-- .../kotlin/j2k/ConstructorConverter.kt | 195 +++--------------- j2k/src/org/jetbrains/kotlin/j2k/Converter.kt | 7 +- .../kotlin/j2k/ExpressionConverter.kt | 10 + j2k/src/org/jetbrains/kotlin/j2k/ast/Class.kt | 2 - .../org/jetbrains/kotlin/j2k/ast/ClassBody.kt | 1 - .../jetbrains/kotlin/j2k/ast/Constructors.kt | 45 ++-- .../org/jetbrains/kotlin/j2k/ast/Element.kt | 11 +- j2k/src/org/jetbrains/kotlin/j2k/ast/Enum.kt | 2 - .../org/jetbrains/kotlin/j2k/ast/Function.kt | 2 +- j2k/testData/fileOrElement/class/kt-639.kt | 18 +- .../comments/commentsForConstructors.kt | 9 +- .../constructors/allCallsPrimary2.kt | 24 +-- .../constructors/artificialPrimary.kt | 28 ++- .../fileOrElement/constructors/chain.kt | 19 +- .../constructors/constructorAnnotations.kt | 13 +- .../constructors/genericIdentifier.kt | 44 ++-- .../fileOrElement/constructors/identifier.kt | 42 ++-- .../constructors/methodCallInFactoryFun.kt | 12 +- .../fileOrElement/constructors/noPrimary.kt | 23 +-- .../constructors/parameterDefaults1.kt | 7 +- .../constructors/parameterDefaults2.kt | 14 +- .../constructors/parameterDefaults3.kt | 7 +- .../constructors/parameterModification.kt | 14 +- .../constructors/privateConstructors.kt | 10 +- .../constructors/qualifiedRefInFactoryFun.kt | 13 +- .../secondaryConstructorsInInnerClass.kt | 89 ++++---- .../secondaryConstructorsInNestedClass.kt | 110 +++++----- .../secondaryConstructorsVisibility.kt | 53 +++-- .../staticFieldRefInFactoryFun.kt | 13 +- .../constructors/withManyDefaultParams.kt | 24 +-- .../FieldUsagesInFactoryMethods.kt | 26 +-- j2k/testData/fileOrElement/issues/kt-638.kt | 44 ++-- 33 files changed, 367 insertions(+), 589 deletions(-) diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ClassBodyConverter.kt b/j2k/src/org/jetbrains/kotlin/j2k/ClassBodyConverter.kt index 063288e13a0..56e2647f594 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ClassBodyConverter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ClassBodyConverter.kt @@ -81,7 +81,6 @@ class ClassBodyConverter(private val psiClass: PsiClass, val members = ArrayList() val defaultObjectMembers = ArrayList() - val factoryFunctions = ArrayList() var primaryConstructorSignature: PrimaryConstructorSignature? = null for ((psiMember, member) in convertedMembers) { if (member is PrimaryConstructor) { @@ -89,11 +88,7 @@ class ClassBodyConverter(private val psiClass: PsiClass, primaryConstructorSignature = member.createSignature(converter) members.add(member.initializer()) } - else if (member is FactoryFunction) { - factoryFunctions.add(member) - } - else if (useDefaultObject - && (if (member is Class) shouldGenerateIntoDefaultObject(member) else psiMember.hasModifierProperty(PsiModifier.STATIC))) { + else if (useDefaultObject && member !is Class && psiMember.hasModifierProperty(PsiModifier.STATIC)) { defaultObjectMembers.add(member) } else { @@ -101,11 +96,19 @@ class ClassBodyConverter(private val psiClass: PsiClass, } } + if (primaryConstructorSignature != null + && primaryConstructorSignature!!.annotations.isEmpty + && primaryConstructorSignature!!.accessModifier == null + && primaryConstructorSignature!!.parameterList.parameters.isEmpty() + && members.none { it is SecondaryConstructor } + ) { + primaryConstructorSignature = null // no "()" after class name is needed in this case + } + val lBrace = LBrace().assignPrototype(psiClass.getLBrace()) val rBrace = RBrace().assignPrototype(psiClass.getRBrace()) - val classBody = ClassBody(primaryConstructorSignature, constructorConverter?.baseClassParams ?: listOf(), members, defaultObjectMembers, factoryFunctions, lBrace, rBrace) - return if (constructorConverter != null) constructorConverter.postProcessConstructors(classBody) else classBody + return ClassBody(primaryConstructorSignature, constructorConverter?.baseClassParams ?: listOf(), members, defaultObjectMembers, lBrace, rBrace) } private fun Converter.convertMember(member: PsiMember, @@ -124,8 +127,6 @@ class ClassBodyConverter(private val psiClass: PsiClass, private fun shouldGenerateDefaultObject(convertedMembers: Map): Boolean { if (psiClass.isEnum()) return false - if (convertedMembers.values().any { it is Class && shouldGenerateIntoDefaultObject(it) }) return true - val members = convertedMembers.keySet().filter { !it.isConstructor() } val defaultObjectMembers = members.filter { it !is PsiClass && it.hasModifierProperty(PsiModifier.STATIC) } val nestedClasses = members.filterIsInstance().filter { it.hasModifierProperty(PsiModifier.STATIC) } @@ -137,10 +138,6 @@ class ClassBodyConverter(private val psiClass: PsiClass, } } - // we generate nested classes with factory functions into default object as a workaround until secondary constructors supported by Kotlin - private fun shouldGenerateIntoDefaultObject(nestedClass: Class) - = !nestedClass.modifiers.contains(Modifier.INNER) && nestedClass.body.factoryFunctions.isNotEmpty() - private fun processAccessorsToDrop() { val fieldToGetterInfo = HashMap() val fieldToSetterInfo = HashMap() diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ConstructorConverter.kt b/j2k/src/org/jetbrains/kotlin/j2k/ConstructorConverter.kt index d1e6a14aee9..656dca73b83 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ConstructorConverter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ConstructorConverter.kt @@ -28,12 +28,6 @@ class ConstructorConverter( private val converter: Converter, private val fieldCorrections: Map ) { - private val typeConverter = converter.typeConverter - - private val tempValName: String = "__" - private fun tempValIdentifier(): Identifier = Identifier(tempValName, false).assignNoPrototype() - - private val className = psiClass.getName()!! private val constructors = psiClass.getConstructors() private val constructorsToDrop = HashSet() private val lastParamDefaults = ArrayList() // defaults for a few last parameters of primary constructor in reverse order @@ -166,39 +160,36 @@ class ConstructorConverter( if (constructor in constructorsToDrop) return null val params = converter.convertParameterList(constructor.getParameterList()) - val containingClass = constructor.getContainingClass() - val typeParameterList = converter.convertTypeParameterList(containingClass?.getTypeParameterList()) - val factoryFunctionType = ClassType(ReferenceElement(containingClass?.declarationIdentifier() ?: Identifier.Empty, typeParameterList.parameters).assignNoPrototype(), - Nullability.NotNull, - converter.settings).assignNoPrototype() + + val thisOrSuper = findThisOrSuperCall(constructor) + val thisOrSuperDeferred = if (thisOrSuper != null) + converter.deferredElement { it.convertExpression(thisOrSuper.getExpression()) } + else + null fun convertBody(codeConverter: CodeConverter): Block { - val bodyConverter = codeConverter.withSpecialExpressionConverter( - object : SpecialExpressionConverter { - override fun convertExpression(expression: PsiExpression, codeConverter: CodeConverter): Expression? { - if (expression is PsiReferenceExpression && expression.isQualifierEmptyOrThis()) { - val member = expression.getReference()?.resolve() as? PsiMember - if (member != null && - !member.isConstructor() && - member.getContainingClass() == constructor.getContainingClass()) { - val isNullable = member is PsiField && typeConverter.variableNullability(member).isNullable(codeConverter.settings) - val qualifier = if (member.hasModifierProperty(PsiModifier.STATIC)) constructor.declarationIdentifier() else tempValIdentifier() - val name = fieldCorrections[member]?.name ?: expression.getReferenceName()!! - return QualifiedExpression(qualifier, Identifier(name, isNullable).assignNoPrototype()) - } - } - - return null - } - }) - return postProcessBody(bodyConverter.convertBlock(constructor.getBody())) + return postProcessBody(codeConverter.withSpecialExpressionConverter(object: SpecialExpressionConverter { + override fun convertExpression(expression: PsiExpression, codeConverter: CodeConverter): Expression? { + if (expression.isThisConstructorCall() || expression.isSuperConstructorCall()) { + return Expression.Empty // skip it + } + return null + } + }).convertBlock(constructor.getBody())) } - return FactoryFunction(constructor.declarationIdentifier(), annotations, correctFactoryFunctionAccess(modifiers), - factoryFunctionType, params, typeParameterList, converter.deferredElement(::convertBody)) + return SecondaryConstructor(annotations, modifiers, params, + converter.deferredElement(::convertBody), thisOrSuperDeferred) } } + private fun findThisOrSuperCall(constructor: PsiMethod): PsiExpressionStatement? { + val statement = constructor.getBody()?.getStatements()?.firstOrNull() as? PsiExpressionStatement ?: return null + val methodCall = statement.getExpression() as? PsiMethodCallExpression ?: return null + val text = methodCall.getMethodExpression().getText() + return if (text == "this" || text == "super") statement else null + } + private fun convertPrimaryConstructor(annotations: Annotations, modifiers: Modifiers, membersToRemove: MutableSet, @@ -246,7 +237,7 @@ class ConstructorConverter( val bodyConverter = codeConverter.withSpecialExpressionConverter( object : ReplacingExpressionConverter(parameterUsageReplacementMap) { override fun convertExpression(expression: PsiExpression, codeConverter: CodeConverter): Expression? { - if (expression is PsiMethodCallExpression && expression.isSuperConstructorCall()) { + if (expression.isSuperConstructorCall()) { return Expression.Empty // skip it } return super.convertExpression(expression, codeConverter) @@ -333,142 +324,8 @@ class ConstructorConverter( return null } - public fun postProcessConstructors(classBody: ClassBody): ClassBody { - if (primaryConstructor == null && constructors.size() > 1) { - return generateArtificialPrimaryConstructor(classBody) - } - else { - processFactoryFunctionsWithConstructorCall(classBody.factoryFunctions) - return classBody - } - } - - private fun generateArtificialPrimaryConstructor(classBody: ClassBody): ClassBody { - assert(classBody.primaryConstructorSignature == null) - - val propertiesToInitialize = classBody.members.filterIsInstance().filter { it.isVal } - for (function in classBody.factoryFunctions) { - function.body!!.updateGenerator { (codeConverter, block) -> - // 2 cases: secondary constructor either calls another constructor or does not call any - val newStatements = processFactoryFunctionWithConstructorCall(block) ?: - insertCallToArtificialPrimary(block, propertiesToInitialize) - Block(newStatements, LBrace().assignNoPrototype(), RBrace().assignNoPrototype()).assignNoPrototype() - } - } - - val parameters = propertiesToInitialize.map { property -> - val varValModifier = if (property.isVal) Parameter.VarValModifier.Val else Parameter.VarValModifier.Var - Parameter(property.identifier, property.type, varValModifier, property.annotations, property.modifiers.filter { it in ACCESS_MODIFIERS }).assignPrototypesFrom(property) - } - - val modifiers = Modifiers.Empty - //TODO: we can generate it private when secondary constructors are supported by Kotlin - //val modifiers = Modifiers(listOf(Modifier.PRIVATE)).assignNoPrototype() - val parameterList = ParameterList(parameters).assignNoPrototype() - val constructorSignature = PrimaryConstructorSignature(Annotations.Empty, modifiers, parameterList).assignNoPrototype() - val updatedMembers = classBody.members.filter { !propertiesToInitialize.contains(it) } - return ClassBody(constructorSignature, classBody.baseClassParams, updatedMembers, classBody.defaultObjectMembers, classBody.factoryFunctions, classBody.lBrace, classBody.rBrace) - } - - private fun processFactoryFunctionsWithConstructorCall(functions: List) { - for (function in functions) { - function.body!!.updateGenerator { (codeConverter, block) -> - val statements = processFactoryFunctionWithConstructorCall(block) - if (statements != null) { - Block(statements, block.lBrace, block.rBrace).assignPrototypesFrom(block) - } - else { - block - } - } - } - } - - private fun processFactoryFunctionWithConstructorCall(body: Block): List? { - val statements = ArrayList(body.statements) - - // searching for other constructor call in form "this(...)" - // it's not necessary the first statement because of statements inserted for writable parameters - for ((i, statement) in statements.withIndex()) { - if (statement is MethodCallExpression) { - if ((statement.methodExpression as? Identifier)?.name == "this") { - val constructorCall = MethodCallExpression.buildNotNull(null, className, statement.arguments).assignPrototypesFrom(statement) - if (i == statements.lastIndex) { // constructor call is the last statement - no intermediate variable needed - statements[i] = ReturnStatement(constructorCall).assignNoPrototype() - return statements - } - val localVar = LocalVariable(tempValIdentifier(), Annotations.Empty, Modifiers.Empty, null, constructorCall, true).assignNoPrototype() - statements[i] = DeclarationStatement(listOf(localVar)).assignNoPrototype() - statements.add(ReturnStatement(tempValIdentifier()).assignNoPrototype()) - return statements - } - } - } - - return null - } - - private fun insertCallToArtificialPrimary(body: Block, propertiesToInitialize: Collection): List { - val initializers = HashMap() - for (property in propertiesToInitialize) { - initializers.put(property, getDefaultInitializer(property)) - } - - val statements = ArrayList() - for (statement in body.statements) { - var keepStatement = true - if (statement is AssignmentExpression) { - val assignee = statement.left - if (assignee is QualifiedExpression && (assignee.qualifier as? Identifier)?.name == tempValName) { - val name = (assignee.identifier as Identifier).name - for (property in propertiesToInitialize) { - if (name == property.identifier.name) { - initializers.put(property, statement.right) - keepStatement = false - } - - } - } - - } - - if (keepStatement) { - statements.add(statement) - } - } - - val arguments = propertiesToInitialize.map { initializers[it] ?: LiteralExpression("null").assignNoPrototype() } - val initializer = MethodCallExpression.buildNotNull(null, className, arguments).assignNoPrototype() - if (statements.isNotEmpty()) { - val localVar = LocalVariable(tempValIdentifier(), - Annotations.Empty, - Modifiers.Empty, - null, - initializer, - true).assignNoPrototype() - statements.add(0, DeclarationStatement(listOf(localVar)).assignNoPrototype()) - statements.add(ReturnStatement(tempValIdentifier()).assignNoPrototype()) - } - else { - statements.add(ReturnStatement(initializer).assignNoPrototype()) - } - return statements - } - - private fun correctFactoryFunctionAccess(modifiers: Modifiers): Modifiers { - val classAccess = converter.convertModifiers(psiClass).accessModifier() - return when(modifiers.accessModifier()) { - Modifier.PUBLIC -> modifiers.without(Modifier.PUBLIC).with(classAccess) - Modifier.PROTECTED -> modifiers.without(Modifier.PROTECTED).with(classAccess) - Modifier.PRIVATE -> modifiers - else/*internal*/ -> if (classAccess != Modifier.PUBLIC) modifiers.with(classAccess) else modifiers - } - } - - private fun PsiMethodCallExpression.isSuperConstructorCall(): Boolean { - val ref = getMethodExpression() - return ref.getCanonicalText() == "super" && ref.resolve()?.isConstructor() ?: false - } + private fun PsiExpression.isSuperConstructorCall() = (this as? PsiMethodCallExpression)?.getMethodExpression()?.getText() == "super" + private fun PsiExpression.isThisConstructorCall() = (this as? PsiMethodCallExpression)?.getMethodExpression()?.getText() == "this" private inner open class ReplacingExpressionConverter(val parameterUsageReplacementMap: Map) : SpecialExpressionConverter { override fun convertExpression(expression: PsiExpression, codeConverter: CodeConverter): Expression? { diff --git a/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt b/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt index e234a9dd6b6..b81af402f0e 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt @@ -209,11 +209,14 @@ class Converter private( annotationConverter.convertAnnotationMethodDefault(method)).assignPrototype(method, noBlankLinesInheritance) } val parameterList = ParameterList(parameters).assignNoPrototype() - val constructorSignature = PrimaryConstructorSignature(Annotations.Empty, Modifiers.Empty, parameterList).assignNoPrototype() + val constructorSignature = if (parameterList.parameters.isNotEmpty()) + PrimaryConstructorSignature(Annotations.Empty, Modifiers.Empty, parameterList).assignNoPrototype() + else + null // to convert fields and nested types - they are not allowed in Kotlin but we convert them and let user refactor code var classBody = ClassBodyConverter(psiClass, this, false).convertBody() - classBody = ClassBody(constructorSignature, classBody.baseClassParams, classBody.members, classBody.defaultObjectMembers, listOf(), classBody.lBrace, classBody.rBrace) + classBody = ClassBody(constructorSignature, classBody.baseClassParams, classBody.members, classBody.defaultObjectMembers, classBody.lBrace, classBody.rBrace) val annotationAnnotation = Annotation(Identifier("annotation").assignNoPrototype(), listOf(), false, false).assignNoPrototype() return Class(psiClass.declarationIdentifier(), diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt b/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt index 08cc7ff9fa7..147010e032a 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt @@ -346,6 +346,16 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter { } override fun visitReferenceExpression(expression: PsiReferenceExpression) { + // to avoid quoting of 'this' and 'super' in calls to this/super class constructors + if (expression.getText() == "this") { + result = ThisExpression(Identifier.Empty) + return + } + if (expression.getText() == "super") { + result = SuperExpression(Identifier.Empty) + return + } + val referenceName = expression.getReferenceName()!! val target = expression.getReference()?.resolve() val isNullable = target is PsiVariable && typeConverter.variableNullability(target).isNullable(codeConverter.settings) diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/Class.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/Class.kt index 267ee758d9d..184f736c394 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/Class.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/Class.kt @@ -30,8 +30,6 @@ open class Class( ) : Member(annotations, modifiers) { override fun generateCode(builder: CodeBuilder) { - builder.append(body.factoryFunctions, "\n", "", "\n\n") - builder.append(annotations) .appendWithSpaceAfter(presentationModifiers()) .append(keyword) diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/ClassBody.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/ClassBody.kt index a754687ff6d..c9aee24c4a5 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/ClassBody.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/ClassBody.kt @@ -25,7 +25,6 @@ class ClassBody ( val baseClassParams: List>, val members: List, val defaultObjectMembers: List, - val factoryFunctions: List, val lBrace: LBrace, val rBrace: RBrace) { diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/Constructors.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/Constructors.kt index 4cc457edf04..51958f86d51 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/Constructors.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/Constructors.kt @@ -44,28 +44,45 @@ class PrimaryConstructor( } } -class PrimaryConstructorSignature(val annotations: Annotations, val modifiers: Modifiers, val parameterList: ParameterList) : Element() { - override fun generateCode(builder: CodeBuilder) { - val accessModifier = modifiers.filter { it in ACCESS_MODIFIERS && it != Modifier.PUBLIC } - if (accessModifier.isEmpty && annotations.isEmpty && parameterList.parameters.isEmpty()) return +class PrimaryConstructorSignature(val annotations: Annotations, private val modifiers: Modifiers, val parameterList: ParameterList) : Element() { + public val accessModifier: Modifier? = run { + val modifier = modifiers.accessModifier() + if (modifier != Modifier.PUBLIC) modifier else null + } + override fun generateCode(builder: CodeBuilder) { if (!annotations.isEmpty) { builder append " " append annotations.withBrackets() } - if (!accessModifier.isEmpty) { - builder append " " append accessModifier + if (accessModifier != null) { + builder append " " append Modifiers(listOf(accessModifier)).assignPrototypesFrom(modifiers) } builder append "(" append parameterList append ")" } } -class FactoryFunction(name: Identifier, - annotations: Annotations, - modifiers: Modifiers, - returnType: Type, - parameterList: ParameterList, - typeParameterList: TypeParameterList, - body: DeferredElement) -: Function(name, annotations, modifiers, returnType, typeParameterList, parameterList, body, false) +class SecondaryConstructor( + annotations: Annotations, + modifiers: Modifiers, + private val parameterList: ParameterList, + private val body: DeferredElement, + private val thisOrSuperCall: DeferredElement? +) : Member(annotations, modifiers) { + + override fun generateCode(builder: CodeBuilder) { + builder.append(annotations) + .appendWithSpaceAfter(modifiers) + .append("constructor(") + .append(parameterList) + .append(")") + + if (thisOrSuperCall != null) { + builder append " : " append thisOrSuperCall + } + + builder append " " append body + } +} + diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/Element.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/Element.kt index 7e2a9f3ae34..a63c9291e37 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/Element.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/Element.kt @@ -95,7 +95,7 @@ abstract class Element { // this class should never be created directly - Converter.deferredElement() should be used! class DeferredElement( - private var generator: (CodeConverter) -> TResult, + private val generator: (CodeConverter) -> TResult, public val converterState: Converter.PersonalState ) : Element() { @@ -126,14 +126,5 @@ class DeferredElement( assert(result != null) { "No code generated for deferred element $this. Possible reason is that it has been created directly instead of Converter.lazyElement() call." } return result!! } - - public fun updateGenerator(generatorUpdater: (codeConverter: CodeConverter, prevResult: TResult) -> TResult) { - assert(result == null, "Cannot update generator when code has been generated") - val prevGenerator = generator - generator = { codeConverter -> - val prevResult = prevGenerator(codeConverter) - generatorUpdater(codeConverter, prevResult) - } - } } diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/Enum.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/Enum.kt index 2fdf888b8ea..f8f4deaeaaa 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/Enum.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/Enum.kt @@ -30,8 +30,6 @@ class Enum( ) : Class(name, annotations, modifiers, typeParameterList, extendsTypes, baseClassParams, implementsTypes, body) { override fun generateCode(builder: CodeBuilder) { - builder.append(body.factoryFunctions, "\n", "", "\n\n") - builder append annotations appendWithSpaceAfter presentationModifiers() append "enum class " append name if (body.primaryConstructorSignature != null) { diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/Function.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/Function.kt index f9a33bc42a2..334017a5598 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/Function.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/Function.kt @@ -18,7 +18,7 @@ package org.jetbrains.kotlin.j2k.ast import org.jetbrains.kotlin.j2k.* -open class Function( +class Function( val name: Identifier, annotations: Annotations, modifiers: Modifiers, diff --git a/j2k/testData/fileOrElement/class/kt-639.kt b/j2k/testData/fileOrElement/class/kt-639.kt index ad65781f5ef..55e79163231 100644 --- a/j2k/testData/fileOrElement/class/kt-639.kt +++ b/j2k/testData/fileOrElement/class/kt-639.kt @@ -1,24 +1,16 @@ -// ERROR: 'internal fun Test(): demo.Test' is already defined in demo -// ERROR: 'public constructor Test()' is already defined in demo -// ERROR: Overload resolution ambiguity: internal fun Test(): demo.Test defined in demo public constructor Test() defined in demo.Test -// ERROR: Overload resolution ambiguity: internal fun Test(): demo.Test defined in demo public constructor Test() defined in demo.Test // ERROR: Type inference failed: Not enough information to infer parameter K in constructor HashMap(p0: kotlin.Int) Please specify it explicitly. // ERROR: Type inference failed: Not enough information to infer parameter K in constructor HashMap(p0: kotlin.Int) Please specify it explicitly. -// ERROR: Overload resolution ambiguity: internal fun Test(): demo.Test defined in demo public constructor Test() defined in demo.Test package demo import java.util.HashMap -fun Test(): Test { - return Test() +class Test { + constructor() { + } + constructor(s: String) { + } } -fun Test(s: String): Test { - return Test() -} - -class Test - class User { fun main() { val m = HashMap(1) diff --git a/j2k/testData/fileOrElement/comments/commentsForConstructors.kt b/j2k/testData/fileOrElement/comments/commentsForConstructors.kt index 683bd968baf..d98cbe5bb37 100644 --- a/j2k/testData/fileOrElement/comments/commentsForConstructors.kt +++ b/j2k/testData/fileOrElement/comments/commentsForConstructors.kt @@ -1,8 +1,3 @@ -// this is a secondary constructor 2 -fun A(s: String): A { - return A(s.length()) -} // end of secondary constructor 2 body - class A// this is a primary constructor (p: Int = 1) { private val v: Int @@ -10,6 +5,10 @@ class A// this is a primary constructor { v = 1 } // end of primary constructor body + + // this is a secondary constructor 2 + constructor(s: String) : this(s.length()) { + } // end of secondary constructor 2 body }// this is a secondary constructor 1 // end of secondary constructor 1 body diff --git a/j2k/testData/fileOrElement/constructors/allCallsPrimary2.kt b/j2k/testData/fileOrElement/constructors/allCallsPrimary2.kt index 0223b9360d8..bf64220e8a9 100644 --- a/j2k/testData/fileOrElement/constructors/allCallsPrimary2.kt +++ b/j2k/testData/fileOrElement/constructors/allCallsPrimary2.kt @@ -1,21 +1,17 @@ -fun C(arg1: Int, arg2: Int, arg3: Int): C { - val __ = C(arg1) - __.myArg2 = arg2 - __.myArg3 = arg3 - return __ -} - -fun C(arg1: Int, arg2: Int): C { - val __ = C(arg1) - __.myArg2 = arg2 - __.myArg3 = 0 - return __ -} - class C(val myArg1: Int) { var myArg2: Int = 0 var myArg3: Int = 0 + constructor(arg1: Int, arg2: Int, arg3: Int) : this(arg1) { + myArg2 = arg2 + myArg3 = arg3 + } + + constructor(arg1: Int, arg2: Int) : this(arg1) { + myArg2 = arg2 + myArg3 = 0 + } + { myArg2 = 0 myArg3 = 0 diff --git a/j2k/testData/fileOrElement/constructors/artificialPrimary.kt b/j2k/testData/fileOrElement/constructors/artificialPrimary.kt index 0fe04149603..07c8e8c69b4 100644 --- a/j2k/testData/fileOrElement/constructors/artificialPrimary.kt +++ b/j2k/testData/fileOrElement/constructors/artificialPrimary.kt @@ -1,18 +1,14 @@ -// ERROR: 'public fun Test(s: kotlin.String): Test' is already defined in root package -// ERROR: 'public constructor Test(s: kotlin.String)' is already defined in root package -// ERROR: None of the following functions can be called with the arguments supplied: public fun Test(): Test defined in root package public fun Test(s: kotlin.String): Test defined in root package public constructor Test(s: kotlin.String) defined in Test -// ERROR: Overload resolution ambiguity: public fun Test(s: kotlin.String): Test defined in root package public constructor Test(s: kotlin.String) defined in Test -public fun Test(): Test { - val __ = Test(null) - __.b = true - return __ -} - -public fun Test(s: String): Test { - return Test(s) -} - -public class Test(private val s: String) { +// ERROR: Property must be initialized or be abstract +public class Test { + private val s: String var b: Boolean = false var d: Double = 0.toDouble() -} \ No newline at end of file + + public constructor() { + b = true + } + + public constructor(s: String) { + this.s = s + } +} diff --git a/j2k/testData/fileOrElement/constructors/chain.kt b/j2k/testData/fileOrElement/constructors/chain.kt index b664fa361f4..f2184bedcb4 100644 --- a/j2k/testData/fileOrElement/constructors/chain.kt +++ b/j2k/testData/fileOrElement/constructors/chain.kt @@ -1,16 +1,13 @@ -fun C(arg1: Int, arg2: Int): C { - val __ = C(arg1, arg2, 0) - System.out.println() - return __ -} +class C(arg1: Int, arg2: Int, arg3: Int) { -fun C(arg1: Int): C { - val __ = C(arg1, 0) - System.out.println() - return __ -} + constructor(arg1: Int, arg2: Int) : this(arg1, arg2, 0) { + System.out.println() + } -class C(arg1: Int, arg2: Int, arg3: Int) + constructor(arg1: Int) : this(arg1, 0) { + System.out.println() + } +} public class User { default object { diff --git a/j2k/testData/fileOrElement/constructors/constructorAnnotations.kt b/j2k/testData/fileOrElement/constructors/constructorAnnotations.kt index 78ae4eb6396..e6ac7ac7758 100644 --- a/j2k/testData/fileOrElement/constructors/constructorAnnotations.kt +++ b/j2k/testData/fileOrElement/constructors/constructorAnnotations.kt @@ -1,14 +1,13 @@ import javaApi.Anon5 - -deprecated("") // this constructor will not be replaced by default parameter value in primary because of this annotation -fun A(a: Int): A { - return A(a, 1) -} - class A [Anon5(10)] -(private val a: Int, private val b: Int) +(private val a: Int, private val b: Int) { + + deprecated("") // this constructor will not be replaced by default parameter value in primary because of this annotation + public constructor(a: Int) : this(a, 1) { + } +} class B [Anon5(11)] () diff --git a/j2k/testData/fileOrElement/constructors/genericIdentifier.kt b/j2k/testData/fileOrElement/constructors/genericIdentifier.kt index c1fb9c1dd98..2049717754b 100644 --- a/j2k/testData/fileOrElement/constructors/genericIdentifier.kt +++ b/j2k/testData/fileOrElement/constructors/genericIdentifier.kt @@ -1,34 +1,30 @@ -// ERROR: 'public fun Identifier(name: T, isNullable: kotlin.Boolean): Identifier' is already defined in root package -// ERROR: 'public constructor Identifier(name: T, myHasDollar: kotlin.Boolean)' is already defined in root package -// ERROR: Cannot choose among the following candidates without completing type inference: public fun Identifier(name: T, isNullable: kotlin.Boolean): Identifier defined in root package public constructor Identifier(name: T, myHasDollar: kotlin.Boolean) defined in Identifier -// ERROR: Cannot choose among the following candidates without completing type inference: public fun Identifier(name: T, isNullable: kotlin.Boolean): Identifier defined in root package public constructor Identifier(name: T, myHasDollar: kotlin.Boolean) defined in Identifier -// ERROR: Cannot choose among the following candidates without completing type inference: public fun Identifier(name: T, isNullable: kotlin.Boolean): Identifier defined in root package public constructor Identifier(name: T, myHasDollar: kotlin.Boolean) defined in Identifier -// ERROR: Overload resolution ambiguity: public fun Identifier(name: kotlin.String, isNullable: kotlin.Boolean): Identifier defined in root package public constructor Identifier(name: kotlin.String, myHasDollar: kotlin.Boolean) defined in Identifier -public fun Identifier(name: T): Identifier { - return Identifier(name, false) -} - -public fun Identifier(name: T, isNullable: Boolean): Identifier { - val __ = Identifier(name, false) - __.myNullable = isNullable - return __ -} - -public fun Identifier(name: T, hasDollar: Boolean, isNullable: Boolean): Identifier { - val __ = Identifier(name, hasDollar) - __.myNullable = isNullable - return __ -} - -public class Identifier(public val name: T, private val myHasDollar: Boolean) { +// ERROR: Property must be initialized or be abstract +public class Identifier { + public val name: T + private val myHasDollar: Boolean private var myNullable = true + + public constructor(name: T) { + this.name = name + } + + public constructor(name: T, isNullable: Boolean) { + this.name = name + myNullable = isNullable + } + + public constructor(name: T, hasDollar: Boolean, isNullable: Boolean) { + this.name = name + myHasDollar = hasDollar + myNullable = isNullable + } } public class User { default object { public fun main() { val i1 = Identifier("name", false, true) - val i2 = Identifier("name", false) + val i2 = Identifier("name", false) val i3 = Identifier("name") } } diff --git a/j2k/testData/fileOrElement/constructors/identifier.kt b/j2k/testData/fileOrElement/constructors/identifier.kt index 3f1af6bb623..30737cc1acf 100644 --- a/j2k/testData/fileOrElement/constructors/identifier.kt +++ b/j2k/testData/fileOrElement/constructors/identifier.kt @@ -1,27 +1,23 @@ -// ERROR: 'public fun Identifier(name: kotlin.String, isNullable: kotlin.Boolean): Identifier' is already defined in root package -// ERROR: 'public constructor Identifier(name: kotlin.String, myHasDollar: kotlin.Boolean)' is already defined in root package -// ERROR: Overload resolution ambiguity: public fun Identifier(name: kotlin.String, isNullable: kotlin.Boolean): Identifier defined in root package public constructor Identifier(name: kotlin.String, myHasDollar: kotlin.Boolean) defined in Identifier -// ERROR: Overload resolution ambiguity: public fun Identifier(name: kotlin.String, isNullable: kotlin.Boolean): Identifier defined in root package public constructor Identifier(name: kotlin.String, myHasDollar: kotlin.Boolean) defined in Identifier -// ERROR: Overload resolution ambiguity: public fun Identifier(name: kotlin.String, isNullable: kotlin.Boolean): Identifier defined in root package public constructor Identifier(name: kotlin.String, myHasDollar: kotlin.Boolean) defined in Identifier -// ERROR: Overload resolution ambiguity: public fun Identifier(name: kotlin.String, isNullable: kotlin.Boolean): Identifier defined in root package public constructor Identifier(name: kotlin.String, myHasDollar: kotlin.Boolean) defined in Identifier -public fun Identifier(name: String): Identifier { - return Identifier(name, false) -} - -public fun Identifier(name: String, isNullable: Boolean): Identifier { - val __ = Identifier(name, false) - __.myNullable = isNullable - return __ -} - -public fun Identifier(name: String, hasDollar: Boolean, isNullable: Boolean): Identifier { - val __ = Identifier(name, hasDollar) - __.myNullable = isNullable - return __ -} - -public class Identifier(public val name: String, private val myHasDollar: Boolean) { +// ERROR: Property must be initialized or be abstract +public class Identifier { + public val name: String + private val myHasDollar: Boolean private var myNullable = true + + public constructor(name: String) { + this.name = name + } + + public constructor(name: String, isNullable: Boolean) { + this.name = name + myNullable = isNullable + } + + public constructor(name: String, hasDollar: Boolean, isNullable: Boolean) { + this.name = name + myHasDollar = hasDollar + myNullable = isNullable + } } public class User { diff --git a/j2k/testData/fileOrElement/constructors/methodCallInFactoryFun.kt b/j2k/testData/fileOrElement/constructors/methodCallInFactoryFun.kt index a3ab97cd273..d536d215788 100644 --- a/j2k/testData/fileOrElement/constructors/methodCallInFactoryFun.kt +++ b/j2k/testData/fileOrElement/constructors/methodCallInFactoryFun.kt @@ -1,17 +1,13 @@ -// ERROR: Cannot access 'staticFoo': it is 'private' in 'Default' -// ERROR: Cannot access 'staticFoo': it is 'private' in 'Default' -fun C(arg1: Int, arg2: Int, other: C): C { - val __ = C(arg1, arg2, 0) - System.out.println(__.foo(1) + __.foo(2) + other.foo(3) + C.staticFoo(4) + C.staticFoo(5)) - return __ -} - class C(private val arg1: Int, private val arg2: Int, private val arg3: Int) { fun foo(p: Int): Int { return p } + constructor(arg1: Int, arg2: Int, other: C) : this(arg1, arg2, 0) { + System.out.println(foo(1) + this.foo(2) + other.foo(3) + staticFoo(4) + C.staticFoo(5)) + } + default object { private fun staticFoo(p: Int): Int { return p diff --git a/j2k/testData/fileOrElement/constructors/noPrimary.kt b/j2k/testData/fileOrElement/constructors/noPrimary.kt index bcb1390a1d8..49561741adb 100644 --- a/j2k/testData/fileOrElement/constructors/noPrimary.kt +++ b/j2k/testData/fileOrElement/constructors/noPrimary.kt @@ -1,21 +1,16 @@ -fun C(arg1: Int, arg2: Int, arg3: Int): C { - return C() -} +class C { + constructor(arg1: Int, arg2: Int, arg3: Int) { + } -fun C(arg1: Int, arg2: Int): C { - val __ = C(arg1, arg2, 0) - System.out.println() - return __ -} + constructor(arg1: Int, arg2: Int) : this(arg1, arg2, 0) { + System.out.println() + } -fun C(arg: Int): C { - val __ = C() - System.out.println(arg) - return __ + constructor(arg: Int) { + System.out.println(arg) + } } -class C - public class User { default object { public fun main() { diff --git a/j2k/testData/fileOrElement/constructors/parameterDefaults1.kt b/j2k/testData/fileOrElement/constructors/parameterDefaults1.kt index 43adfc750b8..9bf9e6ab720 100644 --- a/j2k/testData/fileOrElement/constructors/parameterDefaults1.kt +++ b/j2k/testData/fileOrElement/constructors/parameterDefaults1.kt @@ -1,8 +1,7 @@ package pack +class C(a: Int = 0, b: Int = 0, c: Int = 0, d: Int = 0, e: Int = 0) { -fun C(a: Int): C { - return C(a, 0, 0, 0, 1) + constructor(a: Int) : this(a, 0, 0, 0, 1) { + } } - -class C(a: Int = 0, b: Int = 0, c: Int = 0, d: Int = 0, e: Int = 0) \ No newline at end of file diff --git a/j2k/testData/fileOrElement/constructors/parameterDefaults2.kt b/j2k/testData/fileOrElement/constructors/parameterDefaults2.kt index 2ac8dbb8768..e10eab09eb6 100644 --- a/j2k/testData/fileOrElement/constructors/parameterDefaults2.kt +++ b/j2k/testData/fileOrElement/constructors/parameterDefaults2.kt @@ -1,12 +1,10 @@ package pack +class C(a: Int = 0, b: Int = 0, c: Int = 0, d: Int = 0, e: Int = 0) { -fun C(a1: Int, b1: Int, c1: Int): C { - return C(a1, b1, c1, 0, 0) + constructor(a1: Int, b1: Int, c1: Int) : this(a1, b1, c1, 0, 0) { + } + + constructor(b: Byte) : this(b.toInt(), 0, 0, 0, 0) { + } } - -fun C(b: Byte): C { - return C(b.toInt(), 0, 0, 0, 0) -} - -class C(a: Int = 0, b: Int = 0, c: Int = 0, d: Int = 0, e: Int = 0) \ No newline at end of file diff --git a/j2k/testData/fileOrElement/constructors/parameterDefaults3.kt b/j2k/testData/fileOrElement/constructors/parameterDefaults3.kt index 182b4e5ca09..227426e9caf 100644 --- a/j2k/testData/fileOrElement/constructors/parameterDefaults3.kt +++ b/j2k/testData/fileOrElement/constructors/parameterDefaults3.kt @@ -1,8 +1,7 @@ package pack +class C(a: Int = 0, b: Int = 0, c: Int = 0, d: Int = 0, e: Int = 0) { -fun C(a: Int, b: Int, c: Int): C { - return C(b, a, c, 0, 0) + constructor(a: Int, b: Int, c: Int) : this(b, a, c, 0, 0) { + } } - -class C(a: Int = 0, b: Int = 0, c: Int = 0, d: Int = 0, e: Int = 0) \ No newline at end of file diff --git a/j2k/testData/fileOrElement/constructors/parameterModification.kt b/j2k/testData/fileOrElement/constructors/parameterModification.kt index d0757ca92c7..df35b9cff22 100644 --- a/j2k/testData/fileOrElement/constructors/parameterModification.kt +++ b/j2k/testData/fileOrElement/constructors/parameterModification.kt @@ -1,11 +1,4 @@ -// ERROR: Overload resolution ambiguity: internal fun C(arg1: kotlin.Int, arg2: kotlin.Int): C defined in root package public constructor C(arg1: kotlin.Int, arg2: kotlin.Int = ..., arg3: kotlin.Int = ...) defined in C -fun C(arg1: Int, arg2: Int): C { - var arg2 = arg2 - val __ = C(arg1, arg2, 0) - arg2++ - return __ -} - +// ERROR: Overload resolution ambiguity: public constructor C(arg1: kotlin.Int, arg2: kotlin.Int) defined in C public constructor C(arg1: kotlin.Int, arg2: kotlin.Int = ..., arg3: kotlin.Int = ...) defined in C class C(arg1: Int, arg2: Int = 0, arg3: Int = 0) { private val field: Int @@ -17,6 +10,11 @@ class C(arg1: Int, arg2: Int = 0, arg3: Int = 0) { field = arg3 arg3++ } + + constructor(arg1: Int, arg2: Int) : this(arg1, arg2, 0) { + var arg2 = arg2 + arg2++ + } } public class User { diff --git a/j2k/testData/fileOrElement/constructors/privateConstructors.kt b/j2k/testData/fileOrElement/constructors/privateConstructors.kt index 9b10324dc7c..744daa7200c 100644 --- a/j2k/testData/fileOrElement/constructors/privateConstructors.kt +++ b/j2k/testData/fileOrElement/constructors/privateConstructors.kt @@ -1,7 +1,5 @@ -// ERROR: Too many arguments for internal fun C(arg1: kotlin.Int): C defined in root package -// ERROR: Too many arguments for internal fun C(arg1: kotlin.Int): C defined in root package -fun C(arg1: Int): C { - return C(arg1, 0, 0) -} +class C private(arg1: Int, arg2: Int, arg3: Int = 0) { -class C private(arg1: Int, arg2: Int, arg3: Int = 0) + public constructor(arg1: Int) : this(arg1, 0, 0) { + } +} diff --git a/j2k/testData/fileOrElement/constructors/qualifiedRefInFactoryFun.kt b/j2k/testData/fileOrElement/constructors/qualifiedRefInFactoryFun.kt index 552f3312e42..4c1b685d01c 100644 --- a/j2k/testData/fileOrElement/constructors/qualifiedRefInFactoryFun.kt +++ b/j2k/testData/fileOrElement/constructors/qualifiedRefInFactoryFun.kt @@ -1,12 +1,9 @@ -// ERROR: Cannot access 'arg1': it is 'private' in 'C' -// ERROR: Cannot access 'arg2': it is 'private' in 'C' -fun C(arg1: Int, arg2: Int, other: C): C { - val __ = C(arg1, arg2, 0) - System.out.println(__.arg1 + other.arg2) - return __ -} +class C(private val arg1: Int, private val arg2: Int, private val arg3: Int) { -class C(private val arg1: Int, private val arg2: Int, private val arg3: Int) + constructor(arg1: Int, arg2: Int, other: C) : this(arg1, arg2, 0) { + System.out.println(this.arg1 + other.arg2) + } +} class User { fun foo() { diff --git a/j2k/testData/fileOrElement/constructors/secondaryConstructorsInInnerClass.kt b/j2k/testData/fileOrElement/constructors/secondaryConstructorsInInnerClass.kt index 4106348bbaa..3395ddc7e0d 100644 --- a/j2k/testData/fileOrElement/constructors/secondaryConstructorsInInnerClass.kt +++ b/j2k/testData/fileOrElement/constructors/secondaryConstructorsInInnerClass.kt @@ -1,68 +1,57 @@ class Outer { + private inner class Inner1() { - private fun Inner1(a: Int): Inner1 { - return Inner1() + public constructor(a: Int) : this() { + } + + protected constructor(c: Char) : this() { + } + + private constructor(b: Boolean) : this() { + } } - private fun Inner1(c: Char): Inner1 { - return Inner1() + protected inner class Inner2() { + + public constructor(a: Int) : this() { + } + + protected constructor(c: Char) : this() { + } + + private constructor(b: Boolean) : this() { + } + } - private fun Inner1(b: Boolean): Inner1 { - return Inner1() + inner class Inner3() { + + public constructor(a: Int) : this() { + } + + protected constructor(c: Char) : this() { + } + + private constructor(b: Boolean) : this() { + } } - private inner class Inner1 + public inner class Inner4() { + public constructor(a: Int) : this() { + } - protected fun Inner2(a: Int): Inner2 { - return Inner2() + protected constructor(c: Char) : this() { + } + + private constructor(b: Boolean) : this() { + } } - protected fun Inner2(c: Char): Inner2 { - return Inner2() - } - - private fun Inner2(b: Boolean): Inner2 { - return Inner2() - } - - protected inner class Inner2 - - - fun Inner3(a: Int): Inner3 { - return Inner3() - } - - fun Inner3(c: Char): Inner3 { - return Inner3() - } - - private fun Inner3(b: Boolean): Inner3 { - return Inner3() - } - - inner class Inner3 - - - public fun Inner4(a: Int): Inner4 { - return Inner4() - } - - public fun Inner4(c: Char): Inner4 { - return Inner4() - } - - private fun Inner4(b: Boolean): Inner4 { - return Inner4() - } - - public inner class Inner4 - fun foo() { val inner1 = Inner1(1) val inner2 = Inner2(2) val inner3 = Inner3(3) val inner4 = Inner4(4) } -} \ No newline at end of file +} diff --git a/j2k/testData/fileOrElement/constructors/secondaryConstructorsInNestedClass.kt b/j2k/testData/fileOrElement/constructors/secondaryConstructorsInNestedClass.kt index 2ef4182fb28..127bab99d3a 100644 --- a/j2k/testData/fileOrElement/constructors/secondaryConstructorsInNestedClass.kt +++ b/j2k/testData/fileOrElement/constructors/secondaryConstructorsInNestedClass.kt @@ -1,65 +1,55 @@ class Outer { + private class Nested1() { + + public constructor(a: Int) : this() { + } + + protected constructor(c: Char) : this() { + } + + private constructor(b: Boolean) : this() { + } + } + + protected class Nested2() { + + public constructor(a: Int) : this() { + } + + protected constructor(c: Char) : this() { + } + + private constructor(b: Boolean) : this() { + } + + } + + class Nested3() { + + public constructor(a: Int) : this() { + } + + protected constructor(c: Char) : this() { + } + + private constructor(b: Boolean) : this() { + } + } + + public class Nested4() { + + public constructor(a: Int) : this() { + } + + protected constructor(c: Char) : this() { + } + + private constructor(b: Boolean) : this() { + } + } + default object { - private fun Nested1(a: Int): Nested1 { - return Nested1() - } - - private fun Nested1(c: Char): Nested1 { - return Nested1() - } - - private fun Nested1(b: Boolean): Nested1 { - return Nested1() - } - - private class Nested1 - - - protected fun Nested2(a: Int): Nested2 { - return Nested2() - } - - protected fun Nested2(c: Char): Nested2 { - return Nested2() - } - - private fun Nested2(b: Boolean): Nested2 { - return Nested2() - } - - protected class Nested2 - - - fun Nested3(a: Int): Nested3 { - return Nested3() - } - - fun Nested3(c: Char): Nested3 { - return Nested3() - } - - private fun Nested3(b: Boolean): Nested3 { - return Nested3() - } - - class Nested3 - - - public fun Nested4(a: Int): Nested4 { - return Nested4() - } - - public fun Nested4(c: Char): Nested4 { - return Nested4() - } - - private fun Nested4(b: Boolean): Nested4 { - return Nested4() - } - - public class Nested4 - fun foo() { val nested1 = Nested1(1) val nested2 = Nested2(2) @@ -67,4 +57,4 @@ class Outer { val nested4 = Nested4(4) } } -} \ No newline at end of file +} diff --git a/j2k/testData/fileOrElement/constructors/secondaryConstructorsVisibility.kt b/j2k/testData/fileOrElement/constructors/secondaryConstructorsVisibility.kt index b9a8d39ad2f..496abbc0f4f 100644 --- a/j2k/testData/fileOrElement/constructors/secondaryConstructorsVisibility.kt +++ b/j2k/testData/fileOrElement/constructors/secondaryConstructorsVisibility.kt @@ -1,36 +1,29 @@ -fun A(a: Int): A { - return A() +class A() { + + public constructor(a: Int) : this() { + } + + protected constructor(c: Char) : this() { + } + + constructor(f: Float) : this() { + } + + private constructor(d: Double) : this() { + } } -fun A(c: Char): A { - return A() -} +public class B() { -fun A(f: Float): A { - return A() -} + public constructor(a: Int) : this() { + } -private fun A(d: Double): A { - return A() -} + protected constructor(c: Char) : this() { + } -class A + constructor(f: Float) : this() { + } - -public fun B(a: Int): B { - return B() -} - -public fun B(c: Char): B { - return B() -} - -fun B(f: Float): B { - return B() -} - -private fun B(d: Double): B { - return B() -} - -public class B \ No newline at end of file + private constructor(d: Double) : this() { + } +} \ No newline at end of file diff --git a/j2k/testData/fileOrElement/constructors/staticFieldRefInFactoryFun.kt b/j2k/testData/fileOrElement/constructors/staticFieldRefInFactoryFun.kt index 79b6cb788f5..ff3a82478e5 100644 --- a/j2k/testData/fileOrElement/constructors/staticFieldRefInFactoryFun.kt +++ b/j2k/testData/fileOrElement/constructors/staticFieldRefInFactoryFun.kt @@ -1,12 +1,9 @@ -// ERROR: Cannot access 'staticField1': it is 'private' in 'Default' -// ERROR: Cannot access 'staticField2': it is 'private' in 'Default' -fun C(p: Int): C { - val __ = C() - System.out.println(C.staticField1 + C.staticField2) - return __ -} +class C() { + + constructor(p: Int) : this() { + System.out.println(staticField1 + C.staticField2) + } -class C { default object { private val staticField1 = 0 private val staticField2 = 0 diff --git a/j2k/testData/fileOrElement/constructors/withManyDefaultParams.kt b/j2k/testData/fileOrElement/constructors/withManyDefaultParams.kt index 0c74666d742..894db5c466e 100644 --- a/j2k/testData/fileOrElement/constructors/withManyDefaultParams.kt +++ b/j2k/testData/fileOrElement/constructors/withManyDefaultParams.kt @@ -1,17 +1,6 @@ -// ERROR: 'public fun Test(name: kotlin.String): Test' is already defined in root package -// ERROR: 'public constructor Test(myName: kotlin.String)' is already defined in root package -// ERROR: None of the following functions can be called with the arguments supplied: public fun Test(): Test defined in root package public fun Test(name: kotlin.String): Test defined in root package public constructor Test(myName: kotlin.String) defined in Test -// ERROR: Overload resolution ambiguity: public fun Test(name: kotlin.String): Test defined in root package public constructor Test(myName: kotlin.String) defined in Test -// ERROR: Overload resolution ambiguity: public fun Test(name: kotlin.String): Test defined in root package public constructor Test(myName: kotlin.String) defined in Test -public fun Test(): Test { - return Test(null) -} - -public fun Test(name: String): Test { - return Test(Test.foo(name)) -} - -public class Test(private val myName: String) { +// ERROR: Property must be initialized or be abstract +public class Test { + private val myName: String var a: Boolean = false var b: Double = 0.toDouble() var c: Float = 0.toFloat() @@ -20,6 +9,13 @@ public class Test(private val myName: String) { protected var f: Short = 0 protected var g: Char = ' ' + public constructor() { + } + + public constructor(name: String) { + myName = foo(name) + } + default object { fun foo(n: String): String { diff --git a/j2k/testData/fileOrElement/dropAccessors/FieldUsagesInFactoryMethods.kt b/j2k/testData/fileOrElement/dropAccessors/FieldUsagesInFactoryMethods.kt index 01b45fb9412..a64fdbd8ac1 100644 --- a/j2k/testData/fileOrElement/dropAccessors/FieldUsagesInFactoryMethods.kt +++ b/j2k/testData/fileOrElement/dropAccessors/FieldUsagesInFactoryMethods.kt @@ -1,23 +1,19 @@ -fun C(arg1: Int, arg2: Int, arg3: Int): C { - val __ = C(arg1) - __.arg2 = arg2 - __.arg3 = arg3 - return __ -} - -fun C(arg1: Int, arg2: Int): C { - val __ = C(arg1) - __.arg2 = arg2 - __.arg3 = 0 - return __ -} - class C(val arg1: Int) { var arg2: Int = 0 var arg3: Int = 0 + constructor(arg1: Int, arg2: Int, arg3: Int) : this(arg1) { + this.arg2 = arg2 + this.arg3 = arg3 + } + + constructor(arg1: Int, arg2: Int) : this(arg1) { + this.arg2 = arg2 + arg3 = 0 + } + { arg2 = 0 arg3 = 0 } -} \ No newline at end of file +} diff --git a/j2k/testData/fileOrElement/issues/kt-638.kt b/j2k/testData/fileOrElement/issues/kt-638.kt index 2855bac6129..e23e1a6cbea 100644 --- a/j2k/testData/fileOrElement/issues/kt-638.kt +++ b/j2k/testData/fileOrElement/issues/kt-638.kt @@ -1,34 +1,30 @@ -// ERROR: 'public fun Identifier(name: T, isNullable: kotlin.Boolean): Identifier' is already defined in root package -// ERROR: 'public constructor Identifier(name: T, myHasDollar: kotlin.Boolean)' is already defined in root package -// ERROR: Cannot choose among the following candidates without completing type inference: public fun Identifier(name: T, isNullable: kotlin.Boolean): Identifier defined in root package public constructor Identifier(name: T, myHasDollar: kotlin.Boolean) defined in Identifier -// ERROR: Cannot choose among the following candidates without completing type inference: public fun Identifier(name: T, isNullable: kotlin.Boolean): Identifier defined in root package public constructor Identifier(name: T, myHasDollar: kotlin.Boolean) defined in Identifier -// ERROR: Cannot choose among the following candidates without completing type inference: public fun Identifier(name: T, isNullable: kotlin.Boolean): Identifier defined in root package public constructor Identifier(name: T, myHasDollar: kotlin.Boolean) defined in Identifier -// ERROR: Overload resolution ambiguity: public fun Identifier(name: kotlin.String, isNullable: kotlin.Boolean): Identifier defined in root package public constructor Identifier(name: kotlin.String, myHasDollar: kotlin.Boolean) defined in Identifier -public fun Identifier(name: T): Identifier { - return Identifier(name, false) -} - -public fun Identifier(name: T, isNullable: Boolean): Identifier { - val __ = Identifier(name, false) - __.myNullable = isNullable - return __ -} - -public fun Identifier(name: T, hasDollar: Boolean, isNullable: Boolean): Identifier { - val __ = Identifier(name, hasDollar) - __.myNullable = isNullable - return __ -} - -public class Identifier(public val name: T, private val myHasDollar: Boolean) { +// ERROR: Property must be initialized or be abstract +public class Identifier { + public val name: T + private val myHasDollar: Boolean private var myNullable = true + + public constructor(name: T) { + this.name = name + } + + public constructor(name: T, isNullable: Boolean) { + this.name = name + myNullable = isNullable + } + + public constructor(name: T, hasDollar: Boolean, isNullable: Boolean) { + this.name = name + myHasDollar = hasDollar + myNullable = isNullable + } } public class User { default object { public fun main(args: Array) { val i1 = Identifier("name", false, true) - val i2 = Identifier("name", false) + val i2 = Identifier("name", false) val i3 = Identifier("name") } }