From b37496c3fcecb88e8b36a7f055d98ff71c6c0e53 Mon Sep 17 00:00:00 2001 From: Vyacheslav Gerasimov Date: Tue, 6 Mar 2018 20:55:36 +0300 Subject: [PATCH] 182: Fix compilation for idea 182, nullability changes mostly --- .../KotlinRenameDispatcherHandler.kt.182 | 55 ++++++++++++++ .../KotlinVariableInplaceRenameHandler.kt.182 | 71 +++++++++++++++++++ .../RenameBackingFieldReferenceHandler.kt.182 | 43 +++++++++++ .../rename/RenameDynamicMemberHandler.kt.182 | 46 ++++++++++++ ...RenameKotlinImplicitLambdaParameter.kt.182 | 46 ++++++++++++ ...RenameOnSecondaryConstructorHandler.kt.182 | 52 ++++++++++++++ ...theticDeclarationByReferenceHandler.kt.182 | 37 ++++++++++ 7 files changed, 350 insertions(+) create mode 100644 idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinRenameDispatcherHandler.kt.182 create mode 100644 idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinVariableInplaceRenameHandler.kt.182 create mode 100644 idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameBackingFieldReferenceHandler.kt.182 create mode 100644 idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameDynamicMemberHandler.kt.182 create mode 100644 idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinImplicitLambdaParameter.kt.182 create mode 100644 idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameOnSecondaryConstructorHandler.kt.182 create mode 100644 idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameSyntheticDeclarationByReferenceHandler.kt.182 diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinRenameDispatcherHandler.kt.182 b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinRenameDispatcherHandler.kt.182 new file mode 100644 index 00000000000..c13b27c8959 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinRenameDispatcherHandler.kt.182 @@ -0,0 +1,55 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.extensions.ExtensionPointName +import com.intellij.openapi.extensions.Extensions +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.refactoring.rename.RenameHandler +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull +import java.util.* + +class KotlinRenameDispatcherHandler : RenameHandler { + companion object { + val EP_NAME = ExtensionPointName("org.jetbrains.kotlin.renameHandler") + + private val handlers: Array get() = Extensions.getExtensions(EP_NAME) + } + + internal fun getRenameHandler(dataContext: DataContext): RenameHandler? { + val availableHandlers = handlers.filterTo(LinkedHashSet()) { it.isRenaming(dataContext) } + availableHandlers.singleOrNull()?.let { return it } + availableHandlers.firstIsInstanceOrNull()?.let { availableHandlers -= it } + return availableHandlers.firstOrNull() + } + + override fun isAvailableOnDataContext(dataContext: DataContext) = handlers.any { it.isAvailableOnDataContext(dataContext) } + + override fun isRenaming(dataContext: DataContext) = isAvailableOnDataContext(dataContext) + + override fun invoke(project: Project, editor: Editor?, file: PsiFile?, dataContext: DataContext) { + getRenameHandler(dataContext)?.invoke(project, editor, file, dataContext) + } + + override fun invoke(project: Project, elements: Array, dataContext: DataContext) { + getRenameHandler(dataContext)?.invoke(project, elements, dataContext) + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinVariableInplaceRenameHandler.kt.182 b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinVariableInplaceRenameHandler.kt.182 new file mode 100644 index 00000000000..0faed3abeb3 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinVariableInplaceRenameHandler.kt.182 @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.openapi.editor.Editor +import com.intellij.psi.* +import com.intellij.refactoring.RefactoringActionHandler +import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler +import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer +import org.jetbrains.kotlin.idea.core.unquote +import org.jetbrains.kotlin.psi.* + +open class KotlinVariableInplaceRenameHandler : VariableInplaceRenameHandler() { + companion object { + fun isInplaceRenameAvailable(element: PsiElement): Boolean { + when (element) { + is KtTypeParameter -> return true + is KtDestructuringDeclarationEntry -> return true + is KtParameter -> { + val parent = element.parent + if (parent is KtForExpression) { + return true + } + if (parent is KtParameterList) { + val grandparent = parent.parent + return grandparent is KtCatchClause || grandparent is KtFunctionLiteral + } + } + is KtLabeledExpression, is KtImportAlias -> return true + } + return false + } + } + + protected open class RenamerImpl : VariableInplaceRenamer { + constructor(elementToRename: PsiNamedElement, editor: Editor): super(elementToRename, editor) + constructor( + elementToRename: PsiNamedElement, + editor: Editor, + currentName: String, + oldName: String + ) : super(elementToRename, editor, editor.project!!, currentName, oldName) + + override fun acceptReference(reference: PsiReference): Boolean { + val refElement = reference.element + val textRange = reference.rangeInElement + val referenceText = refElement.text.substring(textRange.startOffset, textRange.endOffset).unquote() + return referenceText == myElementToRename.name + } + + override fun startsOnTheSameElement(handler: RefactoringActionHandler?, element: PsiElement?): Boolean { + return variable == element && (handler is VariableInplaceRenameHandler || handler is KotlinRenameDispatcherHandler) + } + + override fun createInplaceRenamerToRestart(variable: PsiNamedElement, editor: Editor, initialName: String): VariableInplaceRenamer { + return RenamerImpl(variable, editor, initialName, myOldName) + } + } + + override fun createRenamer(elementToRename: PsiElement, editor: Editor): VariableInplaceRenamer? { + val currentElementToRename = elementToRename as PsiNameIdentifierOwner + val currentName = currentElementToRename.nameIdentifier?.text ?: "" + return RenamerImpl(currentElementToRename, editor, currentName, currentName) + } + + override public fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile) = + editor.settings.isVariableInplaceRenameEnabled && element != null && isInplaceRenameAvailable(element) +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameBackingFieldReferenceHandler.kt.182 b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameBackingFieldReferenceHandler.kt.182 new file mode 100644 index 00000000000..0736e42c3ad --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameBackingFieldReferenceHandler.kt.182 @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall +import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils +import org.jetbrains.kotlin.psi.KtSimpleNameExpression + +class RenameBackingFieldReferenceHandler: KotlinVariableInplaceRenameHandler() { + override fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile): Boolean { + val refExpression = file.findElementForRename(editor.caretModel.offset) ?: return false + if (refExpression.text != "field") return false + return refExpression.resolveToCall()?.resultingDescriptor is SyntheticFieldDescriptor + } + + override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext?) { + CodeInsightUtils.showErrorHint(project, editor, "Rename is not applicable to backing field reference", "Rename", null) + } + + override fun invoke(project: Project, elements: Array, dataContext: DataContext) { + // Do nothing: this method is called not from editor + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameDynamicMemberHandler.kt.182 b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameDynamicMemberHandler.kt.182 new file mode 100644 index 00000000000..1cd984b5101 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameDynamicMemberHandler.kt.182 @@ -0,0 +1,46 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall +import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic + +class RenameDynamicMemberHandler: KotlinVariableInplaceRenameHandler() { + override fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile): Boolean { + val callee = PsiTreeUtil.findElementOfClassAtOffset( + file, editor.caretModel.offset, KtSimpleNameExpression::class.java, false + ) ?: return false + val calleeDescriptor = callee.resolveToCall()?.resultingDescriptor ?: return false + return calleeDescriptor.isDynamic() + } + + override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext?) { + CodeInsightUtils.showErrorHint(project, editor, "Rename is not applicable to dynamically invoked members", "Rename", null) + } + + override fun invoke(project: Project, elements: Array, dataContext: DataContext) { + // Do nothing: this method is called not from editor + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinImplicitLambdaParameter.kt.182 b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinImplicitLambdaParameter.kt.182 new file mode 100644 index 00000000000..69899681368 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinImplicitLambdaParameter.kt.182 @@ -0,0 +1,46 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.idea.intentions.ReplaceItWithExplicitFunctionLiteralParamIntention +import org.jetbrains.kotlin.idea.intentions.isAutoCreatedItUsage +import org.jetbrains.kotlin.idea.util.application.executeWriteCommand +import org.jetbrains.kotlin.psi.KtNameReferenceExpression + +class RenameKotlinImplicitLambdaParameter : KotlinVariableInplaceRenameHandler() { + override fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile): Boolean { + val nameExpression = file.findElementForRename(editor.caretModel.offset) + + return nameExpression != null && isAutoCreatedItUsage(nameExpression) + } + + override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext?) { + val intention = ReplaceItWithExplicitFunctionLiteralParamIntention() + project.executeWriteCommand("Convert 'it' to explicit lambda parameter") { + intention.invoke(project, editor, file) + } + } + + override fun invoke(project: Project, elements: Array, dataContext: DataContext) { + // Do nothing: this method is called not from editor + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameOnSecondaryConstructorHandler.kt.182 b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameOnSecondaryConstructorHandler.kt.182 new file mode 100644 index 00000000000..21e7d4bb786 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameOnSecondaryConstructorHandler.kt.182 @@ -0,0 +1,52 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.openapi.actionSystem.CommonDataKeys +import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.psi.util.PsiTreeUtil +import com.intellij.refactoring.rename.RenameHandler +import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils +import org.jetbrains.kotlin.psi.* + + +class RenameOnSecondaryConstructorHandler : RenameHandler { + override fun isAvailableOnDataContext(dataContext: DataContext): Boolean { + val editor = CommonDataKeys.EDITOR.getData(dataContext) ?: return false + val file = CommonDataKeys.PSI_FILE.getData(dataContext) ?: return false + + val element = PsiTreeUtil.findElementOfClassAtOffsetWithStopSet( + file, editor.caretModel.offset, KtSecondaryConstructor::class.java, false, + KtBlockExpression::class.java, KtValueArgumentList::class.java, KtParameterList::class.java, KtConstructorDelegationCall::class.java + ) + return element != null + } + + override fun isRenaming(dataContext: DataContext): Boolean = isAvailableOnDataContext(dataContext) + + override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext?) { + CodeInsightUtils.showErrorHint(project, editor, "Rename is not applicable to secondary constructors", "Rename", null) + } + + override fun invoke(project: Project, elements: Array, dataContext: DataContext?) { + // Do nothing: this method is called not from editor + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameSyntheticDeclarationByReferenceHandler.kt.182 b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameSyntheticDeclarationByReferenceHandler.kt.182 new file mode 100644 index 00000000000..da3f102f65d --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameSyntheticDeclarationByReferenceHandler.kt.182 @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.openapi.actionSystem.CommonDataKeys +import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.refactoring.rename.RenameHandler +import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall +import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.resolve.calls.tower.isSynthesized + +class RenameSyntheticDeclarationByReferenceHandler : RenameHandler { + override fun isAvailableOnDataContext(dataContext: DataContext): Boolean { + val file = CommonDataKeys.PSI_FILE.getData(dataContext) ?: return false + val editor = CommonDataKeys.EDITOR.getData(dataContext) ?: return false + val refExpression = file.findElementForRename(editor.caretModel.offset) ?: return false + return (refExpression.resolveToCall()?.resultingDescriptor)?.isSynthesized ?: false + } + + override fun isRenaming(dataContext: DataContext) = isAvailableOnDataContext(dataContext) + + override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext?) { + CodeInsightUtils.showErrorHint(project, editor, "Rename is not applicable to synthetic declaration", "Rename", null) + } + + override fun invoke(project: Project, elements: Array, dataContext: DataContext?) { + // Do nothing: this method is not called from editor + } +}