Create from usage (function/property): Suggest separate actions for extensions and non-extension declarations

#KT-6023 Fixed
This commit is contained in:
Alexey Sedunov
2015-02-16 14:04:09 +03:00
parent 41a4dd4128
commit 97b0f50d35
55 changed files with 141 additions and 113 deletions
@@ -24,12 +24,12 @@ import java.util.Collections
// TODO: Replace with trait when all subclasses are translated to Kotlin
public abstract class JetIntentionActionsFactory {
protected open fun isApplicableForCodeFragment(): Boolean = false
protected abstract fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>
protected abstract fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>?
public fun createActions(diagnostic: Diagnostic): List<IntentionAction> {
if (diagnostic.getPsiElement().getContainingFile() is JetCodeFragment && !isApplicableForCodeFragment()) {
return Collections.emptyList()
}
return doCreateActions(diagnostic)
return doCreateActions(diagnostic) ?: Collections.emptyList()
}
}
@@ -68,10 +68,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
import org.jetbrains.kotlin.psi.psiUtil.siblings
import org.jetbrains.kotlin.idea.util.isUnit
import com.intellij.openapi.editor.ScrollType
import com.intellij.openapi.editor.LogicalPosition
import com.intellij.openapi.editor.actions.EditorActionUtil
import com.intellij.openapi.editor.actions.LineEndAction
import com.intellij.openapi.editor.actions.EnterAction
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
private val TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList"
@@ -122,19 +118,11 @@ class CallableBuilderConfiguration(
val callableInfos: List<CallableInfo>,
val originalElement: JetElement,
val currentFile: JetFile,
val currentEditor: Editor,
val currentEditor: Editor?,
val isExtension: Boolean = false,
val enableSubstitutions: Boolean = true
)
fun CallableBuilderConfiguration(
callableInfo: CallableInfo,
originalExpression: JetExpression,
currentFile: JetFile,
currentEditor: Editor
): CallableBuilderConfiguration {
return CallableBuilderConfiguration(Collections.singletonList(callableInfo), originalExpression, currentFile, currentEditor)
}
trait CallablePlacement {
class WithReceiver(val receiverTypeCandidate: TypeCandidate): CallablePlacement
class NoReceiver(val containingElement: JetElement): CallablePlacement
@@ -207,6 +195,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
fun build() {
try {
assert (config.currentEditor != null, "Can't run build() without editor")
if (finished) throw IllegalStateException("Current builder has already finished")
buildNext(config.callableInfos.iterator())
}
@@ -217,7 +206,6 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
private inner class Context(val callableInfo: CallableInfo) {
val skipReturnType: Boolean
val isExtension: Boolean
val containingFile: JetFile
val containingFileEditor: Editor
val containingElement: JetElement
@@ -233,7 +221,6 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
val placement = placement
when {
placement is CallablePlacement.NoReceiver -> {
isExtension = false
containingElement = placement.containingElement
receiverClassDescriptor = (containingElement as? JetClassOrObject)?.let { currentFileContext[BindingContext.CLASS, it] }
}
@@ -241,8 +228,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
receiverClassDescriptor =
placement.receiverTypeCandidate.theType.getConstructor().getDeclarationDescriptor() as? ClassDescriptor
val classDeclaration = receiverClassDescriptor?.let { DescriptorToSourceUtils.classDescriptorToDeclaration(it) }
isExtension = !(classDeclaration is JetClassOrObject && classDeclaration.isWritable())
containingElement = if (isExtension) config.currentFile else classDeclaration as JetElement
containingElement = if (config.isExtension) config.currentFile else classDeclaration as JetElement
}
else -> throw IllegalArgumentException("Unexpected placement: $placement")
}
@@ -254,10 +240,10 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
containingFileEditor = FileEditorManager.getInstance(config.currentFile.getProject())!!.getSelectedTextEditor()!!
}
else {
containingFileEditor = config.currentEditor
containingFileEditor = config.currentEditor!!
}
val scope = if (isExtension || receiverClassDescriptor == null) {
val scope = if (config.isExtension || receiverClassDescriptor == null) {
currentFileModule.getPackage(config.currentFile.getPackageFqName())!!.getMemberScope()
}
else {
@@ -531,7 +517,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
private fun setupTypeReferencesForShortening(declaration: JetNamedDeclaration,
typeRefsToShorten: MutableList<JetElement>,
parameterTypeExpressions: List<TypeExpression>) {
if (isExtension) {
if (config.isExtension) {
val receiverTypeRef = JetPsiFactory(declaration).createType(receiverTypeCandidate!!.theType.renderLong(typeParameterNameMap))
replaceWithLongerName(receiverTypeRef, receiverTypeCandidate.theType)
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory
import org.jetbrains.kotlin.diagnostics.Diagnostic
import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.psi.JetBinaryExpression
@@ -27,9 +26,10 @@ import java.util.Collections
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
import org.jetbrains.kotlin.idea.quickfix.JetIntentionActionsFactory
public object CreateBinaryOperationActionFactory: JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
public object CreateBinaryOperationActionFactory: JetIntentionActionsFactory() {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? {
val callExpr = diagnostic.getPsiElement().getParent() as? JetBinaryExpression ?: return null
val token = callExpr.getOperationToken() as JetToken
val operationName = when (token) {
@@ -54,6 +54,6 @@ public object CreateBinaryOperationActionFactory: JetSingleIntentionActionFactor
else -> TypeInfo(callExpr, Variance.OUT_VARIANCE)
}
val parameters = Collections.singletonList(ParameterInfo(TypeInfo(argumentExpr, Variance.IN_VARIANCE)))
return CreateCallableFromUsageFix(callExpr, FunctionInfo(operationName, receiverType, returnType, Collections.emptyList(), parameters))
return CreateCallableFromUsageFixes(callExpr, FunctionInfo(operationName, receiverType, returnType, Collections.emptyList(), parameters))
}
}
@@ -28,16 +28,21 @@ 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 org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
import java.util.HashSet
import org.jetbrains.kotlin.psi.JetElement
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
public class CreateCallableFromUsageFix(
originalExpression: JetExpression,
val callableInfos: List<CallableInfo>) : CreateFromUsageFixBase(originalExpression) {
val callableInfos: List<CallableInfo>,
val isExtension: Boolean
) : CreateFromUsageFixBase(originalExpression) {
{
assert (callableInfos.isNotEmpty(), "No CallableInfos: ${JetPsiUtil.getElementTextWithContext(originalExpression)}")
if (callableInfos.size > 1) {
val receiverSet = callableInfos.mapTo(HashSet<TypeInfo>()) { it.receiverTypeInfo }
if (receiverSet.size > 1) throw AssertionError("All functions must have common receiver: $receiverSet")
@@ -47,6 +52,13 @@ public class CreateCallableFromUsageFix(
}
}
private fun getDeclarationIfApplicable(project: Project, candidate: TypeCandidate): PsiElement? {
val descriptor = candidate.theType.getConstructor().getDeclarationDescriptor()
val declaration = DescriptorToDeclarationUtil.getDeclaration(project, descriptor) ?: return null
if (declaration !is JetClassOrObject && declaration !is PsiClass) return null
return if (isExtension || declaration.canRefactor()) declaration else null
}
override fun getText(): String {
val renderedCallables = callableInfos.map {
val kind = when (it.kind) {
@@ -56,14 +68,31 @@ public class CreateCallableFromUsageFix(
}
"$kind '${it.name}'"
}
return JetBundle.message(
"create.0.from.usage",
renderedCallables.joinToString(prefix = if (isExtension) "extension " else "")
)
}
return JetBundle.message("create.0.from.usage", renderedCallables.joinToString())
fun isAvailable(): Boolean {
val callableInfo = callableInfos.first()
val receiverInfo = callableInfo.receiverTypeInfo
if (receiverInfo is TypeInfo.Empty) return !isExtension
val file = element.getContainingFile() as JetFile
val project = file.getProject()
val callableBuilder =
CallableBuilderConfiguration(callableInfos, element as JetExpression, file, null, isExtension).createBuilder()
val receiverTypeCandidates = callableBuilder.computeTypeCandidates(callableInfo.receiverTypeInfo)
return receiverTypeCandidates.any { getDeclarationIfApplicable(project, it) != null }
}
override fun invoke(project: Project, editor: Editor?, file: JetFile?) {
val callableInfo = callableInfos.first()
val callableBuilder = CallableBuilderConfiguration(callableInfos, element as JetExpression, file!!, editor!!).createBuilder()
val callableBuilder =
CallableBuilderConfiguration(callableInfos, element as JetExpression, file!!, editor!!, isExtension).createBuilder()
fun runBuilder(placement: CallablePlacement) {
callableBuilder.placement = placement
@@ -74,11 +103,7 @@ public class CreateCallableFromUsageFix(
val receiverTypeCandidates = callableBuilder.computeTypeCandidates(callableInfo.receiverTypeInfo)
if (receiverTypeCandidates.isNotEmpty()) {
val containers = receiverTypeCandidates
.map { candidate ->
val descriptor = candidate.theType.getConstructor().getDeclarationDescriptor()
val declaration = DescriptorToDeclarationUtil.getDeclaration(project, descriptor)
if (declaration is JetClassOrObject || declaration is PsiClass) candidate to declaration else null
}
.map { candidate -> getDeclarationIfApplicable(project, candidate)?.let { candidate to it } }
.filterNotNull()
chooseContainerElementIfNecessary(containers, editor, popupTitle, false, { it.second }) {
@@ -96,9 +121,19 @@ public class CreateCallableFromUsageFix(
}
}
public fun CreateCallableFromUsageFix(
public fun CreateCallableFromUsageFixes(
originalExpression: JetExpression,
callableInfos: List<CallableInfo>
) : List<CreateCallableFromUsageFix> {
return listOf(
CreateCallableFromUsageFix(originalExpression, callableInfos, false),
CreateCallableFromUsageFix(originalExpression, callableInfos, true)
).filter { it.isAvailable() }
}
public fun CreateCallableFromUsageFixes(
originalExpression: JetExpression,
callableInfo: CallableInfo
) : CreateCallableFromUsageFix {
return CreateCallableFromUsageFix(originalExpression, callableInfo.singletonOrEmptyList())
) : List<CreateCallableFromUsageFix> {
return CreateCallableFromUsageFixes(originalExpression, Collections.singletonList(callableInfo))
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory
import org.jetbrains.kotlin.diagnostics.Diagnostic
import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.resolve.dataClassUtils.*
@@ -26,9 +25,10 @@ import org.jetbrains.kotlin.psi.JetMultiDeclaration
import org.jetbrains.kotlin.psi.JetForExpression
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
import org.jetbrains.kotlin.idea.quickfix.JetIntentionActionsFactory
object CreateComponentFunctionActionFactory : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
object CreateComponentFunctionActionFactory : JetIntentionActionsFactory() {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? {
val diagnosticWithParameters = Errors.COMPONENT_FUNCTION_MISSING.cast(diagnostic)
val name = diagnosticWithParameters.getA()
if (!isComponentLike(name)) return null
@@ -50,6 +50,6 @@ object CreateComponentFunctionActionFactory : JetSingleIntentionActionFactory()
val entry = entries[componentNumber]
val returnType = TypeInfo(entry, Variance.OUT_VARIANCE)
return CreateCallableFromUsageFix(multiDeclaration!!, FunctionInfo(name.getIdentifier(), ownerType, returnType))
return CreateCallableFromUsageFixes(multiDeclaration!!, FunctionInfo(name.getIdentifier(), ownerType, returnType))
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory
import org.jetbrains.kotlin.diagnostics.Diagnostic
import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.psi.JetCallExpression
@@ -42,9 +41,10 @@ import org.jetbrains.kotlin.psi.JetTypeReference
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.psi.JetAnnotationEntry
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.quickfix.JetIntentionActionsFactory
object CreateFunctionOrPropertyFromCallActionFactory : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
object CreateFunctionOrPropertyFromCallActionFactory : JetIntentionActionsFactory() {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? {
val diagElement = diagnostic.getPsiElement()
if (PsiTreeUtil.getParentOfType(diagElement, javaClass<JetTypeReference>(), javaClass<JetAnnotationEntry>()) != null) return null
@@ -119,6 +119,6 @@ object CreateFunctionOrPropertyFromCallActionFactory : JetSingleIntentionActionF
else -> return null
}
return CreateCallableFromUsageFix(callExpr, callableInfo)
return CreateCallableFromUsageFixes(callExpr, callableInfo)
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory
import org.jetbrains.kotlin.diagnostics.Diagnostic
import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.idea.quickfix.QuickFixUtil
@@ -24,9 +23,10 @@ import org.jetbrains.kotlin.psi.JetArrayAccessExpression
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
import java.util.Collections
import org.jetbrains.kotlin.idea.quickfix.JetIntentionActionsFactory
object CreateGetFunctionActionFactory : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
object CreateGetFunctionActionFactory : JetIntentionActionsFactory() {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? {
val accessExpr = QuickFixUtil.getParentElementOfType(diagnostic, javaClass<JetArrayAccessExpression>()) ?: return null
val arrayExpr = accessExpr.getArrayExpression() ?: return null
val arrayType = TypeInfo(arrayExpr, Variance.IN_VARIANCE)
@@ -36,6 +36,6 @@ object CreateGetFunctionActionFactory : JetSingleIntentionActionFactory() {
}
val returnType = TypeInfo(accessExpr, Variance.OUT_VARIANCE)
return CreateCallableFromUsageFix(accessExpr, FunctionInfo("get", arrayType, returnType, Collections.emptyList(), parameters))
return CreateCallableFromUsageFixes(accessExpr, FunctionInfo("get", arrayType, returnType, Collections.emptyList(), parameters))
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory
import org.jetbrains.kotlin.diagnostics.Diagnostic
import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
@@ -26,14 +25,15 @@ import org.jetbrains.kotlin.idea.quickfix.QuickFixUtil
import org.jetbrains.kotlin.psi.JetForExpression
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
import org.jetbrains.kotlin.idea.quickfix.JetIntentionActionsFactory
object CreateHasNextFunctionActionFactory : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
object CreateHasNextFunctionActionFactory : JetIntentionActionsFactory() {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? {
val diagnosticWithParameters = DiagnosticFactory.cast(diagnostic, Errors.HAS_NEXT_MISSING, Errors.HAS_NEXT_FUNCTION_NONE_APPLICABLE)
val ownerType = TypeInfo(diagnosticWithParameters.getA(), Variance.IN_VARIANCE)
val forExpr = QuickFixUtil.getParentElementOfType(diagnostic, javaClass<JetForExpression>()) ?: return null
val returnType = TypeInfo(KotlinBuiltIns.getInstance().getBooleanType(), Variance.OUT_VARIANCE)
return CreateCallableFromUsageFix(forExpr, FunctionInfo("hasNext", ownerType, returnType))
return CreateCallableFromUsageFixes(forExpr, FunctionInfo("hasNext", ownerType, returnType))
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory
import org.jetbrains.kotlin.diagnostics.Diagnostic
import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.types.Variance
@@ -25,9 +24,10 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
import java.util.Collections
import org.jetbrains.kotlin.idea.quickfix.JetIntentionActionsFactory
object CreateInvokeFunctionActionFactory : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
object CreateInvokeFunctionActionFactory : JetIntentionActionsFactory() {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? {
val callExpr = diagnostic.getPsiElement().getParent() as? JetCallExpression ?: return null
val expectedType = Errors.FUNCTION_EXPECTED.cast(diagnostic).getB()
@@ -44,6 +44,6 @@ object CreateInvokeFunctionActionFactory : JetSingleIntentionActionFactory() {
}
val returnType = TypeInfo(callExpr, Variance.OUT_VARIANCE)
return CreateCallableFromUsageFix(callExpr, FunctionInfo("invoke", receiverType, returnType, Collections.emptyList(), parameters))
return CreateCallableFromUsageFixes(callExpr, FunctionInfo("invoke", receiverType, returnType, Collections.emptyList(), parameters))
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory
import org.jetbrains.kotlin.diagnostics.Diagnostic
import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.psi.JetFile
@@ -30,9 +29,10 @@ import org.jetbrains.kotlin.types.TypeProjectionImpl
import java.util.Collections
import org.jetbrains.kotlin.types.JetTypeImpl
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
import org.jetbrains.kotlin.idea.quickfix.JetIntentionActionsFactory
object CreateIteratorFunctionActionFactory : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
object CreateIteratorFunctionActionFactory : JetIntentionActionsFactory() {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? {
val file = diagnostic.getPsiFile() as? JetFile ?: return null
val forExpr = QuickFixUtil.getParentElementOfType(diagnostic, javaClass<JetForExpression>()) ?: return null
val iterableExpr = forExpr.getLoopRange() ?: return null
@@ -48,6 +48,6 @@ object CreateIteratorFunctionActionFactory : JetSingleIntentionActionFactory() {
val returnJetTypeArguments = Collections.singletonList(returnJetTypeParameterType)
val newReturnJetType = JetTypeImpl(returnJetType.getAnnotations(), returnJetType.getConstructor(), returnJetType.isMarkedNullable(), returnJetTypeArguments, returnJetType.getMemberScope())
val returnType = TypeInfo(newReturnJetType, Variance.OUT_VARIANCE)
return CreateCallableFromUsageFix(forExpr, FunctionInfo("iterator", iterableType, returnType))
return CreateCallableFromUsageFixes(forExpr, FunctionInfo("iterator", iterableType, returnType))
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory
import org.jetbrains.kotlin.diagnostics.Diagnostic
import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.psi.JetExpression
@@ -26,15 +25,16 @@ import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.idea.quickfix.QuickFixUtil
import org.jetbrains.kotlin.psi.JetForExpression
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
import org.jetbrains.kotlin.idea.quickfix.JetIntentionActionsFactory
object CreateNextFunctionActionFactory : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
object CreateNextFunctionActionFactory : JetIntentionActionsFactory() {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? {
val diagnosticWithParameters = DiagnosticFactory.cast(diagnostic, Errors.NEXT_MISSING, Errors.NEXT_NONE_APPLICABLE)
val ownerType = TypeInfo(diagnosticWithParameters.getA(), Variance.IN_VARIANCE)
val forExpr = QuickFixUtil.getParentElementOfType(diagnostic, javaClass<JetForExpression>()) ?: return null
val variableExpr: JetExpression = ((forExpr.getLoopParameter() ?: forExpr.getMultiParameter()) ?: return null) as JetExpression
val returnType = TypeInfo(variableExpr, Variance.OUT_VARIANCE)
return CreateCallableFromUsageFix(forExpr, FunctionInfo("next", ownerType, returnType))
return CreateCallableFromUsageFixes(forExpr, FunctionInfo("next", ownerType, returnType))
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory
import org.jetbrains.kotlin.diagnostics.Diagnostic
import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
@@ -33,9 +32,10 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.Callab
import com.intellij.util.SmartList
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.quickfix.JetIntentionActionsFactory
object CreatePropertyDelegateAccessorsActionFactory : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
object CreatePropertyDelegateAccessorsActionFactory : JetIntentionActionsFactory() {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? {
val expression = diagnostic.getPsiElement() as? JetExpression ?: return null
val context = expression.analyze()
[suppress("UNCHECKED_CAST")]
@@ -79,6 +79,6 @@ object CreatePropertyDelegateAccessorsActionFactory : JetSingleIntentionActionFa
callableInfos.add(setterInfo)
}
return CreateCallableFromUsageFix(expression, callableInfos)
return CreateCallableFromUsageFixes(expression, callableInfos)
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory
import org.jetbrains.kotlin.diagnostics.Diagnostic
import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.idea.quickfix.QuickFixUtil
@@ -33,9 +32,10 @@ import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.quickfix.JetIntentionActionsFactory
object CreateSetFunctionActionFactory : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
object CreateSetFunctionActionFactory : JetIntentionActionsFactory() {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? {
val accessExpr = QuickFixUtil.getParentElementOfType(diagnostic, javaClass<JetArrayAccessExpression>()) ?: return null
val arrayExpr = accessExpr.getArrayExpression() ?: return null
val arrayType = TypeInfo(arrayExpr, Variance.IN_VARIANCE)
@@ -63,6 +63,6 @@ object CreateSetFunctionActionFactory : JetSingleIntentionActionFactory() {
parameters.add(ParameterInfo(valType, "value"))
val returnType = TypeInfo(builtIns.getUnitType(), Variance.OUT_VARIANCE)
return CreateCallableFromUsageFix(accessExpr, FunctionInfo("set", arrayType, returnType, Collections.emptyList(), parameters))
return CreateCallableFromUsageFixes(accessExpr, FunctionInfo("set", arrayType, returnType, Collections.emptyList(), parameters))
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory
import org.jetbrains.kotlin.diagnostics.Diagnostic
import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.types.expressions.OperatorConventions
@@ -24,9 +23,10 @@ import org.jetbrains.kotlin.lexer.JetToken
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.psi.JetUnaryExpression
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
import org.jetbrains.kotlin.idea.quickfix.JetIntentionActionsFactory
public object CreateUnaryOperationActionFactory: JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
public object CreateUnaryOperationActionFactory: JetIntentionActionsFactory() {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? {
val callExpr = diagnostic.getPsiElement().getParent() as? JetUnaryExpression ?: return null
val token = callExpr.getOperationToken() as JetToken
val operationName = OperatorConventions.getNameForOperationSymbol(token) ?: return null
@@ -36,6 +36,6 @@ public object CreateUnaryOperationActionFactory: JetSingleIntentionActionFactory
val receiverType = TypeInfo(receiverExpr, Variance.IN_VARIANCE)
val returnType = if (incDec) TypeInfo.ByReceiverType(Variance.OUT_VARIANCE) else TypeInfo(callExpr, Variance.OUT_VARIANCE)
return CreateCallableFromUsageFix(callExpr, FunctionInfo(operationName.asString(), receiverType, returnType))
return CreateCallableFromUsageFixes(callExpr, FunctionInfo(operationName.asString(), receiverType, returnType))
}
}
@@ -112,7 +112,7 @@ public class CreateClassFromUsageFix(
val constructorInfo = ConstructorInfo(classInfo, expectedTypeInfo)
val builder = CallableBuilderConfiguration(
Collections.singletonList(constructorInfo), element as JetElement, file, editor, kind == PLAIN_CLASS || kind == TRAIT
Collections.singletonList(constructorInfo), element as JetElement, file, editor, false, kind == PLAIN_CLASS || kind == TRAIT
).createBuilder()
builder.placement = CallablePlacement.NoReceiver(targetParent)
CommandProcessor.getInstance().executeCommand(project, { builder.build() }, getText(), null)
@@ -1,4 +1,5 @@
// "Import" "false"
// ACTION: Create extension function 'inc'
// ACTION: Create function 'inc'
// ACTION: Create local variable '++'
// ACTION: Create parameter '++'
@@ -1,5 +1,5 @@
// "Create class 'Foo'" "false"
// ACTION: Create function 'Foo'
// ACTION: Create extension function 'Foo'
// ACTION: Replace with infix function call
// ACTION: Split property declaration
// ERROR: Unresolved reference: Foo
@@ -1,5 +1,5 @@
// "Create class 'Foo'" "false"
// ACTION: Create function 'Foo'
// ACTION: Create extension function 'Foo'
// ACTION: Convert to expression body
// ERROR: Unresolved reference: Foo
@@ -1,5 +1,5 @@
// "Create class 'Foo'" "false"
// ACTION: Create function 'Foo'
// ACTION: Create extension function 'Foo'
// ERROR: Unresolved reference: Foo
class A<T>(val items: List<T>) {
@@ -1,4 +1,5 @@
// "Create class 'A'" "false"
// ACTION: Create extension property 'A'
// ACTION: Create property 'A'
// ERROR: Unresolved reference: A
package p
@@ -1,4 +1,5 @@
// "Create enum constant 'A'" "false"
// ACTION: Create extension property 'A'
// ACTION: Create property 'A'
// ERROR: Unresolved reference: A
package p
@@ -1,4 +1,5 @@
// "Create object 'A'" "false"
// ACTION: Create extension property 'A'
// ACTION: Create property 'A'
// ERROR: Unresolved reference: A
package p
@@ -1,4 +1,4 @@
// "Create function 'plus'" "true"
// "Create extension function 'plus'" "true"
class A<T>(val n: T)
@@ -1,4 +1,4 @@
// "Create function 'plus'" "true"
// "Create extension function 'plus'" "true"
class A<T>(val n: T)
@@ -1,4 +1,4 @@
// "Create function 'foo'" "true"
// "Create extension function 'foo'" "true"
fun test() {
val a: Int = Unit.foo(2)
@@ -1,4 +1,4 @@
// "Create function 'foo'" "true"
// "Create extension function 'foo'" "true"
class A<T>(val n: T)
@@ -1,4 +1,4 @@
// "Create function 'foo'" "true"
// "Create extension function 'foo'" "true"
fun test() {
val a: Int = Unit.<caret>foo(2)
@@ -1,4 +1,4 @@
// "Create function 'foo'" "true"
// "Create extension function 'foo'" "true"
class A<T>(val n: T)
@@ -1,4 +1,4 @@
// "Create function 'foo'" "true"
// "Create extension function 'foo'" "true"
// ERROR: Unresolved reference: foo
fun test(): Int {
@@ -1,4 +1,4 @@
// "Create function 'foo'" "true"
// "Create extension function 'foo'" "true"
// ERROR: Unresolved reference: foo
fun test(): Int {
@@ -1,4 +1,4 @@
// "Create function 'foo'" "true"
// "Create extension function 'foo'" "true"
class A<T>(val items: List<T>) {
fun test(): Int {
@@ -1,4 +1,4 @@
// "Create function 'foo'" "true"
// "Create extension function 'foo'" "true"
class A<T>(val items: List<T>) {
fun test(): Int {
@@ -1,4 +1,4 @@
// "Create function 'foo'" "true"
// "Create extension function 'foo'" "true"
class A<T>(val items: List<T>) {
fun test(): Int {
@@ -1,4 +1,4 @@
// "Create function 'foo'" "true"
// "Create extension function 'foo'" "true"
class A<T>(val items: List<T>) {
fun test(): Int {
@@ -1,4 +1,4 @@
// "Create function 'foo'" "true"
// "Create extension function 'foo'" "true"
class A<T>(val items: List<T>) {
fun test(): Int {
@@ -1,4 +1,4 @@
// "Create function 'foo'" "true"
// "Create extension function 'foo'" "true"
class A<T>(val items: List<T>) {
fun test(): Int {
@@ -1,4 +1,4 @@
// "Create function 'component2'" "true"
// "Create extension function 'component2'" "true"
class FooIterator<T> {
fun hasNext(): Boolean { return false }
fun next(): Any {
@@ -1,4 +1,4 @@
// "Create function 'component2'" "true"
// "Create extension function 'component2'" "true"
class FooIterator<T> {
fun hasNext(): Boolean { return false }
fun next(): Any {
@@ -1,4 +1,4 @@
// "Create function 'get'" "true"
// "Create extension function 'get'" "true"
fun x (y: Any) {
val z: Any = y[""]
}
@@ -1,4 +1,4 @@
// "Create function 'get'" "true"
// "Create extension function 'get'" "true"
fun x (y: Any) {
val z: Any = y<caret>[""]
}
@@ -1,4 +1,4 @@
// "Create function 'invoke'" "true"
// "Create extension function 'invoke'" "true"
class A<T>(val n: T)
@@ -1,4 +1,4 @@
// "Create function 'invoke'" "true"
// "Create extension function 'invoke'" "true"
class A<T>(val n: T)
@@ -1,4 +1,4 @@
// "Create function 'set'" "true"
// "Create extension function 'set'" "true"
import java.util.ArrayList
@@ -1,4 +1,4 @@
// "Create function 'set'" "true"
// "Create extension function 'set'" "true"
class Foo<T> {
fun <T> x (y: Any, w: java.util.ArrayList<T>) {
@@ -1,4 +1,4 @@
// "Create function 'minus'" "true"
// "Create extension function 'minus'" "true"
fun test() {
val a = -false
@@ -1,4 +1,4 @@
// "Create function 'minus'" "true"
// "Create extension function 'minus'" "true"
fun test() {
val a = <caret>-false
@@ -1,4 +1,5 @@
// "Create local variable 'foo'" "false"
// ACTION: Create extension property 'foo'
// ACTION: Create property 'foo'
// ACTION: Split property declaration
// ERROR: Unresolved reference: foo
@@ -1,5 +1,6 @@
// "Create parameter 'foo'" "false"
// ACTION: Split property declaration
// ACTION: Create extension property 'foo'
// ACTION: Create property 'foo'
// ERROR: Unresolved reference: foo
@@ -1,4 +1,4 @@
// "Create property 'foo'" "true"
// "Create extension property 'foo'" "true"
// ERROR: Property must be initialized
fun test() {
@@ -1,4 +1,4 @@
// "Create property 'foo'" "true"
// "Create extension property 'foo'" "true"
// ERROR: Property must be initialized
class A<T>(val n: T)
@@ -1,4 +1,4 @@
// "Create property 'foo'" "true"
// "Create extension property 'foo'" "true"
// ERROR: Property must be initialized
class A<T>(val n: T)
@@ -1,4 +1,5 @@
// "Create property 'foo'" "false"
// ACTION: Create extension function 'bar'
// ACTION: Create function 'bar'
// ACTION: Replace with infix function call
// ERROR: Unresolved reference: bar
@@ -1,4 +1,4 @@
// "Create property 'foo'" "true"
// "Create extension property 'foo'" "true"
// ERROR: Property must be initialized
fun test() {
@@ -1,4 +1,4 @@
// "Create property 'foo'" "true"
// "Create extension property 'foo'" "true"
// ERROR: Property must be initialized
class A<T>(val n: T)
@@ -1,4 +1,4 @@
// "Create property 'foo'" "true"
// "Create extension property 'foo'" "true"
// ERROR: Property must be initialized
class A<T>(val n: T)