Change Signature: Check syntactic validity of types. Warn about unresolved types
This commit is contained in:
@@ -27,7 +27,4 @@ class KtTypeCodeFragment(
|
|||||||
context: PsiElement?
|
context: PsiElement?
|
||||||
) : KtCodeFragment(project, name, text, null, KtNodeTypes.TYPE_CODE_FRAGMENT, context) {
|
) : KtCodeFragment(project, name, text, null, KtNodeTypes.TYPE_CODE_FRAGMENT, context) {
|
||||||
override fun getContentElement() = findChildByClass(KtTypeReference::class.java)
|
override fun getContentElement() = findChildByClass(KtTypeReference::class.java)
|
||||||
|
|
||||||
val hasTypeReference: Boolean
|
|
||||||
get() = getContentElement() != null
|
|
||||||
}
|
}
|
||||||
|
|||||||
+42
-19
@@ -22,13 +22,14 @@ import com.intellij.openapi.editor.event.DocumentAdapter
|
|||||||
import com.intellij.openapi.editor.event.DocumentEvent
|
import com.intellij.openapi.editor.event.DocumentEvent
|
||||||
import com.intellij.openapi.options.ConfigurationException
|
import com.intellij.openapi.options.ConfigurationException
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.ui.Messages
|
||||||
import com.intellij.openapi.ui.VerticalFlowLayout
|
import com.intellij.openapi.ui.VerticalFlowLayout
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.psi.JavaPsiFacade
|
|
||||||
import com.intellij.psi.PsiCodeFragment
|
import com.intellij.psi.PsiCodeFragment
|
||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.refactoring.BaseRefactoringProcessor
|
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||||
|
import com.intellij.refactoring.RefactoringBundle
|
||||||
import com.intellij.refactoring.changeSignature.ChangeSignatureDialogBase
|
import com.intellij.refactoring.changeSignature.ChangeSignatureDialogBase
|
||||||
import com.intellij.refactoring.changeSignature.MethodDescriptor
|
import com.intellij.refactoring.changeSignature.MethodDescriptor
|
||||||
import com.intellij.refactoring.changeSignature.ParameterTableModelItemBase
|
import com.intellij.refactoring.changeSignature.ParameterTableModelItemBase
|
||||||
@@ -46,9 +47,12 @@ import org.jetbrains.kotlin.descriptors.Visibilities
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||||
|
import org.jetbrains.kotlin.idea.core.refactoring.validateElementAndNotNull
|
||||||
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringBundle
|
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringBundle
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinMethodDescriptor.Kind
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinMethodDescriptor.Kind
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.validateElement
|
||||||
import org.jetbrains.kotlin.psi.KtExpressionCodeFragment
|
import org.jetbrains.kotlin.psi.KtExpressionCodeFragment
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
import org.jetbrains.kotlin.psi.KtTypeCodeFragment
|
import org.jetbrains.kotlin.psi.KtTypeCodeFragment
|
||||||
@@ -329,32 +333,54 @@ public class KotlinChangeSignatureDialog(
|
|||||||
validateButtons()
|
validateButtons()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun validateAndCommitData() = null
|
override fun validateAndCommitData(): String? {
|
||||||
|
if (myMethod.canChangeReturnType() == MethodDescriptor.ReadWriteOption.ReadWrite &&
|
||||||
|
myReturnTypeCodeFragment.getTypeInfo(true, false).type == null) {
|
||||||
|
if (Messages.showOkCancelDialog(
|
||||||
|
myProject,
|
||||||
|
"Return type '${myReturnTypeCodeFragment!!.text}' cannot be resolved.\nContinue?",
|
||||||
|
RefactoringBundle.message("changeSignature.refactoring.name"),
|
||||||
|
Messages.getWarningIcon()
|
||||||
|
) != Messages.OK) {
|
||||||
|
return ChangeSignatureDialogBase.EXIT_SILENTLY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (item in parametersTableModel.items) {
|
||||||
|
if (item.typeCodeFragment.getTypeInfo(true, false).type == null) {
|
||||||
|
val paramText = if (item.parameter != parametersTableModel.receiver) "parameter '${item.parameter.name}'" else "receiver"
|
||||||
|
if (Messages.showOkCancelDialog(
|
||||||
|
myProject,
|
||||||
|
"Type '${item.typeCodeFragment.text}' for $paramText cannot be resolved.\nContinue?",
|
||||||
|
RefactoringBundle.message("changeSignature.refactoring.name"),
|
||||||
|
Messages.getWarningIcon()
|
||||||
|
) != Messages.OK) {
|
||||||
|
return ChangeSignatureDialogBase.EXIT_SILENTLY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
override fun canRun() {
|
override fun canRun() {
|
||||||
if (myNamePanel.isVisible()
|
if (myNamePanel.isVisible && myMethod.canChangeName() && !KotlinNameSuggester.isIdentifier(methodName)) {
|
||||||
&& myMethod.canChangeName()
|
|
||||||
&& !JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(getMethodName())) {
|
|
||||||
throw ConfigurationException(KotlinRefactoringBundle.message("function.name.is.invalid"))
|
throw ConfigurationException(KotlinRefactoringBundle.message("function.name.is.invalid"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myMethod.canChangeReturnType() === MethodDescriptor.ReadWriteOption.ReadWrite && !hasTypeReference(myReturnTypeCodeFragment)) {
|
if (myMethod.canChangeReturnType() === MethodDescriptor.ReadWriteOption.ReadWrite) {
|
||||||
throw ConfigurationException(KotlinRefactoringBundle.message("return.type.is.invalid"))
|
(myReturnTypeCodeFragment as? KtTypeCodeFragment)
|
||||||
|
?.validateElement(KotlinRefactoringBundle.message("return.type.is.invalid"))
|
||||||
}
|
}
|
||||||
|
|
||||||
val parameterInfos = parametersTableModel.getItems()
|
for (item in parametersTableModel.items) {
|
||||||
|
val parameterName = item.parameter.name
|
||||||
|
|
||||||
for (item in parameterInfos) {
|
if (item.parameter != parametersTableModel.receiver && !KotlinNameSuggester.isIdentifier(parameterName)) {
|
||||||
val parameterName = item.parameter.getName()
|
|
||||||
|
|
||||||
if (item.parameter != parametersTableModel.getReceiver()
|
|
||||||
&& !JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(parameterName)) {
|
|
||||||
throw ConfigurationException(KotlinRefactoringBundle.message("parameter.name.is.invalid", parameterName))
|
throw ConfigurationException(KotlinRefactoringBundle.message("parameter.name.is.invalid", parameterName))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasTypeReference(item.typeCodeFragment)) {
|
(item.typeCodeFragment as? KtTypeCodeFragment)
|
||||||
throw ConfigurationException(KotlinRefactoringBundle.message("parameter.type.is.invalid", item.typeCodeFragment.getText()))
|
?.validateElement(KotlinRefactoringBundle.message("parameter.type.is.invalid", item.typeCodeFragment.text))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,8 +472,5 @@ public class KotlinChangeSignatureDialog(
|
|||||||
parametersModel.getReceiver(),
|
parametersModel.getReceiver(),
|
||||||
defaultValueContext)
|
defaultValueContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hasTypeReference(codeFragment: PsiCodeFragment?): Boolean
|
|
||||||
= (codeFragment as? KtTypeCodeFragment)?.hasTypeReference ?: false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -676,7 +676,9 @@ public fun (() -> Any).runRefactoringWithPostprocessing(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Throws(ConfigurationException::class)
|
@Throws(ConfigurationException::class)
|
||||||
public fun KtElement.validateElement(errorMessage: String) {
|
public fun KtElement?.validateElement(errorMessage: String) {
|
||||||
|
if (this == null) throw ConfigurationException(errorMessage)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
AnalyzingUtils.checkForSyntacticErrors(this)
|
AnalyzingUtils.checkForSyntacticErrors(this)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user