Hint action to update usages on cut/paste of top-level declarations
This commit is contained in:
@@ -34,6 +34,10 @@
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Factory</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory</implementation-class>
|
||||
<skipForDefaultProject/>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.completion.LookupCancelWatcher</implementation-class>
|
||||
</component>
|
||||
@@ -582,6 +586,7 @@
|
||||
<copyPastePostProcessor implementation="org.jetbrains.kotlin.idea.conversion.copy.ConvertTextJavaCopyPasteProcessor"/>
|
||||
<copyPastePostProcessor implementation="org.jetbrains.kotlin.idea.codeInsight.KotlinCopyPasteReferenceProcessor"/>
|
||||
<copyPastePreProcessor implementation="org.jetbrains.kotlin.idea.editor.KotlinLiteralCopyPasteProcessor"/>
|
||||
<copyPastePostProcessor implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsCopyPasteProcessor"/>
|
||||
|
||||
<breadcrumbsInfoProvider implementation="org.jetbrains.kotlin.idea.codeInsight.KotlinBreadcrumbsInfoProvider"/>
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ class ChangeMemberFunctionSignatureFix private constructor(
|
||||
|
||||
companion object {
|
||||
private val SIGNATURE_SOURCE_RENDERER = IdeDescriptorRenderers.SOURCE_CODE.withOptions {
|
||||
renderDefaultValues = false
|
||||
defaultParameterValueRenderer = null
|
||||
}
|
||||
|
||||
private val SIGNATURE_PREVIEW_RENDERER = DescriptorRenderer.withOptions {
|
||||
@@ -75,7 +75,7 @@ class ChangeMemberFunctionSignatureFix private constructor(
|
||||
modifiers = emptySet()
|
||||
classifierNamePolicy = ClassifierNamePolicy.SHORT
|
||||
unitReturnType = false
|
||||
renderDefaultValues = false
|
||||
defaultParameterValueRenderer = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ class ReplaceProtectedToPublishedApiCallFix(
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
val signatureRenderer = IdeDescriptorRenderers.SOURCE_CODE.withOptions {
|
||||
renderDefaultValues = false
|
||||
defaultParameterValueRenderer = null
|
||||
startFromDeclarationKeyword = true
|
||||
withoutReturnType = true
|
||||
}
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.cutPaste
|
||||
|
||||
import com.intellij.codeInsight.editorActions.CopyPastePostProcessor
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.RangeMarker
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiWhiteSpace
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||
import java.awt.datatransfer.Transferable
|
||||
|
||||
class MoveDeclarationsCopyPasteProcessor : CopyPastePostProcessor<MoveDeclarationsTransferableData>() {
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(MoveDeclarationsCopyPasteProcessor::class.java)
|
||||
|
||||
fun rangeToDeclarations(file: KtFile, startOffset: Int, endOffset: Int): List<KtNamedDeclaration> {
|
||||
val elementsInRange = file.elementsInRange(TextRange(startOffset, endOffset))
|
||||
val meaningfulElements = elementsInRange.filterNot { it is PsiWhiteSpace || it is PsiComment }
|
||||
if (meaningfulElements.isEmpty()) return emptyList()
|
||||
if (!meaningfulElements.all { it is KtNamedDeclaration }) return emptyList()
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return meaningfulElements as List<KtNamedDeclaration>
|
||||
}
|
||||
}
|
||||
|
||||
override fun collectTransferableData(
|
||||
file: PsiFile,
|
||||
editor: Editor,
|
||||
startOffsets: IntArray,
|
||||
endOffsets: IntArray
|
||||
): List<MoveDeclarationsTransferableData> {
|
||||
if (file !is KtFile) return emptyList()
|
||||
if (startOffsets.size != 1) return emptyList()
|
||||
|
||||
val declarations = rangeToDeclarations(file, startOffsets[0], endOffsets[0])
|
||||
if (declarations.isEmpty() || declarations.any { it.parent !is KtFile }) return emptyList()
|
||||
|
||||
if (declarations.any { it.name == null }) return emptyList()
|
||||
val declarationNames = declarations.map { it.name!! }.toSet()
|
||||
|
||||
val stubTexts = declarations.map { MoveDeclarationsTransferableData.STUB_RENDERER.render(it.resolveToDescriptor()) }
|
||||
return listOf(MoveDeclarationsTransferableData(file.virtualFile.url, stubTexts, declarationNames))
|
||||
}
|
||||
|
||||
override fun extractTransferableData(content: Transferable): List<MoveDeclarationsTransferableData> {
|
||||
try {
|
||||
if (content.isDataFlavorSupported(MoveDeclarationsTransferableData.DATA_FLAVOR)) {
|
||||
return listOf(content.getTransferData(MoveDeclarationsTransferableData.DATA_FLAVOR) as MoveDeclarationsTransferableData)
|
||||
}
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
LOG.error(e)
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun processTransferableData(
|
||||
project: Project,
|
||||
editor: Editor,
|
||||
bounds: RangeMarker,
|
||||
caretOffset: Int,
|
||||
indented: Ref<Boolean>,
|
||||
values: List<MoveDeclarationsTransferableData>
|
||||
) {
|
||||
val data = values.single()
|
||||
|
||||
fun putCookie() {
|
||||
if (bounds.isValid) {
|
||||
val cookie = MoveDeclarationsEditorCookie(data, bounds, PsiModificationTracker.SERVICE.getInstance(project).modificationCount)
|
||||
editor.putUserData(MoveDeclarationsEditorCookie.KEY, cookie)
|
||||
}
|
||||
}
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||
putCookie()
|
||||
}
|
||||
else {
|
||||
// in real application we put cookie later to allow all other paste handlers do their work (because modificationCount will change)
|
||||
ApplicationManager.getApplication().invokeLater(::putCookie)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.cutPaste
|
||||
|
||||
import com.intellij.openapi.editor.RangeMarker
|
||||
import com.intellij.openapi.util.Key
|
||||
|
||||
class MoveDeclarationsEditorCookie(
|
||||
val data: MoveDeclarationsTransferableData,
|
||||
val bounds: RangeMarker,
|
||||
val modificationCount: Long
|
||||
) {
|
||||
companion object {
|
||||
val KEY = Key<MoveDeclarationsEditorCookie>("MoveDeclarationsEditorCookie")
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.cutPaste
|
||||
|
||||
import com.intellij.codeInsight.hint.HintManager
|
||||
import com.intellij.codeInspection.HintAction
|
||||
import com.intellij.openapi.actionSystem.ActionManager
|
||||
import com.intellij.openapi.actionSystem.IdeActions
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.RangeMarker
|
||||
import com.intellij.openapi.keymap.KeymapUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import com.intellij.refactoring.BaseRefactoringIntentionAction
|
||||
import org.jetbrains.kotlin.idea.conversion.copy.range
|
||||
|
||||
class MoveDeclarationsIntentionAction(
|
||||
private val processor: MoveDeclarationsProcessor,
|
||||
private val bounds: RangeMarker,
|
||||
private val modificationCount: Long
|
||||
) : BaseRefactoringIntentionAction(), HintAction {
|
||||
override fun startInWriteAction() = false
|
||||
|
||||
override fun getText() = "Update usages to reflect package name change"
|
||||
override fun getFamilyName() = "Update usages on declarations cut/paste"
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor, element: PsiElement): Boolean {
|
||||
return PsiModificationTracker.SERVICE.getInstance(processor.project).modificationCount == modificationCount
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor, element: PsiElement) {
|
||||
processor.performRefactoring()
|
||||
}
|
||||
|
||||
override fun showHint(editor: Editor): Boolean {
|
||||
val range = bounds.range ?: return false
|
||||
if (editor.caretModel.offset != range.endOffset) return false
|
||||
|
||||
if (PsiModificationTracker.SERVICE.getInstance(processor.project).modificationCount != modificationCount) return false
|
||||
|
||||
val hintText = "$text? ${KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_SHOW_INTENTION_ACTIONS))}"
|
||||
HintManager.getInstance().showQuestionHint(editor, hintText, range.endOffset, range.endOffset) {
|
||||
processor.performRefactoring()
|
||||
true
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.cutPaste
|
||||
|
||||
import com.intellij.codeHighlighting.Pass
|
||||
import com.intellij.codeHighlighting.TextEditorHighlightingPass
|
||||
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory
|
||||
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType
|
||||
import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction
|
||||
import com.intellij.openapi.components.AbstractProjectComponent
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import org.jetbrains.kotlin.idea.conversion.copy.range
|
||||
|
||||
class MoveDeclarationsPassFactory(project: Project, highlightingPassRegistrar: TextEditorHighlightingPassRegistrar)
|
||||
: AbstractProjectComponent(project), TextEditorHighlightingPassFactory {
|
||||
|
||||
init {
|
||||
highlightingPassRegistrar.registerTextEditorHighlightingPass(this, TextEditorHighlightingPassRegistrar.Anchor.BEFORE, Pass.POPUP_HINTS, true, true)
|
||||
}
|
||||
|
||||
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
|
||||
return MyPass(file.project, file, editor)
|
||||
}
|
||||
|
||||
private class MyPass(
|
||||
private val project: Project,
|
||||
private val file: PsiFile,
|
||||
private val editor: Editor
|
||||
) : TextEditorHighlightingPass(project, editor.document, true) {
|
||||
|
||||
override fun doCollectInformation(progress: ProgressIndicator) {}
|
||||
|
||||
override fun doApplyInformationToEditor() {
|
||||
val info = buildHighlightingInfo()
|
||||
UpdateHighlightersUtil.setHighlightersToEditor(project, myDocument!!, 0, file.textLength, listOfNotNull(info), colorsScheme, id)
|
||||
}
|
||||
|
||||
private fun buildHighlightingInfo(): HighlightInfo? {
|
||||
val cookie = editor.getUserData(MoveDeclarationsEditorCookie.KEY) ?: return null
|
||||
|
||||
if (cookie.modificationCount != PsiModificationTracker.SERVICE.getInstance(project).modificationCount) return null
|
||||
|
||||
val processor = MoveDeclarationsProcessor.build(editor, cookie)
|
||||
|
||||
if (processor == null) {
|
||||
editor.putUserData(MoveDeclarationsEditorCookie.KEY, null)
|
||||
return null
|
||||
}
|
||||
|
||||
val info = HighlightInfo.newHighlightInfo(HighlightInfoType.INFORMATION)
|
||||
.range(cookie.bounds.range!!)
|
||||
.createUnconditionally()
|
||||
QuickFixAction.registerQuickFixAction(info, MoveDeclarationsIntentionAction(processor, cookie.bounds, cookie.modificationCount))
|
||||
|
||||
return info
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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.cutPaste
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.RangeMarker
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.runRefactoringAndKeepDelayedRequests
|
||||
import org.jetbrains.kotlin.idea.conversion.copy.range
|
||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
|
||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||
import org.jetbrains.kotlin.idea.util.getSourceRoot
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
class MoveDeclarationsProcessor(
|
||||
val project: Project,
|
||||
private val sourcePsiFile: KtFile,
|
||||
private val targetPsiFile: KtFile,
|
||||
private val pastedDeclarations: List<KtNamedDeclaration>,
|
||||
private val stubTexts: List<String>
|
||||
) {
|
||||
companion object {
|
||||
fun build(editor: Editor, cookie: MoveDeclarationsEditorCookie): MoveDeclarationsProcessor? {
|
||||
val data = cookie.data
|
||||
val project = editor.project ?: return null
|
||||
val range = cookie.bounds.range ?: return null
|
||||
|
||||
val sourceFileUrl = data.sourceFileUrl
|
||||
val sourceFile = VirtualFileManager.getInstance().findFileByUrl(sourceFileUrl) ?: return null
|
||||
if (sourceFile.getSourceRoot(project) == null) return null
|
||||
|
||||
val psiDocumentManager = PsiDocumentManager.getInstance(project)
|
||||
psiDocumentManager.commitAllDocuments()
|
||||
|
||||
val targetPsiFile = psiDocumentManager.getPsiFile(editor.document) as? KtFile ?: return null
|
||||
if (targetPsiFile.virtualFile.getSourceRoot(project) == null) return null
|
||||
val sourcePsiFile = PsiManager.getInstance(project).findFile(sourceFile) as? KtFile ?: return null
|
||||
if (targetPsiFile == sourcePsiFile) return null
|
||||
|
||||
val declarations = MoveDeclarationsCopyPasteProcessor.rangeToDeclarations(targetPsiFile, range.startOffset, range.endOffset)
|
||||
if (declarations.isEmpty() || declarations.any { it.parent !is KtFile }) return null
|
||||
|
||||
if (sourcePsiFile.packageFqName == targetPsiFile.packageFqName) return null
|
||||
|
||||
// check that declarations were cut (not copied)
|
||||
val filteredDeclarations = sourcePsiFile.declarations.filter { it.name in data.declarationNames }
|
||||
val stubs = data.stubTexts.toSet()
|
||||
if (filteredDeclarations.any { MoveDeclarationsTransferableData.STUB_RENDERER.render(it.resolveToDescriptor()) in stubs }) return null
|
||||
|
||||
return MoveDeclarationsProcessor(project, sourcePsiFile, targetPsiFile, declarations, data.stubTexts)
|
||||
}
|
||||
}
|
||||
|
||||
private val psiDocumentManager = PsiDocumentManager.getInstance(project)
|
||||
private val sourceDocument = psiDocumentManager.getDocument(sourcePsiFile)!!
|
||||
|
||||
fun performRefactoring() {
|
||||
psiDocumentManager.commitAllDocuments()
|
||||
|
||||
val commandName = "Usage update"
|
||||
val commandGroupId = Any() // we need to group both commands for undo
|
||||
|
||||
val insertedRange = project.executeWriteCommand<RangeMarker>(commandName, commandGroupId) {
|
||||
//TODO: can stub declarations interfere with pasted declarations? I could not find such cases
|
||||
insertStubDeclarations()
|
||||
}
|
||||
psiDocumentManager.commitDocument(sourceDocument)
|
||||
|
||||
val stubDeclarations = MoveDeclarationsCopyPasteProcessor.rangeToDeclarations(sourcePsiFile, insertedRange.startOffset, insertedRange.endOffset)
|
||||
assert(stubDeclarations.size == pastedDeclarations.size) //TODO: can they ever differ?
|
||||
|
||||
val mover = object: Mover {
|
||||
override fun invoke(declaration: KtNamedDeclaration, targetContainer: KtElement): KtNamedDeclaration {
|
||||
val index = stubDeclarations.indexOf(declaration)
|
||||
assert(index >= 0)
|
||||
declaration.delete()
|
||||
return pastedDeclarations[index]
|
||||
}
|
||||
}
|
||||
|
||||
val declarationProcessor = MoveKotlinDeclarationsProcessor(
|
||||
MoveDeclarationsDescriptor(
|
||||
elementsToMove = stubDeclarations,
|
||||
moveTarget = KotlinMoveTargetForExistingElement(targetPsiFile),
|
||||
delegate = MoveDeclarationsDelegate.TopLevel,
|
||||
project = project
|
||||
),
|
||||
mover
|
||||
)
|
||||
|
||||
val declarationUsages = declarationProcessor.findUsages().toList()
|
||||
// val changeInfo = ContainerChangeInfo(ContainerInfo.Package(sourcePackageName), ContainerInfo.Package(targetPackageName))
|
||||
// val internalUsages = file.getInternalReferencesToUpdateOnPackageNameChange(changeInfo)
|
||||
|
||||
project.executeWriteCommand(commandName, commandGroupId) {
|
||||
|
||||
// postProcessMoveUsages(internalUsages) //TODO?
|
||||
project.runRefactoringAndKeepDelayedRequests { declarationProcessor.execute(declarationUsages) }
|
||||
|
||||
psiDocumentManager.doPostponedOperationsAndUnblockDocument(sourceDocument)
|
||||
assert(insertedRange.isValid)
|
||||
sourceDocument.deleteString(insertedRange.startOffset, insertedRange.endOffset)
|
||||
}
|
||||
}
|
||||
|
||||
private fun insertStubDeclarations(): RangeMarker {
|
||||
val insertionOffset = sourcePsiFile.declarations.firstOrNull()?.startOffset ?: sourcePsiFile.textLength
|
||||
val textToInsert = "\n//start\n\n" + stubTexts.joinToString(separator = "\n") + "\n//end\n"
|
||||
sourceDocument.insertString(insertionOffset, textToInsert)
|
||||
return sourceDocument.createRangeMarker(TextRange(insertionOffset, insertionOffset + textToInsert.length))
|
||||
}
|
||||
}
|
||||
+43
@@ -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.cutPaste
|
||||
|
||||
import com.intellij.codeInsight.editorActions.TextBlockTransferableData
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import java.awt.datatransfer.DataFlavor
|
||||
|
||||
//TODO: how to make it work inside same project only?
|
||||
class MoveDeclarationsTransferableData(
|
||||
val sourceFileUrl: String,
|
||||
val stubTexts: List<String>,
|
||||
val declarationNames: Set<String>
|
||||
) : TextBlockTransferableData {
|
||||
|
||||
override fun getFlavor() = DATA_FLAVOR
|
||||
override fun getOffsetCount() = 0
|
||||
|
||||
override fun getOffsets(offsets: IntArray?, index: Int) = index
|
||||
override fun setOffsets(offsets: IntArray?, index: Int) = index
|
||||
|
||||
companion object {
|
||||
val DATA_FLAVOR = DataFlavor(MoveDeclarationsCopyPasteProcessor::class.java, "class: MoveDeclarationsCopyPasteProcessor")
|
||||
|
||||
val STUB_RENDERER = IdeDescriptorRenderers.SOURCE_CODE.withOptions {
|
||||
defaultParameterValueRenderer = { "xxx" } // we need default value to be parsed as expression
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user