في بعض الأحيان تكون الأشياء البسيطة مرهقة للغاية ، خاصة عندما تحتاج إلى القيام بها باستمرار. أحد هذه الأشياء عند العمل مع إطار عمل Moxy هو إضافة استراتيجيات للوظائف. لتسريع هذه العملية ، تم كتابة مكون إضافي يوفر ، عن طريق "alt + enter" ، اختيار إستراتيجية إذا لم يكن هناك أو حوارًا مع استبدال لإستراتيجية أخرى. أولئك الذين يريدون أن يعرفوا كيف يعمل ، مرحبا بكم في القطط.

Moxy, . , .
, adev_one , .
Inspection
, . code inspections. PSI (Program Structure Interface), , , alt+enter .
code inspections.
PSI — , , .. , , parent child. , , Psi viewer plugin.
.
, KtNamedFunction.
Inpection.
. plugins.xml
<depends>org.jetbrains.kotlin</depends>
<depends>com.intellij.modules.lang</depends>
build.gradle
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation "org.jetbrains.kotlin:kotlin-reflect"
implementation "com.github.moxy-community:moxy:1.0.13"
}
intellij {
...
plugins = ["Kotlin"]
...
}
inpection.
AbstractKotlinInspection
class MvpViewStrategyInspection : AbstractKotlinInspection() {}
:
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor
Visitor, .
Visitor , kotlin - Visitor. KtNamedFunction :
org.jetbrains.kotlin.psi VisitorWrappersKt.class
public fun namedFunctionVisitor(block: (KtNamedFunction) → Unit): KtVisitorVoid
PSI: , MvpView. , ProblemsHolder.
:
private val fixes = MoxyStrategy.values().map { AddStrategyFix(it) }.toTypedArray()
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return namedFunctionVisitor { ktNamedFunction ->
if (!ktNamedFunction.isClassInheritMvpView() ||
ktNamedFunction.isHasMoxyAnnotation()
) return@namedFunctionVisitor
holder.registerProblem(
ktNamedFunction,
StrategyIntentionType.MissingStrategy.title,
*fixes
)
}
}
AddStrategyFix? , LocalQuickFix. , :
class AddStrategyFix(
private val strategy: MoxyStrategy
) : LocalQuickFix {
override fun getFamilyName(): String = "add ${strategy.className}"
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val ktFunction = (descriptor.psiElement as KtNamedFunction)
val editor = ktFunction.getProjectEditor()
ktFunction.addStrategyAnnotation(strategy, project, editor)
}
}
getFamilyName
— , .
applyFix
. .
Inspection plguin.xml, ( Activity Manifest)
<extensions defaultExtensionNs="com.intellij">
<localInspection language="kotlin"
displayName="missing strategy for function"
groupPath="Moxy"
groupBundle="messages.InspectionsBundle"
groupKey="group.names.probable.bugs"
enabledByDefault="true"
level="ERROR"
implementationClass="com.maksimnovikov.inspection.MvpViewStrategyInspection"/>
</extensions>
:

StateStrategyType
.
AddToEndSingleTagStrategy
tag
.

Intention
, . .
Intention.
Inspection, . intention. .
Intention.
PsiElementBaseIntentionAction
:
class MvpViewStrategyIntention : PsiElementBaseIntentionAction(){
override fun getText(): String
override fun getFamilyName(): String
override fun isAvailable(project: Project, editor: Editor?, element: PsiElement): Boolean
override fun invoke(project: Project, editor: Editor?, element: PsiElement)
}
getText —
getFamilyName — intention
isAvailable — , intention .
invoke — , intention
isAvailable invoke:
isAvailable
, intention . .
child , . .
override fun isAvailable(project: Project, editor: Editor?, element: PsiElement): Boolean {
if ((element.containingFile ?: return false) !is KtFile) return false
if (!element.isClassInheritMvpView()) return false
val ktFunction = element.getParentOfType<KtNamedFunction>() ?: return false
return ktFunction.isHasMoxyAnnotation()
}
invoke
Intention , .
IDE swing. , , . — JBPopupFactory
fun <T> Editor.showSelectPopup(
items: List<T>,
onSelected: (T) -> Unit
) {
JBPopupFactory.getInstance()
.createPopupChooserBuilder(items)
.setRequestFocus(true)
.setCancelOnClickOutside(true)
.setItemChosenCallback { onSelected(it) }
.createPopup()
.showInBestPositionFor(this)
}
, , . WriteCommandAction.runWriteCommandAction(project) {}
override fun invoke(project: Project, editor: Editor, element: PsiElement) {
editor.showSelectPopup(MoxyStrategy.values().toList()) { selectedStrategy ->
WriteCommandAction.runWriteCommandAction(project) {
val ktFunction = element.getParentOfType<KtNamedFunction>() ?: return@runWriteCommandAction
ktFunction.replaceAnnotation(selectedStrategy, project, editor)
}
}
}
intention plugin.xml
<extensions defaultExtensionNs="com.intellij">
<intentionAction>
<className>com.maksimnovikov.intention.MvpViewStrategyIntention</className>
<category>Moxy intentions</category>
</intentionAction>
</extensions>
:


. . , , . Moxy.
. - . . . .