i18n: add bundle for idea/refactoring/move
This commit is contained in:
committed by
Dmitry Gridin
parent
93493bdc09
commit
73de63cefc
@@ -168,6 +168,12 @@ fix.import.kind.delegate.accessors=Delegate accessors
|
|||||||
fix.import.kind.component.functions=Component functions
|
fix.import.kind.component.functions=Component functions
|
||||||
fix.import.exclude=Exclude ''{0}'' from auto-import
|
fix.import.exclude=Exclude ''{0}'' from auto-import
|
||||||
|
|
||||||
|
fix.move.file.to.package.family=Move file to package-matching directory
|
||||||
|
fix.move.file.to.package.text=Move file to {0}
|
||||||
|
|
||||||
|
fix.change.package.family=Change file's package to match directory
|
||||||
|
fix.change.package.text=Change file''s package to {0}
|
||||||
|
|
||||||
action.add.import.chooser.title=Imports
|
action.add.import.chooser.title=Imports
|
||||||
|
|
||||||
goto.super.chooser.function.title=Choose super function
|
goto.super.chooser.function.title=Choose super function
|
||||||
@@ -225,6 +231,11 @@ hierarchy.legend.member.is.defined.in.class=Member is defined in the class
|
|||||||
hierarchy.legend.member.defined.in.superclass=Member is not defined in the class but defined in superclass
|
hierarchy.legend.member.defined.in.superclass=Member is not defined in the class but defined in superclass
|
||||||
hierarchy.legend.member.should.be.defined=Member should be defined since the class is not abstract
|
hierarchy.legend.member.should.be.defined=Member should be defined since the class is not abstract
|
||||||
|
|
||||||
|
intention.change.package.text=Change package
|
||||||
|
|
||||||
|
intention.extract.declarations.from.file.text=Extract declaration from current file
|
||||||
|
intention.extract.declarations.from.file.text.details=Extract ''{0}'' {1, choice, 0#|1#and subclasses }from current file
|
||||||
|
|
||||||
intention.suppress.family=Suppress Warnings
|
intention.suppress.family=Suppress Warnings
|
||||||
intention.suppress.text=Suppress ''{0}'' for {1} {2}
|
intention.suppress.text=Suppress ''{0}'' for {1} {2}
|
||||||
|
|
||||||
@@ -737,6 +748,8 @@ configuration.warning.text.modules.override.project.settings={0} modules overrid
|
|||||||
action.text.append=Append
|
action.text.append=Append
|
||||||
action.text.cancel=Cancel
|
action.text.cancel=Cancel
|
||||||
action.text.overwrite=Overwrite
|
action.text.overwrite=Overwrite
|
||||||
|
button.text.move.nested.class.0.to.upper.level=Move &nested class {0} to upper level
|
||||||
|
button.text.move.nested.class.0.to.another.class=&Move nested class {0} to another class
|
||||||
cannot.extract.method=Cannot find statements to extract
|
cannot.extract.method=Cannot find statements to extract
|
||||||
cannot.extract.super.call=Cannot extract super-call
|
cannot.extract.super.call=Cannot extract super-call
|
||||||
cannot.inline.property.with.accessor.s.and.backing.field=Cannot inline property with accessor(s) and backing field
|
cannot.inline.property.with.accessor.s.and.backing.field=Cannot inline property with accessor(s) and backing field
|
||||||
@@ -751,10 +764,14 @@ cannot.refactor.package.expression=Cannot introduce package reference
|
|||||||
cannot.refactor.syntax.errors=Cannot refactor due to erroneous code
|
cannot.refactor.syntax.errors=Cannot refactor due to erroneous code
|
||||||
cannot.refactor.synthesized.function=Cannot refactor synthesized function ''{0}''
|
cannot.refactor.synthesized.function=Cannot refactor synthesized function ''{0}''
|
||||||
checkbox.text.declare.with.var=Declare with &var
|
checkbox.text.declare.with.var=Declare with &var
|
||||||
|
checkbox.text.delete.empty.source.files=&Delete empty source files
|
||||||
checkbox.text.extension.property=E&xtension property:\u0020
|
checkbox.text.extension.property=E&xtension property:\u0020
|
||||||
checkbox.text.introduce.default.value=Introduce &default value
|
checkbox.text.introduce.default.value=Introduce &default value
|
||||||
|
checkbox.text.open.moved.files.in.editor=Open moved member in editor
|
||||||
checkbox.text.replace.all.occurrences.0=&Replace all occurrences ({0})
|
checkbox.text.replace.all.occurrences.0=&Replace all occurrences ({0})
|
||||||
|
checkbox.text.search.references=Search &references
|
||||||
checkbox.text.specify.type.explicitly=Specify &type explicitly
|
checkbox.text.specify.type.explicitly=Specify &type explicitly
|
||||||
|
checkbox.text.update.package.directive=Update package directive (Kotlin files)
|
||||||
column.name.receiver=Receiver:
|
column.name.receiver=Receiver:
|
||||||
column.name.val.var=Val/Var
|
column.name.val.var=Val/Var
|
||||||
declarations.are.used.outside.of.selected.code.fragment=Following declarations are used outside of selected code fragment:
|
declarations.are.used.outside.of.selected.code.fragment=Following declarations are used outside of selected code fragment:
|
||||||
@@ -798,11 +815,17 @@ introduce.type.parameter.to.declaration=Introduce type parameter to declaration
|
|||||||
introduce.type.parameter=Introduce Type Parameter
|
introduce.type.parameter=Introduce Type Parameter
|
||||||
introduce.variable=Introduce Variable
|
introduce.variable=Introduce Variable
|
||||||
label.text.default.receiver.value=&Default receiver value:\u0020
|
label.text.default.receiver.value=&Default receiver value:\u0020
|
||||||
|
label.text.destination.directory=&Destination directory:
|
||||||
|
label.text.file.name=File &name:
|
||||||
label.text.introduce.as=&Introduce as:\u0020
|
label.text.introduce.as=&Introduce as:\u0020
|
||||||
label.text.name=&Name:\u0020
|
label.text.name=&Name:\u0020
|
||||||
|
label.text.package.name=Packa&ge name:
|
||||||
label.text.receiver.type=Receiver &type:\u0020
|
label.text.receiver.type=Receiver &type:\u0020
|
||||||
label.text.target.file.name=Target file name:
|
label.text.target.file.name=Target file name:
|
||||||
|
label.text.to.file=To &file:
|
||||||
|
label.text.to.package=To p&ackage:
|
||||||
label.text.type=&Type:\u0020
|
label.text.type=&Type:\u0020
|
||||||
|
label.text.update.package.directive=&Update package directive
|
||||||
label.text.visibility=&Visibility:\u0020
|
label.text.visibility=&Visibility:\u0020
|
||||||
member.info.abstract.0=abstract {0}
|
member.info.abstract.0=abstract {0}
|
||||||
member.info.companion.0=companion {0}
|
member.info.companion.0=companion {0}
|
||||||
@@ -830,35 +853,60 @@ selected.code.fragment.has.multiple.exit.points=Selected code fragment has multi
|
|||||||
selected.code.fragment.has.multiple.output.values=Selected code fragment has more than 3 output values:
|
selected.code.fragment.has.multiple.output.values=Selected code fragment has more than 3 output values:
|
||||||
selected.code.fragment.has.output.values.and.exit.points=Selected code fragment has output values as well as alternative exit points
|
selected.code.fragment.has.output.values.and.exit.points=Selected code fragment has output values as well as alternative exit points
|
||||||
setter.of.0.will.become.invisible.after.extraction = Setter of {0} will become invisible after extraction
|
setter.of.0.will.become.invisible.after.extraction = Setter of {0} will become invisible after extraction
|
||||||
|
text.0.1.must.be.moved.with.sealed.parent.class.and.all.its.subclasses={0} ''{1}'' must be moved with sealed parent class and all its subclasses
|
||||||
|
text.0.is.invalid.destination.package=''{0}'' is invalid destination package name
|
||||||
text.0.is.not.allowed.in.the.target.context=''{0}'' is not allowed in the target context
|
text.0.is.not.allowed.in.the.target.context=''{0}'' is not allowed in the target context
|
||||||
|
text.0.is.not.valid.package.name={0} is not a valid package name
|
||||||
text.0.to.inline={0} to inline
|
text.0.to.inline={0} to inline
|
||||||
|
text.0.uses.1.which.will.be.inaccessible.after.move={0} uses {1} which will be inaccessible after move
|
||||||
|
text.0.uses.internal.1.which.will.be.inaccessible.after.move={0} uses internal {1} which will be inaccessible after move
|
||||||
text.0.will.no.longer.be.accessible.after.signature.change={0} will no longer be accessible after signature change
|
text.0.will.no.longer.be.accessible.after.signature.change={0} will no longer be accessible after signature change
|
||||||
|
text.all.declarations.must.belong.to.the.same.directory.or.class=All declarations must belong to the same directory or class
|
||||||
text.all=All
|
text.all=All
|
||||||
text.anonymous=[Anonymous]
|
text.anonymous=[Anonymous]
|
||||||
|
text.at.least.one.file.must.be.selected=At least one member must be selected
|
||||||
text.callee.text.would.be.shown.here=Callee text would be shown here
|
text.callee.text.would.be.shown.here=Callee text would be shown here
|
||||||
text.caller.text.with.highlighted.callee.call.would.be.shown.here=Caller text\nwith highlighted callee call would be shown here
|
text.caller.text.with.highlighted.callee.call.would.be.shown.here=Caller text\nwith highlighted callee call would be shown here
|
||||||
|
text.cannot.create.target.directory.0=Cannot create target directory {0}
|
||||||
|
text.cannot.determine.source.directory=Can't determine sources directory
|
||||||
|
text.cannot.find.package.corresponding.to.0=Could not find package corresponding to {0}
|
||||||
|
text.cannot.find.target.package.name=Cannot find target package name
|
||||||
text.cannot.inline.0.1.usages=Cannot inline {0}/{1} usages
|
text.cannot.inline.0.1.usages=Cannot inline {0}/{1} usages
|
||||||
|
text.cannot.move.for.current.project=Can't move for current project
|
||||||
|
text.cannot.move.inner.class.0.into.itself=Cannot move nested class {0} to itself
|
||||||
|
text.cannot.move.to.original.file=Can't move to the original file
|
||||||
|
text.change.file.package.to.0=Change file''s package to ''{0}''
|
||||||
|
text.choose.containing.file=Choose Containing File
|
||||||
|
text.class.0.already.exists.in.package.1=Class {0} already exists in package {1}
|
||||||
text.class.0.already.exists.in.the.target.scope=Class {0} already exists in the target scope
|
text.class.0.already.exists.in.the.target.scope=Class {0} already exists in the target scope
|
||||||
text.constructor=constructor
|
text.constructor=constructor
|
||||||
text.create.destructuring.declaration=Create destructuring declaration
|
text.create.destructuring.declaration=Create destructuring declaration
|
||||||
text.create.single.variable=Create single variable
|
text.create.single.variable=Create single variable
|
||||||
text.declaration=declaration
|
text.declaration=declaration
|
||||||
|
text.declarations.clash.move.0.destination.1.declared.in.scope.2=Following declarations would clash: to move {0} and destination {1} declared in scope {2}
|
||||||
text.default.value=\ // default value = {0}
|
text.default.value=\ // default value = {0}
|
||||||
|
text.destination.class.should.be.kotlin.class=Destination class must be a Kotlin class
|
||||||
text.duplicating.local.variable=Duplicating local variable ''{0}''
|
text.duplicating.local.variable=Duplicating local variable ''{0}''
|
||||||
text.duplicating.parameter=Duplicating parameter ''{0}''
|
text.duplicating.parameter=Duplicating parameter ''{0}''
|
||||||
text.duplicating.property=Duplicating property ''{0}''
|
text.duplicating.property=Duplicating property ''{0}''
|
||||||
text.explicit.receiver.is.already.present.in.call.element.0=Explicit receiver is already present in call element: {0}
|
text.explicit.receiver.is.already.present.in.call.element.0=Explicit receiver is already present in call element: {0}
|
||||||
text.extract.superclass=Extract Superclass
|
text.extract.superclass=Extract Superclass
|
||||||
text.file.0.already.exists.in.1=File {0} already exists in {1}
|
text.file.0.already.exists.in.1=File {0} already exists in {1}
|
||||||
|
text.file.name.cannot.be.empty=File name may not be empty
|
||||||
text.function.already.exists=Function already exists: ''{0}''
|
text.function.already.exists=Function already exists: ''{0}''
|
||||||
text.function=function
|
text.function=function
|
||||||
|
text.implicit.companion.object.will.be.inaccessible.0=Implicit companion object will be inaccessible: {0}
|
||||||
|
text.incorrect.target.path.directory.0.does.not.belong.to.current.project=Incorrect target path. Directory {0} does not belong to current project.
|
||||||
|
text.indirect.outer.instances.will.not.be.extracted.0=Indirect outer instances won''t be extracted: {0}
|
||||||
text.inline.0.1.2=Inline {0} ''{1}''? {2}
|
text.inline.0.1.2=Inline {0} ''{1}''? {2}
|
||||||
text.inline.0=Inline {0}
|
text.inline.0=Inline {0}
|
||||||
text.inline.all.references.and.0.the.1=Inline all references and {0} the kind {1}
|
text.inline.all.references.and.0.the.1=Inline all references and {0} the kind {1}
|
||||||
text.inline.recursive.function.is.supported.only.on.references=Inline recursive function is supported only on references
|
text.inline.recursive.function.is.supported.only.on.references=Inline recursive function is supported only on references
|
||||||
text.inline.this.reference.and.keep.the.0=Inline this reference and keep the {0}
|
text.inline.this.reference.and.keep.the.0=Inline this reference and keep the {0}
|
||||||
text.inlining.0.1=Inlining {0} {1}
|
text.inlining.0.1=Inlining {0} {1}
|
||||||
text.introduce.default.value=Intro&duce default value
|
text.introduce.default.value=Intro&duce default value
|
||||||
|
text.invalid.target.path.0=Invalid target path {0}
|
||||||
|
text.invalid.target.specified=Invalid target specified
|
||||||
text.keep=keep
|
text.keep=keep
|
||||||
text.lambda.parameter=lambda parameter
|
text.lambda.parameter=lambda parameter
|
||||||
text.lambda.parameters=Lambda ¶meters:\u0020
|
text.lambda.parameters=Lambda ¶meters:\u0020
|
||||||
@@ -866,8 +914,22 @@ text.lambda.return.type=Lambda return &type
|
|||||||
text.lazy.property=lazy property
|
text.lazy.property=lazy property
|
||||||
text.local.property=property
|
text.local.property=property
|
||||||
text.local.variable=local variable
|
text.local.variable=local variable
|
||||||
|
text.looking.for.usages=Looking for Usages
|
||||||
|
text.member.extension.call.will.not.be.processed.0=Member extension call won''t be processed: {0}
|
||||||
|
text.move.declaration.no.support.for.companion.objects=Move declaration is not supported for companion objects
|
||||||
|
text.move.declaration.no.support.for.enums=Move declaration is not supported for enum entries
|
||||||
|
text.move.declaration.supports.only.top.levels.and.nested.classes=Move declaration is only supported for top-level declarations and nested classes
|
||||||
|
text.move.declarations=Move declarations
|
||||||
|
text.move.file.0=Move {0}
|
||||||
|
text.move.refactoring.not.available.during.indexing=Move refactoring is not available while indexing is in progress
|
||||||
|
text.moving.multiple.nested.classes.to.top.level.not.supported=Moving multiple nested classes to top-level is not supported
|
||||||
text.name=Name
|
text.name=Name
|
||||||
|
text.nested.classes.to.upper.level=Nested Classes to Upper Level
|
||||||
|
text.no.elements.to.move.are.selected=No elements to move are selected
|
||||||
|
text.no.files.to.move=There is no given files to move
|
||||||
text.no.name.provided.for.type.alias=No name provided for type alias
|
text.no.name.provided.for.type.alias=No name provided for type alias
|
||||||
|
text.no.package.corresponds.to.directory=No package corresponds to this directory
|
||||||
|
text.package.directive.dont.match.file.location=Package directive doesn't match file location
|
||||||
text.parameter.0=parameter ''{0}''
|
text.parameter.0=parameter ''{0}''
|
||||||
text.parameter.name=Parameter &name:\u0020
|
text.parameter.name=Parameter &name:\u0020
|
||||||
text.parameter.reference.can.t.be.safely.replaced.with.0.since.1.is.ambiguous.in.this.context=Parameter reference can''t be safely replaced with {0} since {1} is ambiguous in this context
|
text.parameter.reference.can.t.be.safely.replaced.with.0.since.1.is.ambiguous.in.this.context=Parameter reference can''t be safely replaced with {0} since {1} is ambiguous in this context
|
||||||
@@ -877,15 +939,19 @@ text.parameter=parameter ''{0}''
|
|||||||
text.parameters=&Parameters
|
text.parameters=&Parameters
|
||||||
text.proceed.with.extraction=Proceed with extraction
|
text.proceed.with.extraction=Proceed with extraction
|
||||||
text.process.duplicates=Process Duplicates
|
text.process.duplicates=Process Duplicates
|
||||||
|
text.processing.file.0=Processing {0}
|
||||||
text.property.with.getter=property with getter
|
text.property.with.getter=property with getter
|
||||||
text.property.with.initializer=property with initializer
|
text.property.with.initializer=property with initializer
|
||||||
text.property=property
|
text.property=property
|
||||||
|
text.qualified.call.will.not.be.processed.0=Qualified call won''t be processed: {0}
|
||||||
text.receiver.can.t.be.safely.transformed.to.value.argument=Receiver can''t be safely transformed to value argument: {0}
|
text.receiver.can.t.be.safely.transformed.to.value.argument=Receiver can''t be safely transformed to value argument: {0}
|
||||||
text.receiver=receiver
|
text.receiver=receiver
|
||||||
text.refactoring.can.t.be.performed.on.the.selected.code.element=Refactoring can''t be performed on the selected code element
|
text.refactoring.can.t.be.performed.on.the.selected.code.element=Refactoring can''t be performed on the selected code element
|
||||||
text.refactoring.is.not.applicable.to.this.code.fragment=Refactoring is not applicable to this code fragment
|
text.refactoring.is.not.applicable.to.this.code.fragment=Refactoring is not applicable to this code fragment
|
||||||
|
text.references.in.code.to.0.1.and.its.declarations=References in code to {0} {1} and its declarations
|
||||||
text.remove.0.no.longer.used=Remove {0} no longer used
|
text.remove.0.no.longer.used=Remove {0} no longer used
|
||||||
text.remove=remove
|
text.remove=remove
|
||||||
|
text.sealed.class.0.must.be.moved.with.all.its.subclasses=Sealed class ''{0}'' must be moved with all its subclasses
|
||||||
text.select.target.code.block.file=Select target code block / file
|
text.select.target.code.block.file=Select target code block / file
|
||||||
text.select.target.code.block=Select target code block
|
text.select.target.code.block=Select target code block
|
||||||
text.select.target.file=Select target file
|
text.select.target.file=Select target file
|
||||||
@@ -899,10 +965,13 @@ text.type.already.exists.in.the.target.scope=Type {0} already exists in the targ
|
|||||||
text.type.parameter.names.must.be.distinct=Type parameter names must be distinct
|
text.type.parameter.names.must.be.distinct=Type parameter names must be distinct
|
||||||
text.type.parameters=Type &Parameters
|
text.type.parameters=Type &Parameters
|
||||||
text.type=Type
|
text.type=Type
|
||||||
|
text.unexpected.element.type.0=Unexpected element type: {0}
|
||||||
text.update.usages.to.reflect.declaration.0.move=Update usages to reflect {0, choice, 0#declaration|1#declarations} move
|
text.update.usages.to.reflect.declaration.0.move=Update usages to reflect {0, choice, 0#declaration|1#declarations} move
|
||||||
|
text.updating.usages.progress=Updating usages...
|
||||||
text.variable=variable
|
text.variable=variable
|
||||||
|
title.change.signature=Change Signature
|
||||||
title.inline.function=Inline Function
|
title.inline.function=Inline Function
|
||||||
title.introduce.parameter.to.declaration=Introduce parameter to declaration
|
title.introduce.parameter.to.declaration=Introduce parameter to declaration
|
||||||
|
title.move.nested.classes.to.upper.level=Move Nested Classes to Upper Level
|
||||||
title.select.target.code.block=Select target code block
|
title.select.target.code.block=Select target code block
|
||||||
unsupported.usage.0=Unsupported usage: {0}
|
unsupported.usage.0=Unsupported usage: {0}
|
||||||
title.change.signature=Change Signature
|
|
||||||
+19
-7
@@ -23,6 +23,7 @@ import com.intellij.openapi.application.ApplicationManager
|
|||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.core.quoteSegmentsIfNeeded
|
import org.jetbrains.kotlin.idea.core.quoteSegmentsIfNeeded
|
||||||
import org.jetbrains.kotlin.idea.core.util.CodeInsightUtils
|
import org.jetbrains.kotlin.idea.core.util.CodeInsightUtils
|
||||||
import org.jetbrains.kotlin.idea.intentions.SelfTargetingOffsetIndependentIntention
|
import org.jetbrains.kotlin.idea.intentions.SelfTargetingOffsetIndependentIntention
|
||||||
@@ -33,7 +34,10 @@ import org.jetbrains.kotlin.name.FqNameUnsafe
|
|||||||
import org.jetbrains.kotlin.psi.KtPackageDirective
|
import org.jetbrains.kotlin.psi.KtPackageDirective
|
||||||
|
|
||||||
class ChangePackageIntention :
|
class ChangePackageIntention :
|
||||||
SelfTargetingOffsetIndependentIntention<KtPackageDirective>(KtPackageDirective::class.java, "Change package") {
|
SelfTargetingOffsetIndependentIntention<KtPackageDirective>(
|
||||||
|
KtPackageDirective::class.java,
|
||||||
|
KotlinBundle.message("intention.change.package.text")
|
||||||
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val PACKAGE_NAME_VAR = "PACKAGE_NAME"
|
private const val PACKAGE_NAME_VAR = "PACKAGE_NAME"
|
||||||
}
|
}
|
||||||
@@ -79,27 +83,35 @@ class ChangePackageIntention :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun templateFinished(template: Template, brokenOff: Boolean) {
|
override fun templateFinished(template: Template, brokenOff: Boolean) {
|
||||||
if (brokenOff || enteredName == null || affectedRange == null) return
|
if (brokenOff) return
|
||||||
|
val name = enteredName ?: return
|
||||||
|
val range = affectedRange ?: return
|
||||||
|
|
||||||
// Restore original name and run refactoring
|
// Restore original name and run refactoring
|
||||||
|
|
||||||
val document = editor.document
|
val document = editor.document
|
||||||
project.executeWriteCommand(text) {
|
project.executeWriteCommand(text) {
|
||||||
document.replaceString(
|
document.replaceString(
|
||||||
affectedRange!!.startOffset,
|
range.startOffset,
|
||||||
affectedRange!!.endOffset,
|
range.endOffset,
|
||||||
FqName(currentName).quoteSegmentsIfNeeded()
|
FqName(currentName).quoteSegmentsIfNeeded()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
PsiDocumentManager.getInstance(project).commitDocument(document)
|
PsiDocumentManager.getInstance(project).commitDocument(document)
|
||||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document)
|
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document)
|
||||||
|
|
||||||
if (!FqNameUnsafe(enteredName!!).hasIdentifiersOnly()) {
|
if (!FqNameUnsafe(name).hasIdentifiersOnly()) {
|
||||||
CodeInsightUtils.showErrorHint(project, editor, "$enteredName is not a valid package name", "Change package", null)
|
CodeInsightUtils.showErrorHint(
|
||||||
|
project,
|
||||||
|
editor,
|
||||||
|
KotlinBundle.message("text.0.is.not.valid.package.name", name),
|
||||||
|
KotlinBundle.message("intention.change.package.text"),
|
||||||
|
null
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
KotlinChangePackageRefactoring(file).run(FqName(enteredName!!))
|
KotlinChangePackageRefactoring(file).run(FqName(name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-1
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.idea.refactoring.move.changePackage
|
package org.jetbrains.kotlin.idea.refactoring.move.changePackage
|
||||||
|
|
||||||
import com.intellij.refactoring.RefactoringBundle
|
import com.intellij.refactoring.RefactoringBundle
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.runRefactoringAndKeepDelayedRequests
|
import org.jetbrains.kotlin.idea.codeInsight.shorten.runRefactoringAndKeepDelayedRequests
|
||||||
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
|
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
|
||||||
import org.jetbrains.kotlin.idea.core.util.runSynchronouslyWithProgress
|
import org.jetbrains.kotlin.idea.core.util.runSynchronouslyWithProgress
|
||||||
@@ -54,7 +55,7 @@ class KotlinChangePackageRefactoring(val file: KtFile) {
|
|||||||
val changeInfo = ContainerChangeInfo(ContainerInfo.Package(currentFqName), ContainerInfo.Package(newFqName))
|
val changeInfo = ContainerChangeInfo(ContainerInfo.Package(currentFqName), ContainerInfo.Package(newFqName))
|
||||||
val internalUsages = file.getInternalReferencesToUpdateOnPackageNameChange(changeInfo)
|
val internalUsages = file.getInternalReferencesToUpdateOnPackageNameChange(changeInfo)
|
||||||
|
|
||||||
project.executeWriteCommand("Change file's package to '${newFqName.asString()}'") {
|
project.executeWriteCommand(KotlinBundle.message("text.change.file.package.to.0", newFqName)) {
|
||||||
packageDirective.fqName = newFqName.quoteIfNeeded()
|
packageDirective.fqName = newFqName.quoteIfNeeded()
|
||||||
postProcessMoveUsages(internalUsages)
|
postProcessMoveUsages(internalUsages)
|
||||||
project.runRefactoringAndKeepDelayedRequests { declarationProcessor.execute(declarationUsages) }
|
project.runRefactoringAndKeepDelayedRequests { declarationProcessor.execute(declarationUsages) }
|
||||||
|
|||||||
+6
-5
@@ -18,6 +18,7 @@ import com.intellij.refactoring.move.moveClassesOrPackages.AutocreatingSingleSou
|
|||||||
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesUtil
|
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesUtil
|
||||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil
|
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil
|
||||||
import com.intellij.refactoring.util.RefactoringMessageUtil
|
import com.intellij.refactoring.util.RefactoringMessageUtil
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.core.getFqNameByDirectory
|
import org.jetbrains.kotlin.idea.core.getFqNameByDirectory
|
||||||
import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefix
|
import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefix
|
||||||
import org.jetbrains.kotlin.idea.core.packageMatchesDirectoryOrImplicit
|
import org.jetbrains.kotlin.idea.core.packageMatchesDirectoryOrImplicit
|
||||||
@@ -59,15 +60,15 @@ class PackageDirectoryMismatchInspection : AbstractKotlinInspection() {
|
|||||||
holder.registerProblem(
|
holder.registerProblem(
|
||||||
file,
|
file,
|
||||||
textRange,
|
textRange,
|
||||||
"Package directive doesn't match file location",
|
KotlinBundle.message("text.package.directive.dont.match.file.location"),
|
||||||
*fixes.toTypedArray()
|
*fixes.toTypedArray()
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
private class MoveFileToPackageFix(val dirName: String) : LocalQuickFix {
|
private class MoveFileToPackageFix(val dirName: String) : LocalQuickFix {
|
||||||
override fun getFamilyName() = "Move file to package-matching directory"
|
override fun getFamilyName() = KotlinBundle.message("fix.move.file.to.package.family")
|
||||||
|
|
||||||
override fun getName() = "Move file to $dirName"
|
override fun getName() = KotlinBundle.message("fix.move.file.to.package.text", dirName)
|
||||||
|
|
||||||
override fun startInWriteAction() = false
|
override fun startInWriteAction() = false
|
||||||
|
|
||||||
@@ -103,9 +104,9 @@ class PackageDirectoryMismatchInspection : AbstractKotlinInspection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class ChangePackageFix(val packageName: String, val packageFqName: FqName) : LocalQuickFix {
|
private class ChangePackageFix(val packageName: String, val packageFqName: FqName) : LocalQuickFix {
|
||||||
override fun getFamilyName() = "Change file's package to match directory"
|
override fun getFamilyName() = KotlinBundle.message("fix.change.package.family")
|
||||||
|
|
||||||
override fun getName() = "Change file's package to $packageName"
|
override fun getName() = KotlinBundle.message("fix.change.package.text", packageName)
|
||||||
|
|
||||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||||
val file = descriptor.psiElement as? KtFile ?: return
|
val file = descriptor.psiElement as? KtFile ?: return
|
||||||
|
|||||||
+2
-1
@@ -25,6 +25,7 @@ import com.intellij.psi.search.searches.ReferencesSearch
|
|||||||
import com.intellij.refactoring.MoveDestination
|
import com.intellij.refactoring.MoveDestination
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.util.containers.MultiMap
|
import com.intellij.util.containers.MultiMap
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.createMoveUsageInfoIfPossible
|
import org.jetbrains.kotlin.idea.refactoring.move.createMoveUsageInfoIfPossible
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.KotlinDirectoryMoveTarget
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.KotlinDirectoryMoveTarget
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.analyzeConflictsInFile
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.analyzeConflictsInFile
|
||||||
@@ -78,7 +79,7 @@ class KotlinAwareDelegatingMoveDestination(
|
|||||||
|
|
||||||
val extraUsages = ArrayList<UsageInfo>()
|
val extraUsages = ArrayList<UsageInfo>()
|
||||||
try {
|
try {
|
||||||
progressIndicator.text = "Looking for Usages"
|
progressIndicator.text = KotlinBundle.message("text.looking.for.usages")
|
||||||
for ((index, element) in extraElementsForReferenceSearch.withIndex()) {
|
for ((index, element) in extraElementsForReferenceSearch.withIndex()) {
|
||||||
progressIndicator.fraction = (index + 1) / extraElementsForReferenceSearch.size.toDouble()
|
progressIndicator.fraction = (index + 1) / extraElementsForReferenceSearch.size.toDouble()
|
||||||
ReferencesSearch.search(element, projectScope).mapNotNullTo(extraUsages) { ref ->
|
ReferencesSearch.search(element, projectScope).mapNotNullTo(extraUsages) { ref ->
|
||||||
|
|||||||
+12
-4
@@ -15,11 +15,13 @@ import com.intellij.openapi.project.Project
|
|||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.psi.PsiDirectory
|
import com.intellij.psi.PsiDirectory
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
|
import com.intellij.refactoring.RefactoringBundle
|
||||||
import com.intellij.refactoring.move.MoveCallback
|
import com.intellij.refactoring.move.MoveCallback
|
||||||
import com.intellij.refactoring.util.CommonRefactoringUtil
|
import com.intellij.refactoring.util.CommonRefactoringUtil
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withTimeoutOrNull
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.core.moveCaret
|
import org.jetbrains.kotlin.idea.core.moveCaret
|
||||||
import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
|
import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
|
||||||
@@ -38,7 +40,10 @@ import org.jetbrains.kotlin.resolve.source.getPsi
|
|||||||
private const val TIMEOUT_FOR_IMPORT_OPTIMIZING_MS: Long = 700L
|
private const val TIMEOUT_FOR_IMPORT_OPTIMIZING_MS: Long = 700L
|
||||||
|
|
||||||
class ExtractDeclarationFromCurrentFileIntention :
|
class ExtractDeclarationFromCurrentFileIntention :
|
||||||
SelfTargetingRangeIntention<KtClassOrObject>(KtClassOrObject::class.java, "Extract declaration from current file"),
|
SelfTargetingRangeIntention<KtClassOrObject>(
|
||||||
|
KtClassOrObject::class.java,
|
||||||
|
KotlinBundle.message("intention.extract.declarations.from.file.text")
|
||||||
|
),
|
||||||
LowPriorityAction {
|
LowPriorityAction {
|
||||||
|
|
||||||
private fun KtClassOrObject.tryGetExtraClassesToMove(): List<KtNamedDeclaration>? {
|
private fun KtClassOrObject.tryGetExtraClassesToMove(): List<KtNamedDeclaration>? {
|
||||||
@@ -66,8 +71,11 @@ class ExtractDeclarationFromCurrentFileIntention :
|
|||||||
|
|
||||||
val endOffset = element.nameIdentifier?.endOffset ?: return null
|
val endOffset = element.nameIdentifier?.endOffset ?: return null
|
||||||
|
|
||||||
text = if (extraClassesToMove.isNotEmpty()) "Extract '${element.name}' and subclasses from current file"
|
text = KotlinBundle.message(
|
||||||
else "Extract '${element.name}' from current file"
|
"intention.extract.declarations.from.file.text.details",
|
||||||
|
element.name.toString(),
|
||||||
|
extraClassesToMove.size
|
||||||
|
)
|
||||||
|
|
||||||
return TextRange(startOffset, endOffset)
|
return TextRange(startOffset, endOffset)
|
||||||
}
|
}
|
||||||
@@ -86,7 +94,7 @@ class ExtractDeclarationFromCurrentFileIntention :
|
|||||||
|
|
||||||
if (targetFile !== null) {
|
if (targetFile !== null) {
|
||||||
if (ApplicationManager.getApplication().isUnitTestMode) {
|
if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||||
throw CommonRefactoringUtil.RefactoringErrorHintException("File $targetFileName already exists")
|
throw CommonRefactoringUtil.RefactoringErrorHintException(RefactoringBundle.message("file.already.exist", targetFileName))
|
||||||
}
|
}
|
||||||
// If automatic move is not possible, fall back to full-fledged Move Declarations refactoring
|
// If automatic move is not possible, fall back to full-fledged Move Declarations refactoring
|
||||||
runFullFledgedMoveRefactoring(project, element, packageName, directory, targetFile, file)
|
runFullFledgedMoveRefactoring(project, element, packageName, directory, targetFile, file)
|
||||||
|
|||||||
+5
-1
@@ -13,6 +13,7 @@ import com.intellij.util.containers.MultiMap
|
|||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
import org.jetbrains.kotlin.asJava.toLightClass
|
||||||
import org.jetbrains.kotlin.asJava.unwrapped
|
import org.jetbrains.kotlin.asJava.unwrapped
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.isToBeShortened
|
import org.jetbrains.kotlin.idea.codeInsight.shorten.isToBeShortened
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.*
|
import org.jetbrains.kotlin.idea.refactoring.move.*
|
||||||
@@ -101,7 +102,10 @@ sealed class MoveDeclarationsDelegate {
|
|||||||
val isConflict = when (usage) {
|
val isConflict = when (usage) {
|
||||||
is ImplicitCompanionAsDispatchReceiverUsageInfo -> {
|
is ImplicitCompanionAsDispatchReceiverUsageInfo -> {
|
||||||
if (!isValidTargetForImplicitCompanionAsDispatchReceiver(descriptor, usage.companionDescriptor)) {
|
if (!isValidTargetForImplicitCompanionAsDispatchReceiver(descriptor, usage.companionDescriptor)) {
|
||||||
conflicts.putValue(element, "Implicit companion object will be inaccessible: ${element.text}")
|
conflicts.putValue(
|
||||||
|
element,
|
||||||
|
KotlinBundle.message("text.implicit.companion.object.will.be.inaccessible.0", element.text)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -12,6 +12,7 @@ import com.intellij.refactoring.RefactoringBundle
|
|||||||
import com.intellij.usageView.UsageViewBundle
|
import com.intellij.usageView.UsageViewBundle
|
||||||
import com.intellij.usageView.UsageViewDescriptor
|
import com.intellij.usageView.UsageViewDescriptor
|
||||||
import com.intellij.usageView.UsageViewUtil
|
import com.intellij.usageView.UsageViewUtil
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
|
|
||||||
internal class MoveFilesWithDeclarationsViewDescriptor(
|
internal class MoveFilesWithDeclarationsViewDescriptor(
|
||||||
private val myElementsToMove: Array<PsiElement>,
|
private val myElementsToMove: Array<PsiElement>,
|
||||||
@@ -27,8 +28,11 @@ internal class MoveFilesWithDeclarationsViewDescriptor(
|
|||||||
UsageViewUtil.getType(myElementsToMove[0]),
|
UsageViewUtil.getType(myElementsToMove[0]),
|
||||||
newParent.virtualFile.presentableUrl
|
newParent.virtualFile.presentableUrl
|
||||||
).capitalize()
|
).capitalize()
|
||||||
myCodeReferencesText =
|
myCodeReferencesText = KotlinBundle.message(
|
||||||
"References in code to ${UsageViewUtil.getType(myElementsToMove[0])} ${UsageViewUtil.getLongName(myElementsToMove[0])} and its declarations"
|
"text.references.in.code.to.0.1.and.its.declarations",
|
||||||
|
UsageViewUtil.getType(myElementsToMove[0]),
|
||||||
|
UsageViewUtil.getLongName(myElementsToMove[0])
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
myProcessedElementsHeader =
|
myProcessedElementsHeader =
|
||||||
StringUtil.capitalize(RefactoringBundle.message("move.files.elements.header", newParent.virtualFile.presentableUrl))
|
StringUtil.capitalize(RefactoringBundle.message("move.files.elements.header", newParent.virtualFile.presentableUrl))
|
||||||
|
|||||||
+16
-8
@@ -23,14 +23,15 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.ui.Messages
|
import com.intellij.openapi.ui.Messages
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringSettings
|
|
||||||
import com.intellij.refactoring.RefactoringBundle
|
import com.intellij.refactoring.RefactoringBundle
|
||||||
import com.intellij.refactoring.move.MoveCallback
|
import com.intellij.refactoring.move.MoveCallback
|
||||||
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesImpl
|
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesImpl
|
||||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil
|
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil
|
||||||
import com.intellij.refactoring.util.CommonRefactoringUtil
|
import com.intellij.refactoring.util.CommonRefactoringUtil
|
||||||
import org.jetbrains.kotlin.asJava.unwrapped
|
import org.jetbrains.kotlin.asJava.unwrapped
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.core.getPackage
|
import org.jetbrains.kotlin.idea.core.getPackage
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringSettings
|
||||||
import org.jetbrains.kotlin.idea.refactoring.canRefactor
|
import org.jetbrains.kotlin.idea.refactoring.canRefactor
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.MoveHandlerDelegateCompat
|
import org.jetbrains.kotlin.idea.refactoring.move.MoveHandlerDelegateCompat
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.KotlinAwareMoveFilesOrDirectoriesDialog
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.KotlinAwareMoveFilesOrDirectoriesDialog
|
||||||
@@ -142,7 +143,11 @@ class MoveKotlinDeclarationsHandler internal constructor(private val handlerActi
|
|||||||
val container = getUniqueContainer(elements)
|
val container = getUniqueContainer(elements)
|
||||||
if (container == null) {
|
if (container == null) {
|
||||||
handlerActions.showErrorHint(
|
handlerActions.showErrorHint(
|
||||||
project, editor, "All declarations must belong to the same directory or class", MOVE_DECLARATIONS, null
|
project,
|
||||||
|
editor,
|
||||||
|
KotlinBundle.message("text.all.declarations.must.belong.to.the.same.directory.or.class"),
|
||||||
|
MOVE_DECLARATIONS,
|
||||||
|
null
|
||||||
)
|
)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -157,21 +162,22 @@ class MoveKotlinDeclarationsHandler internal constructor(private val handlerActi
|
|||||||
|
|
||||||
// todo: allow moving companion object
|
// todo: allow moving companion object
|
||||||
if (elementsToSearch.any { it is KtObjectDeclaration && it.isCompanion() }) {
|
if (elementsToSearch.any { it is KtObjectDeclaration && it.isCompanion() }) {
|
||||||
val message = RefactoringBundle.getCannotRefactorMessage("Move declaration is not supported for companion objects")
|
val message = RefactoringBundle.getCannotRefactorMessage(
|
||||||
|
KotlinBundle.message("text.move.declaration.no.support.for.companion.objects")
|
||||||
|
)
|
||||||
handlerActions.showErrorHint(project, editor, message, MOVE_DECLARATIONS, null)
|
handlerActions.showErrorHint(project, editor, message, MOVE_DECLARATIONS, null)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elementsToSearch.any { !it.canMove() }) {
|
if (elementsToSearch.any { !it.canMove() }) {
|
||||||
val message =
|
val message =
|
||||||
RefactoringBundle
|
RefactoringBundle.getCannotRefactorMessage(KotlinBundle.message("text.move.declaration.supports.only.top.levels.and.nested.classes"))
|
||||||
.getCannotRefactorMessage("Move declaration is only supported for top-level declarations and nested classes")
|
|
||||||
handlerActions.showErrorHint(project, editor, message, MOVE_DECLARATIONS, null)
|
handlerActions.showErrorHint(project, editor, message, MOVE_DECLARATIONS, null)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elementsToSearch.any { it is KtEnumEntry }) {
|
if (elementsToSearch.any { it is KtEnumEntry }) {
|
||||||
val message = RefactoringBundle.getCannotRefactorMessage("Move declaration is not supported for enum entries")
|
val message = RefactoringBundle.getCannotRefactorMessage(KotlinBundle.message("text.move.declaration.no.support.for.enums"))
|
||||||
handlerActions.showErrorHint(project, editor, message, MOVE_DECLARATIONS, null)
|
handlerActions.showErrorHint(project, editor, message, MOVE_DECLARATIONS, null)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -223,7 +229,9 @@ class MoveKotlinDeclarationsHandler internal constructor(private val handlerActi
|
|||||||
// todo: allow moving multiple classes to upper level
|
// todo: allow moving multiple classes to upper level
|
||||||
if (targetContainer !is KtClassOrObject) {
|
if (targetContainer !is KtClassOrObject) {
|
||||||
val message =
|
val message =
|
||||||
RefactoringBundle.getCannotRefactorMessage("Moving multiple nested classes to top-level is not supported")
|
RefactoringBundle.getCannotRefactorMessage(
|
||||||
|
KotlinBundle.message("text.moving.multiple.nested.classes.to.top.level.not.supported")
|
||||||
|
)
|
||||||
handlerActions.showErrorHint(project, editor, message, MOVE_DECLARATIONS, null)
|
handlerActions.showErrorHint(project, editor, message, MOVE_DECLARATIONS, null)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -315,4 +323,4 @@ class MoveKotlinDeclarationsHandler internal constructor(private val handlerActi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val MOVE_DECLARATIONS = "Move Declarations"
|
private val MOVE_DECLARATIONS: String get() = KotlinBundle.message("text.move.declarations")
|
||||||
+2
-2
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration
|
|||||||
import org.jetbrains.kotlin.asJava.findFacadeClass
|
import org.jetbrains.kotlin.asJava.findFacadeClass
|
||||||
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||||
import org.jetbrains.kotlin.asJava.toLightElements
|
import org.jetbrains.kotlin.asJava.toLightElements
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToBeShortenedDescendantsToWaitingSet
|
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToBeShortenedDescendantsToWaitingSet
|
||||||
import org.jetbrains.kotlin.idea.core.deleteSingle
|
import org.jetbrains.kotlin.idea.core.deleteSingle
|
||||||
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
|
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
|
||||||
@@ -138,7 +139,6 @@ class MoveKotlinDeclarationsProcessor(
|
|||||||
private val throwOnConflicts: Boolean = false
|
private val throwOnConflicts: Boolean = false
|
||||||
) : BaseRefactoringProcessor(descriptor.project) {
|
) : BaseRefactoringProcessor(descriptor.project) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val REFACTORING_NAME = "Move declarations"
|
|
||||||
const val REFACTORING_ID = "move.kotlin.declarations"
|
const val REFACTORING_ID = "move.kotlin.declarations"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,5 +365,5 @@ class MoveKotlinDeclarationsProcessor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCommandName(): String = REFACTORING_NAME
|
override fun getCommandName(): String = KotlinBundle.message("text.move.declarations")
|
||||||
}
|
}
|
||||||
+2
-1
@@ -27,6 +27,7 @@ import com.intellij.usageView.UsageInfo
|
|||||||
import com.intellij.usageView.UsageViewDescriptor
|
import com.intellij.usageView.UsageViewDescriptor
|
||||||
import com.intellij.util.containers.MultiMap
|
import com.intellij.util.containers.MultiMap
|
||||||
import com.intellij.util.text.UniqueNameGenerator
|
import com.intellij.util.text.UniqueNameGenerator
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
class MoveToKotlinFileProcessor @JvmOverloads constructor(
|
class MoveToKotlinFileProcessor @JvmOverloads constructor(
|
||||||
@@ -49,7 +50,7 @@ class MoveToKotlinFileProcessor @JvmOverloads constructor(
|
|||||||
moveCallback,
|
moveCallback,
|
||||||
prepareSuccessfulCallback
|
prepareSuccessfulCallback
|
||||||
) {
|
) {
|
||||||
override fun getCommandName() = "Move ${sourceFile.name}"
|
override fun getCommandName() = KotlinBundle.message("text.move.file.0", sourceFile.name)
|
||||||
|
|
||||||
override fun createUsageViewDescriptor(usages: Array<out UsageInfo>): UsageViewDescriptor {
|
override fun createUsageViewDescriptor(usages: Array<out UsageInfo>): UsageViewDescriptor {
|
||||||
return MoveFilesWithDeclarationsViewDescriptor(arrayOf(sourceFile), targetDirectory)
|
return MoveFilesWithDeclarationsViewDescriptor(arrayOf(sourceFile), targetDirectory)
|
||||||
|
|||||||
+28
-10
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.asJava.toLightMethods
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.caches.project.forcedModuleInfo
|
import org.jetbrains.kotlin.idea.caches.project.forcedModuleInfo
|
||||||
import org.jetbrains.kotlin.idea.caches.project.getModuleInfoByVirtualFile
|
import org.jetbrains.kotlin.idea.caches.project.getModuleInfoByVirtualFile
|
||||||
import org.jetbrains.kotlin.idea.caches.project.implementedModules
|
import org.jetbrains.kotlin.idea.caches.project.implementedModules
|
||||||
@@ -399,7 +400,11 @@ class MoveConflictChecker(
|
|||||||
val newDescriptorToCheck = referencedDescriptor.asPredicted(targetContainer, actualVisibility) ?: continue
|
val newDescriptorToCheck = referencedDescriptor.asPredicted(targetContainer, actualVisibility) ?: continue
|
||||||
|
|
||||||
if (originalDescriptorToCheck.isVisibleIn(referencingDescriptor) && !newDescriptorToCheck.isVisibleIn(referencingDescriptor)) {
|
if (originalDescriptorToCheck.isVisibleIn(referencingDescriptor) && !newDescriptorToCheck.isVisibleIn(referencingDescriptor)) {
|
||||||
val message = "${render(container)} uses ${render(referencedElement)} which will be inaccessible after move"
|
val message = KotlinBundle.message(
|
||||||
|
"text.0.uses.1.which.will.be.inaccessible.after.move",
|
||||||
|
render(container),
|
||||||
|
render(referencedElement)
|
||||||
|
)
|
||||||
conflicts.putValue(element, message.capitalize())
|
conflicts.putValue(element, message.capitalize())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -473,7 +478,11 @@ class MoveConflictChecker(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isVisible) {
|
if (!isVisible) {
|
||||||
val message = "${render(declaration)} uses ${render(target)} which will be inaccessible after move"
|
val message = KotlinBundle.message(
|
||||||
|
"text.0.uses.1.which.will.be.inaccessible.after.move",
|
||||||
|
render(declaration),
|
||||||
|
render(target)
|
||||||
|
)
|
||||||
conflicts.putValue(refExpr, message.capitalize())
|
conflicts.putValue(refExpr, message.capitalize())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -502,7 +511,11 @@ class MoveConflictChecker(
|
|||||||
val usageModule = ModuleUtilCore.findModuleForPsiElement(element) ?: continue
|
val usageModule = ModuleUtilCore.findModuleForPsiElement(element) ?: continue
|
||||||
if (usageModule != targetModule && targetModule !in usageModule.implementedModules && !isToBeMoved(element)) {
|
if (usageModule != targetModule && targetModule !in usageModule.implementedModules && !isToBeMoved(element)) {
|
||||||
val container = element.getUsageContext()
|
val container = element.getUsageContext()
|
||||||
val message = "${render(container)} uses internal ${render(memberToCheck)} which will be inaccessible after move"
|
val message = KotlinBundle.message(
|
||||||
|
"text.0.uses.internal.1.which.will.be.inaccessible.after.move",
|
||||||
|
render(container),
|
||||||
|
render(memberToCheck)
|
||||||
|
)
|
||||||
conflicts.putValue(element, message.capitalize())
|
conflicts.putValue(element, message.capitalize())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -537,10 +550,14 @@ class MoveConflictChecker(
|
|||||||
if (isToBeMoved(rootClass) && subclasses.all { isToBeMoved(it) }) continue
|
if (isToBeMoved(rootClass) && subclasses.all { isToBeMoved(it) }) continue
|
||||||
|
|
||||||
val message = if (elementToMove == rootClass) {
|
val message = if (elementToMove == rootClass) {
|
||||||
"Sealed class '${rootClass.name}' must be moved with all its subclasses"
|
KotlinBundle.message("text.sealed.class.0.must.be.moved.with.all.its.subclasses", rootClass.name.toString())
|
||||||
} else {
|
} else {
|
||||||
val type = ElementDescriptionUtil.getElementDescription(elementToMove, UsageViewTypeLocation.INSTANCE).capitalize()
|
val type = ElementDescriptionUtil.getElementDescription(elementToMove, UsageViewTypeLocation.INSTANCE).capitalize()
|
||||||
"$type '${rootClass.name}' must be moved with sealed parent class and all its subclasses"
|
KotlinBundle.message(
|
||||||
|
"text.0.1.must.be.moved.with.sealed.parent.class.and.all.its.subclasses",
|
||||||
|
type,
|
||||||
|
rootClass.name.toString()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
conflicts.putValue(elementToMove, message)
|
conflicts.putValue(elementToMove, message)
|
||||||
}
|
}
|
||||||
@@ -624,11 +641,12 @@ class MoveConflictChecker(
|
|||||||
|
|
||||||
moveTarget.getContainerDescriptor()?.let { baseDescriptor ->
|
moveTarget.getContainerDescriptor()?.let { baseDescriptor ->
|
||||||
walkDeclarations(baseDescriptor, declarationDescriptor) { conflictingDeclaration, conflictingScope ->
|
walkDeclarations(baseDescriptor, declarationDescriptor) { conflictingDeclaration, conflictingScope ->
|
||||||
val message =
|
val message = KotlinBundle.message(
|
||||||
"Following declarations would clash: to move ${render(declarationDescriptor)} " +
|
"text.declarations.clash.move.0.destination.1.declared.in.scope.2",
|
||||||
"and destination ${render(conflictingDeclaration)} declared in scope " +
|
render(declarationDescriptor),
|
||||||
render(conflictingScope)
|
render(conflictingDeclaration),
|
||||||
|
render(conflictingScope)
|
||||||
|
)
|
||||||
conflicts.putValue(declaration, message)
|
conflicts.putValue(declaration, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-4
@@ -30,6 +30,7 @@ import com.intellij.ui.TextFieldWithHistoryWithBrowseButton
|
|||||||
import com.intellij.ui.components.JBLabelDecorator
|
import com.intellij.ui.components.JBLabelDecorator
|
||||||
import com.intellij.util.ui.FormBuilder
|
import com.intellij.util.ui.FormBuilder
|
||||||
import com.intellij.util.ui.UIUtil
|
import com.intellij.util.ui.UIUtil
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.core.packageMatchesDirectoryOrImplicit
|
import org.jetbrains.kotlin.idea.core.packageMatchesDirectoryOrImplicit
|
||||||
import org.jetbrains.kotlin.idea.core.util.onTextChange
|
import org.jetbrains.kotlin.idea.core.util.onTextChange
|
||||||
import org.jetbrains.kotlin.idea.refactoring.isInKotlinAwareSourceRoot
|
import org.jetbrains.kotlin.idea.refactoring.isInKotlinAwareSourceRoot
|
||||||
@@ -63,8 +64,10 @@ class KotlinAwareMoveFilesOrDirectoriesDialog(
|
|||||||
|
|
||||||
private val nameLabel = JBLabelDecorator.createJBLabelDecorator().setBold(true)
|
private val nameLabel = JBLabelDecorator.createJBLabelDecorator().setBold(true)
|
||||||
private val targetDirectoryField = TextFieldWithHistoryWithBrowseButton()
|
private val targetDirectoryField = TextFieldWithHistoryWithBrowseButton()
|
||||||
private val searchReferencesCb = NonFocusableCheckBox("Search r${UIUtil.MNEMONIC}eferences").apply { isSelected = true }
|
private val searchReferencesCb = NonFocusableCheckBox(KotlinBundle.message("checkbox.text.search.references")).apply {
|
||||||
private val openInEditorCb = NonFocusableCheckBox("Open moved files in editor")
|
isSelected = true
|
||||||
|
}
|
||||||
|
private val openInEditorCb = NonFocusableCheckBox(KotlinBundle.message("checkbox.text.open.moved.files.in.editor"))
|
||||||
private val updatePackageDirectiveCb = NonFocusableCheckBox()
|
private val updatePackageDirectiveCb = NonFocusableCheckBox()
|
||||||
|
|
||||||
override fun getHelpId() = HELP_ID
|
override fun getHelpId() = HELP_ID
|
||||||
@@ -144,7 +147,7 @@ class KotlinAwareMoveFilesOrDirectoriesDialog(
|
|||||||
|
|
||||||
val singleFile = jetFiles.singleOrNull()
|
val singleFile = jetFiles.singleOrNull()
|
||||||
isSelected = singleFile == null || singleFile.packageMatchesDirectoryOrImplicit()
|
isSelected = singleFile == null || singleFile.packageMatchesDirectoryOrImplicit()
|
||||||
text = "Update package directive (Kotlin files)"
|
text = KotlinBundle.message("checkbox.text.update.package.directive")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +172,7 @@ class KotlinAwareMoveFilesOrDirectoriesDialog(
|
|||||||
val elementsToMove = directory?.let { existentDirectory ->
|
val elementsToMove = directory?.let { existentDirectory ->
|
||||||
val choice = if (psiElements.size > 1 || psiElements[0] is PsiDirectory) intArrayOf(-1) else null
|
val choice = if (psiElements.size > 1 || psiElements[0] is PsiDirectory) intArrayOf(-1) else null
|
||||||
psiElements.filterNot {
|
psiElements.filterNot {
|
||||||
it is PsiFile && CopyFilesOrDirectoriesHandler.checkFileExist(existentDirectory, choice, it, it.name, "Move")
|
it is PsiFile && CopyFilesOrDirectoriesHandler.checkFileExist(existentDirectory, choice, it, it.name, title)
|
||||||
}
|
}
|
||||||
} ?: psiElements.toList()
|
} ?: psiElements.toList()
|
||||||
|
|
||||||
|
|||||||
+6
-5
@@ -15,6 +15,7 @@ import com.intellij.psi.PsiFileSystemItem
|
|||||||
import com.intellij.refactoring.move.MoveCallback
|
import com.intellij.refactoring.move.MoveCallback
|
||||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil
|
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil
|
||||||
import com.intellij.util.IncorrectOperationException
|
import com.intellij.util.IncorrectOperationException
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.refactoring.isInKotlinAwareSourceRoot
|
import org.jetbrains.kotlin.idea.refactoring.isInKotlinAwareSourceRoot
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.getOrCreateDirectory
|
import org.jetbrains.kotlin.idea.refactoring.move.getOrCreateDirectory
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.KotlinAwareMoveFilesOrDirectoriesProcessor
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.KotlinAwareMoveFilesOrDirectoriesProcessor
|
||||||
@@ -64,7 +65,7 @@ class KotlinAwareMoveFilesOrDirectoriesModel(
|
|||||||
try {
|
try {
|
||||||
return getOrCreateDirectory(targetDirectoryName, project)
|
return getOrCreateDirectory(targetDirectoryName, project)
|
||||||
} catch (e: IncorrectOperationException) {
|
} catch (e: IncorrectOperationException) {
|
||||||
throw ConfigurationException("Cannot create target directory $targetDirectoryName")
|
throw ConfigurationException(KotlinBundle.message("text.cannot.create.target.directory.0", targetDirectoryName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,21 +75,21 @@ class KotlinAwareMoveFilesOrDirectoriesModel(
|
|||||||
private fun checkModel() {
|
private fun checkModel() {
|
||||||
|
|
||||||
elementsToMove.firstOrNull { it !is PsiFile && it !is PsiDirectory }?.let {
|
elementsToMove.firstOrNull { it !is PsiFile && it !is PsiDirectory }?.let {
|
||||||
throw ConfigurationException("Unexpected element type: $it")
|
throw ConfigurationException(KotlinBundle.message("text.unexpected.element.type.0", it))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elementsToMove.isEmpty()) {
|
if (elementsToMove.isEmpty()) {
|
||||||
throw ConfigurationException("There is no given files to move")
|
throw ConfigurationException(KotlinBundle.message("text.no.files.to.move"))
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Paths.get(targetDirectoryName)
|
Paths.get(targetDirectoryName)
|
||||||
} catch (e: InvalidPathException) {
|
} catch (e: InvalidPathException) {
|
||||||
throw ConfigurationException("Invalid target path $targetDirectoryName")
|
throw ConfigurationException(KotlinBundle.message("text.invalid.target.path.0", targetDirectoryName))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DumbService.isDumb(project)) {
|
if (DumbService.isDumb(project)) {
|
||||||
throw ConfigurationException("Move refactoring is not available while indexing is in progress")
|
throw ConfigurationException(KotlinBundle.message("text.move.refactoring.not.available.during.indexing"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -11,6 +11,7 @@ import com.intellij.openapi.ui.DialogWrapper
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.refactoring.RefactoringBundle
|
import com.intellij.refactoring.RefactoringBundle
|
||||||
import com.intellij.refactoring.util.RadioUpDownListener
|
import com.intellij.refactoring.util.RadioUpDownListener
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.psi.KtClass
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtEnumEntry
|
import org.jetbrains.kotlin.psi.KtEnumEntry
|
||||||
@@ -40,10 +41,10 @@ internal class KotlinSelectNestedClassRefactoringDialog private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun createCenterPanel(): JComponent? {
|
override fun createCenterPanel(): JComponent? {
|
||||||
moveToUpperLevelButton.text = BundleBase.replaceMnemonicAmpersand("Move &nested class ${nestedClass.name} to upper level")
|
moveToUpperLevelButton.text = KotlinBundle.message("button.text.move.nested.class.0.to.upper.level", nestedClass.name.toString())
|
||||||
moveToUpperLevelButton.isSelected = true
|
moveToUpperLevelButton.isSelected = true
|
||||||
|
|
||||||
moveMembersButton.text = BundleBase.replaceMnemonicAmpersand("&Move nested class ${nestedClass.name} to another class")
|
moveMembersButton.text = KotlinBundle.message("button.text.move.nested.class.0.to.another.class", nestedClass.name.toString())
|
||||||
|
|
||||||
ButtonGroup().apply {
|
ButtonGroup().apply {
|
||||||
add(moveToUpperLevelButton)
|
add(moveToUpperLevelButton)
|
||||||
|
|||||||
+6
-3
@@ -11,6 +11,7 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import com.intellij.refactoring.RefactoringBundle
|
import com.intellij.refactoring.RefactoringBundle
|
||||||
import com.intellij.refactoring.move.MoveCallback
|
import com.intellij.refactoring.move.MoveCallback
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
@@ -25,10 +26,10 @@ internal class MoveKotlinNestedClassesModel(
|
|||||||
) : Model<MoveKotlinDeclarationsProcessor> {
|
) : Model<MoveKotlinDeclarationsProcessor> {
|
||||||
|
|
||||||
private fun getCheckedTargetClass(): KtElement {
|
private fun getCheckedTargetClass(): KtElement {
|
||||||
val targetClass = this.targetClass ?: throw ConfigurationException("No destination class specified")
|
val targetClass = this.targetClass ?: throw ConfigurationException(RefactoringBundle.message("no.destination.class.specified"))
|
||||||
|
|
||||||
if (targetClass !is KtClassOrObject) {
|
if (targetClass !is KtClassOrObject) {
|
||||||
throw ConfigurationException("Destination class must be a Kotlin class")
|
throw ConfigurationException(KotlinBundle.message("text.destination.class.should.be.kotlin.class"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (originalClass === targetClass) {
|
if (originalClass === targetClass) {
|
||||||
@@ -37,7 +38,9 @@ internal class MoveKotlinNestedClassesModel(
|
|||||||
|
|
||||||
for (classOrObject in selectedElementsToMove) {
|
for (classOrObject in selectedElementsToMove) {
|
||||||
if (PsiTreeUtil.isAncestor(classOrObject, targetClass, false)) {
|
if (PsiTreeUtil.isAncestor(classOrObject, targetClass, false)) {
|
||||||
throw ConfigurationException("Cannot move nested class ${classOrObject.name} to itself")
|
throw ConfigurationException(
|
||||||
|
KotlinBundle.message("text.cannot.move.inner.class.0.into.itself", classOrObject.name.toString())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -80,7 +80,7 @@
|
|||||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<text value="Packa&ge name:"/>
|
<text resource-bundle="org/jetbrains/kotlin/idea/KotlinBundle" key="label.text.package.name"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="18010" class="com.intellij.refactoring.ui.PackageNameReferenceEditorCombo" binding="packageNameField" custom-create="true">
|
<component id="18010" class="com.intellij.refactoring.ui.PackageNameReferenceEditorCombo" binding="packageNameField" custom-create="true">
|
||||||
|
|||||||
+4
-3
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NonNls;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle;
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils;
|
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils;
|
||||||
import org.jetbrains.kotlin.idea.core.CollectingNameValidator;
|
import org.jetbrains.kotlin.idea.core.CollectingNameValidator;
|
||||||
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester;
|
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester;
|
||||||
@@ -73,7 +74,7 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase {
|
|||||||
this.innerClass = innerClass;
|
this.innerClass = innerClass;
|
||||||
this.targetContainer = targetContainer;
|
this.targetContainer = targetContainer;
|
||||||
this.innerClassDescriptor = (ClassDescriptor) ResolutionUtils.unsafeResolveToDescriptor(innerClass, BodyResolveMode.FULL);
|
this.innerClassDescriptor = (ClassDescriptor) ResolutionUtils.unsafeResolveToDescriptor(innerClass, BodyResolveMode.FULL);
|
||||||
setTitle("Move Nested Classes to Upper Level");
|
setTitle(KotlinBundle.message("title.move.nested.classes.to.upper.level"));
|
||||||
init();
|
init();
|
||||||
packageNameLabel.setLabelFor(packageNameField.getChildComponent());
|
packageNameLabel.setLabelFor(packageNameField.getChildComponent());
|
||||||
classNameLabel.setLabelFor(classNameField);
|
classNameLabel.setLabelFor(classNameField);
|
||||||
@@ -89,7 +90,7 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getMovePropertySuffix() {
|
protected String getMovePropertySuffix() {
|
||||||
return "Nested Classes to Upper Level";
|
return KotlinBundle.message("text.nested.classes.to.upper.level");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -99,7 +100,7 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getCbTitle() {
|
protected String getCbTitle() {
|
||||||
return "Open moved member in editor";
|
return KotlinBundle.message("checkbox.text.open.moved.files.in.editor");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClassName() {
|
public String getClassName() {
|
||||||
|
|||||||
+7
-4
@@ -20,6 +20,7 @@ import com.intellij.refactoring.RefactoringBundle
|
|||||||
import com.intellij.refactoring.util.RefactoringMessageUtil
|
import com.intellij.refactoring.util.RefactoringMessageUtil
|
||||||
import com.intellij.refactoring.util.RefactoringUtil
|
import com.intellij.refactoring.util.RefactoringUtil
|
||||||
import com.intellij.util.IncorrectOperationException
|
import com.intellij.util.IncorrectOperationException
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||||
@@ -135,14 +136,16 @@ internal abstract class MoveKotlinNestedClassesToUpperLevelModel(
|
|||||||
|
|
||||||
if (targetContainer is PsiDirectory || targetContainer is KtFile) {
|
if (targetContainer is PsiDirectory || targetContainer is KtFile) {
|
||||||
val targetPackageFqName = getTargetPackageFqName(target)
|
val targetPackageFqName = getTargetPackageFqName(target)
|
||||||
?: throw ConfigurationException("No package corresponds to this directory")
|
?: throw ConfigurationException(KotlinBundle.message("text.no.package.corresponds.to.directory"))
|
||||||
|
|
||||||
val existingClass = innerClassDescriptor?.let { DescriptorUtils.getContainingModule(it) }
|
val existingClass = innerClassDescriptor?.let { DescriptorUtils.getContainingModule(it) }
|
||||||
?.getPackage(targetPackageFqName)
|
?.getPackage(targetPackageFqName)
|
||||||
?.memberScope
|
?.memberScope
|
||||||
?.getContributedClassifier(Name.identifier(className), NoLookupLocation.FROM_IDE)
|
?.getContributedClassifier(Name.identifier(className), NoLookupLocation.FROM_IDE)
|
||||||
if (existingClass != null) {
|
if (existingClass != null) {
|
||||||
throw ConfigurationException("Class $className already exists in package $targetPackageFqName")
|
throw ConfigurationException(
|
||||||
|
KotlinBundle.message("text.class.0.already.exists.in.package.1", className, targetPackageFqName)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val targetDir = targetContainer as? PsiDirectory ?: targetContainer.containingFile.containingDirectory
|
val targetDir = targetContainer as? PsiDirectory ?: targetContainer.containingFile.containingDirectory
|
||||||
@@ -150,7 +153,7 @@ internal abstract class MoveKotlinNestedClassesToUpperLevelModel(
|
|||||||
if (message != null) throw ConfigurationException(message)
|
if (message != null) throw ConfigurationException(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
return targetContainer ?: throw ConfigurationException("Invalid target specified")
|
return targetContainer ?: throw ConfigurationException(KotlinBundle.message("text.invalid.target.specified"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(ConfigurationException::class)
|
@Throws(ConfigurationException::class)
|
||||||
@@ -158,7 +161,7 @@ internal abstract class MoveKotlinNestedClassesToUpperLevelModel(
|
|||||||
val target = getTargetContainerWithValidation()
|
val target = getTargetContainerWithValidation()
|
||||||
if (target is PsiDirectory) {
|
if (target is PsiDirectory) {
|
||||||
val targetPackageFqName = getTargetPackageFqName(target)
|
val targetPackageFqName = getTargetPackageFqName(target)
|
||||||
?: throw ConfigurationException("Cannot find target package name")
|
?: throw ConfigurationException(KotlinBundle.message("text.cannot.find.target.package.name"))
|
||||||
|
|
||||||
val suggestedName = KotlinNameSuggester.suggestNameByName(className) {
|
val suggestedName = KotlinNameSuggester.suggestNameByName(className) {
|
||||||
target.findFile(it + "." + KotlinFileType.EXTENSION) == null
|
target.findFile(it + "." + KotlinFileType.EXTENSION) == null
|
||||||
|
|||||||
+7
-7
@@ -45,7 +45,7 @@
|
|||||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<text value="To p&ackage:"/>
|
<text resource-bundle="org/jetbrains/kotlin/idea/KotlinBundle" key="label.text.to.package"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="9ea97" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="fileChooser">
|
<component id="9ea97" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="fileChooser">
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<text value="To &file:"/>
|
<text resource-bundle="org/jetbrains/kotlin/idea/KotlinBundle" key="label.text.to.file"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="67853" class="javax.swing.JTextField" binding="tfFileNameInPackage" default-binding="true">
|
<component id="67853" class="javax.swing.JTextField" binding="tfFileNameInPackage" default-binding="true">
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<horizontalAlignment value="2"/>
|
<horizontalAlignment value="2"/>
|
||||||
<horizontalTextPosition value="11"/>
|
<horizontalTextPosition value="11"/>
|
||||||
<text value="File &name:"/>
|
<text resource-bundle="org/jetbrains/kotlin/idea/KotlinBundle" key="label.text.file.name"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<grid id="ce694" binding="targetPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
<grid id="ce694" binding="targetPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<labelFor value="36327"/>
|
<labelFor value="36327"/>
|
||||||
<text value="&Destination directory:"/>
|
<text resource-bundle="org/jetbrains/kotlin/idea/KotlinBundle" key="label.text.destination.directory"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="36327" class="com.intellij.ui.ComboboxWithBrowseButton" binding="destinationFolderCB" custom-create="true">
|
<component id="36327" class="com.intellij.ui.ComboboxWithBrowseButton" binding="destinationFolderCB" custom-create="true">
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<selected value="true"/>
|
<selected value="true"/>
|
||||||
<text value="&Update package directive"/>
|
<text resource-bundle="org/jetbrains/kotlin/idea/KotlinBundle" key="label.text.update.package.directive"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<grid id="69aba" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
<grid id="69aba" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
@@ -148,7 +148,7 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<selected value="true"/>
|
<selected value="true"/>
|
||||||
<text value="Search &references"/>
|
<text resource-bundle="org/jetbrains/kotlin/idea/KotlinBundle" key="checkbox.text.search.references"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="cc60e" class="javax.swing.JCheckBox" binding="cbDeleteEmptySourceFiles">
|
<component id="cc60e" class="javax.swing.JCheckBox" binding="cbDeleteEmptySourceFiles">
|
||||||
@@ -157,7 +157,7 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<selected value="true"/>
|
<selected value="true"/>
|
||||||
<text value="&Delete empty source files"/>
|
<text resource-bundle="org/jetbrains/kotlin/idea/KotlinBundle" key="checkbox.text.delete.empty.source.files"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
</children>
|
</children>
|
||||||
|
|||||||
+6
-2
@@ -31,6 +31,7 @@ import com.intellij.util.ui.UIUtil;
|
|||||||
import kotlin.collections.CollectionsKt;
|
import kotlin.collections.CollectionsKt;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle;
|
||||||
import org.jetbrains.kotlin.idea.core.PackageUtilsKt;
|
import org.jetbrains.kotlin.idea.core.PackageUtilsKt;
|
||||||
import org.jetbrains.kotlin.idea.core.util.PhysicalFileSystemUtilsKt;
|
import org.jetbrains.kotlin.idea.core.util.PhysicalFileSystemUtilsKt;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringSettings;
|
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringSettings;
|
||||||
@@ -268,7 +269,10 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileChooser.addActionListener(e -> {
|
fileChooser.addActionListener(e -> {
|
||||||
KotlinFileChooserDialog dialog = new KotlinFileChooserDialog("Choose Containing File", myProject);
|
KotlinFileChooserDialog dialog = new KotlinFileChooserDialog(
|
||||||
|
KotlinBundle.message("text.choose.containing.file"),
|
||||||
|
myProject
|
||||||
|
);
|
||||||
|
|
||||||
File targetFile1 = new File(fileChooser.getText());
|
File targetFile1 = new File(fileChooser.getText());
|
||||||
PsiFile targetPsiFile = PhysicalFileSystemUtilsKt.toPsiFile(targetFile1, myProject);
|
PsiFile targetPsiFile = PhysicalFileSystemUtilsKt.toPsiFile(targetFile1, myProject);
|
||||||
@@ -387,7 +391,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
private List<KtNamedDeclaration> getSelectedElementsToMoveChecked() throws ConfigurationException {
|
private List<KtNamedDeclaration> getSelectedElementsToMoveChecked() throws ConfigurationException {
|
||||||
List<KtNamedDeclaration> elementsToMove = getSelectedElementsToMove();
|
List<KtNamedDeclaration> elementsToMove = getSelectedElementsToMove();
|
||||||
if (elementsToMove.isEmpty()) {
|
if (elementsToMove.isEmpty()) {
|
||||||
throw new ConfigurationException("No elements to move are selected");
|
throw new ConfigurationException(KotlinBundle.message("text.no.elements.to.move.are.selected"));
|
||||||
}
|
}
|
||||||
return elementsToMove;
|
return elementsToMove;
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-14
@@ -6,20 +6,23 @@
|
|||||||
package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui
|
package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui
|
||||||
|
|
||||||
import com.intellij.openapi.fileTypes.FileTypeManager
|
import com.intellij.openapi.fileTypes.FileTypeManager
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.options.ConfigurationException
|
import com.intellij.openapi.options.ConfigurationException
|
||||||
import com.intellij.psi.*
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiDirectory
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
import com.intellij.psi.PsiManager
|
||||||
|
import com.intellij.psi.PsiNameHelper
|
||||||
import com.intellij.refactoring.BaseRefactoringProcessor
|
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||||
import com.intellij.refactoring.MoveDestination
|
import com.intellij.refactoring.MoveDestination
|
||||||
import com.intellij.refactoring.PackageWrapper
|
import com.intellij.refactoring.PackageWrapper
|
||||||
import com.intellij.refactoring.move.MoveCallback
|
import com.intellij.refactoring.move.MoveCallback
|
||||||
import com.intellij.refactoring.move.moveClassesOrPackages.AutocreatingSingleSourceRootMoveDestination
|
import com.intellij.refactoring.move.moveClassesOrPackages.AutocreatingSingleSourceRootMoveDestination
|
||||||
import com.intellij.refactoring.move.moveClassesOrPackages.MultipleRootsMoveDestination
|
import com.intellij.refactoring.move.moveClassesOrPackages.MultipleRootsMoveDestination
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.core.getPackage
|
import org.jetbrains.kotlin.idea.core.getPackage
|
||||||
import org.jetbrains.kotlin.idea.core.util.toPsiDirectory
|
import org.jetbrains.kotlin.idea.core.util.toPsiDirectory
|
||||||
import org.jetbrains.kotlin.idea.core.util.toPsiFile
|
import org.jetbrains.kotlin.idea.core.util.toPsiFile
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
|
||||||
import org.jetbrains.kotlin.idea.refactoring.getOrCreateKotlinFile
|
import org.jetbrains.kotlin.idea.refactoring.getOrCreateKotlinFile
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.getOrCreateDirectory
|
import org.jetbrains.kotlin.idea.refactoring.move.getOrCreateDirectory
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
|
||||||
@@ -51,8 +54,8 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
private inline fun <T, K> Set<T>.mapToSingleOrNull(transform: (T) -> K?): K? =
|
private inline fun <T, K> Set<T>.mapToSingleOrNull(transform: (T) -> K?): K? =
|
||||||
mapTo(mutableSetOf(), transform).singleOrNull()
|
mapTo(mutableSetOf(), transform).singleOrNull()
|
||||||
|
|
||||||
private fun checkedGetSourceDirectory() =
|
private fun checkedGetSourceDirectory() = sourceFiles.mapToSingleOrNull { it.parent }
|
||||||
sourceFiles.mapToSingleOrNull { it.parent } ?: throw ConfigurationException("Can't determine sources directory")
|
?: throw ConfigurationException(KotlinBundle.message("text.cannot.determine.source.directory"))
|
||||||
|
|
||||||
private val sourceFiles: Set<KtFile> = elementsToMove.mapTo(mutableSetOf()) { it.containingKtFile }
|
private val sourceFiles: Set<KtFile> = elementsToMove.mapTo(mutableSetOf()) { it.containingKtFile }
|
||||||
|
|
||||||
@@ -134,7 +137,7 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
val targetFile = try {
|
val targetFile = try {
|
||||||
Paths.get(targetFilePath).toFile()
|
Paths.get(targetFilePath).toFile()
|
||||||
} catch (e: InvalidPathException) {
|
} catch (e: InvalidPathException) {
|
||||||
throw ConfigurationException("Invalid target path $targetFilePath")
|
throw ConfigurationException(KotlinBundle.message("text.invalid.target.path.0", targetFilePath))
|
||||||
}
|
}
|
||||||
|
|
||||||
checkTargetFileName(targetFile.name)
|
checkTargetFileName(targetFile.name)
|
||||||
@@ -142,7 +145,7 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
val jetFile = targetFile.toPsiFile(project) as? KtFile
|
val jetFile = targetFile.toPsiFile(project) as? KtFile
|
||||||
if (jetFile != null) {
|
if (jetFile != null) {
|
||||||
if (sourceFiles.singleOrNull() == jetFile) {
|
if (sourceFiles.singleOrNull() == jetFile) {
|
||||||
throw ConfigurationException("Can't move to the original file")
|
throw ConfigurationException(KotlinBundle.message("text.cannot.move.to.original.file"))
|
||||||
}
|
}
|
||||||
return KotlinMoveTargetForExistingElement(jetFile)
|
return KotlinMoveTargetForExistingElement(jetFile)
|
||||||
}
|
}
|
||||||
@@ -151,17 +154,21 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
?: throw ConfigurationException("Incorrect target path. Directory is not specified.")
|
?: throw ConfigurationException("Incorrect target path. Directory is not specified.")
|
||||||
|
|
||||||
val projectBasePath = project.basePath
|
val projectBasePath = project.basePath
|
||||||
?: throw ConfigurationException("Can't move for current project")
|
?: throw ConfigurationException(KotlinBundle.message("text.cannot.move.for.current.project"))
|
||||||
|
|
||||||
if (!targetDirectoryPath.startsWith(projectBasePath)) {
|
if (!targetDirectoryPath.startsWith(projectBasePath)) {
|
||||||
throw ConfigurationException("Incorrect target path. Directory $targetDirectoryPath does not belong to current project.")
|
throw ConfigurationException(
|
||||||
|
KotlinBundle.message("text.incorrect.target.path.directory.0.does.not.belong.to.current.project", targetDirectoryPath)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val psiDirectory = targetDirectoryPath.toFile().toPsiDirectory(project)
|
val psiDirectory = targetDirectoryPath.toFile().toPsiDirectory(project)
|
||||||
|
|
||||||
val targetPackageFqName = sourceFiles.singleOrNull()?.packageFqName
|
val targetPackageFqName = sourceFiles.singleOrNull()?.packageFqName
|
||||||
?: psiDirectory?.getPackage()?.let { FqName(it.qualifiedName) }
|
?: psiDirectory?.getPackage()?.let { FqName(it.qualifiedName) }
|
||||||
?: throw ConfigurationException("Could not find package corresponding to $targetDirectoryPath")
|
?: throw ConfigurationException(
|
||||||
|
KotlinBundle.message("text.cannot.find.package.corresponding.to.0", targetDirectoryPath)
|
||||||
|
)
|
||||||
|
|
||||||
val targetDirectoryPathString = targetDirectoryPath.toString()
|
val targetDirectoryPathString = targetDirectoryPath.toString()
|
||||||
val finalTargetPackageFqName = targetPackageFqName.asString()
|
val finalTargetPackageFqName = targetPackageFqName.asString()
|
||||||
@@ -180,14 +187,13 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
if (isMoveToPackage) selectMoveTargetToPackage() else selectMoveTargetToFile()
|
if (isMoveToPackage) selectMoveTargetToPackage() else selectMoveTargetToFile()
|
||||||
|
|
||||||
private fun verifyBeforeRun() {
|
private fun verifyBeforeRun() {
|
||||||
|
if (elementsToMove.isEmpty()) throw ConfigurationException(KotlinBundle.message("text.at.least.one.file.must.be.selected"))
|
||||||
if (elementsToMove.isEmpty()) throw ConfigurationException("At least one member must be selected")
|
|
||||||
if (sourceFiles.isEmpty()) throw ConfigurationException("None elements were selected")
|
if (sourceFiles.isEmpty()) throw ConfigurationException("None elements were selected")
|
||||||
if (singleSourceFileMode && fileNameInPackage.isBlank()) throw ConfigurationException("File name may not be empty")
|
if (singleSourceFileMode && fileNameInPackage.isBlank()) throw ConfigurationException(KotlinBundle.message("text.file.name.cannot.be.empty"))
|
||||||
|
|
||||||
if (isMoveToPackage) {
|
if (isMoveToPackage) {
|
||||||
if (targetPackage.isNotEmpty() && !PsiNameHelper.getInstance(project).isQualifiedName(targetPackage)) {
|
if (targetPackage.isNotEmpty() && !PsiNameHelper.getInstance(project).isQualifiedName(targetPackage)) {
|
||||||
throw ConfigurationException("\'$targetPackage\' is invalid destination package name")
|
throw ConfigurationException(KotlinBundle.message("text.0.is.invalid.destination.package", targetPackage))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val targetFile = File(targetFilePath).toPsiFile(project)
|
val targetFile = File(targetFilePath).toPsiFile(project)
|
||||||
|
|||||||
+2
-1
@@ -16,6 +16,7 @@ import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectori
|
|||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.util.Function
|
import com.intellij.util.Function
|
||||||
import com.intellij.util.containers.MultiMap
|
import com.intellij.util.containers.MultiMap
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefix
|
import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefix
|
||||||
import org.jetbrains.kotlin.idea.core.getPackage
|
import org.jetbrains.kotlin.idea.core.getPackage
|
||||||
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
|
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
|
||||||
@@ -76,7 +77,7 @@ class KotlinMoveDirectoryWithClassesHelper : MoveDirectoryWithClassesHelper() {
|
|||||||
for ((index, usageInfo) in infos.withIndex()) {
|
for ((index, usageInfo) in infos.withIndex()) {
|
||||||
if (usageInfo !is FileUsagesWrapper) continue
|
if (usageInfo !is FileUsagesWrapper) continue
|
||||||
|
|
||||||
ProgressManager.getInstance().progressIndicator?.text2 = "Processing ${usageInfo.psiFile.name}"
|
ProgressManager.getInstance().progressIndicator?.text2 = KotlinBundle.message("text.processing.file.0", usageInfo.psiFile.name)
|
||||||
|
|
||||||
runReadAction {
|
runReadAction {
|
||||||
analyzeConflictsInFile(usageInfo.psiFile, usageInfo.usages, moveTarget, files, conflicts) {
|
analyzeConflictsInFile(usageInfo.psiFile, usageInfo.usages, moveTarget, files, conflicts) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.intellij.util.SmartList
|
|||||||
import com.intellij.util.containers.MultiMap
|
import com.intellij.util.containers.MultiMap
|
||||||
import org.jetbrains.kotlin.asJava.unwrapped
|
import org.jetbrains.kotlin.asJava.unwrapped
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
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.caches.resolve.analyzeWithAllCompilerChecks
|
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithAllCompilerChecks
|
||||||
@@ -520,7 +521,7 @@ fun postProcessMoveUsages(
|
|||||||
|
|
||||||
val progressStep = 1.0 / sortedUsages.size
|
val progressStep = 1.0 / sortedUsages.size
|
||||||
val progressIndicator = ProgressManager.getInstance().progressIndicator
|
val progressIndicator = ProgressManager.getInstance().progressIndicator
|
||||||
progressIndicator?.text = "Updating usages..."
|
progressIndicator?.text = KotlinBundle.message("text.updating.usages.progress")
|
||||||
usageLoop@ for ((i, usage) in sortedUsages.withIndex()) {
|
usageLoop@ for ((i, usage) in sortedUsages.withIndex()) {
|
||||||
progressIndicator?.fraction = (i + 1) * progressStep
|
progressIndicator?.fraction = (i + 1) * progressStep
|
||||||
postProcessMoveUsage(usage, oldToNewElementsMapping, nonCodeUsages, shorteningMode)
|
postProcessMoveUsage(usage, oldToNewElementsMapping, nonCodeUsages, shorteningMode)
|
||||||
@@ -537,7 +538,7 @@ sealed class OuterInstanceReferenceUsageInfo(element: PsiElement, private val is
|
|||||||
val element = element ?: return false
|
val element = element ?: return false
|
||||||
|
|
||||||
if (isIndirectOuter) {
|
if (isIndirectOuter) {
|
||||||
conflicts.putValue(element, "Indirect outer instances won't be extracted: ${element.text}")
|
conflicts.putValue(element, KotlinBundle.message("text.indirect.outer.instances.will.not.be.extracted.0", element.text))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,12 +567,12 @@ sealed class OuterInstanceReferenceUsageInfo(element: PsiElement, private val is
|
|||||||
val fullCall = callElement?.let { it.getQualifiedExpressionForSelector() ?: it } ?: return false
|
val fullCall = callElement?.let { it.getQualifiedExpressionForSelector() ?: it } ?: return false
|
||||||
return when {
|
return when {
|
||||||
fullCall is KtQualifiedExpression -> {
|
fullCall is KtQualifiedExpression -> {
|
||||||
conflicts.putValue(fullCall, "Qualified call won't be processed: ${fullCall.text}")
|
conflicts.putValue(fullCall, KotlinBundle.message("text.qualified.call.will.not.be.processed.0", fullCall.text))
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
isDoubleReceiver -> {
|
isDoubleReceiver -> {
|
||||||
conflicts.putValue(fullCall, "Member extension call won't be processed: ${fullCall.text}")
|
conflicts.putValue(fullCall, KotlinBundle.message("text.member.extension.call.will.not.be.processed.0", fullCall.text))
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
else -> false
|
else -> false
|
||||||
|
|||||||
Reference in New Issue
Block a user