Create From Usage: Add support of get/set functions in property delegates
#KT-5977 Fixed
This commit is contained in:
@@ -658,6 +658,11 @@ public class KotlinBuiltIns {
|
||||
return getAnnotation().getDefaultType();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassDescriptor getPropertyMetadata() {
|
||||
return getBuiltInClassByName("PropertyMetadata");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassDescriptor getPropertyMetadataImpl() {
|
||||
return getBuiltInClassByName("PropertyMetadataImpl");
|
||||
|
||||
@@ -184,7 +184,7 @@ map.platform.class.to.kotlin.multiple=Change all usages of ''{0}'' in this file
|
||||
map.platform.class.to.kotlin.advertisement=Choose an appropriate Kotlin class
|
||||
map.platform.class.to.kotlin.family=Change to Kotlin class
|
||||
create.from.usage.family=Create from usage
|
||||
create.function.from.usage=Create function ''{0}'' from usage
|
||||
create.0.from.usage=Create {0} from usage
|
||||
create.property.from.usage=Create property ''{0}'' from usage
|
||||
create.local.variable.from.usage=Create local variable ''{0}''
|
||||
create.parameter.from.usage=Create parameter ''{0}''
|
||||
|
||||
@@ -264,5 +264,8 @@ public class QuickFixRegistrar {
|
||||
QuickFixes.factories.put(NEXT_NONE_APPLICABLE, CreateNextFunctionActionFactory.INSTANCE$);
|
||||
QuickFixes.factories.put(ITERATOR_MISSING, CreateIteratorFunctionActionFactory.INSTANCE$);
|
||||
QuickFixes.factories.put(COMPONENT_FUNCTION_MISSING, CreateComponentFunctionActionFactory.INSTANCE$);
|
||||
|
||||
QuickFixes.factories.put(DELEGATE_SPECIAL_FUNCTION_MISSING, CreatePropertyDelegateAccessorsActionFactory.INSTANCE$);
|
||||
QuickFixes.factories.put(DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE, CreatePropertyDelegateAccessorsActionFactory.INSTANCE$);
|
||||
}
|
||||
}
|
||||
|
||||
+39
-27
@@ -101,7 +101,7 @@ fun List<TypeCandidate>.getTypeByRenderedType(renderedType: String): JetType? =
|
||||
firstOrNull { it.renderedType == renderedType }?.theType
|
||||
|
||||
class CallableBuilderConfiguration(
|
||||
val callableInfo: CallableInfo,
|
||||
val callableInfos: List<CallableInfo>,
|
||||
val originalExpression: JetExpression,
|
||||
val currentFile: JetFile,
|
||||
val currentEditor: Editor
|
||||
@@ -128,6 +128,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
|
||||
public var placement: CallablePlacement by Delegates.notNull()
|
||||
|
||||
private val elementsToShorten = ArrayList<JetElement>()
|
||||
|
||||
fun computeTypeCandidates(typeInfo: TypeInfo): List<TypeCandidate> =
|
||||
typeCandidates.getOrPut(typeInfo) { typeInfo.getPossibleTypes(this).map { TypeCandidate(it) } }
|
||||
|
||||
@@ -165,19 +167,27 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildNext(iterator: Iterator<CallableInfo>) {
|
||||
if (iterator.hasNext()) {
|
||||
val context = Context(iterator.next())
|
||||
runWriteAction { context.buildAndRunTemplate { buildNext(iterator) } }
|
||||
}
|
||||
else {
|
||||
ShortenReferences.process(elementsToShorten)
|
||||
}
|
||||
}
|
||||
|
||||
fun build() {
|
||||
try {
|
||||
if (finished) throw IllegalStateException("Current builder has already finished")
|
||||
|
||||
val context = Context()
|
||||
runWriteAction { context.buildAndRunTemplate() }
|
||||
buildNext(config.callableInfos.iterator())
|
||||
}
|
||||
finally {
|
||||
finished = true
|
||||
}
|
||||
}
|
||||
|
||||
private inner class Context {
|
||||
private inner class Context(val callableInfo: CallableInfo) {
|
||||
val skipReturnType: Boolean
|
||||
val isExtension: Boolean
|
||||
val containingFile: JetFile
|
||||
@@ -231,12 +241,13 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
val substitutions = ownerTypeArguments.zip(classTypeParameters).map {
|
||||
JetTypeSubstitution(it.first.getType(), it.second.getType())
|
||||
}.copyToArray()
|
||||
config.callableInfo.parameterInfos.forEach {
|
||||
|
||||
callableInfo.parameterInfos.forEach {
|
||||
computeTypeCandidates(it.typeInfo, substitutions, scope)
|
||||
}
|
||||
|
||||
val returnTypeCandidates = computeTypeCandidates(config.callableInfo.returnTypeInfo, substitutions, scope)
|
||||
skipReturnType = config.callableInfo is FunctionInfo
|
||||
val returnTypeCandidates = computeTypeCandidates(callableInfo.returnTypeInfo, substitutions, scope)
|
||||
skipReturnType = callableInfo is FunctionInfo
|
||||
&& returnTypeCandidates.size == 1
|
||||
&& returnTypeCandidates.first().theType.isUnit()
|
||||
|
||||
@@ -245,9 +256,9 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
|
||||
// figure out type parameter renames to avoid conflicts
|
||||
typeParameterNameMap = getTypeParameterRenames(scope)
|
||||
config.callableInfo.parameterInfos.forEach { renderTypeCandidates(it.typeInfo, typeParameterNameMap) }
|
||||
callableInfo.parameterInfos.forEach { renderTypeCandidates(it.typeInfo, typeParameterNameMap) }
|
||||
if (!skipReturnType) {
|
||||
renderTypeCandidates(config.callableInfo.returnTypeInfo, typeParameterNameMap)
|
||||
renderTypeCandidates(callableInfo.returnTypeInfo, typeParameterNameMap)
|
||||
}
|
||||
receiverTypeCandidate?.render(typeParameterNameMap)
|
||||
}
|
||||
@@ -262,7 +273,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
private fun createDeclarationSkeleton(): JetCallableDeclaration {
|
||||
with (config) {
|
||||
val assignmentToReplace =
|
||||
if (containingElement is JetBlockExpression && (config.callableInfo as? PropertyInfo)?.writable ?: false) {
|
||||
if (containingElement is JetBlockExpression && (callableInfo as? PropertyInfo)?.writable ?: false) {
|
||||
originalExpression as JetBinaryExpression
|
||||
}
|
||||
else null
|
||||
@@ -367,13 +378,13 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
|
||||
allTypeParametersNotInScope.addAll(receiverTypeCandidate?.typeParameters?.toList() ?: Collections.emptyList())
|
||||
|
||||
config.callableInfo.parameterInfos.stream()
|
||||
callableInfo.parameterInfos.stream()
|
||||
.flatMap { typeCandidates[it.typeInfo]!!.stream() }
|
||||
.flatMap { it.typeParameters.stream() }
|
||||
.toCollection(allTypeParametersNotInScope)
|
||||
|
||||
if (!skipReturnType) {
|
||||
computeTypeCandidates(config.callableInfo.returnTypeInfo).stream().flatMapTo(allTypeParametersNotInScope) { it.typeParameters.stream() }
|
||||
computeTypeCandidates(callableInfo.returnTypeInfo).stream().flatMapTo(allTypeParametersNotInScope) { it.typeParameters.stream() }
|
||||
}
|
||||
|
||||
val validator = CollectingValidator { scope.getClassifier(Name.identifier(it)) == null }
|
||||
@@ -383,7 +394,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
}
|
||||
|
||||
private fun setupTypeReferencesForShortening(declaration: JetCallableDeclaration,
|
||||
typeRefsToShorten: MutableList<JetTypeReference>,
|
||||
typeRefsToShorten: MutableList<JetElement>,
|
||||
parameterTypeExpressions: List<TypeExpression>) {
|
||||
if (isExtension) {
|
||||
val receiverTypeRef = JetPsiFactory(declaration).createType(receiverTypeCandidate!!.theType.renderLong(typeParameterNameMap))
|
||||
@@ -397,7 +408,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
|
||||
val returnTypeRef = declaration.getTypeReference()
|
||||
if (returnTypeRef != null) {
|
||||
val returnType = typeCandidates[config.callableInfo.returnTypeInfo]!!.getTypeByRenderedType(
|
||||
val returnType = typeCandidates[callableInfo.returnTypeInfo]!!.getTypeByRenderedType(
|
||||
returnTypeRef.getText()
|
||||
?: throw AssertionError("Expression for return type shouldn't be empty: declaration = ${declaration.getText()}")
|
||||
)
|
||||
@@ -440,7 +451,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, DescriptorUtils.getFqName(it).asString())
|
||||
properties.setProperty(FileTemplate.ATTRIBUTE_SIMPLE_CLASS_NAME, it.getName().asString())
|
||||
}
|
||||
properties.setProperty(ATTRIBUTE_FUNCTION_NAME, config.callableInfo.name)
|
||||
properties.setProperty(ATTRIBUTE_FUNCTION_NAME, callableInfo.name)
|
||||
|
||||
val bodyText = try {
|
||||
fileTemplate!!.getText(properties)
|
||||
@@ -460,7 +471,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
|
||||
private fun setupReturnTypeTemplate(builder: TemplateBuilder, declaration: JetCallableDeclaration): TypeExpression? {
|
||||
val returnTypeRef = declaration.getTypeReference() ?: return null
|
||||
val candidates = typeCandidates[config.callableInfo.returnTypeInfo]!!
|
||||
val candidates = typeCandidates[callableInfo.returnTypeInfo]!!
|
||||
return when (candidates.size) {
|
||||
0 -> null
|
||||
|
||||
@@ -478,7 +489,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
}
|
||||
|
||||
private fun setupValVarTemplate(builder: TemplateBuilder, property: JetProperty) {
|
||||
if (!(config.callableInfo as PropertyInfo).writable) {
|
||||
if (!(callableInfo as PropertyInfo).writable) {
|
||||
builder.replaceElement(property.getValOrVarNode().getPsi()!!, ValVarExpression)
|
||||
}
|
||||
}
|
||||
@@ -487,12 +498,12 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
val typeParameterMap = HashMap<String, Array<String>>()
|
||||
val receiverTypeParameterNames = receiverTypeCandidate?.let { it.typeParameterNames!! } ?: ArrayUtil.EMPTY_STRING_ARRAY
|
||||
|
||||
config.callableInfo.parameterInfos.stream().flatMap { typeCandidates[it.typeInfo]!!.stream() }.forEach {
|
||||
callableInfo.parameterInfos.stream().flatMap { typeCandidates[it.typeInfo]!!.stream() }.forEach {
|
||||
typeParameterMap[it.renderedType!!] = it.typeParameterNames!!
|
||||
}
|
||||
|
||||
if (declaration.getTypeReference() != null) {
|
||||
typeCandidates[config.callableInfo.returnTypeInfo]!!.forEach {
|
||||
typeCandidates[callableInfo.returnTypeInfo]!!.forEach {
|
||||
typeParameterMap[it.renderedType!!] = it.typeParameterNames!!
|
||||
}
|
||||
}
|
||||
@@ -502,10 +513,10 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
}
|
||||
|
||||
private fun setupParameterTypeTemplates(builder: TemplateBuilder, parameterList: List<JetParameter>): List<TypeExpression> {
|
||||
assert(parameterList.size == config.callableInfo.parameterInfos.size)
|
||||
assert(parameterList.size == callableInfo.parameterInfos.size)
|
||||
|
||||
val typeParameters = ArrayList<TypeExpression>()
|
||||
for ((parameter, jetParameter) in config.callableInfo.parameterInfos.zip(parameterList)) {
|
||||
for ((parameter, jetParameter) in callableInfo.parameterInfos.zip(parameterList)) {
|
||||
val parameterTypeExpression = TypeExpression(typeCandidates[parameter.typeInfo]!!)
|
||||
val parameterTypeRef = jetParameter.getTypeReference()!!
|
||||
builder.replaceElement(parameterTypeRef, parameterTypeExpression)
|
||||
@@ -542,7 +553,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
typeRef.replace(fullyQualifiedReceiverTypeRef)
|
||||
}
|
||||
|
||||
fun buildAndRunTemplate() {
|
||||
// build templates
|
||||
fun buildAndRunTemplate(onFinish: () -> Unit) {
|
||||
val declarationSkeleton = createDeclarationSkeleton()
|
||||
val project = declarationSkeleton.getProject()
|
||||
val declarationPointer = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(declarationSkeleton)
|
||||
@@ -576,7 +588,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
// the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it
|
||||
val templateImpl = builder.buildInlineTemplate() as TemplateImpl
|
||||
val variables = templateImpl.getVariables()!!
|
||||
for (i in 0..(config.callableInfo.parameterInfos.size - 1)) {
|
||||
for (i in 0..(callableInfo.parameterInfos.size - 1)) {
|
||||
Collections.swap(variables, i * 2, i * 2 + 1)
|
||||
}
|
||||
|
||||
@@ -596,7 +608,6 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
val newDeclaration = PsiTreeUtil.findElementOfClassAtOffset(
|
||||
containingFile, offset, javaClass<JetCallableDeclaration>(), false
|
||||
)!!
|
||||
val typeRefsToShorten = ArrayList<JetTypeReference>()
|
||||
|
||||
ApplicationManager.getApplication()!!.runWriteAction {
|
||||
// file templates
|
||||
@@ -605,9 +616,10 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
}
|
||||
|
||||
// change short type names to fully qualified ones (to be shortened below)
|
||||
setupTypeReferencesForShortening(newDeclaration, typeRefsToShorten, parameterTypeExpressions)
|
||||
ShortenReferences.process(typeRefsToShorten)
|
||||
setupTypeReferencesForShortening(newDeclaration, elementsToShorten, parameterTypeExpressions)
|
||||
}
|
||||
|
||||
onFinish()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+33
-8
@@ -10,24 +10,42 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||
import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject
|
||||
import org.jetbrains.jet.plugin.refactoring.chooseContainerElementIfNecessary
|
||||
import org.jetbrains.jet.plugin.refactoring.getExtractionContainers
|
||||
import org.jetbrains.jet.lang.psi.JetClassBody
|
||||
import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.*
|
||||
import org.jetbrains.jet.lang.psi.JetExpression
|
||||
import org.jetbrains.jet.utils.addToStdlib.singletonOrEmptyList
|
||||
|
||||
public class CreateCallableFromUsageFix(
|
||||
originalExpression: JetExpression,
|
||||
val callableInfo: CallableInfo) : CreateFromUsageFixBase(originalExpression) {
|
||||
override fun getText(): String {
|
||||
val key = when (callableInfo.kind) {
|
||||
CallableKind.FUNCTION -> "create.function.from.usage"
|
||||
CallableKind.PROPERTY -> "create.property.from.usage"
|
||||
val callableInfos: List<CallableInfo>) : CreateFromUsageFixBase(originalExpression) {
|
||||
{
|
||||
if (callableInfos.size > 1) {
|
||||
val callableInfo = callableInfos.first()
|
||||
|
||||
val receiver = callableInfo.receiverTypeInfo
|
||||
if (!callableInfos.all { it.receiverTypeInfo == receiver }) throw AssertionError("All functions must have common receiver")
|
||||
|
||||
val containers = callableInfo.possibleContainers
|
||||
if (!callableInfos.all { it.possibleContainers == containers }) throw AssertionError("All functions must have common containers")
|
||||
}
|
||||
return JetBundle.message(key, callableInfo.name)
|
||||
}
|
||||
|
||||
override fun getText(): String {
|
||||
val renderedCallables = callableInfos.map {
|
||||
val kind = when (it.kind) {
|
||||
CallableKind.FUNCTION -> "function"
|
||||
CallableKind.PROPERTY -> "property"
|
||||
}
|
||||
"$kind '${it.name}'"
|
||||
}
|
||||
|
||||
return JetBundle.message("create.0.from.usage", renderedCallables.joinToString())
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: JetFile?) {
|
||||
val callableBuilder = CallableBuilderConfiguration(callableInfo, element as JetExpression, file!!, editor!!).createBuilder()
|
||||
val callableInfo = callableInfos.firstOrNull() ?: return
|
||||
|
||||
val callableBuilder = CallableBuilderConfiguration(callableInfos, element as JetExpression, file!!, editor!!).createBuilder()
|
||||
|
||||
fun runBuilder(placement: CallablePlacement) {
|
||||
callableBuilder.placement = placement
|
||||
@@ -59,3 +77,10 @@ public class CreateCallableFromUsageFix(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun CreateCallableFromUsageFix(
|
||||
originalExpression: JetExpression,
|
||||
callableInfo: CallableInfo
|
||||
) : CreateCallableFromUsageFix {
|
||||
return CreateCallableFromUsageFix(originalExpression, callableInfo.singletonOrEmptyList())
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package org.jetbrains.jet.plugin.quickfix.createFromUsage.createFunction
|
||||
|
||||
import org.jetbrains.jet.plugin.quickfix.JetSingleIntentionActionFactory
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.TypeInfo
|
||||
import org.jetbrains.jet.lang.types.Variance
|
||||
import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.ParameterInfo
|
||||
import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.FunctionInfo
|
||||
import org.jetbrains.jet.lang.psi.JetProperty
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.getParentByType
|
||||
import org.jetbrains.jet.lang.psi.JetExpression
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.CallableInfo
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor
|
||||
|
||||
object CreatePropertyDelegateAccessorsActionFactory : JetSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||
val expression = diagnostic.getPsiElement() as? JetExpression ?: return null
|
||||
val context = AnalyzerFacadeWithCache.getContextForElement(expression)
|
||||
[suppress("UNCHECKED_CAST")]
|
||||
|
||||
fun isApplicableForAccessor(accessor: PropertyAccessorDescriptor?): Boolean =
|
||||
accessor != null && context[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, accessor] == null
|
||||
|
||||
val builtIns = KotlinBuiltIns.getInstance()
|
||||
|
||||
val property = expression.getParentByType(javaClass<JetProperty>()) ?: return null
|
||||
val propertyDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, property] as? PropertyDescriptor
|
||||
?: return null
|
||||
|
||||
val propertyReceiver = propertyDescriptor.getExtensionReceiverParameter() ?: propertyDescriptor.getDispatchReceiverParameter()
|
||||
val propertyType = propertyDescriptor.getType()
|
||||
|
||||
val accessorReceiverType = TypeInfo(expression, Variance.IN_VARIANCE)
|
||||
val thisRefParam = ParameterInfo(TypeInfo(propertyReceiver?.getType() ?: builtIns.getNullableNothingType(), Variance.IN_VARIANCE))
|
||||
val metadataParam = ParameterInfo(TypeInfo(builtIns.getPropertyMetadata().getDefaultType(), Variance.IN_VARIANCE))
|
||||
|
||||
val callableInfos = SmartList<CallableInfo>()
|
||||
|
||||
if (isApplicableForAccessor(propertyDescriptor.getGetter())) {
|
||||
val getterInfo = FunctionInfo(
|
||||
name = "get",
|
||||
receiverTypeInfo = accessorReceiverType,
|
||||
returnTypeInfo = TypeInfo(propertyType, Variance.OUT_VARIANCE),
|
||||
parameterInfos = listOf(thisRefParam, metadataParam)
|
||||
)
|
||||
callableInfos.add(getterInfo)
|
||||
}
|
||||
|
||||
if (propertyDescriptor.isVar() && isApplicableForAccessor(propertyDescriptor.getSetter())) {
|
||||
val newValueParam = ParameterInfo(TypeInfo(propertyType, Variance.IN_VARIANCE))
|
||||
val setterInfo = FunctionInfo(
|
||||
name = "set",
|
||||
receiverTypeInfo = accessorReceiverType,
|
||||
returnTypeInfo = TypeInfo(builtIns.getUnitType(), Variance.OUT_VARIANCE),
|
||||
parameterInfos = listOf(thisRefParam, metadataParam, newValueParam)
|
||||
)
|
||||
callableInfos.add(setterInfo)
|
||||
}
|
||||
|
||||
return CreateCallableFromUsageFix(expression, callableInfos)
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.psi.JetClassBody
|
||||
import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.PropertyInfo
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.getAssignmentByLHS
|
||||
import org.jetbrains.jet.plugin.quickfix.createFromUsage.callableBuilder.getExpressionForTypeGuess
|
||||
import org.jetbrains.jet.utils.addToStdlib.singletonOrEmptyList
|
||||
|
||||
object CreateLocalVariableActionFactory: JetSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||
@@ -50,7 +51,7 @@ object CreateLocalVariableActionFactory: JetSingleIntentionActionFactory() {
|
||||
override fun getText(): String = JetBundle.message("create.local.variable.from.usage", propertyInfo.name)
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: JetFile?) {
|
||||
with (CallableBuilderConfiguration(propertyInfo, assignment ?: refExpr, file!!, editor!!).createBuilder()) {
|
||||
with (CallableBuilderConfiguration(propertyInfo.singletonOrEmptyList(), assignment ?: refExpr, file!!, editor!!).createBuilder()) {
|
||||
val actualContainer = when (container) {
|
||||
is JetBlockExpression -> container
|
||||
else -> ConvertToBlockBodyAction().convert(container as JetDeclarationWithBody).getBodyExpression()!!
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// "Create function 'get' from usage" "true"
|
||||
class F {
|
||||
fun get(x: X, propertyMetadata: PropertyMetadata): Int {
|
||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class X {
|
||||
val f: Int by F()
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// "Create function 'get', function 'set' from usage" "true"
|
||||
class F {
|
||||
fun get(x: X, propertyMetadata: PropertyMetadata): Int {
|
||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
fun set(x: X, propertyMetadata: PropertyMetadata, i: Int) {
|
||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class X {
|
||||
var f: Int by F()
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Create function 'get' from usage" "true"
|
||||
class F {
|
||||
fun set(x: X, propertyMetadata: PropertyMetadata, i: Int) { }
|
||||
|
||||
fun get(x: X, propertyMetadata: PropertyMetadata): Int {
|
||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
class X {
|
||||
var f: Int by F()
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Create function 'set' from usage" "true"
|
||||
class F {
|
||||
fun get(x: X, propertyMetadata: PropertyMetadata): Int = 1
|
||||
|
||||
fun set(x: X, propertyMetadata: PropertyMetadata, i: Int) {
|
||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
class X {
|
||||
var f: Int by F()
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Create function 'get' from usage" "true"
|
||||
class F {
|
||||
|
||||
}
|
||||
|
||||
class X {
|
||||
val f: Int by F()<caret>
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Create function 'get', function 'set' from usage" "true"
|
||||
class F {
|
||||
|
||||
}
|
||||
|
||||
class X {
|
||||
var f: Int by F()<caret>
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Create function 'get' from usage" "true"
|
||||
class F {
|
||||
fun set(x: X, propertyMetadata: PropertyMetadata, i: Int) { }
|
||||
}
|
||||
|
||||
class X {
|
||||
var f: Int by F()<caret>
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Create function 'set' from usage" "true"
|
||||
class F {
|
||||
fun get(x: X, propertyMetadata: PropertyMetadata): Int = 1
|
||||
}
|
||||
|
||||
class X {
|
||||
var f: Int by F()<caret>
|
||||
}
|
||||
@@ -440,13 +440,13 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/changeSignature/beforeAddFunctionParameterAndChangeTypes.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeAddFunctionParameterLongNameRuntime.kt")
|
||||
public void testAddFunctionParameterLongNameRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/changeSignature/beforeAddFunctionParameterLongNameRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeAddParameterNotAvailableForBuiltins.kt")
|
||||
public void testAddParameterNotAvailableForBuiltins() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/changeSignature/beforeAddParameterNotAvailableForBuiltins.kt");
|
||||
@@ -628,7 +628,7 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@InnerTestClasses({CreateFunction.BinaryOperations.class, CreateFunction.Call.class, CreateFunction.Component.class, CreateFunction.Get.class, CreateFunction.HasNext.class, CreateFunction.Invoke.class, CreateFunction.Iterator.class, CreateFunction.Next.class, CreateFunction.Set.class, CreateFunction.UnaryOperations.class})
|
||||
@InnerTestClasses({CreateFunction.BinaryOperations.class, CreateFunction.Call.class, CreateFunction.Component.class, CreateFunction.DelegateAccessors.class, CreateFunction.Get.class, CreateFunction.HasNext.class, CreateFunction.Invoke.class, CreateFunction.Iterator.class, CreateFunction.Next.class, CreateFunction.Set.class, CreateFunction.UnaryOperations.class})
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CreateFunction extends AbstractQuickFixTest {
|
||||
public void testAllFilesPresentInCreateFunction() throws Exception {
|
||||
@@ -795,13 +795,13 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeFunOnUserType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeFunOnUserTypeWithDeclarations.kt")
|
||||
public void testFunOnUserTypeWithDeclarations() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeFunOnUserTypeWithDeclarations.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeFunOnUserTypeWithTypeParams.kt")
|
||||
public void testFunOnUserTypeWithTypeParams() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeFunOnUserTypeWithTypeParams.kt");
|
||||
@@ -962,6 +962,39 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction/delegateAccessors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DelegateAccessors extends AbstractQuickFixTest {
|
||||
public void testAllFilesPresentInDelegateAccessors() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createFunction/delegateAccessors"), Pattern.compile("^before(\\w+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("beforeVal.kt")
|
||||
public void testVal() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/delegateAccessors/beforeVal.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("beforeVar.kt")
|
||||
public void testVar() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/delegateAccessors/beforeVar.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("beforeVarMissingGet.kt")
|
||||
public void testVarMissingGet() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/delegateAccessors/beforeVarMissingGet.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("beforeVarMissingSet.kt")
|
||||
public void testVarMissingSet() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/delegateAccessors/beforeVarMissingSet.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction/get")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -3201,13 +3234,13 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeAddition/beforeWrongGetterParameterType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeWrongGetterParameterTypeLongNameRuntime.kt")
|
||||
public void testWrongGetterParameterTypeLongNameRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeAddition/beforeWrongGetterParameterTypeLongNameRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeWrongSetterParameterType.kt")
|
||||
public void testWrongSetterParameterType() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeAddition/beforeWrongSetterParameterType.kt");
|
||||
@@ -3268,25 +3301,25 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeChangeFunctionLiteralParameterTypeToFunctionType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeChangeFunctionLiteralParameterTypeToFunctionTypeLongNameRuntime.kt")
|
||||
public void testChangeFunctionLiteralParameterTypeToFunctionTypeLongNameRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeChangeFunctionLiteralParameterTypeToFunctionTypeLongNameRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeChangeFunctionReturnTypeToMatchExpectedTypeOfCall.kt")
|
||||
public void testChangeFunctionReturnTypeToMatchExpectedTypeOfCall() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToMatchExpectedTypeOfCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeChangeFunctionReturnTypeToMatchExpectedTypeOfCallLongNameRuntime.kt")
|
||||
public void testChangeFunctionReturnTypeToMatchExpectedTypeOfCallLongNameRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToMatchExpectedTypeOfCallLongNameRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeChangeReturnTypeWhenFunctionNameIsMissing.kt")
|
||||
public void testChangeReturnTypeWhenFunctionNameIsMissing() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeChangeReturnTypeWhenFunctionNameIsMissing.kt");
|
||||
@@ -3316,13 +3349,13 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeExpectedParameterTypeMismatch.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeExpectedParameterTypeMismatchLongNameRuntime.kt")
|
||||
public void testExpectedParameterTypeMismatchLongNameRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeExpectedParameterTypeMismatchLongNameRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeExpectedReturnTypeMismatch.kt")
|
||||
public void testExpectedReturnTypeMismatch() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeExpectedReturnTypeMismatch.kt");
|
||||
@@ -3346,13 +3379,13 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforePropertyTypeMismatch.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforePropertyTypeMismatchLongNameRuntime.kt")
|
||||
public void testPropertyTypeMismatchLongNameRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforePropertyTypeMismatchLongNameRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeReturnTypeMismatch.kt")
|
||||
public void testReturnTypeMismatch() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/beforeReturnTypeMismatch.kt");
|
||||
@@ -3426,13 +3459,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/casts/beforeTypeMismatch5.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeTypeMismatchLongNameRuntime.kt")
|
||||
public void testTypeMismatchLongNameRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/casts/beforeTypeMismatchLongNameRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch")
|
||||
@@ -3538,7 +3570,7 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType5.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("beforeChangeParameterTypeLongNameRuntime.kt")
|
||||
public void testChangeParameterTypeLongNameRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeParameterTypeLongNameRuntime.kt");
|
||||
|
||||
Reference in New Issue
Block a user