Create From Usage: Quick-fix for properties

This commit is contained in:
Alexey Sedunov
2014-09-30 21:10:11 +04:00
parent 8386bcd4e0
commit 58126b28ca
59 changed files with 514 additions and 36 deletions
@@ -185,6 +185,7 @@ map.platform.class.to.kotlin.advertisement=Choose an appropriate Kotlin class
map.platform.class.to.kotlin.family=Change to Kotlin class map.platform.class.to.kotlin.family=Change to Kotlin class
create.from.usage.family=Create from usage create.from.usage.family=Create from usage
create.function.from.usage=Create function ''{0}'' from usage create.function.from.usage=Create function ''{0}'' from usage
create.property.from.usage=Create property ''{0}'' from usage
create.local.variable.from.usage=Create local variable ''{0}'' create.local.variable.from.usage=Create local variable ''{0}''
create.parameter.from.usage=Create parameter ''{0}'' create.parameter.from.usage=Create parameter ''{0}''
choose.target.class.or.trait.title=Choose target class or trait choose.target.class.or.trait.title=Choose target class or trait
@@ -233,10 +233,10 @@ public class QuickFixRegistrar {
QuickFixes.factories.put(NO_VALUE_FOR_PARAMETER, CreateBinaryOperationActionFactory.INSTANCE$); QuickFixes.factories.put(NO_VALUE_FOR_PARAMETER, CreateBinaryOperationActionFactory.INSTANCE$);
QuickFixes.factories.put(TOO_MANY_ARGUMENTS, CreateBinaryOperationActionFactory.INSTANCE$); QuickFixes.factories.put(TOO_MANY_ARGUMENTS, CreateBinaryOperationActionFactory.INSTANCE$);
QuickFixes.factories.put(UNRESOLVED_REFERENCE_WRONG_RECEIVER, CreateFunctionFromCallActionFactory.INSTANCE$); QuickFixes.factories.put(UNRESOLVED_REFERENCE_WRONG_RECEIVER, CreateFunctionOrPropertyFromCallActionFactory.INSTANCE$);
QuickFixes.factories.put(UNRESOLVED_REFERENCE, CreateFunctionFromCallActionFactory.INSTANCE$); QuickFixes.factories.put(UNRESOLVED_REFERENCE, CreateFunctionOrPropertyFromCallActionFactory.INSTANCE$);
QuickFixes.factories.put(NO_VALUE_FOR_PARAMETER, CreateFunctionFromCallActionFactory.INSTANCE$); QuickFixes.factories.put(NO_VALUE_FOR_PARAMETER, CreateFunctionOrPropertyFromCallActionFactory.INSTANCE$);
QuickFixes.factories.put(TOO_MANY_ARGUMENTS, CreateFunctionFromCallActionFactory.INSTANCE$); QuickFixes.factories.put(TOO_MANY_ARGUMENTS, CreateFunctionOrPropertyFromCallActionFactory.INSTANCE$);
QuickFixes.factories.put(UNRESOLVED_REFERENCE, CreateLocalVariableActionFactory.INSTANCE$); QuickFixes.factories.put(UNRESOLVED_REFERENCE, CreateLocalVariableActionFactory.INSTANCE$);
@@ -298,9 +298,13 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
classBody = containingElement.add(psiFactory.createEmptyClassBody()) as JetClassBody classBody = containingElement.add(psiFactory.createEmptyClassBody()) as JetClassBody
containingElement.addBefore(psiFactory.createWhiteSpace(), classBody) containingElement.addBefore(psiFactory.createWhiteSpace(), classBody)
} }
val rBrace = classBody!!.getRBrace()
return (rBrace?.let { append(declaration, it, true) } if (declaration is JetNamedFunction) {
?: append(declaration, classBody!!.getLastChild()!!, false)) as JetCallableDeclaration val rBrace = classBody!!.getRBrace()
return (rBrace?.let { append(declaration, it, true) }
?: append(declaration, classBody!!.getLastChild()!!, false)) as JetCallableDeclaration
}
return prepend(declaration, classBody!!.getLBrace()!!, true) as JetCallableDeclaration
} }
is JetBlockExpression -> { is JetBlockExpression -> {
@@ -13,6 +13,7 @@ import org.jetbrains.jet.plugin.util.supertypes
import org.jetbrains.jet.lang.types.TypeUtils import org.jetbrains.jet.lang.types.TypeUtils
import org.jetbrains.jet.lang.types.ErrorUtils import org.jetbrains.jet.lang.types.ErrorUtils
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.psi.JetElement
/** /**
* Represents a concrete type or a set of types yet to be inferred from an expression. * Represents a concrete type or a set of types yet to be inferred from an expression.
@@ -75,6 +76,7 @@ class CallableInfo (
val kind: CallableKind, val kind: CallableKind,
val receiverTypeInfo: TypeInfo, val receiverTypeInfo: TypeInfo,
val returnTypeInfo: TypeInfo, val returnTypeInfo: TypeInfo,
val possibleContainers: List<JetElement>,
val parameterInfos: List<ParameterInfo> = Collections.emptyList() val parameterInfos: List<ParameterInfo> = Collections.emptyList()
) { ) {
{ {
@@ -83,14 +85,16 @@ class CallableInfo (
} }
fun createFunctionInfo(name: String, fun createFunctionInfo(name: String,
receiverTypeInfo: TypeInfo, receiverTypeInfo: TypeInfo,
returnTypeInfo: TypeInfo, returnTypeInfo: TypeInfo,
parameterInfos: List<ParameterInfo> = Collections.emptyList()): CallableInfo { possibleContainers: List<JetElement> = Collections.emptyList(),
return CallableInfo(name, CallableKind.FUNCTION, receiverTypeInfo, returnTypeInfo, parameterInfos) parameterInfos: List<ParameterInfo> = Collections.emptyList()): CallableInfo {
return CallableInfo(name, CallableKind.FUNCTION, receiverTypeInfo, returnTypeInfo, possibleContainers, parameterInfos)
} }
fun createPropertyInfo(name: String, fun createPropertyInfo(name: String,
receiverTypeInfo: TypeInfo, receiverTypeInfo: TypeInfo,
returnTypeInfo: TypeInfo): CallableInfo { returnTypeInfo: TypeInfo,
return CallableInfo(name, CallableKind.PROPERTY, receiverTypeInfo, returnTypeInfo) possibleContainers: List<JetElement>): CallableInfo {
return CallableInfo(name, CallableKind.PROPERTY, receiverTypeInfo, returnTypeInfo, possibleContainers)
} }
@@ -38,6 +38,6 @@ public object CreateBinaryOperationActionFactory: JetSingleIntentionActionFactor
else -> TypeInfo(callExpr, Variance.OUT_VARIANCE) else -> TypeInfo(callExpr, Variance.OUT_VARIANCE)
} }
val parameters = Collections.singletonList(ParameterInfo(TypeInfo(argumentExpr, Variance.IN_VARIANCE))) val parameters = Collections.singletonList(ParameterInfo(TypeInfo(argumentExpr, Variance.IN_VARIANCE)))
return CreateFunctionFromUsageFix(callExpr, createFunctionInfo(operationName, receiverType, returnType, parameters)) return CreateFunctionFromUsageFix(callExpr, createFunctionInfo(operationName, receiverType, returnType, Collections.emptyList(), parameters))
} }
} }
@@ -17,7 +17,11 @@ import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.*
public class CreateFunctionFromUsageFix(element: PsiElement, val functionInfo: CallableInfo) : CreateFromUsageFixBase(element) { public class CreateFunctionFromUsageFix(element: PsiElement, val functionInfo: CallableInfo) : CreateFromUsageFixBase(element) {
override fun getText(): String { override fun getText(): String {
return JetBundle.message("create.function.from.usage", functionInfo.name) val key = when (functionInfo.kind) {
CallableKind.FUNCTION -> "create.function.from.usage"
CallableKind.PROPERTY -> "create.property.from.usage"
}
return JetBundle.message(key, functionInfo.name)
} }
override fun invoke(project: Project, editor: Editor?, file: JetFile?) { override fun invoke(project: Project, editor: Editor?, file: JetFile?) {
@@ -42,7 +46,7 @@ public class CreateFunctionFromUsageFix(element: PsiElement, val functionInfo: C
else { else {
assert(functionInfo.receiverTypeInfo is TypeInfo.Empty, "No receiver type candidates: ${element.getText()} in ${file.getText()}") assert(functionInfo.receiverTypeInfo is TypeInfo.Empty, "No receiver type candidates: ${element.getText()} in ${file.getText()}")
chooseContainerElementIfNecessary(element.getExtractionContainers(), editor, popupTitle, true, { it }) { chooseContainerElementIfNecessary(functionInfo.possibleContainers, editor, popupTitle, true, { it }) {
val container = if (it is JetClassBody) it.getParent() as JetClassOrObject else it val container = if (it is JetClassBody) it.getParent() as JetClassOrObject else it
runBuilder(CallablePlacement.NoReceiver(container)) runBuilder(CallablePlacement.NoReceiver(container))
} }
@@ -6,7 +6,6 @@ import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.jet.lang.psi.JetCallExpression import org.jetbrains.jet.lang.psi.JetCallExpression
import org.jetbrains.jet.lang.types.Variance import org.jetbrains.jet.lang.types.Variance
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.plugin.quickfix.QuickFixUtil
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
import org.jetbrains.jet.lexer.JetTokens import org.jetbrains.jet.lexer.JetTokens
import org.jetbrains.jet.lang.psi.JetQualifiedExpression import org.jetbrains.jet.lang.psi.JetQualifiedExpression
@@ -17,9 +16,13 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.Qualifier
import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.* import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.*
import org.jetbrains.jet.lang.diagnostics.Errors import org.jetbrains.jet.lang.diagnostics.Errors
import org.jetbrains.jet.lang.psi.psiUtil.getParentByType import org.jetbrains.jet.lang.psi.psiUtil.getParentByType
import org.jetbrains.jet.lang.psi.psiUtil.getParentByTypeAndBranch import org.jetbrains.jet.lang.psi.JetExpression
import java.util.Collections
import org.jetbrains.jet.plugin.refactoring.getExtractionContainers
import org.jetbrains.jet.lang.psi.JetClassBody
import org.jetbrains.jet.lang.psi.JetFile
object CreateFunctionFromCallActionFactory : JetSingleIntentionActionFactory() { object CreateFunctionOrPropertyFromCallActionFactory : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? { override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val diagElement = diagnostic.getPsiElement() val diagElement = diagnostic.getPsiElement()
val callExpr = when (diagnostic.getFactory()) { val callExpr = when (diagnostic.getFactory()) {
@@ -32,10 +35,14 @@ object CreateFunctionFromCallActionFactory : JetSingleIntentionActionFactory() {
Errors.TOO_MANY_ARGUMENTS -> diagElement.getParentByType(javaClass<JetCallExpression>()) Errors.TOO_MANY_ARGUMENTS -> diagElement.getParentByType(javaClass<JetCallExpression>())
else -> throw AssertionError("Unexpected diagnostic: ${diagnostic.getFactory()}") else -> throw AssertionError("Unexpected diagnostic: ${diagnostic.getFactory()}")
} } as? JetExpression ?: return null
if (callExpr !is JetCallExpression) return null
val calleeExpr = when (callExpr) {
is JetCallExpression -> callExpr.getCalleeExpression()
is JetSimpleNameExpression -> callExpr
else -> null
} as? JetSimpleNameExpression ?: return null
val calleeExpr = callExpr.getCalleeExpression() as? JetSimpleNameExpression ?: return null
if (calleeExpr.getReferencedNameElementType() != JetTokens.IDENTIFIER) return null if (calleeExpr.getReferencedNameElementType() != JetTokens.IDENTIFIER) return null
val callParent = callExpr.getParent() val callParent = callExpr.getParent()
@@ -54,15 +61,34 @@ object CreateFunctionFromCallActionFactory : JetSingleIntentionActionFactory() {
else -> TypeInfo(receiver.getType(), Variance.IN_VARIANCE) else -> TypeInfo(receiver.getType(), Variance.IN_VARIANCE)
} }
val anyType = KotlinBuiltIns.getInstance().getNullableAnyType() val possibleContainers =
val parameters = callExpr.getValueArguments().map { if (receiverType is TypeInfo.Empty) {
ParameterInfo( val containers = with(fullCallExpr.getExtractionContainers()) {
it.getArgumentExpression()?.let { TypeInfo(it, Variance.IN_VARIANCE) } ?: TypeInfo(anyType, Variance.IN_VARIANCE), if (callExpr is JetCallExpression) this else filter { it is JetClassBody || it is JetFile }
it.getArgumentName()?.getReferenceExpression()?.getReferencedName() }
) if (containers.isNotEmpty()) containers else return null
} }
else Collections.emptyList()
val returnType = TypeInfo(fullCallExpr, Variance.OUT_VARIANCE) val returnType = TypeInfo(fullCallExpr, Variance.OUT_VARIANCE)
return CreateFunctionFromUsageFix(callExpr, createFunctionInfo(calleeExpr.getReferencedName(), receiverType, returnType, parameters))
val callableInfo = when (callExpr) {
is JetCallExpression -> {
val anyType = KotlinBuiltIns.getInstance().getNullableAnyType()
val parameters = callExpr.getValueArguments().map {
ParameterInfo(
it.getArgumentExpression()?.let { TypeInfo(it, Variance.IN_VARIANCE) } ?: TypeInfo(anyType, Variance.IN_VARIANCE),
it.getArgumentName()?.getReferenceExpression()?.getReferencedName()
)
}
createFunctionInfo(calleeExpr.getReferencedName(), receiverType, returnType, possibleContainers, parameters)
}
is JetSimpleNameExpression -> createPropertyInfo(calleeExpr.getReferencedName(), receiverType, returnType, possibleContainers)
else -> return null
}
return CreateFunctionFromUsageFix(callExpr, callableInfo)
} }
} }
@@ -7,6 +7,7 @@ import org.jetbrains.jet.plugin.quickfix.QuickFixUtil
import org.jetbrains.jet.lang.psi.JetArrayAccessExpression import org.jetbrains.jet.lang.psi.JetArrayAccessExpression
import org.jetbrains.jet.lang.types.Variance import org.jetbrains.jet.lang.types.Variance
import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.* import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.*
import java.util.Collections
object CreateGetFunctionActionFactory : JetSingleIntentionActionFactory() { object CreateGetFunctionActionFactory : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? { override fun createAction(diagnostic: Diagnostic): IntentionAction? {
@@ -19,6 +20,6 @@ object CreateGetFunctionActionFactory : JetSingleIntentionActionFactory() {
} }
val returnType = TypeInfo(accessExpr, Variance.OUT_VARIANCE) val returnType = TypeInfo(accessExpr, Variance.OUT_VARIANCE)
return CreateFunctionFromUsageFix(accessExpr, createFunctionInfo("get", arrayType, returnType, parameters)) return CreateFunctionFromUsageFix(accessExpr, createFunctionInfo("get", arrayType, returnType, Collections.emptyList(), parameters))
} }
} }
@@ -10,6 +10,7 @@ import org.jetbrains.jet.lang.psi.JetCallExpression
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.diagnostics.Errors import org.jetbrains.jet.lang.diagnostics.Errors
import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.* import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.*
import java.util.Collections
object CreateInvokeFunctionActionFactory : JetSingleIntentionActionFactory() { object CreateInvokeFunctionActionFactory : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? { override fun createAction(diagnostic: Diagnostic): IntentionAction? {
@@ -29,6 +30,6 @@ object CreateInvokeFunctionActionFactory : JetSingleIntentionActionFactory() {
} }
val returnType = TypeInfo(callExpr, Variance.OUT_VARIANCE) val returnType = TypeInfo(callExpr, Variance.OUT_VARIANCE)
return CreateFunctionFromUsageFix(callExpr, createFunctionInfo("invoke", receiverType, returnType, parameters)) return CreateFunctionFromUsageFix(callExpr, createFunctionInfo("invoke", receiverType, returnType, Collections.emptyList(), parameters))
} }
} }
@@ -10,6 +10,7 @@ import java.util.ArrayList
import org.jetbrains.jet.lang.psi.JetBinaryExpression import org.jetbrains.jet.lang.psi.JetBinaryExpression
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.* import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.*
import java.util.Collections
object CreateSetFunctionActionFactory : JetSingleIntentionActionFactory() { object CreateSetFunctionActionFactory : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? { override fun createAction(diagnostic: Diagnostic): IntentionAction? {
@@ -27,6 +28,6 @@ object CreateSetFunctionActionFactory : JetSingleIntentionActionFactory() {
parameters.add(ParameterInfo(valType, "value")) parameters.add(ParameterInfo(valType, "value"))
val returnType = TypeInfo(KotlinBuiltIns.getInstance().getUnitType(), Variance.OUT_VARIANCE) val returnType = TypeInfo(KotlinBuiltIns.getInstance().getUnitType(), Variance.OUT_VARIANCE)
return CreateFunctionFromUsageFix(accessExpr, createFunctionInfo("set", arrayType, returnType, parameters)) return CreateFunctionFromUsageFix(accessExpr, createFunctionInfo("set", arrayType, returnType, Collections.emptyList(), parameters))
} }
} }
@@ -25,6 +25,8 @@ import org.jetbrains.jet.lang.psi.JetPropertyAccessor
import org.jetbrains.jet.lang.psi.JetElement import org.jetbrains.jet.lang.psi.JetElement
import org.jetbrains.jet.plugin.intentions.ConvertToBlockBodyAction import org.jetbrains.jet.plugin.intentions.ConvertToBlockBodyAction
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody import org.jetbrains.jet.lang.psi.JetDeclarationWithBody
import org.jetbrains.jet.plugin.refactoring.getExtractionContainers
import org.jetbrains.jet.lang.psi.JetClassBody
object CreateLocalVariableActionFactory: JetSingleIntentionActionFactory() { object CreateLocalVariableActionFactory: JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? { override fun createAction(diagnostic: Diagnostic): IntentionAction? {
@@ -35,7 +37,9 @@ object CreateLocalVariableActionFactory: JetSingleIntentionActionFactory() {
.filter { it is JetBlockExpression || it is JetDeclarationWithBody } .filter { it is JetBlockExpression || it is JetDeclarationWithBody }
.firstOrNull() as? JetElement ?: return null .firstOrNull() as? JetElement ?: return null
val propertyInfo = createPropertyInfo(refExpr.getReferencedName(), TypeInfo.Empty, TypeInfo(refExpr, Variance.OUT_VARIANCE)) val containers = refExpr.getExtractionContainers().filterNot { it is JetClassBody || it is JetFile }
val propertyInfo =
createPropertyInfo(refExpr.getReferencedName(), TypeInfo.Empty, TypeInfo(refExpr, Variance.OUT_VARIANCE), containers)
return object: CreateFromUsageFixBase(refExpr) { return object: CreateFromUsageFixBase(refExpr) {
override fun getText(): String = JetBundle.message("create.local.variable.from.usage", propertyInfo.name) override fun getText(): String = JetBundle.message("create.local.variable.from.usage", propertyInfo.name)
@@ -1,6 +1,7 @@
// "class com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFixBase" "false" // "class com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFixBase" "false"
// ACTION: Create local variable 'PrivateClass' // ACTION: Create local variable 'PrivateClass'
// ACTION: Create parameter 'PrivateClass' // ACTION: Create parameter 'PrivateClass'
// ACTION: Create property 'PrivateClass' from usage
// ERROR: Unresolved reference: PrivateClass // ERROR: Unresolved reference: PrivateClass
fun test() { fun test() {
@@ -1,5 +1,6 @@
// "Create local variable 'foo'" "false" // "Create local variable 'foo'" "false"
// ACTION: Create parameter 'foo' // ACTION: Create parameter 'foo'
// ACTION: Create property 'foo' from usage
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
class A { class A {
@@ -1,4 +1,5 @@
// "Create local variable 'foo'" "false" // "Create local variable 'foo'" "false"
// ACTION: Create property 'foo' from usage
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
val t: Int = <caret>foo val t: Int = <caret>foo
@@ -1,4 +1,5 @@
// "Create local variable 'foo'" "false" // "Create local variable 'foo'" "false"
// ACTION: Create property 'foo' from usage
// ACTION: Split property declaration // ACTION: Split property declaration
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
@@ -1,6 +1,7 @@
// "Create parameter 'foo'" "false" // "Create parameter 'foo'" "false"
// ACTION: Convert to expression body // ACTION: Convert to expression body
// ACTION: Create local variable 'foo' // ACTION: Create local variable 'foo'
// ACTION: Create property 'foo' from usage
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
class A { class A {
@@ -1,6 +1,7 @@
// "Create parameter 'foo'" "false" // "Create parameter 'foo'" "false"
// ACTION: Convert to expression body // ACTION: Convert to expression body
// ACTION: Create local variable 'foo' // ACTION: Create local variable 'foo'
// ACTION: Create property 'foo' from usage
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
object A { object A {
@@ -1,6 +1,7 @@
// "Create parameter 'foo'" "false" // "Create parameter 'foo'" "false"
// ACTION: Convert to expression body // ACTION: Convert to expression body
// ACTION: Create local variable 'foo' // ACTION: Create local variable 'foo'
// ACTION: Create property 'foo' from usage
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
trait A { trait A {
@@ -1,6 +1,7 @@
// "Create parameter 'foo'" "false" // "Create parameter 'foo'" "false"
// ACTION: Convert to expression body // ACTION: Convert to expression body
// ACTION: Create local variable 'foo' // ACTION: Create local variable 'foo'
// ACTION: Create property 'foo' from usage
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
val test: Int get() { val test: Int get() {
@@ -1,6 +1,7 @@
// "Create parameter 'foo'" "false" // "Create parameter 'foo'" "false"
// ACTION: Convert to expression body // ACTION: Convert to expression body
// ACTION: Create local variable 'foo' // ACTION: Create local variable 'foo'
// ACTION: Create property 'foo' from usage
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
class A { class A {
@@ -1,6 +1,7 @@
// "Create parameter 'foo'" "false" // "Create parameter 'foo'" "false"
// ACTION: Convert to expression body // ACTION: Convert to expression body
// ACTION: Create local variable 'foo' // ACTION: Create local variable 'foo'
// ACTION: Create property 'foo' from usage
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
class A<T> { class A<T> {
@@ -1,5 +1,6 @@
// "Create parameter 'foo'" "false" // "Create parameter 'foo'" "false"
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
// ACTION: Create property 'foo' from usage
class A { class A {
val <T> test: T = <caret>foo val <T> test: T = <caret>foo
@@ -1,4 +1,5 @@
// "Create parameter 'foo'" "false" // "Create parameter 'foo'" "false"
// ACTION: Create property 'foo' from usage
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
class A<T> { class A<T> {
@@ -1,4 +1,5 @@
// "Create parameter 'foo'" "false" // "Create parameter 'foo'" "false"
// ACTION: Create property 'foo' from usage
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
class A { class A {
@@ -1,4 +1,5 @@
// "Create parameter 'foo'" "false" // "Create parameter 'foo'" "false"
// ACTION: Create property 'foo' from usage
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
object A { object A {
@@ -1,4 +1,5 @@
// "Create parameter 'foo'" "false" // "Create parameter 'foo'" "false"
// ACTION: Create property 'foo' from usage
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
val test: Int = <caret>foo val test: Int = <caret>foo
@@ -1,5 +1,6 @@
// "Create parameter 'foo'" "false" // "Create parameter 'foo'" "false"
// ACTION: Split property declaration // ACTION: Split property declaration
// ACTION: Create property 'foo' from usage
// ERROR: Unresolved reference: foo // ERROR: Unresolved reference: foo
class A class A
@@ -0,0 +1,12 @@
// "Create property 'foo' from usage" "true"
// ERROR: <html>Type mismatch.<table><tr><td>Required:</td><td>kotlin.Int</td></tr><tr><td>Found:</td><td>A&lt;kotlin.Int&gt;</td></tr></table></html>
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T) {
val foo: Any
}
fun test(): Int {
return A(1).foo as A<Int>
}
@@ -0,0 +1,9 @@
// "Create property 'foo' from usage" "true"
fun test() {
val foo: Int
fun nestedTest(): Int {
return foo
}
}
@@ -0,0 +1,12 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A {
class B {
val foo: Int
fun test(): Int {
return foo
}
}
}
@@ -0,0 +1,12 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A {
object B {
val foo: Int
fun test(): Int {
return foo
}
}
}
@@ -0,0 +1,10 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T) {
val foo: A<Int>
fun test(): A<Int> {
return this.foo
}
}
@@ -0,0 +1,11 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T) {
val foo: A<Int>
}
fun <U> A<U>.test(): A<Int> {
return this.foo
}
@@ -0,0 +1,12 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T) {
inner class B<U>(val m: U) {
val foo: A<Int>
fun test(): A<Int> {
return this.foo
}
}
}
@@ -0,0 +1,12 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T) {
val foo: A<Int>
inner class B<U>(val m: U) {
fun test(): A<Int> {
return this@A.foo
}
}
}
@@ -0,0 +1,8 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized
fun test(): Int {
return foo
}
val foo: Int
@@ -0,0 +1,14 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T) {
class object {
val foo: Int
}
}
fun test() {
val a: Int = A.foo
}
@@ -0,0 +1,8 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized
fun test() {
val a: Int = Unit.foo
}
val Unit.foo: Int
@@ -0,0 +1,10 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized
class A<T>(val n: T)
fun test() {
val a: A<Int> = 2.foo
}
val Int.foo: A<Int>
@@ -0,0 +1,11 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
object A {
val foo: Int
}
fun test() {
val a: Int = A.foo
}
@@ -0,0 +1,11 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T) {
val foo: A<T>
}
fun test() {
val a: A<Int> = A(1).foo
}
@@ -0,0 +1,11 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T) {
val foo: A<T>
}
fun test<U>(u: U) {
val a: A<U> = A(u).foo
}
@@ -0,0 +1,13 @@
// "Create property 'foo' from usage" "false"
// ACTION: Create function 'bar' from usage
// ACTION: Replace with infix function call
// ERROR: Unresolved reference: bar
// ERROR: Unresolved reference: foo
class A<T>(val n: T) {
val foo: Int = 1
}
fun test() {
A(1).<caret>bar(foo)
}
@@ -0,0 +1,9 @@
// "Create property 'foo' from usage" "true"
// ERROR: <html>Type mismatch.<table><tr><td>Required:</td><td>kotlin.Int</td></tr><tr><td>Found:</td><td>A&lt;kotlin.Int&gt;</td></tr></table></html>
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T)
fun test(): Int {
return A(1).<caret>foo as A<Int>
}
@@ -0,0 +1,13 @@
// "Create property 'foo' from usage" "false"
// ACTION: Convert to expression body
// ACTION: Disable 'Convert to Expression Body'
// ACTION: Edit intention settings
// ACTION: Create parameter 'foo'
// ACTION: Create local variable 'foo'
// ERROR: Unresolved reference: foo
fun test() {
fun nestedTest(): Int {
return <caret>foo
}
}
@@ -0,0 +1,10 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A {
class B {
fun test(): Int {
return <caret>foo
}
}
}
@@ -0,0 +1,10 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A {
object B {
fun test(): Int {
return <caret>foo
}
}
}
@@ -0,0 +1,8 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T) {
fun test(): A<Int> {
return this.<caret>foo
}
}
@@ -0,0 +1,8 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T)
fun <U> A<U>.test(): A<Int> {
return this.<caret>foo
}
@@ -0,0 +1,10 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T) {
inner class B<U>(val m: U) {
fun test(): A<Int> {
return this.<caret>foo
}
}
}
@@ -0,0 +1,10 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T) {
inner class B<U>(val m: U) {
fun test(): A<Int> {
return this@A.<caret>foo
}
}
}
@@ -0,0 +1,6 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized
fun test(): Int {
return <caret>foo
}
@@ -0,0 +1,12 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T) {
class object {
}
}
fun test() {
val a: Int = A.<caret>foo
}
@@ -0,0 +1,6 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized
fun test() {
val a: Int = Unit.<caret>foo
}
@@ -0,0 +1,8 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized
class A<T>(val n: T)
fun test() {
val a: A<Int> = 2.<caret>foo
}
@@ -0,0 +1,8 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
object A
fun test() {
val a: Int = A.<caret>foo
}
@@ -0,0 +1,8 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T)
fun test() {
val a: A<Int> = A(1).<caret>foo
}
@@ -0,0 +1,8 @@
// "Create property 'foo' from usage" "true"
// ERROR: Property must be initialized or be abstract
class A<T>(val n: T)
fun test<U>(u: U) {
val a: A<U> = A(u).<caret>foo
}
@@ -1164,7 +1164,7 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
@TestMetadata("idea/testData/quickfix/createFromUsage/createVariable") @TestMetadata("idea/testData/quickfix/createFromUsage/createVariable")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({CreateVariable.LocalVariable.class, CreateVariable.Parameter.class}) @InnerTestClasses({CreateVariable.LocalVariable.class, CreateVariable.Parameter.class, CreateVariable.Property.class})
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class) @RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
public static class CreateVariable extends AbstractQuickFixTest { public static class CreateVariable extends AbstractQuickFixTest {
public void testAllFilesPresentInCreateVariable() throws Exception { public void testAllFilesPresentInCreateVariable() throws Exception {
@@ -1455,6 +1455,112 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
} }
@TestMetadata("idea/testData/quickfix/createFromUsage/createVariable/property")
@TestDataPath("$PROJECT_ROOT")
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
public static class Property extends AbstractQuickFixTest {
public void testAllFilesPresentInProperty() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createVariable/property"), Pattern.compile("^before(\\w+)\\.kt$"), true);
}
@TestMetadata("beforeCallOnUserType.kt")
public void testCallOnUserType() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeCallOnUserType.kt");
doTest(fileName);
}
@TestMetadata("beforeInconsistentTypes.kt")
public void testInconsistentTypes() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeInconsistentTypes.kt");
doTest(fileName);
}
@TestMetadata("beforeLocalValNoReceiver.kt")
public void testLocalValNoReceiver() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeLocalValNoReceiver.kt");
doTest(fileName);
}
@TestMetadata("beforeMemberValNoReceiver.kt")
public void testMemberValNoReceiver() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeMemberValNoReceiver.kt");
doTest(fileName);
}
@TestMetadata("beforeObjectMemberValNoReceiver.kt")
public void testObjectMemberValNoReceiver() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeObjectMemberValNoReceiver.kt");
doTest(fileName);
}
@TestMetadata("beforeThisInClass.kt")
public void testThisInClass() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeThisInClass.kt");
doTest(fileName);
}
@TestMetadata("beforeThisInExtension.kt")
public void testThisInExtension() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeThisInExtension.kt");
doTest(fileName);
}
@TestMetadata("beforeThisInNestedClass1.kt")
public void testThisInNestedClass1() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeThisInNestedClass1.kt");
doTest(fileName);
}
@TestMetadata("beforeThisInNestedClass2.kt")
public void testThisInNestedClass2() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeThisInNestedClass2.kt");
doTest(fileName);
}
@TestMetadata("beforeTopLevelValNoReceiver.kt")
public void testTopLevelValNoReceiver() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeTopLevelValNoReceiver.kt");
doTest(fileName);
}
@TestMetadata("beforeValOnClassObject.kt")
public void testValOnClassObject() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeValOnClassObject.kt");
doTest(fileName);
}
@TestMetadata("beforeValOnLibObject.kt")
public void testValOnLibObject() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeValOnLibObject.kt");
doTest(fileName);
}
@TestMetadata("beforeValOnLibType.kt")
public void testValOnLibType() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeValOnLibType.kt");
doTest(fileName);
}
@TestMetadata("beforeValOnUserObject.kt")
public void testValOnUserObject() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeValOnUserObject.kt");
doTest(fileName);
}
@TestMetadata("beforeValOnUserType.kt")
public void testValOnUserType() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeValOnUserType.kt");
doTest(fileName);
}
@TestMetadata("beforeValOnUserTypeWithTypeParams.kt")
public void testValOnUserTypeWithTypeParams() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeValOnUserTypeWithTypeParams.kt");
doTest(fileName);
}
}
} }
} }