From 7430f10e96bb48882e7c70e3b0f799c12426771b Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 4 Jul 2014 15:05:36 +0400 Subject: [PATCH] Extract Function: Extract ParametersInfo class --- .../extractFunction/extractFunctionUtils.kt | 72 ++++++++++--------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractFunctionUtils.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractFunctionUtils.kt index f4af2b2410f..246edb6a38c 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractFunctionUtils.kt +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractFunctionUtils.kt @@ -398,17 +398,23 @@ private class DelegatingParameter( override fun copy(name: String, parameterType: JetType): Parameter = DelegatingParameter(original, name, parameterType) } +private class ParametersInfo { + var errorMessage: ErrorMessage? = null + val replacementMap: MutableMap = HashMap() + val originalRefToParameter: MutableMap = HashMap() + val parameters: MutableSet = HashSet() + val typeParameters: MutableSet = HashSet() + val nonDenotableTypes: MutableSet = HashSet() +} + private fun ExtractionData.inferParametersInfo( commonParent: PsiElement, pseudocode: Pseudocode, bindingContext: BindingContext, - modifiedVarDescriptors: Set, - replacementMap: MutableMap, - originalRefToParameter: MutableMap, - parameters: MutableSet, - typeParameters: MutableSet, - nonDenotableTypes: MutableSet -): ErrorMessage? { + modifiedVarDescriptors: Set +): ParametersInfo { + val info = ParametersInfo() + val varNameValidator = JetNameValidatorImpl( commonParent.getParentByType(javaClass()), originalElements.first, @@ -424,7 +430,8 @@ private fun ExtractionData.inferParametersInfo( val selector = (ref.getParent() as? JetCallExpression) ?: ref val superExpr = (selector.getParent() as? JetQualifiedExpression)?.getReceiverExpression() as? JetSuperExpression if (superExpr != null) { - return ErrorMessage.SUPER_CALL + info.errorMessage = ErrorMessage.SUPER_CALL + return info } val receiverArgument = resolvedCall?.getReceiverArgument() @@ -453,10 +460,12 @@ private fun ExtractionData.inferParametersInfo( } if (referencedClassDescriptor != null) { - if (!referencedClassDescriptor.getDefaultType().processTypeIfExtractable(typeParameters, nonDenotableTypes, false)) continue + if (!referencedClassDescriptor.getDefaultType().processTypeIfExtractable( + info.typeParameters, info.nonDenotableTypes, false + )) continue val replacingDescriptor = (originalDescriptor as? ConstructorDescriptor)?.getContainingDeclaration() ?: originalDescriptor - replacementMap[refInfo.offsetInBody] = FqNameReplacement(DescriptorUtils.getFqNameSafe(replacingDescriptor)) + info.replacementMap[refInfo.offsetInBody] = FqNameReplacement(DescriptorUtils.getFqNameSafe(replacingDescriptor)) } else { val extractThis = hasThisReceiver || thisExpr != null @@ -476,7 +485,7 @@ private fun ExtractionData.inferParametersInfo( ?: DEFAULT_PARAMETER_TYPE } - if (!parameterType.processTypeIfExtractable(typeParameters, nonDenotableTypes)) continue + if (!parameterType.processTypeIfExtractable(info.typeParameters, info.nonDenotableTypes)) continue val parameterTypePredicate = pseudocode.getElementValue(originalRef)?.let { getExpectedTypePredicate(it, bindingContext) } ?: AllTypes @@ -501,24 +510,24 @@ private fun ExtractionData.inferParametersInfo( } parameter.refCount++ - originalRefToParameter[originalRef] = parameter + info.originalRefToParameter[originalRef] = parameter parameter.addDefaultType(parameterType) parameter.addTypePredicate(parameterTypePredicate) - replacementMap[refInfo.offsetInBody] = + info.replacementMap[refInfo.offsetInBody] = if (hasThisReceiver && extractThis) AddPrefixReplacement(parameter) else RenameReplacement(parameter) } } } - for (typeToCheck in typeParameters.flatMapTo(HashSet()) { it.collectReferencedTypes(bindingContext) }) { - typeToCheck.processTypeIfExtractable(typeParameters, nonDenotableTypes) + for (typeToCheck in info.typeParameters.flatMapTo(HashSet()) { it.collectReferencedTypes(bindingContext) }) { + typeToCheck.processTypeIfExtractable(info.typeParameters, info.nonDenotableTypes) } - parameters.addAll(extractedDescriptorToParameter.values()) + info.parameters.addAll(extractedDescriptorToParameter.values()) - return null + return info } private fun ExtractionData.checkDeclarationsMovingOutOfScope( @@ -591,28 +600,21 @@ fun ExtractionData.performAnalysis(): AnalysisResult { val modifiedVarDescriptors = localInstructions.getModifiedVarDescriptors(bindingContext) - val replacementMap = HashMap() - val originalRefToParameter = HashMap() - val parameters = HashSet() - val typeParameters = HashSet() - val nonDenotableTypes = HashSet() - val parameterError = inferParametersInfo( - commonParent, pseudocode, bindingContext, modifiedVarDescriptors, replacementMap, originalRefToParameter, parameters, typeParameters, nonDenotableTypes - ) - if (parameterError != null) { - return AnalysisResult(null, Status.CRITICAL_ERROR, listOf(parameterError)) + val paramsInfo = inferParametersInfo(commonParent, pseudocode, bindingContext, modifiedVarDescriptors) + if (paramsInfo.errorMessage != null) { + return AnalysisResult(null, Status.CRITICAL_ERROR, listOf(paramsInfo.errorMessage!!)) } val messages = ArrayList() val (controlFlow, controlFlowMessage) = - analyzeControlFlow(localInstructions, pseudocode, bindingContext, modifiedVarDescriptors, options, parameters) + analyzeControlFlow(localInstructions, pseudocode, bindingContext, modifiedVarDescriptors, options, paramsInfo.parameters) controlFlowMessage?.let { messages.add(it) } - controlFlow.returnType.processTypeIfExtractable(typeParameters, nonDenotableTypes) + controlFlow.returnType.processTypeIfExtractable(paramsInfo.typeParameters, paramsInfo.nonDenotableTypes) - if (nonDenotableTypes.isNotEmpty()) { - val typeStr = nonDenotableTypes.map {DescriptorRenderer.HTML.renderType(it)}.sort() + if (paramsInfo.nonDenotableTypes.isNotEmpty()) { + val typeStr = paramsInfo.nonDenotableTypes.map {DescriptorRenderer.HTML.renderType(it)}.sort() return AnalysisResult( null, Status.CRITICAL_ERROR, @@ -634,12 +636,12 @@ fun ExtractionData.performAnalysis(): AnalysisResult { controlFlow.elementToInsertAfterCall.accept( object: JetTreeVisitorVoid() { override fun visitSimpleNameExpression(expression: JetSimpleNameExpression) { - originalRefToParameter[expression]?.let { it.refCount-- } + paramsInfo.originalRefToParameter[expression]?.let { it.refCount-- } } } ) } - val adjustedParameters = parameters.filterTo(HashSet()) { it.refCount > 0 } + val adjustedParameters = paramsInfo.parameters.filterTo(HashSet()) { it.refCount > 0 } val receiverCandidates = adjustedParameters.filterTo(HashSet()) { it.receiverCandidate } val receiverParameter = if (receiverCandidates.size == 1) receiverCandidates.first() else null @@ -652,8 +654,8 @@ fun ExtractionData.performAnalysis(): AnalysisResult { "", adjustedParameters.sortBy { it.name }, receiverParameter, - typeParameters.sortBy { it.originalDeclaration.getName()!! }, - replacementMap, + paramsInfo.typeParameters.sortBy { it.originalDeclaration.getName()!! }, + paramsInfo.replacementMap, if (messages.empty) controlFlow else controlFlow.toDefault() ), if (messages.empty) Status.SUCCESS else Status.NON_CRITICAL_ERROR,