Refactoring
This commit is contained in:
+155
-152
@@ -78,9 +78,6 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
|||||||
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
|
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
import java.lang.AssertionError
|
|
||||||
import java.lang.IllegalArgumentException
|
|
||||||
import java.lang.IllegalStateException
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -96,7 +93,7 @@ class TypeCandidate(val theType: KotlinType, scope: HierarchicalScope? = null) {
|
|||||||
fun render(typeParameterNameMap: Map<TypeParameterDescriptor, String>, fakeFunction: FunctionDescriptor?) {
|
fun render(typeParameterNameMap: Map<TypeParameterDescriptor, String>, fakeFunction: FunctionDescriptor?) {
|
||||||
renderedTypes = theType.renderShort(typeParameterNameMap)
|
renderedTypes = theType.renderShort(typeParameterNameMap)
|
||||||
renderedTypeParameters = typeParameters.map {
|
renderedTypeParameters = typeParameters.map {
|
||||||
RenderedTypeParameter(it, it.containingDeclaration == fakeFunction, typeParameterNameMap[it]!!)
|
RenderedTypeParameter(it, it.containingDeclaration == fakeFunction, typeParameterNameMap.getValue(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,8 +102,7 @@ class TypeCandidate(val theType: KotlinType, scope: HierarchicalScope? = null) {
|
|||||||
if (scope == null) {
|
if (scope == null) {
|
||||||
typeParameters = typeParametersInType.toTypedArray()
|
typeParameters = typeParametersInType.toTypedArray()
|
||||||
renderedTypes = theType.renderShort(Collections.emptyMap())
|
renderedTypes = theType.renderShort(Collections.emptyMap())
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
typeParameters = getTypeParameterNamesNotInScope(typeParametersInType, scope).toTypedArray()
|
typeParameters = getTypeParameterNamesNotInScope(typeParametersInType, scope).toTypedArray()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,26 +111,26 @@ class TypeCandidate(val theType: KotlinType, scope: HierarchicalScope? = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
data class RenderedTypeParameter(
|
data class RenderedTypeParameter(
|
||||||
val typeParameter: TypeParameterDescriptor,
|
val typeParameter: TypeParameterDescriptor,
|
||||||
val fake: Boolean,
|
val fake: Boolean,
|
||||||
val text: String
|
val text: String
|
||||||
)
|
)
|
||||||
|
|
||||||
fun List<TypeCandidate>.getTypeByRenderedType(renderedTypes: List<String>): KotlinType? =
|
fun List<TypeCandidate>.getTypeByRenderedType(renderedTypes: List<String>): KotlinType? =
|
||||||
firstOrNull { it.renderedTypes == renderedTypes }?.theType
|
firstOrNull { it.renderedTypes == renderedTypes }?.theType
|
||||||
|
|
||||||
class CallableBuilderConfiguration(
|
class CallableBuilderConfiguration(
|
||||||
val callableInfos: List<CallableInfo>,
|
val callableInfos: List<CallableInfo>,
|
||||||
val originalElement: KtElement,
|
val originalElement: KtElement,
|
||||||
val currentFile: KtFile = originalElement.containingKtFile,
|
val currentFile: KtFile = originalElement.containingKtFile,
|
||||||
val currentEditor: Editor? = null,
|
val currentEditor: Editor? = null,
|
||||||
val isExtension: Boolean = false,
|
val isExtension: Boolean = false,
|
||||||
val enableSubstitutions: Boolean = true
|
val enableSubstitutions: Boolean = true
|
||||||
)
|
)
|
||||||
|
|
||||||
sealed class CallablePlacement {
|
sealed class CallablePlacement {
|
||||||
class WithReceiver(val receiverTypeCandidate: TypeCandidate): CallablePlacement()
|
class WithReceiver(val receiverTypeCandidate: TypeCandidate) : CallablePlacement()
|
||||||
class NoReceiver(val containingElement: PsiElement): CallablePlacement()
|
class NoReceiver(val containingElement: PsiElement) : CallablePlacement()
|
||||||
}
|
}
|
||||||
|
|
||||||
class CallableBuilder(val config: CallableBuilderConfiguration) {
|
class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||||
@@ -168,12 +164,13 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun computeTypeCandidates(typeInfo: TypeInfo): List<TypeCandidate> =
|
fun computeTypeCandidates(typeInfo: TypeInfo): List<TypeCandidate> =
|
||||||
typeCandidates.getOrPut(typeInfo) { typeInfo.getPossibleTypes(this).map { TypeCandidate(it) } }
|
typeCandidates.getOrPut(typeInfo) { typeInfo.getPossibleTypes(this).map { TypeCandidate(it) } }
|
||||||
|
|
||||||
private fun computeTypeCandidates(
|
private fun computeTypeCandidates(
|
||||||
typeInfo: TypeInfo,
|
typeInfo: TypeInfo,
|
||||||
substitutions: List<KotlinTypeSubstitution>,
|
substitutions: List<KotlinTypeSubstitution>,
|
||||||
scope: HierarchicalScope): List<TypeCandidate> {
|
scope: HierarchicalScope
|
||||||
|
): List<TypeCandidate> {
|
||||||
if (!typeInfo.substitutionsAllowed) return computeTypeCandidates(typeInfo)
|
if (!typeInfo.substitutionsAllowed) return computeTypeCandidates(typeInfo)
|
||||||
return typeCandidates.getOrPut(typeInfo) {
|
return typeCandidates.getOrPut(typeInfo) {
|
||||||
val types = typeInfo.getPossibleTypes(this).asReversed()
|
val types = typeInfo.getPossibleTypes(this).asReversed()
|
||||||
@@ -181,7 +178,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
// We have to use semantic equality here
|
// We have to use semantic equality here
|
||||||
data class EqWrapper(val _type: KotlinType) {
|
data class EqWrapper(val _type: KotlinType) {
|
||||||
override fun equals(other: Any?) = this === other
|
override fun equals(other: Any?) = this === other
|
||||||
|| other is EqWrapper && KotlinTypeChecker.DEFAULT.equalTypes(_type, other._type)
|
|| other is EqWrapper && KotlinTypeChecker.DEFAULT.equalTypes(_type, other._type)
|
||||||
|
|
||||||
override fun hashCode() = 0 // no good way to compute hashCode() that would agree with our equals()
|
override fun hashCode() = 0 // no good way to compute hashCode() that would agree with our equals()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,8 +207,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
val context = Context(iterator.next())
|
val context = Context(iterator.next())
|
||||||
runWriteAction { context.buildAndRunTemplate { buildNext(iterator) } }
|
runWriteAction { context.buildAndRunTemplate { buildNext(iterator) } }
|
||||||
ApplicationManager.getApplication().invokeLater { context.showDialogIfNeeded() }
|
ApplicationManager.getApplication().invokeLater { context.showDialogIfNeeded() }
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
runWriteAction { ShortenReferences.DEFAULT.process(elementsToShorten) }
|
runWriteAction { ShortenReferences.DEFAULT.process(elementsToShorten) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,8 +217,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
assert(config.currentEditor != null) { "Can't run build() without editor" }
|
assert(config.currentEditor != null) { "Can't run build() without editor" }
|
||||||
if (finished) throw IllegalStateException("Current builder has already finished")
|
if (finished) throw IllegalStateException("Current builder has already finished")
|
||||||
buildNext(config.callableInfos.iterator())
|
buildNext(config.callableInfos.iterator())
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
finished = true
|
finished = true
|
||||||
onFinish()
|
onFinish()
|
||||||
}
|
}
|
||||||
@@ -248,7 +244,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
when (placement) {
|
when (placement) {
|
||||||
is CallablePlacement.NoReceiver -> {
|
is CallablePlacement.NoReceiver -> {
|
||||||
containingElement = placement.containingElement
|
containingElement = placement.containingElement
|
||||||
receiverClassDescriptor = with (placement.containingElement) {
|
receiverClassDescriptor = with(placement.containingElement) {
|
||||||
when (this) {
|
when (this) {
|
||||||
is KtClassOrObject -> currentFileContext[BindingContext.CLASS, this]
|
is KtClassOrObject -> currentFileContext[BindingContext.CLASS, this]
|
||||||
is PsiClass -> getJavaClassDescriptor()
|
is PsiClass -> getJavaClassDescriptor()
|
||||||
@@ -279,13 +275,12 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
jetFileToEdit = containingElement.containingKtFile
|
jetFileToEdit = containingElement.containingKtFile
|
||||||
containingFileEditor = if (jetFileToEdit != config.currentFile) {
|
containingFileEditor = if (jetFileToEdit != config.currentFile) {
|
||||||
FileEditorManager.getInstance(project).selectedTextEditor!!
|
FileEditorManager.getInstance(project).selectedTextEditor!!
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
config.currentEditor!!
|
config.currentEditor!!
|
||||||
}
|
}
|
||||||
null
|
null
|
||||||
} else {
|
} else {
|
||||||
val dialog = object: DialogWithEditor(project, "Create from usage", "") {
|
val dialog = object : DialogWithEditor(project, "Create from usage", "") {
|
||||||
override fun doOKAction() {
|
override fun doOKAction() {
|
||||||
project.executeWriteCommand("Premature end of template") {
|
project.executeWriteCommand("Premature end of template") {
|
||||||
TemplateManagerImpl.getTemplateState(editor)?.gotoEnd(false)
|
TemplateManagerImpl.getTemplateState(editor)?.gotoEnd(false)
|
||||||
@@ -313,17 +308,18 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
if (config.enableSubstitutions) {
|
if (config.enableSubstitutions) {
|
||||||
collectSubstitutionsForReceiverTypeParameters(receiverType, substitutionMap)
|
collectSubstitutionsForReceiverTypeParameters(receiverType, substitutionMap)
|
||||||
val typeArgumentsForFakeFunction = callableInfo.typeParameterInfos
|
val typeArgumentsForFakeFunction = callableInfo.typeParameterInfos
|
||||||
.map {
|
.map {
|
||||||
val typeCandidates = computeTypeCandidates(it)
|
val typeCandidates = computeTypeCandidates(it)
|
||||||
assert (typeCandidates.size == 1) { "Ambiguous type candidates for type parameter $it: $typeCandidates" }
|
assert(typeCandidates.size == 1) { "Ambiguous type candidates for type parameter $it: $typeCandidates" }
|
||||||
typeCandidates.first().theType
|
typeCandidates.first().theType
|
||||||
}
|
}
|
||||||
.subtract(substitutionMap.keys)
|
.subtract(substitutionMap.keys)
|
||||||
fakeFunction = createFakeFunctionDescriptor(scope, typeArgumentsForFakeFunction.size)
|
fakeFunction = createFakeFunctionDescriptor(scope, typeArgumentsForFakeFunction.size)
|
||||||
collectSubstitutionsForCallableTypeParameters(fakeFunction, typeArgumentsForFakeFunction, substitutionMap)
|
collectSubstitutionsForCallableTypeParameters(fakeFunction, typeArgumentsForFakeFunction, substitutionMap)
|
||||||
mandatoryTypeParametersAsCandidates = listOfNotNull(receiverTypeCandidate) + typeArgumentsForFakeFunction.map { TypeCandidate(substitutionMap[it]!!, scope) }
|
mandatoryTypeParametersAsCandidates = listOfNotNull(receiverTypeCandidate) + typeArgumentsForFakeFunction.map {
|
||||||
}
|
TypeCandidate(substitutionMap[it]!!, scope)
|
||||||
else {
|
}
|
||||||
|
} else {
|
||||||
fakeFunction = null
|
fakeFunction = null
|
||||||
mandatoryTypeParametersAsCandidates = Collections.emptyList()
|
mandatoryTypeParametersAsCandidates = Collections.emptyList()
|
||||||
}
|
}
|
||||||
@@ -362,35 +358,38 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
return receiverClassDescriptor.scopeForMemberDeclarationResolution
|
return receiverClassDescriptor.scopeForMemberDeclarationResolution
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (receiverClassDescriptor is JavaClassDescriptor) { "Unexpected receiver class: $receiverClassDescriptor" }
|
assert(receiverClassDescriptor is JavaClassDescriptor) { "Unexpected receiver class: $receiverClassDescriptor" }
|
||||||
|
|
||||||
val projections = ((receiverClassDescriptor as JavaClassDescriptor).declaredTypeParameters)
|
val projections = ((receiverClassDescriptor as JavaClassDescriptor).declaredTypeParameters)
|
||||||
.map { TypeProjectionImpl(it.defaultType) }
|
.map { TypeProjectionImpl(it.defaultType) }
|
||||||
val memberScope = receiverClassDescriptor.getMemberScope(projections)
|
val memberScope = receiverClassDescriptor.getMemberScope(projections)
|
||||||
|
|
||||||
return LexicalScopeImpl(memberScope.memberScopeAsImportingScope(), receiverClassDescriptor, false, null,
|
return LexicalScopeImpl(
|
||||||
LexicalScopeKind.SYNTHETIC) {
|
memberScope.memberScopeAsImportingScope(), receiverClassDescriptor, false, null,
|
||||||
|
LexicalScopeKind.SYNTHETIC
|
||||||
|
) {
|
||||||
receiverClassDescriptor.typeConstructor.parameters.forEach { addClassifierDescriptor(it) }
|
receiverClassDescriptor.typeConstructor.parameters.forEach { addClassifierDescriptor(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectSubstitutionsForReceiverTypeParameters(
|
private fun collectSubstitutionsForReceiverTypeParameters(
|
||||||
receiverType: KotlinType?,
|
receiverType: KotlinType?,
|
||||||
result: MutableMap<KotlinType, KotlinType>
|
result: MutableMap<KotlinType, KotlinType>
|
||||||
) {
|
) {
|
||||||
if (placement is CallablePlacement.NoReceiver) return
|
if (placement is CallablePlacement.NoReceiver) return
|
||||||
|
|
||||||
val classTypeParameters = receiverType?.arguments ?: Collections.emptyList()
|
val classTypeParameters = receiverType?.arguments ?: Collections.emptyList()
|
||||||
val ownerTypeArguments = (placement as? CallablePlacement.WithReceiver)?.receiverTypeCandidate?.theType?.arguments
|
val ownerTypeArguments = (placement as? CallablePlacement.WithReceiver)?.receiverTypeCandidate?.theType?.arguments
|
||||||
?: Collections.emptyList()
|
?: Collections.emptyList()
|
||||||
assert(ownerTypeArguments.size == classTypeParameters.size)
|
assert(ownerTypeArguments.size == classTypeParameters.size)
|
||||||
ownerTypeArguments.zip(classTypeParameters).forEach { result[it.first.type] = it.second.type }
|
ownerTypeArguments.zip(classTypeParameters).forEach { result[it.first.type] = it.second.type }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectSubstitutionsForCallableTypeParameters(
|
private fun collectSubstitutionsForCallableTypeParameters(
|
||||||
fakeFunction: FunctionDescriptor,
|
fakeFunction: FunctionDescriptor,
|
||||||
typeArguments: Set<KotlinType>,
|
typeArguments: Set<KotlinType>,
|
||||||
result: MutableMap<KotlinType, KotlinType>) {
|
result: MutableMap<KotlinType, KotlinType>
|
||||||
|
) {
|
||||||
for ((typeArgument, typeParameter) in typeArguments.zip(fakeFunction.typeParameters)) {
|
for ((typeArgument, typeParameter) in typeArguments.zip(fakeFunction.typeParameters)) {
|
||||||
result[typeArgument] = typeParameter.defaultType
|
result[typeArgument] = typeParameter.defaultType
|
||||||
}
|
}
|
||||||
@@ -398,34 +397,36 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
|
|
||||||
private fun createFakeFunctionDescriptor(scope: HierarchicalScope, typeParameterCount: Int): FunctionDescriptor {
|
private fun createFakeFunctionDescriptor(scope: HierarchicalScope, typeParameterCount: Int): FunctionDescriptor {
|
||||||
val fakeFunction = SimpleFunctionDescriptorImpl.create(
|
val fakeFunction = SimpleFunctionDescriptorImpl.create(
|
||||||
MutablePackageFragmentDescriptor(currentFileModule, FqName("fake")),
|
MutablePackageFragmentDescriptor(currentFileModule, FqName("fake")),
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
Name.identifier("fake"),
|
Name.identifier("fake"),
|
||||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||||
SourceElement.NO_SOURCE
|
SourceElement.NO_SOURCE
|
||||||
)
|
)
|
||||||
|
|
||||||
val validator = CollectingNameValidator { scope.findClassifier(Name.identifier(it), NoLookupLocation.FROM_IDE) == null }
|
val validator = CollectingNameValidator { scope.findClassifier(Name.identifier(it), NoLookupLocation.FROM_IDE) == null }
|
||||||
val parameterNames = KotlinNameSuggester.suggestNamesForTypeParameters(typeParameterCount, validator)
|
val parameterNames = KotlinNameSuggester.suggestNamesForTypeParameters(typeParameterCount, validator)
|
||||||
val typeParameters = (0..typeParameterCount - 1).map {
|
val typeParameters = (0 until typeParameterCount).map {
|
||||||
TypeParameterDescriptorImpl.createWithDefaultBound(
|
TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||||
fakeFunction,
|
fakeFunction,
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
false,
|
false,
|
||||||
Variance.INVARIANT,
|
Variance.INVARIANT,
|
||||||
Name.identifier(parameterNames[it]),
|
Name.identifier(parameterNames[it]),
|
||||||
it
|
it
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fakeFunction.initialize(null, null, typeParameters, Collections.emptyList(), null,
|
return fakeFunction.initialize(
|
||||||
null, Visibilities.INTERNAL)
|
null, null, typeParameters, Collections.emptyList(), null,
|
||||||
|
null, Visibilities.INTERNAL
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderTypeCandidates(
|
private fun renderTypeCandidates(
|
||||||
typeInfo: TypeInfo,
|
typeInfo: TypeInfo,
|
||||||
typeParameterNameMap: Map<TypeParameterDescriptor, String>,
|
typeParameterNameMap: Map<TypeParameterDescriptor, String>,
|
||||||
fakeFunction: FunctionDescriptor?
|
fakeFunction: FunctionDescriptor?
|
||||||
) {
|
) {
|
||||||
typeCandidates[typeInfo]?.forEach { it.render(typeParameterNameMap, fakeFunction) }
|
typeCandidates[typeInfo]?.forEach { it.render(typeParameterNameMap, fakeFunction) }
|
||||||
}
|
}
|
||||||
@@ -436,12 +437,11 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createDeclarationSkeleton(): KtNamedDeclaration {
|
private fun createDeclarationSkeleton(): KtNamedDeclaration {
|
||||||
with (config) {
|
with(config) {
|
||||||
val assignmentToReplace =
|
val assignmentToReplace =
|
||||||
if (containingElement is KtBlockExpression && (callableInfo as? PropertyInfo)?.writable ?: false) {
|
if (containingElement is KtBlockExpression && (callableInfo as? PropertyInfo)?.writable == true) {
|
||||||
originalElement as KtBinaryExpression
|
originalElement as KtBinaryExpression
|
||||||
}
|
} else null
|
||||||
else null
|
|
||||||
|
|
||||||
val ownerTypeString = if (isExtension) {
|
val ownerTypeString = if (isExtension) {
|
||||||
val renderedType = receiverTypeCandidate!!.renderedTypes.first()
|
val renderedType = receiverTypeCandidate!!.renderedTypes.first()
|
||||||
@@ -455,8 +455,9 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
val prefix = if (classKind == ClassKind.ANNOTATION_CLASS) "val " else ""
|
val prefix = if (classKind == ClassKind.ANNOTATION_CLASS) "val " else ""
|
||||||
val list = callableInfo.parameterInfos.indices.joinToString(", ") { i -> "${prefix}p$i: Any" }
|
val list = callableInfo.parameterInfos.indices.joinToString(", ") { i -> "${prefix}p$i: Any" }
|
||||||
return if (callableInfo.parameterInfos.isNotEmpty()
|
return if (callableInfo.parameterInfos.isNotEmpty()
|
||||||
|| callableInfo.kind == CallableKind.FUNCTION
|
|| callableInfo.kind == CallableKind.FUNCTION
|
||||||
|| callableInfo.kind == CallableKind.CONSTRUCTOR) "($list)" else list
|
|| callableInfo.kind == CallableKind.CONSTRUCTOR
|
||||||
|
) "($list)" else list
|
||||||
}
|
}
|
||||||
|
|
||||||
val paramList = when (callableInfo.kind) {
|
val paramList = when (callableInfo.kind) {
|
||||||
@@ -474,13 +475,14 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
val visibilityKeyword = modifierList.visibilityModifierType()
|
val visibilityKeyword = modifierList.visibilityModifierType()
|
||||||
if (visibilityKeyword == null) {
|
if (visibilityKeyword == null) {
|
||||||
val defaultVisibility =
|
val defaultVisibility =
|
||||||
if (callableInfo.isAbstract) ""
|
if (callableInfo.isAbstract) ""
|
||||||
else if (containingElement is KtClassOrObject
|
else if (containingElement is KtClassOrObject
|
||||||
&& !(containingElement is KtClass && containingElement.isInterface())
|
&& !(containingElement is KtClass && containingElement.isInterface())
|
||||||
&& containingElement.isAncestor(config.originalElement)
|
&& containingElement.isAncestor(config.originalElement)
|
||||||
&& callableInfo.kind != CallableKind.CONSTRUCTOR) "private "
|
&& callableInfo.kind != CallableKind.CONSTRUCTOR
|
||||||
else if (isExtension) "private "
|
) "private "
|
||||||
else ""
|
else if (isExtension) "private "
|
||||||
|
else ""
|
||||||
append(defaultVisibility)
|
append(defaultVisibility)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,7 +490,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
if (callableInfo.isAbstract
|
if (callableInfo.isAbstract
|
||||||
&& containingElement is KtClass
|
&& containingElement is KtClass
|
||||||
&& !containingElement.isInterface()
|
&& !containingElement.isInterface()
|
||||||
&& !modifierList.hasModifier(KtTokens.ABSTRACT_KEYWORD)) {
|
&& !modifierList.hasModifier(KtTokens.ABSTRACT_KEYWORD)
|
||||||
|
) {
|
||||||
modifierList.appendModifier(KtTokens.ABSTRACT_KEYWORD)
|
modifierList.appendModifier(KtTokens.ABSTRACT_KEYWORD)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,22 +513,20 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
containingElement is KtClass && containingElement.hasModifier(KtTokens.EXTERNAL_KEYWORD) -> ""
|
containingElement is KtClass && containingElement.hasModifier(KtTokens.EXTERNAL_KEYWORD) -> ""
|
||||||
containingElement is KtObjectDeclaration && containingElement.hasModifier(KtTokens.EXTERNAL_KEYWORD) -> ""
|
containingElement is KtObjectDeclaration && containingElement.hasModifier(KtTokens.EXTERNAL_KEYWORD) -> ""
|
||||||
containingElement is KtObjectDeclaration && containingElement.isCompanion()
|
containingElement is KtObjectDeclaration && containingElement.isCompanion()
|
||||||
&& containingElement.parent.parent is KtClass
|
&& containingElement.parent.parent is KtClass
|
||||||
&& (containingElement.parent.parent as KtClass).hasModifier(KtTokens.EXTERNAL_KEYWORD) -> ""
|
&& (containingElement.parent.parent as KtClass).hasModifier(KtTokens.EXTERNAL_KEYWORD) -> ""
|
||||||
isExpectClassMember -> ""
|
isExpectClassMember -> ""
|
||||||
else -> "{\n\n}"
|
else -> "{\n\n}"
|
||||||
|
|
||||||
}
|
}
|
||||||
@Suppress("USELESS_CAST") // KT-10755
|
@Suppress("USELESS_CAST") // KT-10755
|
||||||
if (callableInfo is FunctionInfo) {
|
when {
|
||||||
psiFactory.createFunction("${modifiers}fun<> $header $body") as KtNamedDeclaration
|
callableInfo is FunctionInfo -> psiFactory.createFunction("${modifiers}fun<> $header $body") as KtNamedDeclaration
|
||||||
}
|
(callableInfo as ConstructorInfo).isPrimary -> {
|
||||||
else if ((callableInfo as ConstructorInfo).isPrimary) {
|
val constructorText = if (modifiers.isNotEmpty()) "${modifiers}constructor$paramList" else paramList
|
||||||
val constructorText = if (modifiers.isNotEmpty()) "${modifiers}constructor$paramList" else paramList
|
psiFactory.createPrimaryConstructor(constructorText) as KtNamedDeclaration
|
||||||
psiFactory.createPrimaryConstructor(constructorText) as KtNamedDeclaration
|
}
|
||||||
}
|
else -> psiFactory.createSecondaryConstructor("${modifiers}constructor$paramList $body") as KtNamedDeclaration
|
||||||
else {
|
|
||||||
psiFactory.createSecondaryConstructor("${modifiers}constructor$paramList $body") as KtNamedDeclaration
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CallableKind.CLASS_WITH_PRIMARY_CONSTRUCTOR -> {
|
CallableKind.CLASS_WITH_PRIMARY_CONSTRUCTOR -> {
|
||||||
@@ -550,7 +551,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
psiFactory.createDeclaration<KtClassOrObject>(
|
psiFactory.createDeclaration<KtClassOrObject>(
|
||||||
"$openMod$innerMod${kind.keyword} $safeName$typeParamList$paramList$returnTypeString $classBody"
|
"$openMod$innerMod${kind.keyword} $safeName$typeParamList$paramList$returnTypeString $classBody"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -566,8 +567,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
append("\nset() {}")
|
append("\nset() {}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else ""
|
||||||
else ""
|
|
||||||
psiFactory.createProperty("$modifiers$valVar<> $header$accessors")
|
psiFactory.createProperty("$modifiers$valVar<> $header$accessors")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -579,16 +579,14 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
|
|
||||||
val container = if (containingElement is KtClass && callableInfo.isForCompanion) {
|
val container = if (containingElement is KtClass && callableInfo.isForCompanion) {
|
||||||
containingElement.getOrCreateCompanionObject()
|
containingElement.getOrCreateCompanionObject()
|
||||||
}
|
} else containingElement
|
||||||
else containingElement
|
|
||||||
val declarationInPlace = placeDeclarationInContainer(declaration, container, config.originalElement, jetFileToEdit)
|
val declarationInPlace = placeDeclarationInContainer(declaration, container, config.originalElement, jetFileToEdit)
|
||||||
|
|
||||||
if (declarationInPlace is KtSecondaryConstructor) {
|
if (declarationInPlace is KtSecondaryConstructor) {
|
||||||
val containingClass = declarationInPlace.containingClassOrObject!!
|
val containingClass = declarationInPlace.containingClassOrObject!!
|
||||||
if (containingClass.primaryConstructorParameters.isNotEmpty()) {
|
if (containingClass.primaryConstructorParameters.isNotEmpty()) {
|
||||||
declarationInPlace.replaceImplicitDelegationCallWithExplicit(true)
|
declarationInPlace.replaceImplicitDelegationCallWithExplicit(true)
|
||||||
}
|
} else if ((receiverClassDescriptor as ClassDescriptor).getSuperClassOrAny().constructors.all { it.valueParameters.isNotEmpty() }) {
|
||||||
else if ((receiverClassDescriptor as ClassDescriptor).getSuperClassOrAny().constructors.all { it.valueParameters.isNotEmpty() }) {
|
|
||||||
declarationInPlace.replaceImplicitDelegationCallWithExplicit(false)
|
declarationInPlace.replaceImplicitDelegationCallWithExplicit(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -601,9 +599,9 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
val allTypeParametersNotInScope = LinkedHashSet<TypeParameterDescriptor>()
|
val allTypeParametersNotInScope = LinkedHashSet<TypeParameterDescriptor>()
|
||||||
|
|
||||||
mandatoryTypeParametersAsCandidates.asSequence()
|
mandatoryTypeParametersAsCandidates.asSequence()
|
||||||
.plus(callableInfo.parameterInfos.asSequence().flatMap { typeCandidates[it.typeInfo]!!.asSequence() })
|
.plus(callableInfo.parameterInfos.asSequence().flatMap { typeCandidates[it.typeInfo]!!.asSequence() })
|
||||||
.flatMap { it.typeParameters.asSequence() }
|
.flatMap { it.typeParameters.asSequence() }
|
||||||
.toCollection(allTypeParametersNotInScope)
|
.toCollection(allTypeParametersNotInScope)
|
||||||
|
|
||||||
if (!skipReturnType) {
|
if (!skipReturnType) {
|
||||||
computeTypeCandidates(callableInfo.returnTypeInfo).asSequence().flatMapTo(allTypeParametersNotInScope) {
|
computeTypeCandidates(callableInfo.returnTypeInfo).asSequence().flatMapTo(allTypeParametersNotInScope) {
|
||||||
@@ -612,13 +610,17 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val validator = CollectingNameValidator { scope.findClassifier(Name.identifier(it), NoLookupLocation.FROM_IDE) == null }
|
val validator = CollectingNameValidator { scope.findClassifier(Name.identifier(it), NoLookupLocation.FROM_IDE) == null }
|
||||||
val typeParameterNames = allTypeParametersNotInScope.map { KotlinNameSuggester.suggestNameByName(it.name.asString(), validator) }
|
val typeParameterNames = allTypeParametersNotInScope.map {
|
||||||
|
KotlinNameSuggester.suggestNameByName(it.name.asString(), validator)
|
||||||
|
}
|
||||||
|
|
||||||
return allTypeParametersNotInScope.zip(typeParameterNames).toMap()
|
return allTypeParametersNotInScope.zip(typeParameterNames).toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupTypeReferencesForShortening(declaration: KtNamedDeclaration,
|
private fun setupTypeReferencesForShortening(
|
||||||
parameterTypeExpressions: List<TypeExpression>) {
|
declaration: KtNamedDeclaration,
|
||||||
|
parameterTypeExpressions: List<TypeExpression>
|
||||||
|
) {
|
||||||
if (config.isExtension) {
|
if (config.isExtension) {
|
||||||
val receiverTypeText = receiverTypeCandidate!!.theType.renderLong(typeParameterNameMap).first()
|
val receiverTypeText = receiverTypeCandidate!!.theType.renderLong(typeParameterNameMap).first()
|
||||||
val replacingTypeRef = KtPsiFactory(declaration).createType(receiverTypeText)
|
val replacingTypeRef = KtPsiFactory(declaration).createType(receiverTypeText)
|
||||||
@@ -628,7 +630,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
val returnTypeRefs = declaration.getReturnTypeReferences()
|
val returnTypeRefs = declaration.getReturnTypeReferences()
|
||||||
if (returnTypeRefs.isNotEmpty()) {
|
if (returnTypeRefs.isNotEmpty()) {
|
||||||
val returnType = typeCandidates[callableInfo.returnTypeInfo]!!.getTypeByRenderedType(
|
val returnType = typeCandidates[callableInfo.returnTypeInfo]!!.getTypeByRenderedType(
|
||||||
returnTypeRefs.map { it.text }
|
returnTypeRefs.map { it.text }
|
||||||
)
|
)
|
||||||
if (returnType != null) {
|
if (returnType != null) {
|
||||||
// user selected a given type
|
// user selected a given type
|
||||||
@@ -643,7 +645,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
val parameterTypeRef = parameter.typeReference
|
val parameterTypeRef = parameter.typeReference
|
||||||
if (parameterTypeRef != null) {
|
if (parameterTypeRef != null) {
|
||||||
val parameterType = parameterTypeExpressions[i].typeCandidates.getTypeByRenderedType(
|
val parameterType = parameterTypeExpressions[i].typeCandidates.getTypeByRenderedType(
|
||||||
listOf(parameterTypeRef.text)
|
listOf(parameterTypeRef.text)
|
||||||
)
|
)
|
||||||
if (parameterType != null) {
|
if (parameterType != null) {
|
||||||
replaceWithLongerName(listOf(parameterTypeRef), parameterType)
|
replaceWithLongerName(listOf(parameterTypeRef), parameterType)
|
||||||
@@ -675,11 +677,11 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
if (skipReturnType && callableInfo is FunctionInfo && callableInfo.preferEmptyBody) return
|
if (skipReturnType && callableInfo is FunctionInfo && callableInfo.preferEmptyBody) return
|
||||||
val oldBody = func.bodyExpression ?: return
|
val oldBody = func.bodyExpression ?: return
|
||||||
val bodyText = getFunctionBodyTextFromTemplate(
|
val bodyText = getFunctionBodyTextFromTemplate(
|
||||||
func.project,
|
func.project,
|
||||||
TemplateKind.FUNCTION,
|
TemplateKind.FUNCTION,
|
||||||
if (callableInfo.name.isNotEmpty()) callableInfo.name else null,
|
if (callableInfo.name.isNotEmpty()) callableInfo.name else null,
|
||||||
if (skipReturnType) "Unit" else (func as? KtFunction)?.typeReference?.text ?: "",
|
if (skipReturnType) "Unit" else (func as? KtFunction)?.typeReference?.text ?: "",
|
||||||
receiverClassDescriptor?.importableFqName ?: receiverClassDescriptor?.name?.let { FqName.topLevel(it) }
|
receiverClassDescriptor?.importableFqName ?: receiverClassDescriptor?.name?.let { FqName.topLevel(it) }
|
||||||
)
|
)
|
||||||
oldBody.replace(KtPsiFactory(func).createBlock(bodyText))
|
oldBody.replace(KtPsiFactory(func).createBlock(bodyText))
|
||||||
}
|
}
|
||||||
@@ -692,8 +694,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
}
|
}
|
||||||
if (renderedTypeArgs.isEmpty()) {
|
if (renderedTypeArgs.isEmpty()) {
|
||||||
oldTypeArgumentList.delete()
|
oldTypeArgumentList.delete()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
oldTypeArgumentList.replace(KtPsiFactory(callElement).createTypeArguments(renderedTypeArgs.joinToString(", ", "<", ">")))
|
oldTypeArgumentList.replace(KtPsiFactory(callElement).createTypeArguments(renderedTypeArgs.joinToString(", ", "<", ">")))
|
||||||
elementsToShorten.add(callElement.typeArgumentList!!)
|
elementsToShorten.add(callElement.typeArgumentList!!)
|
||||||
}
|
}
|
||||||
@@ -733,8 +734,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupTypeParameterListTemplate(
|
private fun setupTypeParameterListTemplate(
|
||||||
builder: TemplateBuilderImpl,
|
builder: TemplateBuilderImpl,
|
||||||
declaration: KtNamedDeclaration
|
declaration: KtNamedDeclaration
|
||||||
): TypeParameterListExpression? {
|
): TypeParameterListExpression? {
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is KtObjectDeclaration -> return null
|
is KtObjectDeclaration -> return null
|
||||||
@@ -750,8 +751,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
mandatoryTypeParametersAsCandidates.asSequence().flatMapTo(mandatoryTypeParameters) { it.renderedTypeParameters!!.asSequence() }
|
mandatoryTypeParametersAsCandidates.asSequence().flatMapTo(mandatoryTypeParameters) { it.renderedTypeParameters!!.asSequence() }
|
||||||
|
|
||||||
callableInfo.parameterInfos.asSequence()
|
callableInfo.parameterInfos.asSequence()
|
||||||
.flatMap { typeCandidates[it.typeInfo]!!.asSequence() }
|
.flatMap { typeCandidates[it.typeInfo]!!.asSequence() }
|
||||||
.forEach { typeParameterMap[it.renderedTypes.first()] = it.renderedTypeParameters!! }
|
.forEach { typeParameterMap[it.renderedTypes.first()] = it.renderedTypeParameters!! }
|
||||||
|
|
||||||
if (declaration.getReturnTypeReference() != null) {
|
if (declaration.getReturnTypeReference() != null) {
|
||||||
typeCandidates[callableInfo.returnTypeInfo]!!.forEach {
|
typeCandidates[callableInfo.returnTypeInfo]!!.forEach {
|
||||||
@@ -760,12 +761,12 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val expression = TypeParameterListExpression(
|
val expression = TypeParameterListExpression(
|
||||||
mandatoryTypeParameters,
|
mandatoryTypeParameters,
|
||||||
typeParameterMap,
|
typeParameterMap,
|
||||||
callableInfo.kind != CallableKind.CLASS_WITH_PRIMARY_CONSTRUCTOR
|
callableInfo.kind != CallableKind.CLASS_WITH_PRIMARY_CONSTRUCTOR
|
||||||
)
|
)
|
||||||
val leftSpace = typeParameterList.prevSibling as? PsiWhiteSpace
|
val leftSpace = typeParameterList.prevSibling as? PsiWhiteSpace
|
||||||
val rangeStart = if (leftSpace != null) leftSpace.startOffset else typeParameterList.startOffset
|
val rangeStart = leftSpace?.startOffset ?: typeParameterList.startOffset
|
||||||
val offset = typeParameterList.startOffset
|
val offset = typeParameterList.startOffset
|
||||||
val range = UnfairTextRange(rangeStart - offset, typeParameterList.endOffset - offset)
|
val range = UnfairTextRange(rangeStart - offset, typeParameterList.endOffset - offset)
|
||||||
builder.replaceElement(typeParameterList, range, "TYPE_PARAMETER_LIST", expression, false)
|
builder.replaceElement(typeParameterList, range, "TYPE_PARAMETER_LIST", expression, false)
|
||||||
@@ -819,8 +820,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
val adjustedDeclaration = when (declaration) {
|
val adjustedDeclaration = when (declaration) {
|
||||||
is KtNamedFunction, is KtProperty -> {
|
is KtNamedFunction, is KtProperty -> {
|
||||||
val klass = psiFactory.createClass("class Foo {}")
|
val klass = psiFactory.createClass("class Foo {}")
|
||||||
klass.getBody()!!.add(declaration)
|
klass.body!!.add(declaration)
|
||||||
(declaration.replace(klass) as KtClass).getBody()!!.declarations.first()
|
(declaration.replace(klass) as KtClass).body!!.declarations.first()
|
||||||
}
|
}
|
||||||
else -> declaration
|
else -> declaration
|
||||||
}
|
}
|
||||||
@@ -876,8 +877,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
if (superCall != null) {
|
if (superCall != null) {
|
||||||
val lParen = superCall.argumentList.firstChild
|
val lParen = superCall.argumentList.firstChild
|
||||||
targetEditor.caretModel.moveToOffset(lParen.endOffset)
|
targetEditor.caretModel.moveToOffset(lParen.endOffset)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
targetEditor.caretModel.moveToOffset(newJavaMember.startOffset)
|
targetEditor.caretModel.moveToOffset(newJavaMember.startOffset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -962,10 +962,12 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
if (brokenOff && !ApplicationManager.getApplication().isUnitTestMode) return
|
if (brokenOff && !ApplicationManager.getApplication().isUnitTestMode) return
|
||||||
|
|
||||||
// file templates
|
// file templates
|
||||||
val newDeclaration = PsiTreeUtil.findElementOfClassAtOffset(jetFileToEdit,
|
val newDeclaration = PsiTreeUtil.findElementOfClassAtOffset(
|
||||||
declarationMarker.startOffset,
|
jetFileToEdit,
|
||||||
declaration::class.java,
|
declarationMarker.startOffset,
|
||||||
false) ?: return
|
declaration::class.java,
|
||||||
|
false
|
||||||
|
) ?: return
|
||||||
|
|
||||||
runWriteAction {
|
runWriteAction {
|
||||||
postprocessDeclaration(newDeclaration)
|
postprocessDeclaration(newDeclaration)
|
||||||
@@ -982,7 +984,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
&& newDeclaration.initializer == null
|
&& newDeclaration.initializer == null
|
||||||
&& callableInfo is PropertyInfo
|
&& callableInfo is PropertyInfo
|
||||||
&& callableInfo.withInitializer
|
&& callableInfo.withInitializer
|
||||||
&& !callableInfo.isLateinitPreferred) {
|
&& !callableInfo.isLateinitPreferred
|
||||||
|
) {
|
||||||
newDeclaration.initializer = KtPsiFactory(newDeclaration).createExpression("TODO(\"initialize me\")")
|
newDeclaration.initializer = KtPsiFactory(newDeclaration).createExpression("TODO(\"initialize me\")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1001,8 +1004,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
setupEditor(newDeclaration)
|
setupEditor(newDeclaration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
declarationMarker.dispose()
|
declarationMarker.dispose()
|
||||||
finished = true
|
finished = true
|
||||||
onFinish()
|
onFinish()
|
||||||
@@ -1030,10 +1032,10 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
// TODO: Simplify and use formatter as much as possible
|
// TODO: Simplify and use formatter as much as possible
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
internal fun <D : KtNamedDeclaration> placeDeclarationInContainer(
|
internal fun <D : KtNamedDeclaration> placeDeclarationInContainer(
|
||||||
declaration: D,
|
declaration: D,
|
||||||
container: PsiElement,
|
container: PsiElement,
|
||||||
anchor: PsiElement,
|
anchor: PsiElement,
|
||||||
fileToEdit: KtFile = container.containingFile as KtFile
|
fileToEdit: KtFile = container.containingFile as KtFile
|
||||||
): D {
|
): D {
|
||||||
val psiFactory = KtPsiFactory(container)
|
val psiFactory = KtPsiFactory(container)
|
||||||
val newLine = psiFactory.createNewLine()
|
val newLine = psiFactory.createNewLine()
|
||||||
@@ -1065,17 +1067,18 @@ internal fun <D : KtNamedDeclaration> placeDeclarationInContainer(
|
|||||||
|
|
||||||
val actualContainer = (container as? KtClassOrObject)?.getOrCreateBody() ?: container
|
val actualContainer = (container as? KtClassOrObject)?.getOrCreateBody() ?: container
|
||||||
|
|
||||||
fun addDeclarationToClassOrObject(classOrObject: KtClassOrObject,
|
fun addDeclarationToClassOrObject(
|
||||||
declaration: KtNamedDeclaration): KtNamedDeclaration {
|
classOrObject: KtClassOrObject,
|
||||||
|
declaration: KtNamedDeclaration
|
||||||
|
): KtNamedDeclaration {
|
||||||
val classBody = classOrObject.getOrCreateBody()
|
val classBody = classOrObject.getOrCreateBody()
|
||||||
return if (declaration is KtNamedFunction) {
|
return if (declaration is KtNamedFunction) {
|
||||||
val neighbor = PsiTreeUtil.skipSiblingsBackward(
|
val neighbor = PsiTreeUtil.skipSiblingsBackward(
|
||||||
classBody.rBrace ?: classBody.lastChild!!,
|
classBody.rBrace ?: classBody.lastChild!!,
|
||||||
PsiWhiteSpace::class.java
|
PsiWhiteSpace::class.java
|
||||||
)
|
)
|
||||||
classBody.addAfter(declaration, neighbor) as KtNamedDeclaration
|
classBody.addAfter(declaration, neighbor) as KtNamedDeclaration
|
||||||
}
|
} else classBody.addAfter(declaration, classBody.lBrace!!) as KtNamedDeclaration
|
||||||
else classBody.addAfter(declaration, classBody.lBrace!!) as KtNamedDeclaration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1083,8 +1086,7 @@ internal fun <D : KtNamedDeclaration> placeDeclarationInContainer(
|
|||||||
val sibling = anchor.parentsWithSelf.first { it.parent == actualContainer }
|
val sibling = anchor.parentsWithSelf.first { it.parent == actualContainer }
|
||||||
return if (addBefore) {
|
return if (addBefore) {
|
||||||
actualContainer.addBefore(declaration, sibling)
|
actualContainer.addBefore(declaration, sibling)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
actualContainer.addAfter(declaration, sibling)
|
actualContainer.addAfter(declaration, sibling)
|
||||||
} as D
|
} as D
|
||||||
}
|
}
|
||||||
@@ -1105,9 +1107,11 @@ internal fun <D : KtNamedDeclaration> placeDeclarationInContainer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addNextToOriginalElementContainer(insertToBlock
|
addNextToOriginalElementContainer(
|
||||||
|| (declaration is KtProperty && actualContainer !is KtFile)
|
insertToBlock
|
||||||
|| declaration is KtTypeAlias)
|
|| (declaration is KtProperty && actualContainer !is KtFile)
|
||||||
|
|| declaration is KtTypeAlias
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
container is KtFile -> container.add(declaration) as D
|
container is KtFile -> container.add(declaration) as D
|
||||||
@@ -1117,8 +1121,7 @@ internal fun <D : KtNamedDeclaration> placeDeclarationInContainer(
|
|||||||
val wrappingClass = psiFactory.createClass("class ${container.name} {\n}")
|
val wrappingClass = psiFactory.createClass("class ${container.name} {\n}")
|
||||||
addDeclarationToClassOrObject(wrappingClass, declaration)
|
addDeclarationToClassOrObject(wrappingClass, declaration)
|
||||||
(fileToEdit.add(wrappingClass) as KtClass).declarations.first() as D
|
(fileToEdit.add(wrappingClass) as KtClass).declarations.first() as D
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
fileToEdit.add(declaration) as D
|
fileToEdit.add(declaration) as D
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1126,7 +1129,7 @@ internal fun <D : KtNamedDeclaration> placeDeclarationInContainer(
|
|||||||
container is KtClassOrObject -> {
|
container is KtClassOrObject -> {
|
||||||
var sibling: PsiElement? = container.declarations.lastOrNull { it::class == declaration::class }
|
var sibling: PsiElement? = container.declarations.lastOrNull { it::class == declaration::class }
|
||||||
if (sibling == null && declaration is KtProperty) {
|
if (sibling == null && declaration is KtProperty) {
|
||||||
sibling = container.getBody()?.lBrace
|
sibling = container.body?.lBrace
|
||||||
}
|
}
|
||||||
|
|
||||||
insertMember(null, container, declaration, sibling)
|
insertMember(null, container, declaration, sibling)
|
||||||
|
|||||||
Reference in New Issue
Block a user