-
Notifications
You must be signed in to change notification settings - Fork 380
/
RsExtractStructFieldsAction.kt
66 lines (57 loc) · 2.42 KB
/
RsExtractStructFieldsAction.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
* Use of this source code is governed by the MIT license that can be
* found in the LICENSE file.
*/
package org.rust.ide.refactoring.extractStructFields
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.rust.RsBundle
import org.rust.ide.refactoring.RsBaseEditorRefactoringAction
import org.rust.ide.refactoring.generate.StructMember
import org.rust.ide.refactoring.generate.showStructMemberChooserDialog
import org.rust.lang.core.psi.RsStructItem
import org.rust.lang.core.psi.ext.ancestorOrSelf
import org.rust.lang.core.psi.ext.isTupleStruct
import org.rust.lang.core.types.emptySubstitution
data class RsExtractStructFieldsContext(
val struct: RsStructItem,
val fields: List<StructMember>,
val name: String
)
class RsExtractStructFieldsAction : RsBaseEditorRefactoringAction() {
override fun isAvailableOnElementInEditorAndFile(
element: PsiElement,
editor: Editor,
file: PsiFile,
context: DataContext
): Boolean = findApplicableContext(editor, file) != null
override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext?) {
val struct = findApplicableContext(editor, file) ?: return
val fields = StructMember.fromStruct(struct, emptySubstitution)
val chosenFields = showStructMemberChooserDialog(
project,
struct,
fields,
RsBundle.message("action.Rust.RsExtractStructFields.choose.fields.title"),
allowEmptySelection = false
) ?: return
if (chosenFields.isEmpty()) return
val name = showExtractStructFieldsDialog(project) ?: return
val ctx = RsExtractStructFieldsContext(struct, chosenFields, name)
val processor = RsExtractStructFieldsProcessor(project, editor, ctx)
processor.setPreviewUsages(false)
processor.run()
}
companion object {
private fun findApplicableContext(editor: Editor, file: PsiFile): RsStructItem? {
val offset = editor.caretModel.offset
val struct = file.findElementAt(offset)?.ancestorOrSelf<RsStructItem>() ?: return null
if (struct.isTupleStruct) return null
if (struct.blockFields?.namedFieldDeclList?.isEmpty() != false) return null
return struct
}
}
}