Create from Usage: Disable "Create property" (non-abstract) in interfaces. Make "Create function" (non-abstract) generate function body in interfaces
#KT-13365 Fixed
This commit is contained in:
@@ -216,6 +216,7 @@ These artifacts include extensions for the types available in the latter JDKs, s
|
||||
- [`KT-13262`](https://youtrack.jetbrains.com/issue/KT-13262) "Wrap with safe let call" quickfix produces wrong result for qualified function
|
||||
- [`KT-13364`](https://youtrack.jetbrains.com/issue/KT-13364) Do not suggest creating annotations/enum classes for unresolved type parameter bounds
|
||||
- [`KT-12627`](https://youtrack.jetbrains.com/issue/KT-12627) Allow warnings suppression for secondary constructor
|
||||
- [`KT-13365`](https://youtrack.jetbrains.com/issue/KT-13365) Disable "Create property" (non-abstract) in interfaces. Make "Create function" (non-abstract) generate function body in interfaces
|
||||
|
||||
##### New features
|
||||
|
||||
|
||||
+1
-1
@@ -447,6 +447,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
if (containingElement is KtClass && containingElement.isInterface()) "" else "abstract "
|
||||
}
|
||||
else if (containingElement is KtClassOrObject
|
||||
&& !(containingElement is KtClass && containingElement.isInterface())
|
||||
&& containingElement.isAncestor(config.originalElement)
|
||||
&& callableInfo.kind != CallableKind.SECONDARY_CONSTRUCTOR) "private "
|
||||
else ""
|
||||
@@ -454,7 +455,6 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
val declaration: KtNamedDeclaration = when (callableInfo.kind) {
|
||||
CallableKind.FUNCTION, CallableKind.SECONDARY_CONSTRUCTOR -> {
|
||||
val body = when {
|
||||
containingElement is KtClass && containingElement.isInterface() && !config.isExtension -> ""
|
||||
callableInfo.kind == CallableKind.SECONDARY_CONSTRUCTOR -> ""
|
||||
callableInfo.isAbstract -> ""
|
||||
else -> "{}"
|
||||
|
||||
+18
-1
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.canRefactor
|
||||
import org.jetbrains.kotlin.idea.refactoring.getExtractionContainers
|
||||
import org.jetbrains.kotlin.idea.refactoring.isInterfaceClass
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -183,7 +184,23 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
|
||||
return PropertyInfo(name, receiverType, returnType, varExpected, possibleContainers)
|
||||
}
|
||||
|
||||
object Default : Property()
|
||||
object Default : Property() {
|
||||
override fun doCreateCallableInfo(
|
||||
expression: KtSimpleNameExpression,
|
||||
context: BindingContext,
|
||||
name: String,
|
||||
receiverType: TypeInfo,
|
||||
possibleContainers: List<KtElement>
|
||||
): CallableInfo? {
|
||||
return super.doCreateCallableInfo(
|
||||
expression,
|
||||
context,
|
||||
name,
|
||||
receiverType,
|
||||
possibleContainers.filterNot { it is KtClassBody && (it.parent as KtClassOrObject).isInterfaceClass() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object Abstract : Property() {
|
||||
override fun doCreateCallableInfo(
|
||||
|
||||
+5
-1
@@ -141,7 +141,10 @@ abstract class CreateCallableFromUsageFixBase<E : KtElement>(
|
||||
|
||||
val receiverInfo = callableInfos.first().receiverTypeInfo
|
||||
|
||||
if (receiverInfo is TypeInfo.Empty) return !isExtension
|
||||
if (receiverInfo is TypeInfo.Empty) {
|
||||
if (callableInfos.any { it is PropertyInfo && it.possibleContainers.isEmpty() }) return false
|
||||
return !isExtension
|
||||
}
|
||||
// TODO: Remove after companion object extensions are supported
|
||||
if (isExtension && receiverInfo.staticContextRequired) return false
|
||||
|
||||
@@ -158,6 +161,7 @@ abstract class CreateCallableFromUsageFixBase<E : KtElement>(
|
||||
isFunction && insertToJavaInterface && receiverInfo.staticContextRequired ->
|
||||
false
|
||||
!isExtension && declaration is KtTypeParameter -> false
|
||||
propertyInfo != null && !propertyInfo.isAbstract && declaration is KtClass && declaration.isInterface() -> false
|
||||
else ->
|
||||
declaration != null
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,7 +1,9 @@
|
||||
// "Create member function 'T.foo'" "true"
|
||||
|
||||
interface T {
|
||||
fun foo(s: String, i: Int): Boolean
|
||||
fun foo(s: String, i: Int): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
fun test(t: T) {
|
||||
|
||||
-1
@@ -1,7 +1,6 @@
|
||||
// "Create parameter 'foo'" "false"
|
||||
// ACTION: Convert to expression body
|
||||
// ACTION: Create local variable 'foo'
|
||||
// ACTION: Create property 'foo'
|
||||
// ACTION: Create abstract property 'foo'
|
||||
// ACTION: Rename reference
|
||||
// ERROR: Unresolved reference: foo
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Create property 'foo'" "false"
|
||||
// ACTION: Create abstract property 'foo'
|
||||
// ACTION: Create local variable 'foo'
|
||||
// ACTION: Create object 'foo'
|
||||
// ACTION: Create parameter 'foo'
|
||||
// ACTION: Rename reference
|
||||
// ERROR: Unresolved reference: foo
|
||||
|
||||
interface IF1 {
|
||||
fun af2() = <caret>foo
|
||||
}
|
||||
@@ -3564,6 +3564,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nonAbstractInInterface.kt")
|
||||
public void testNonAbstractInInterface() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/nonAbstractInInterface.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("objectMemberValNoReceiver.kt")
|
||||
public void testObjectMemberValNoReceiver() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/objectMemberValNoReceiver.kt");
|
||||
|
||||
Reference in New Issue
Block a user