diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiFactory.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiFactory.kt
index b6f3833a5e1..99b7fa37cb0 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiFactory.kt
+++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiFactory.kt
@@ -207,6 +207,10 @@ public class JetPsiFactory(private val project: Project) {
return createDeclaration(funDecl)
}
+ public fun createSecondaryConstructor(decl: String): JetSecondaryConstructor {
+ return createClass("class Foo {\n $decl \n}").getSecondaryConstructors().first()
+ }
+
public fun createModifierList(modifier: JetKeywordToken): JetModifierList {
return createModifierList(modifier.getValue())
}
diff --git a/idea/resources/fileTemplates/code/New Kotlin Secondary Constructor Body.kt.ft b/idea/resources/fileTemplates/code/New Kotlin Secondary Constructor Body.kt.ft
new file mode 100644
index 00000000000..488cc7226de
--- /dev/null
+++ b/idea/resources/fileTemplates/code/New Kotlin Secondary Constructor Body.kt.ft
@@ -0,0 +1 @@
+//To change body of created constructors use File | Settings | File Templates.
\ No newline at end of file
diff --git a/idea/resources/fileTemplates/code/New Kotlin Secondary Constructor Body.kt.html b/idea/resources/fileTemplates/code/New Kotlin Secondary Constructor Body.kt.html
new file mode 100644
index 00000000000..0c35380ba9d
--- /dev/null
+++ b/idea/resources/fileTemplates/code/New Kotlin Secondary Constructor Body.kt.html
@@ -0,0 +1,28 @@
+
+
+
+
+ This is a built-in template used for filling the body of a Kotlin secondary
+ constructor each time it is generated by the program, e.g. when using the Create secondary constructor from Usage intention action.
+ The template is editable. Along with Kotlin expressions and comments, you can also use the predefined variables
+ that will be then expanded into the corresponding values.
+ |
+
+
+
+
+ | Predefined variables will take the following values: |
+
+
+ | ${CLASS_NAME} |
+ |
+ qualified name of the class where function is created |
+
+
+ | ${SIMPLE_CLASS_NAME} |
+ |
+ non-qualified name of the class where function is implemented |
+
+
+
+
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/CallableBuilder.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/CallableBuilder.kt
index 773023a536d..8a82843ab51 100644
--- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/CallableBuilder.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/CallableBuilder.kt
@@ -16,73 +16,61 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder
+import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils
import com.intellij.codeInsight.navigation.NavigationUtil
import com.intellij.codeInsight.template.*
+import com.intellij.codeInsight.template.impl.TemplateImpl
+import com.intellij.codeInsight.template.impl.TemplateManagerImpl
import com.intellij.ide.fileTemplates.FileTemplate
import com.intellij.ide.fileTemplates.FileTemplateManager
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.Editor
+import com.intellij.openapi.editor.ScrollType
import com.intellij.openapi.fileEditor.FileEditorManager
+import com.intellij.openapi.fileEditor.OpenFileDescriptor
import com.intellij.openapi.progress.ProcessCanceledException
-import com.intellij.psi.PsiDocumentManager
+import com.intellij.openapi.ui.DialogWrapper
+import com.intellij.psi.*
+import com.intellij.psi.codeStyle.JavaCodeStyleManager
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.util.IncorrectOperationException
-import org.jetbrains.kotlin.descriptors.*
-import org.jetbrains.kotlin.psi.*
-import org.jetbrains.kotlin.resolve.BindingContext
-import org.jetbrains.kotlin.resolve.DescriptorUtils
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.resolve.scopes.JetScope
-import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
-import kotlin.properties.Delegates
-import java.util.LinkedHashSet
-import java.util.Collections
-import java.util.HashMap
-import java.util.ArrayList
-import java.util.Properties
-import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
-import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
-import com.intellij.psi.PsiWhiteSpace
-import com.intellij.psi.PsiElement
-import org.jetbrains.kotlin.lexer.JetTokens
-import org.jetbrains.kotlin.types.checker.JetTypeChecker
-import com.intellij.psi.SmartPointerManager
-import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
+import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
-import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
+import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
-import java.util.LinkedHashMap
-import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.ClassKind
-import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
-import com.intellij.openapi.editor.ScrollType
-import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
-import com.intellij.psi.PsiClass
-import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils
-import com.intellij.psi.PsiMethod
-import com.intellij.openapi.fileEditor.OpenFileDescriptor
-import com.intellij.psi.codeStyle.JavaCodeStyleManager
-import com.intellij.psi.PsiModifier
-import com.intellij.psi.PsiField
-import com.intellij.psi.PsiMember
+import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
import org.jetbrains.kotlin.idea.caches.resolve.getJavaClassDescriptor
-import org.jetbrains.kotlin.resolve.scopes.ChainedScope
-import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl
-import org.jetbrains.kotlin.resolve.scopes.RedeclarationHandler
-import org.jetbrains.kotlin.resolve.scopes.WritableScope
-import com.intellij.psi.PsiMethodCallExpression
-import com.intellij.psi.PsiExpressionStatement
+import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
+import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.ClassKind
import org.jetbrains.kotlin.idea.refactoring.*
import org.jetbrains.kotlin.idea.util.*
-import com.intellij.openapi.ui.*
-import com.intellij.codeInsight.template.impl.*
-import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
-import org.jetbrains.kotlin.idea.util.application.*
-import org.jetbrains.kotlin.psi.psiUtil.*
+import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
+import org.jetbrains.kotlin.idea.util.application.runWriteAction
+import org.jetbrains.kotlin.lexer.JetTokens
+import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.psiUtil.isAncestor
+import org.jetbrains.kotlin.psi.psiUtil.parents
+import org.jetbrains.kotlin.psi.psiUtil.siblings
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
+import org.jetbrains.kotlin.resolve.DescriptorUtils
+import org.jetbrains.kotlin.resolve.scopes.*
+import org.jetbrains.kotlin.types.JetType
+import org.jetbrains.kotlin.types.TypeProjectionImpl
+import org.jetbrains.kotlin.types.Variance
+import org.jetbrains.kotlin.types.checker.JetTypeChecker
+import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
+import java.util.*
+import kotlin.properties.Delegates
private val TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList"
private val TEMPLATE_FROM_USAGE_FUNCTION_BODY = "New Kotlin Function Body.kt"
+private val TEMPLATE_FROM_USAGE_SECONDARY_CONSTRUCTOR_BODY = "New Kotlin Secondary Constructor Body.kt"
private val ATTRIBUTE_FUNCTION_NAME = "FUNCTION_NAME"
/**
@@ -322,8 +310,9 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
skipReturnType = when (callableInfo.kind) {
CallableKind.FUNCTION ->
returnTypeCandidate?.theType?.isUnit() ?: false
- CallableKind.CONSTRUCTOR ->
+ CallableKind.CLASS_WITH_PRIMARY_CONSTRUCTOR ->
callableInfo.returnTypeInfo == TypeInfo.Empty || returnTypeCandidate?.theType?.isAny() ?: false
+ CallableKind.SECONDARY_CONSTRUCTOR -> true
CallableKind.PROPERTY -> containingElement is JetBlockExpression
}
@@ -437,7 +426,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
val ownerTypeString = if (isExtension) "${receiverTypeCandidate!!.renderedType!!}." else ""
- val classKind = (callableInfo as? ConstructorInfo)?.classInfo?.kind
+ val classKind = (callableInfo as? PrimaryConstructorInfo)?.classInfo?.kind
fun renderParamList(): String {
val prefix = if (classKind == ClassKind.ANNOTATION_CLASS) "val " else ""
@@ -446,7 +435,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
}
val paramList = when (callableInfo.kind) {
- CallableKind.FUNCTION, CallableKind.CONSTRUCTOR -> renderParamList()
+ CallableKind.FUNCTION, CallableKind.CLASS_WITH_PRIMARY_CONSTRUCTOR, CallableKind.SECONDARY_CONSTRUCTOR ->
+ renderParamList()
CallableKind.PROPERTY -> ""
}
val returnTypeString = if (skipReturnType || assignmentToReplace != null) "" else ": Any"
@@ -455,20 +445,27 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
val psiFactory = JetPsiFactory(currentFile)
val modifiers =
- if (containingElement is JetClassOrObject && containingElement.isAncestor(config.originalElement))
+ if (containingElement is JetClassOrObject
+ && containingElement.isAncestor(config.originalElement)
+ && callableInfo.kind != CallableKind.SECONDARY_CONSTRUCTOR)
"private "
else ""
val declaration : JetNamedDeclaration = when (callableInfo.kind) {
- CallableKind.FUNCTION -> {
+ CallableKind.FUNCTION, CallableKind.SECONDARY_CONSTRUCTOR -> {
val body = when {
containingElement is JetClass && containingElement.isTrait() && !config.isExtension -> ""
else -> "{}"
}
- psiFactory.createFunction("${modifiers}fun<> $header $body")
+ if (callableInfo.kind == CallableKind.FUNCTION) {
+ psiFactory.createFunction("${modifiers}fun<> $header $body")
+ }
+ else {
+ psiFactory.createSecondaryConstructor("${modifiers}constructor$paramList $body")
+ }
}
- CallableKind.CONSTRUCTOR -> {
- with((callableInfo as ConstructorInfo).classInfo) {
+ CallableKind.CLASS_WITH_PRIMARY_CONSTRUCTOR -> {
+ with((callableInfo as PrimaryConstructorInfo).classInfo) {
val classBody = when (kind) {
ClassKind.ANNOTATION_CLASS, ClassKind.ENUM_ENTRY -> ""
else -> "{\n\n}"
@@ -557,23 +554,19 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
containingElement is JetFile -> containingElement.add(declaration) as JetNamedDeclaration
- containingElement is PsiClass -> jetFileToEdit.add(declaration) as JetNamedDeclaration
+ containingElement is PsiClass -> {
+ if (declaration is JetSecondaryConstructor) {
+ val wrappingClass = psiFactory.createClass("class ${containingElement.getName()} {\n}")
+ addDeclarationToClassOrObject(wrappingClass, declaration, psiFactory)
+ (jetFileToEdit.add(wrappingClass) as JetClass).getDeclarations().first() as JetNamedDeclaration
+ }
+ else {
+ jetFileToEdit.add(declaration) as JetNamedDeclaration
+ }
+ }
containingElement is JetClassOrObject -> {
- var classBody = containingElement.getBody()
- if (classBody == null) {
- classBody = containingElement.add(psiFactory.createEmptyClassBody()) as JetClassBody
- containingElement.addBefore(psiFactory.createWhiteSpace(), classBody)
- }
-
- if (declaration is JetNamedFunction) {
- val anchor = PsiTreeUtil.skipSiblingsBackward(
- classBody!!.getRBrace() ?: classBody!!.getLastChild()!!,
- javaClass()
- )
- classBody.addAfter(declaration, anchor) as JetNamedDeclaration
- }
- else classBody.addAfter(declaration, classBody!!.getLBrace()!!) as JetNamedDeclaration
+ addDeclarationToClassOrObject(containingElement, declaration, psiFactory)
}
else -> throw AssertionError("Invalid containing element: ${containingElement.getText()}")
}
@@ -590,6 +583,25 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
}
}
+ private fun addDeclarationToClassOrObject(classOrObject: JetClassOrObject,
+ declaration: JetNamedDeclaration,
+ psiFactory: JetPsiFactory): JetNamedDeclaration {
+ var classBody = classOrObject.getBody()
+ if (classBody == null) {
+ classBody = classOrObject.add(psiFactory.createEmptyClassBody()) as JetClassBody
+ classOrObject.addBefore(psiFactory.createWhiteSpace(), classBody)
+ }
+
+ return if (declaration is JetNamedFunction) {
+ val anchor = PsiTreeUtil.skipSiblingsBackward(
+ classBody!!.getRBrace() ?: classBody!!.getLastChild()!!,
+ javaClass()
+ )
+ classBody.addAfter(declaration, anchor) as JetNamedDeclaration
+ }
+ else classBody.addAfter(declaration, classBody!!.getLBrace()!!) as JetNamedDeclaration
+ }
+
private fun getTypeParameterRenames(scope: JetScope): Map {
val allTypeParametersNotInScope = LinkedHashSet()
@@ -660,17 +672,24 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
return typeRefsToShorten
}
- private fun setupFunctionBody(func: JetNamedFunction) {
+ private fun setupFunctionBody(func: JetFunction) {
val oldBody = func.getBodyExpression() ?: return
- val fileTemplate = FileTemplateManager.getInstance()!!.getCodeTemplate(TEMPLATE_FROM_USAGE_FUNCTION_BODY)
+ val templateName = when (func) {
+ is JetSecondaryConstructor -> TEMPLATE_FROM_USAGE_SECONDARY_CONSTRUCTOR_BODY
+ is JetNamedFunction -> TEMPLATE_FROM_USAGE_FUNCTION_BODY
+ else -> throw AssertionError("Unexpected declaration: " + JetPsiUtil.getElementTextWithContext(func))
+ }
+ val fileTemplate = FileTemplateManager.getInstance()!!.getCodeTemplate(templateName)
val properties = Properties()
properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, if (skipReturnType) "Unit" else func.getTypeReference()!!.getText())
receiverClassDescriptor?.let {
properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, DescriptorUtils.getFqName(it).asString())
properties.setProperty(FileTemplate.ATTRIBUTE_SIMPLE_CLASS_NAME, it.getName().asString())
}
- properties.setProperty(ATTRIBUTE_FUNCTION_NAME, callableInfo.name)
+ if (callableInfo.name.isNotEmpty()) {
+ properties.setProperty(ATTRIBUTE_FUNCTION_NAME, callableInfo.name)
+ }
val bodyText = try {
fileTemplate!!.getText(properties)
@@ -766,7 +785,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
val expression = TypeParameterListExpression(
mandatoryTypeParameters,
typeParameterMap,
- callableInfo.kind != CallableKind.CONSTRUCTOR
+ callableInfo.kind != CallableKind.CLASS_WITH_PRIMARY_CONSTRUCTOR
)
builder.replaceElement(typeParameterList, expression, false)
return expression
@@ -831,8 +850,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
}
return when (adjustedDeclaration) {
- is JetNamedFunction -> {
- createJavaMethod(adjustedDeclaration, targetClass)
+ is JetNamedFunction, is JetSecondaryConstructor -> {
+ createJavaMethod(adjustedDeclaration as JetFunction, targetClass)
}
is JetProperty -> {
createJavaField(adjustedDeclaration, targetClass)
@@ -859,7 +878,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
}
val needStatic = when (callableInfo) {
- is ConstructorInfo -> with(callableInfo.classInfo) {
+ is PrimaryConstructorInfo -> with(callableInfo.classInfo) {
!inner && kind != ClassKind.ENUM_ENTRY && kind != ClassKind.ENUM_CLASS
}
else -> callableInfo.receiverTypeInfo.staticContextRequired
@@ -896,7 +915,12 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
val caretModel = containingFileEditor.getCaretModel()
val selectionModel = containingFileEditor.getSelectionModel()
- caretModel.moveToOffset(declaration.getNameIdentifier().getTextRange().getEndOffset())
+ if (declaration is JetSecondaryConstructor) {
+ caretModel.moveToOffset(declaration.getConstructorKeyword().getTextRange().getEndOffset())
+ }
+ else {
+ caretModel.moveToOffset(declaration.getNameIdentifier()!!.getTextRange().getEndOffset())
+ }
fun positionBetween(left: PsiElement, right: PsiElement) {
val from = left.siblings(withItself = false, forward = true).firstOrNull { it !is PsiWhiteSpace } ?: return
@@ -908,8 +932,10 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
}
when (declaration) {
- is JetNamedFunction -> {
- (declaration.getBodyExpression() as? JetBlockExpression)?.let { positionBetween(it.getLBrace(), it.getRBrace()) }
+ is JetNamedFunction, is JetSecondaryConstructor -> {
+ ((declaration as JetFunction).getBodyExpression() as? JetBlockExpression)?.let {
+ positionBetween(it.getLBrace(), it.getRBrace())
+ }
}
is JetClassOrObject -> {
caretModel.moveToOffset(declaration.getTextRange().getStartOffset())
@@ -995,8 +1021,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
runWriteAction {
// file templates
- if (newDeclaration is JetNamedFunction) {
- setupFunctionBody(newDeclaration)
+ if (newDeclaration is JetNamedFunction || newDeclaration is JetSecondaryConstructor) {
+ setupFunctionBody(newDeclaration as JetFunction)
}
val callElement = config.originalElement as? JetCallElement
diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/CallableInfo.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/CallableInfo.kt
index 9c79476b2a6..c457180069e 100644
--- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/CallableInfo.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/CallableInfo.kt
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder
+import com.intellij.psi.PsiElement
import java.util.Collections
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.types.Variance
@@ -119,7 +120,8 @@ class ParameterInfo(
enum class CallableKind {
FUNCTION
- CONSTRUCTOR
+ CLASS_WITH_PRIMARY_CONSTRUCTOR
+ SECONDARY_CONSTRUCTOR
PROPERTY
}
@@ -144,13 +146,20 @@ class FunctionInfo(name: String,
override val kind: CallableKind get() = CallableKind.FUNCTION
}
-class ConstructorInfo(val classInfo: ClassInfo, expectedTypeInfo: TypeInfo): CallableInfo(
+class PrimaryConstructorInfo(val classInfo: ClassInfo, expectedTypeInfo: TypeInfo): CallableInfo(
classInfo.name, TypeInfo.Empty, expectedTypeInfo.forceNotNull(), Collections.emptyList(), classInfo.typeArguments
) {
- override val kind: CallableKind get() = CallableKind.CONSTRUCTOR
+ override val kind: CallableKind get() = CallableKind.CLASS_WITH_PRIMARY_CONSTRUCTOR
override val parameterInfos: List get() = classInfo.parameterInfos
}
+class SecondaryConstructorInfo(
+ override val parameterInfos: List,
+ val targetClass: PsiElement
+): CallableInfo("", TypeInfo.Empty, TypeInfo.Empty, Collections.emptyList(), Collections.emptyList()) {
+ override val kind: CallableKind get() = CallableKind.SECONDARY_CONSTRUCTOR
+}
+
class PropertyInfo(name: String,
receiverTypeInfo: TypeInfo,
returnTypeInfo: TypeInfo,
diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromUsageFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromUsageFix.kt
index cb4e90f62fa..63fb1396bc0 100644
--- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromUsageFix.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromUsageFix.kt
@@ -16,25 +16,20 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
-import org.jetbrains.kotlin.idea.quickfix.createFromUsage.CreateFromUsageFixBase
-import org.jetbrains.kotlin.psi.JetFile
-import com.intellij.openapi.editor.Editor
-import org.jetbrains.kotlin.idea.JetBundle
-import com.intellij.openapi.project.Project
import com.intellij.openapi.command.CommandProcessor
-import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
-import org.jetbrains.kotlin.psi.JetClassOrObject
-import org.jetbrains.kotlin.idea.refactoring.chooseContainerElementIfNecessary
-import org.jetbrains.kotlin.psi.JetClassBody
-import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
-import org.jetbrains.kotlin.psi.JetExpression
-import java.util.HashSet
-import org.jetbrains.kotlin.psi.JetElement
+import com.intellij.openapi.editor.Editor
+import com.intellij.openapi.project.Project
import com.intellij.psi.PsiClass
-import java.util.Collections
-import org.jetbrains.kotlin.psi.JetPsiUtil
-import org.jetbrains.kotlin.idea.refactoring.canRefactor
import com.intellij.psi.PsiElement
+import org.jetbrains.kotlin.idea.JetBundle
+import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
+import org.jetbrains.kotlin.idea.quickfix.createFromUsage.CreateFromUsageFixBase
+import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
+import org.jetbrains.kotlin.idea.refactoring.canRefactor
+import org.jetbrains.kotlin.idea.refactoring.chooseContainerElementIfNecessary
+import org.jetbrains.kotlin.psi.*
+import java.util.Collections
+import java.util.HashSet
public class CreateCallableFromUsageFix(
originalExpression: JetExpression,
@@ -64,9 +59,10 @@ public class CreateCallableFromUsageFix(
val kind = when (it.kind) {
CallableKind.FUNCTION -> "function"
CallableKind.PROPERTY -> "property"
+ CallableKind.SECONDARY_CONSTRUCTOR -> "secondary constructor"
else -> throw AssertionError("Unexpected callable info: $it")
}
- "$kind '${it.name}'"
+ if (it.name.isNotEmpty()) "$kind '${it.name}'" else kind
}
return JetBundle.message(
"create.0.from.usage",
@@ -114,6 +110,11 @@ public class CreateCallableFromUsageFix(
CommandProcessor.getInstance().executeCommand(project, { callableBuilder.build() }, getText(), null)
}
+ if (callableInfo is SecondaryConstructorInfo) {
+ runBuilder(CallablePlacement.NoReceiver(callableInfo.targetClass))
+ return
+ }
+
val popupTitle = JetBundle.message("choose.target.class.or.trait.title")
val receiverTypeCandidates = callableBuilder.computeTypeCandidates(callableInfo.receiverTypeInfo)
if (receiverTypeCandidates.isNotEmpty()) {
diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromUsageFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromUsageFix.kt
index 728c4c34d49..3e2e7017310 100644
--- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromUsageFix.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromUsageFix.kt
@@ -26,14 +26,8 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiDirectory
import org.jetbrains.kotlin.idea.JetFileType
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
-import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
-import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.ParameterInfo
-import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.ConstructorInfo
-import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.CallableBuilderConfiguration
import java.util.Collections
-import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.createBuilder
import com.intellij.openapi.command.CommandProcessor
-import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.CallablePlacement
import org.jetbrains.kotlin.idea.refactoring.getOrCreateKotlinFile
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.ClassKind.*
import com.intellij.psi.PsiPackage
@@ -45,6 +39,7 @@ import org.jetbrains.kotlin.idea.refactoring.canRefactor
import com.intellij.psi.PsiMember
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiFile
+import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
enum class ClassKind(val keyword: String, val description: String) {
PLAIN_CLASS: ClassKind("class", "class")
@@ -124,7 +119,7 @@ public class CreateClassFromUsageFix(
else -> throw AssertionError("Unexpected element: " + targetParent.getText())
} ?: return
- val constructorInfo = ConstructorInfo(classInfo, expectedTypeInfo)
+ val constructorInfo = PrimaryConstructorInfo(classInfo, expectedTypeInfo)
val builder = CallableBuilderConfiguration(
Collections.singletonList(constructorInfo), element as JetElement, file, editor, false, kind == PLAIN_CLASS || kind == TRAIT
).createBuilder()
diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/jetRefactoringUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/jetRefactoringUtil.kt
index 3d19d88efc5..dfa3543cd1b 100644
--- a/idea/src/org/jetbrains/kotlin/idea/refactoring/jetRefactoringUtil.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/jetRefactoringUtil.kt
@@ -481,7 +481,7 @@ private fun copyTypeParameters(
}
}
-public fun createJavaMethod(function: JetNamedFunction, targetClass: PsiClass): PsiMethod {
+public fun createJavaMethod(function: JetFunction, targetClass: PsiClass): PsiMethod {
val template = LightClassUtil.getLightClassMethod(function)
?: throw AssertionError("Can't generate light method: ${JetPsiUtil.getElementTextWithContext(function)}")
return createJavaMethod(template, targetClass)