рд╢рд╛рдирджрд╛рд░ рдкреНрд▓рдЧрдЗрдиреНрд╕, рд╡реЙрд▓реНрдпреВрдоред 2. рдЕрднреНрдпрд╛рд╕

рдпрд╣рд╛рдВ рдЖрдк рдкреНрд▓рдЧ-рдЗрди рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рд╕рд╛рде рдкрд╣рд▓рд╛ рд▓реЗрдЦ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред


рдФрд░ рдЗрд╕ рднрд╛рдЧ рдореЗрдВ рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдкреНрд▓рдЧрдЗрди рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рджреМрд░рд╛рди рд╣рдореЗрдВ рдХрд┐рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛ рдФрд░ рд╣рдордиреЗ рдЙрдиреНрд╣реЗрдВ рдХреИрд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред
рдЫрд╡рд┐


рдореИрдВ рдХрд┐рд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛?


  • рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рднрд╛рдЧ
    • рдмрд╣реБ рдпреВрдЖрдИ
    • рдкреНрд▓рдЧрдЗрдиреНрд╕ рдореЗрдВ рдбрд┐
    • рдХреЛрдб рдЬрдирд░реЗрд╢рди
    • рдХреЛрдб рд╕рдВрд╢реЛрдзрди
  • рдЖрдЧреЗ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ?
    • рдЯрд┐рдкреНрд╕
    • рдкреВрдЫреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рд╢реНрди

рдмрд╣реБ рдпреВрдЖрдИ


рдкрд╣рд▓реА рдЪреАрдЬрд╝ рдЬреЛ рд╣рдореЗрдВ рдХрд░рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рдереА рд╡рд╣ рдереА рдПрдХ рдорд▓реНрдЯреА-рдкреЗрдЬ UIред рд╣рдордиреЗ рдкрд╣рд▓реЗ рдЬрдЯрд┐рд▓ рдлреЙрд░реНрдо рдХреЛ рдЪреЗрдХрдорд╛рд░реНрдХ, рдЗрдирдкреБрдЯ рдлрд╝реАрд▓реНрдб рдХреЗ рдПрдХ рд╕рдореВрд╣ рдХреЗ рд╕рд╛рде рдмрдирд╛рдпрд╛ред рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж, рд╣рдордиреЗ рдореЙрдбреНрдпреВрд▓ рдХреА рдПрдХ рд╕реВрдЪреА рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдЬрд┐рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирдП рдореЙрдбреНрдпреВрд▓ рд╕реЗ рдЬреЛрдбрд╝ рд╕рдХрддрд╛ рд╣реИред рдФрд░ рд╣рдо рдЙрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЙрдбреНрдпреВрд▓ рдХреЛ рднреА рдЪреБрдирдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд╣рдо рдирд┐рд░реНрдорд┐рдд рдореЙрдбреНрдпреВрд▓ рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рддреЗ рд╣реИрдВред


рдПрдХ рд░реВрдк рдкрд░ рдЗрддрдиреЗ рд╕рд╛рд░реЗ рдирд┐рдпрдВрддреНрд░рдг рд░рдЦрдирд╛ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЙрдиреНрд╣реЛрдВрдиреЗ рддреАрди рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреГрд╖реНрда, рддреАрди рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХреБрдХреА рдХрдЯрд░ рдмрдирд╛рдПред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдЬрд╛рджреВрдЧрд░ рд╕рдВрд╡рд╛рджред


рдЫрд╡рд┐


рд▓реЗрдХрд┐рди рдкреНрд▓рдЧрдЗрдиреНрд╕ рдореЗрдВ рдорд▓реНрдЯреА-рдкреЗрдЬ рдпреВрдЖрдИ рдмрдирд╛рдиреЗ рдХреЗ рдмрд╛рдж рд╕реЗ рдмрд╣реБрдд рджрд░реНрджрдирд╛рдХ рд╣реИ, рдореИрдВ рдХреБрдЫ рддреИрдпрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдФрд░ IDEA рдХреЗ рдЖрдВрддреЛрдВ рдореЗрдВ, рд╣рдордиреЗ рд╡рд┐рдЬрд╛рд░реНрдбрдбрд╛рдпрд▓реЙрдЧ рдирд╛рдордХ рдПрдХ рд╡рд░реНрдЧ рдХреА рдЦреЛрдЬ рдХреАред


рдЫрд╡рд┐


рдпрд╣ рдПрдХ рдирд┐рдпрдорд┐рдд рд╕рдВрд╡рд╛рдж рдкрд░ рдПрдХ рдЖрд╡рд░рдг рд╡рд░реНрдЧ рд╣реИ, рдЬреЛ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рд╡рд┐рдЬрд╝рд╛рд░реНрдб рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдкреНрд░рдЧрддрд┐ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░ рд░рд╣рд╛ рд╣реИ, рдФрд░ рдЖрд╡рд╢реНрдпрдХ рдмрдЯрди (рдкрд┐рдЫрд▓рд╛, рдЕрдЧрд▓рд╛, рд╕рдорд╛рдкреНрдд, рдЖрджрд┐) рджрд┐рдЦрд╛ рд░рд╣рд╛ рд╣реИред рдПрдХ рд╡рд┐рд╢реЗрд╖ WizardModel, рд╡рд┐рдЬрд╝рд╛рд░реНрдбрдбрд╛рдпрд▓реЙрдЧ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд┐рдЬрд╝рд╛рд░реНрдбрд╕реНрдЯреЗрдкреНрд╕ рдЬреЛрдбрд╝реЗ рдЧрдП рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдЬрд╝рд╛рд░реНрдбрд╕реНрдЯреЗрдк рдПрдХ рдЕрд▓рдЧ рд░реВрдк рд╣реИред


рдЕрдкрдиреЗ рд╕рд░рд▓рддрдо рд░реВрдк рдореЗрдВ, рд╕рдВрд╡рд╛рдж рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:


WizardDialog
class MyWizardDialog( model: MyWizardModel, private val onFinishButtonClickedListener: (MyWizardModel) -> Unit ): WizardDialog<MyWizardModel>(true, true, model) { override fun onWizardGoalAchieved() { super.onWizardGoalAchieved() onFinishButtonClickedListener.invoke(myModel) } } 

рд╣рдо WizardDialog рд╡рд░реНрдЧ рд╕реЗ рдЗрдирд╣реЗрд░рд┐рдЯ рдХрд░реЗрдВрдЧреЗ , рд╣рдорд╛рд░реЗ WizardModel рдХреЗ рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдкреИрд░рд╛рдореАрдЯрд░ рдХрд░реЗрдВред рдЗрд╕ рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдХреЙрд▓рдмреИрдХ ( onWizardGoalAchieve ) рд╣реИ, рдЬреЛ рд╣рдореЗрдВ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд┐рдЬрд╝рд╛рд░реНрдб рд╕реЗ рдЕрдВрдд рддрдХ рдЧрдпрд╛ рдФрд░ "рдлрд┐рдирд┐рд╢" рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд┐рдпрд╛ред
рдпрд╣ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рднреАрддрд░ рд╕реЗ рдХреЗрд╡рд▓ рд╡рд┐рдЬрд╝рд╛рд░реНрдбрдореЙрдбрд▓ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рд╡рд┐рдЬрд╝рд╛рд░реНрдб рдХреЗ рдкрд╛рд░рд┐рдд рд╣реЛрдиреЗ рдХреЗ рджреМрд░рд╛рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдПрдХрддреНрд░ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдбреЗрдЯрд╛, рдЖрдкрдХреЛ рд╡рд┐рдЬрд╝рд╛рд░реНрдбрдореЙрдбрд▓ рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред


WizardModel
 class MyWizardModel: WizardModel("Title for my wizard") { init { this.add(MyWizardStep1()) this.add(MyWizardStep2()) this.add(MyWizardStep3()) } } 

рдореЙрдбрд▓ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ: рд╣рдо рд╡рд┐рдЬрд╝рд╛рд░реНрдбрдореЙрдбрд▓ рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдмрд┐рд▓реНрдЯ-рдЗрди рдРрдб рдореЗрдердб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбрд╛рдпрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ рд╡рд┐рдЬрд╛рд░реНрдбрд╕реНрдЯреЗрдкреНрд╕ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ ред


WizardStep
 class MyWizardStep1: WizardStep<MyWizardModel>() { private lateinit var contentPanel: JPanel override fun prepare(state: WizardNavigationState?): JComponent { return contentPanel } } 

рд╡рд┐рдЬрд╛рд░реНрдбрд╕реНрдЯреЗрдкреНрд╕ рднреА рд╕рд░рд▓ рд╣реИрдВ: рд╡рд┐рдЬрд╛рд░реНрдбрд╕реНрдЯреЗрдк рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ , рдЗрд╕реЗ рд╣рдорд╛рд░реЗ рдореЙрдбрд▓ рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдорд╛рдирдХреАрдХреГрдд рдХрд░реЗрдВ , рдФрд░, рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд, рддреИрдпрд╛рд░ рд╡рд┐рдзрд┐ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░реЗрдВ, рдЬреЛ рдЖрдкрдХреЗ рднрд╡рд┐рд╖реНрдп рдХреЗ рд░реВрдк рдХреЗ рдореВрд▓ рдШрдЯрдХ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИред


рд╕рд░рд▓ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдРрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдореЗрдВ, рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдЖрдкрдХрд╛ рд░реВрдк рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдХрд╛ рд╣реЛрдЧрд╛:


рдЫрд╡рд┐


рдпрд╣рд╛рдВ рдЖрдк рдЙрди рд╕рдордп рдХреЛ рдпрд╛рдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рд╣рдо рдПрдВрдбреНрд░реЙрдЗрдб рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рдЕрднреА рддрдХ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдереЗ рдХрд┐ рдХреНрд▓реАрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░, рдПрдорд╡реАрдкреА рдХреНрдпрд╛ рд╣реИ рдФрд░ рд╕рднреА рдХреЛрдб рдПрдХ рдЧрддрд┐рд╡рд┐рдзрд┐ рдореЗрдВ рд▓рд┐рдЦреЗ рд╣реИрдВред рд╡рд╛рд╕реНрддреБрд╢рд┐рд▓реНрдк рд▓рдбрд╝рд╛рдИ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдХреНрд╖реЗрддреНрд░ рд╣реИ, рдФрд░ рдпрджрд┐ рдЖрдк рднреНрд░рдорд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдкреНрд▓рдЧ рдЗрди рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдЦреБрдж рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдирд┐рд╖реНрдХрд░реНрд╖


рдпрджрд┐ рдЖрдкрдХреЛ рдПрдХ рдмрд╣реБ-рдкреГрд╖реНрда UI рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рд╡рд┐рдЬрд╝рд╛рд░реНрдбрдбрд╛рдпрд▓реЙрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ - рдпрд╣ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛ред


рд╣рдо рдЕрдЧрд▓реЗ рд╡рд┐рд╖рдп рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВ - рдкреНрд▓рдЧ рдЗрди рдореЗрдВ DIред


рдкреНрд▓рдЧрдЗрдиреНрд╕ рдореЗрдВ рдбрд┐


рдПрдХ рдкреНрд▓рдЧрдЗрди рдХреЗ рдЕрдВрджрд░ рдирд┐рд░реНрднрд░рддрд╛ рдЗрдВрдЬреЗрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реЛ рд╕рдХрддреА рд╣реИ?
рдкрд╣рд▓рд╛ рдХрд╛рд░рдг рдкреНрд▓рдЧрдЗрди рдХреЗ рдЕрдВрджрд░ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХрд╛ рд╕рдВрдЧрдарди рд╣реИред


рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ, рдЖрдорддреМрд░ рдкрд░ рдкреНрд▓рдЧрдЗрди рдХреЗ рдЕрдВрджрд░ рдХрд┐рд╕реА рддрд░рд╣ рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХрд╛ рдирд┐рд░реАрдХреНрд╖рдг рдХреНрдпреЛрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ? рдПрдХ рдкреНрд▓рдЧ-рдЗрди рдПрдХ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдЪреАрдЬ рд╣реИ, рдПрдХ рдмрд╛рд░ рдЬрдм рдореИрдВрдиреЗ рдЗрд╕реЗ рд▓рд┐рдЦрд╛ рдерд╛, рдФрд░ рдореИрдВ рд╕рдм рдХреБрдЫ рднреВрд▓ рдЧрдпрд╛ рдерд╛ред
рд╣рд╛рдВ, рд▓реЗрдХрд┐рди рдирд╣реАрдВред
рдЬрдм рдЖрдкрдХрд╛ рдкреНрд▓рдЧрдЗрди рдмрдврд╝рддрд╛ рд╣реИ, рдЬрдм рдЖрдк рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рддреЛ рд╕рдВрд░рдЪрд┐рдд рдХреЛрдб рдХрд╛ рд╕рд╡рд╛рд▓ рдЕрдкрдиреЗ рдЖрдк рдЙрдарддрд╛ рд╣реИред рдпрд╣рд╛рдВ DI рдХрд╛рдо рдЖ рд╕рдХрддрд╛ рд╣реИред


рджреВрд╕рд░рд╛, рдЕрдзрд┐рдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХрд╛рд░рдг - DI рдХреА рдорджрдж рд╕реЗ рдЖрдк рдЕрдиреНрдп рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреЗ рдЧрдП рдШрдЯрдХреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдЗрд╡реЗрдВрдЯ рдмрд╕реЗрдВ, рд▓реЙрдЧрд░ рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред


рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдЖрдк рдЗрдВрдЯреЗрд▓реАрдЬреЗ рдЖрдИрдбреАрдИрдП рдХреЗ рдЕрдВрджрд░ рдХрд┐рд╕реА рднреА рдбреАрдЖрдИ рдлреНрд░реЗрдорд╡рд░реНрдХ (рд╕реНрдкреНрд░рд┐рдВрдЧ, рдбреИрдЧрд░, рдЖрджрд┐) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рд╣реИрдВ, рдЖрдкрдХрд╛ рдЕрдкрдирд╛ рдбреАрдЖрдИ рдлреНрд░реЗрдорд╡рд░реНрдХ рд╣реИ, рдЬреЛ рдЕрдореВрд░реНрдд рдХреЗ рдкрд╣рд▓реЗ рддреАрди рд╕реНрддрд░реЛрдВ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╣реА рдмрд╛рдд рдХреА рдереА: рдПрдкреНрд▓рд┐рдХреЗрд╢рди , рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдФрд░ рдореЙрдбреНрдпреВрд▓ ред


рдЫрд╡рд┐


рдЗрди рд╕реНрддрд░реЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХрд╛ рдЕрдкрдирд╛ рдЕрдореВрд░реНрддрди рд╣реИ рдЬрд┐рд╕реЗ рдШрдЯрдХ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЖрд╡рд╢реНрдпрдХ рд╕реНрддрд░ рдХреЗ рдШрдЯрдХ рдХреЛ рдЗрд╕ рд╕реНрддрд░ рдХреА рд╡рд╕реНрддреБ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкреНрд░рддрд┐ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП ApplicationComponent рдХреЛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╡рд░реНрдЧ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рд░ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ Project Instances рдХреЗ рд▓рд┐рдП ProjectComponent рдХреЗ рд╕рдорд╛рди рд╣реИ, рдФрд░ рдЗрд╕реА рддрд░рд╣ред


DI рдврд╛рдВрдЪреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ?


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рд╡рд░реНрдЧ рдмрдирд╛рдПрдВ рдЬреЛ рдЖрд╡рд╢реНрдпрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдШрдЯрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ - рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╡рд░реНрдЧ рдЬреЛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдХрдВрдкреНрд▓реЗрдВрдЯ , рдпрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯрдХрдВрдкреЛрдиреЗрдВрдЯ , рдпрд╛ рдореЙрдбреНрдпреВрд▓рдХрдВрдкреНрд▓реЗрдВрдЯ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ ред рдЙрд╕реА рд╕рдордп, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЙрд╕ рд╕реНрддрд░ рдХреА рдПрдХ рд╡рд╕реНрддреБ рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣рдо рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдпрд╣, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, ProjectComponent рдореЗрдВ рдЖрдк Project рд╡рд░реНрдЧ рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдШрдЯрдХ рдХрдХреНрд╖рд╛рдПрдВ рдмрдирд╛рдирд╛
 class MyAppComponent( val application: Application, val anotherApplicationComponent: AnotherAppComponent ): ApplicationComponent class MyProjectComponent( val project: Project, val anotherProjectComponent: AnotherProjectComponent, val myAppComponent: MyAppComponent ): ProjectComponent class MyModuleComponent( val module: Module, val anotherModuleComponent: AnotherModuleComponent, val myProjectComponent: MyProjectComponent, val myAppComponent: MyAppComponent ): ModuleComponent 

рджреВрд╕рд░реЗ, рд╕рдорд╛рди рд╕реНрддрд░ рдпрд╛ рдЙрдЪреНрдЪрддрд░ рдХреЗ рдЕрдиреНрдп рдШрдЯрдХреЛрдВ рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, ProjectComponent рдореЗрдВ рдЖрдк рдЕрдиреНрдп ProjectComponent рдпрд╛ ApplicationComponent рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рдЖрдк "рдПрд▓рд┐рдпрди" рдШрдЯрдХреЛрдВ рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВред


рдЙрд╕реА рд╕рдордп, IDEA рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реИ рдХрд┐ рд╕рдВрдкреВрд░реНрдг рдирд┐рд░реНрднрд░рддрд╛ рдЧреНрд░рд╛рдл рдХреЛ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдЗрдХрдЯреНрдард╛ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд╕рднреА рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рд╕рд╣реА рдХреНрд░рдо рдореЗрдВ рдмрдирд╛рдП рдЬрд╛рдПрдВрдЧреЗ рдФрд░ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕рдВрд╢реЛрдзрд┐рдд рд╣реЛрдВрдЧреЗред


рдЕрдЧрд▓реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ plugin.xml рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдШрдЯрдХ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░реЗрдВред рдЬреИрд╕реЗ рд╣реА рдЖрдк рдШрдЯрдХ рдШрдЯрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЕрдиреБрдкреНрд░рдпреЛрдЧрдХрдВрдкреЛрдиреЗрдВрдЯ ), IDEA рддреБрд░рдВрдд plugin.xml рдореЗрдВ рдЕрдкрдиреЗ рдШрдЯрдХ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдкреЗрд╢рдХрд╢ рдХрд░реЗрдЧрд╛ред


Plugin.xml рдореЗрдВ рдШрдЯрдХ рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд░реЗрдВ
 <idea-plugin> ... <project-components> <component> <interface-class> com.experiment.MyProjectComponent </interface-class> <implementation-class> com.experiments.MyProjectComponentImpl </implementation-class> </component> </project-components> </idea-plugin> 

рдпрд╣ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ? рдПрдХ рд╡рд┐рд╢реЗрд╖ <рдкреНрд░реЛрдЬреЗрдХреНрдЯ-рдШрдЯрдХ> рдЯреИрдЧ рдкреНрд░рдХрдЯ рд╣реЛрддрд╛ рд╣реИ ( <рдПрдкреНрд▓рд┐рдХреЗрд╢рди-рдШрдЯрдХ> , <рдореЙрдбреНрдпреВрд▓-рдШрдЯрдХ> - рд╕реНрддрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░)ред рдЗрд╕рдХреЗ рдЕрдВрджрд░ рдПрдХ рдЯреИрдЧ рд╣реИ , рдЗрд╕рдореЗрдВ рджреЛ рдФрд░ рдЯреИрдЧ рд╣реИрдВ: <рдЗрдВрдЯрд░рдлрд╝реЗрд╕-рдХреНрд▓рд╛рд╕> , рдЬрд╣рд╛рдВ рдЖрдкрдХреЗ рдШрдЯрдХ рдХрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдирд╛рдо рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ <рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди-рд╡рд░реНрдЧ> , рдЬрд╣рд╛рдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд░реНрдЧ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдПрдХ рдФрд░ рдПрдХ рд╣реА рд╡рд░реНрдЧ рдПрдХ рдШрдЯрдХ рдпрд╛ рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдк рдПрдХрд▓ <рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди-рд╡рд░реНрдЧ> рдЯреИрдЧ рдХреЗ рд╕рд╛рде рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЕрдВрддрд┐рдо рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдШрдЯрдХ рдХреЛ рд╕рдВрдмрдВрдзрд┐рдд рд╡рд╕реНрддреБ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд, рд╣рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЗрдВрд╕реНрдЯреЗрдВрд╕ рд╕реЗ ApplicationComponent рдорд┐рд▓рддрд╛ рд╣реИ, ProjectComponent рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реЗ рдорд┐рд▓рддрд╛ рд╣реИ , рдЖрджрд┐ред


рдШрдЯрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
 val myAppComponent = application.getComponent(MyAppComponent::class.java) val myProjectComponent = project.getComponent(MyProjectComponent::class.java) val myModuleComponent = module.getComponent(MyModuleComponent::class.java) 

рдирд┐рд╖реНрдХрд░реНрд╖


  1. рдЖрдИрдбреАрдИрдП рдХреЗ рдЕрдВрджрд░ рдПрдХ рдбреАрдЖрдИ рдлреНрд░реЗрдорд╡рд░реНрдХ рд╣реИ - рдЕрдкрдиреЗ рджрдо рдкрд░ рдХреБрдЫ рднреА рдЦреАрдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ: рди рддреЛ рдбреИрдЧрд░ рдФрд░ рди рд╣реА рд╕реНрдкреНрд░рд┐рдВрдЧред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
  2. рдЗрд╕ DI рдХреЗ рд╕рд╛рде, рдЖрдк рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рдШрдЯрдХреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рд░рд╕ рд╣реА рд╣реИред

рддреАрд╕рд░реЗ рдХрд╛рд░реНрдп - рдХреЛрдб рдЬрдирд░реЗрд╢рди рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВред


рдХреЛрдб рдЬрдирд░реЗрд╢рди


рдпрд╛рдж рд░рдЦреЗрдВ, рдЪреЗрдХрд▓рд┐рд╕реНрдЯ рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдмрд╣реБрдд рд╕рд╛рд░реА рдлрд╛рдЗрд▓реЗрдВ рдмрдирд╛рдиреЗ рдХрд╛ рдХрд╛рдо рдерд╛? рд╣рд░ рдмрд╛рд░ рдЬрдм рд╣рдо рдПрдХ рдирдпрд╛ рдореЙрдбреНрдпреВрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдлрд╝рд╛рдЗрд▓реЛрдВ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдмрдирд╛рддреЗ рд╣реИрдВ: рдЗрдВрдЯрд░реЗрдХреНрдЯрд░реНрд╕, рдкреНрд░реЗрдЬреЗрдВрдЯрд░реНрд╕, рдЯреБрдХрдбрд╝реЗред рдПрдХ рдирдпрд╛ рдореЙрдбреНрдпреВрд▓ рдмрдирд╛рддреЗ рд╕рдордп, рдпреЗ рдШрдЯрдХ рдПрдХ-рджреВрд╕рд░реЗ рд╕реЗ рдмрд╣реБрдд рдорд┐рд▓рддреЗ-рдЬреБрд▓рддреЗ рд╣реИрдВ, рдФрд░ рдореИрдВ рдпрд╣ рд╕реАрдЦрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рдЗрд╕ рдврд╛рдВрдЪреЗ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдХреИрд╕реЗ рдЙрддреНрдкрдиреНрди рдХрд┐рдпрд╛ рдЬрд╛рдПред


рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕


рдПрдХ рд╕рдорд╛рди рдХреЛрдб рдХрд╛ рдПрдХ рдЯрди рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдХреНрдпрд╛ рд╣реИ? рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЛ рджреЗрдЦрдиреЗ рдФрд░ рд╕рдордЭрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдХрд┐ рдХреЛрдб рдЬрдирд░реЗрдЯрд░ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рд╣реИрдВред


рдмрд┐рд▓реНрдб.рдЧреНрд░реЗрдбрд▓ рдлрд╝рд╛рдЗрд▓ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдПрдХ рдЯреБрдХрдбрд╝рд╛
 apply plugin: 'com.android.library' <if (isKotlinProject) { apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' <if (isModuleWithUI) { apply plugin: 'kotlin-android-extensions' }> }> ... android { ... <if (isMoxyEnabled) { kapt { arguments { arg("moxyReflectorPackage", '<include var="packageName">') } } }> ... } ... dependencies { compileOnly project(':common') compileOnly project(':core-utils') <for (moduleName in enabledModules) { compileOnly project('<include var="moduleName">') }> ... } 

рдкрд╣рд▓рд╛: рд╣рдо рдЗрди рдкреИрдЯрд░реНрдиреЛрдВ рдХреЗ рдЕрдВрджрд░ рдХреА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рддреЗ рдереЗред рдореИрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрддрд╛ рд╣реВрдВ: рдпрджрд┐ рдкреНрд▓рдЧрдЗрди рдХрд┐рд╕реА рддрд░рд╣ рдпреВрдЖрдИ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ, рддреЛ рд╣рдо рд╡рд┐рд╢реЗрд╖ рдЧреНрд░реЗрдбрд▓- рдкреНрд▓рдЧрдЗрди рдХреЛрдЯрд▓рд┐рди-рдПрдВрдбреНрд░реЙрдЗрдб-рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред


рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдЕрдВрджрд░ рдХреА рд╕реНрдерд┐рддрд┐
 <if (isKotlinProject) { apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' <if (isModuleWithUI) { apply plugin: 'kotlin-android-extensions' }> }> 

рджреВрд╕рд░реА рдЪреАрдЬ рдЬреЛ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд╡рд╣ рдЗрд╕ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдЕрдВрджрд░ рдПрдХ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рд╣рдо Moxy рдХреЗ рд▓рд┐рдП kapt рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдПрдиреЛрдЯреЗрд╢рди рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкреИрдХреЗрдЬ рдХрд╛ рдирд╛рдо рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред


рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЗ рдЕрдВрджрд░ рдЪрд░ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ
 kapt { arguments { arg("moxyReflectorPackage", '<include var="packageName">') } } 

рдПрдХ рдФрд░ рдЪреАрдЬ рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдП рд╡рд╣ рд╣реИ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдЕрдВрджрд░ рд▓реВрдк рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ред рдЙрд╕ рдлреЙрд░реНрдо рдХреЛ рдпрд╛рдж рд░рдЦреЗрдВ рдЬрд╣рд╛рдВ рд╣рдордиреЗ рдЙрди рдореЙрдбреНрдпреВрд▓ рдХреА рд╕реВрдЪреА рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдирдП рдореЙрдбреНрдпреВрд▓ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ? рд╣рдо рдПрдХ рд▓реВрдк рдореЗрдВ рдЙрдирдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЬрд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рд╣реА рдкрдВрдХреНрддрд┐ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред


рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рд▓реВрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
 <for (moduleName in enabledModules) { compileOnly project('<include var="moduleName">') }> 

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдордиреЗ рдХреЛрдб рдЬрдирд░реЗрдЯрд░ рдХреЗ рд▓рд┐рдП рддреАрди рд╢рд░реНрддреЗрдВ рд╕рд╛рдордиреЗ рд░рдЦреАрдВ:


  • рд╣рдо рд╢рд░реНрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ
  • рдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдореВрд▓реНрдпреЛрдВ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛
  • рд╣рдореЗрдВ рдкреИрдЯрд░реНрди рдореЗрдВ рдЫреЛрд░реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ

рдХреЛрдб рдЬрдирд░реЗрдЯрд░


рдХреЛрдб рдЬрдирд░реЗрдЯрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд▓реНрдк рдХреНрдпрд╛ рд╣реИрдВ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рдХреЛрдб рдЬрдирд░реЗрдЯрд░ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЙрдмреЗрд░ рдХреЗ рд▓реЛрдЧреЛрдВ рдиреЗ рдРрд╕рд╛ рдХрд┐рдпрд╛: рдЙрдиреНрд╣реЛрдВрдиреЗ рдЕрдкрдиреА рдЦреБрдж рдХреА рдкреНрд▓рдЧ-рдЗрди рд░рд┐рдмрд▓реНрд╕ (рддрдерд╛рдХрдерд┐рдд рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рд▓ рдпреВрдирд┐рдЯреНрд╕) рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦреА ред рд╡реЗ рдЕрдкрдиреА рд╕реНрд╡рдпрдВ рдХреА рдЯреЗрдореНрдкрд▓реЗрдЯ рднрд╛рд╖рд╛ рдХреЗ рд╕рд╛рде рдЖрдП, рдЬрд┐рд╕рдореЗрдВ рдЙрдиреНрд╣реЛрдВрдиреЗ рдХреЗрд╡рд▓ рдЪрд░ рдбрд╛рд▓рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред рдЙрдиреНрд╣реЛрдВрдиреЗ рдЬрдирд░реЗрдЯрд░ рдХреЗ рд╕реНрддрд░ рдкрд░ рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рд▓рд╛рдпрд╛ред рд▓реЗрдХрд┐рди рд╣рдордиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рд╣рдо рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред


рджреВрд╕рд░рд╛ рд╡рд┐рдХрд▓реНрдк IDEA рдореЗрдВ рдирд┐рд░реНрдорд┐рдд FileTemplateManager рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛ред рдХреНрдпреЛрдВрдХрд┐ рдЙрд╕рдХреЗ рдкрд╛рд╕ рдПрдХ рдЗрдВрдЬрди рдХреЗ рд░реВрдк рдореЗрдВ рд╡реЗрд▓реЛрд╕рд┐рдЯреА рд╣реИ , рдЬрд┐рд╕рдореЗрдВ рдЬрд╛рд╡рд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореЗрдВ рдЕрдЧреНрд░реЗрд╖рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдХреБрдЫ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, FileTemplateManager рдмреЙрдХреНрд╕ рд╕реЗ рдЬрд╛рд╡рд╛ рдпрд╛ XML рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЕрдиреНрдп рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЙрддреНрдкрдиреНрди рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдФрд░ рд╣рдореЗрдВ рдЧреНрд░реВрд╡реА рдлрд╛рдЗрд▓реЗрдВ, рдХреЛрдЯрд▓рд┐рди, рдкреНрд░реЛрдЧрд╛рд░реНрдб рдФрд░ рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреА рдлрд╛рдЗрд▓реЗрдВ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред


рддреАрд╕рд░рд╛ рд╡рд┐рдХрд▓реНрдк рдерд╛ ... FreeMarker ред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдлреНрд░реА - рдореЗрдХрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реИрдВ, рддреЛ рдЙрдиреНрд╣реЗрдВ рдлреЗрдВрдХрдиреЗ рдореЗрдВ рдЬрд▓реНрджрдмрд╛рдЬреА рди рдХрд░реЗрдВ - рд╡реЗ рдкреНрд▓рдЧрдЗрди рдХреЗ рдЕрдВрджрд░ рдЖрдкрдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред


рдХреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдкреНрд▓рдЧрдЗрди рдХреЗ рдЕрдВрджрд░ FreeMarker рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ? рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдлрд╝рд╛рдЗрд▓ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЬреЛрдбрд╝реЗрдВред рдЖрдк / рд░рд┐рд╕реЛрд░реНрд╕ рдлрд╝реЛрд▓реНрдбрд░ рдХреЗ рдЕрдВрджрд░ / рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдлрд╝реЛрд▓реНрдбрд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╣рдорд╛рд░реЗ рд╕рднреА рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЛ рд╕рднреА рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ - рдкреНрд░реЗрдЬреЗрдВрдЯреЗрдЯрд░, рдЯреБрдХрдбрд╝реЗ рдЖрджрд┐ред


рдЫрд╡рд┐


рдЙрд╕рдХреЗ рдмрд╛рдж, рдЖрдкрдХреЛ FreeMarker рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдкрд░ рдирд┐рд░реНрднрд░рддрд╛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдЪреВрдВрдХрд┐ рдкреНрд▓рдЧрдЗрди рдЧреНрд░реИрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдПрдХ рдирд┐рд░реНрднрд░рддрд╛ рдЬреЛрдбрд╝рдирд╛ рд╕реАрдзрд╛ рд╣реИред


FreeMarker рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдкрд░ рдирд┐рд░реНрднрд░рддрд╛ рдЬреЛрдбрд╝реЗрдВ
 dependencies { ... compile 'org.freemarker:freemarker:2.3.28' } 

рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдорд╛рд░реЗ рдкреНрд▓рдЧрдЗрди рдХреЗ рдЕрдВрджрд░ FreeMarker рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВред рдореИрдВ рдЖрдкрдХреЛ рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдЗрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рдпрд╣рд╛рдВ рдХреЙрдкреА рдХрд░реЗрдВ - рдпрд╣ рдЕрддреНрдпрд╛рдЪрд╛рд░, рдкреАрдбрд╝рд╛, рдЗрд╕реЗ рдХреЙрдкреА рдХрд░реЗрдВ рдФрд░ рд╕рдм рдХреБрдЫ рдмрд╕ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред


FreeMarker рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди
 class TemplatesFactory(val project: Project) : ProjectComponent { private val freeMarkerConfig by lazy { Configuration(Configuration.VERSION_2_3_28).apply { setClassForTemplateLoading( TemplatesFactory::class.java, "/templates" ) defaultEncoding = Charsets.UTF_8.name() templateExceptionHandler = TemplateExceptionHandler.RETHROW_HANDLER logTemplateExceptions = false wrapUncheckedExceptions = true } } ... 

рдпрд╣ FreeMarker рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдлрд╝рд╛рдЗрд▓реЗрдВ рдмрдирд╛рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЗрд╕рдХреЗ рдирд╛рдо рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕реЗ рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдорд┐рд▓рддрд╛ рд╣реИ рдФрд░ рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ FileWriter рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбрд┐рд╕реНрдХ рдкрд░ рд╕реАрдзреЗ рд╡рд╛рдВрдЫрд┐рдд рдкрд╛рда рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рддреЗ рд╣реИрдВред


FileWriter рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдирд╛
 class TemplatesFactory(val project: Project) : ProjectComponent { ... fun generate( pathToFile: String, templateFileName: String, data: Map<String, Any> ) { val template = freeMarkerConfig.getTemplate(templateFileName) FileWriter(pathToFile, false).use { writer -> template.process(data, writer) } } } 

рдФрд░ рдХрд╛рд░реНрдп рд╣рд▓ рдХрд░рдиреЗ рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдирд╣реАрдВред рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рднрд╛рдЧ рдореЗрдВ, рдореИрдВрдиреЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдХрд┐ рдкреВрд░реЗ рдЖрдИрдбреАрдИрдП рдХреЛ рдкреАрдПрд╕рдЖрдИ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рд╛рде рдЕрдиреБрдорддрд┐ рджреА рдЧрдИ рд╣реИ, рдФрд░ рдЗрд╕реЗ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рдЖрдк PSI рд╕рдВрд░рдЪрдирд╛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, FileWriter рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ) рдХреЛ рджрд░рдХрд┐рдирд╛рд░ рдХрд░рдХреЗ рдлрд╝рд╛рдЗрд▓реЗрдВ рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ IDEA рдиреЗ рдХреЗрд╡рд▓ рдпрд╣ рдирд╣реАрдВ рд╕рдордЭрд╛ рдХрд┐ рдЖрдкрдиреЗ рдХреБрдЫ рдмрдирд╛рдпрд╛ рд╣реИ рдФрд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдЯреНрд░реА рдореЗрдВ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред рд╣рдордиреЗ IDEA рдХреЛ рдЕрдиреБрдХреНрд░рдорд┐рдд рдХрд░рдиреЗ рдФрд░ рдмрдирд╛рдИ рдЧрдИ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рджреЗрдЦрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд▓рдЧрднрдЧ рд╕рд╛рдд рдорд┐рдирдЯ рдЗрдВрддрдЬрд╛рд░ рдХрд┐рдпрд╛ред


рдирд┐рд╖реНрдХрд░реНрд╖ - рдпрд╣ рд╕рд╣реА рд╣реИ, рдлрд╝рд╛рдЗрд▓реЗрдВ рдмрдирд╛рдПрдБ, рдкреАрдПрд╕рдЖрдИ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдПред


рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ PSI рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рдПрдБ


рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЪрд▓реЛ PsiDirectory рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдлрд╝реЛрд▓реНрдбрд░ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рджреЗрдЦрд╛ ред рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреА рдЖрд░рдВрдн рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЛ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдлрд╝рдВрдХреНрд╢рдВрд╕ рдЕрдиреБрдорд╛рдирдкреНрд░рдпреЛрдЧрджрд┐рд░ рдФрд░ toPsiDirectory рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:


PsiDirectory Project рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
 val projectPsiDirectory = project.guessProjectDir()?.toPsiDirectory(project) 

рдмрд╛рдж рдХреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рдпрд╛ рддреЛ PsiDirectory findSubdirectory рд╡рд░реНрдЧ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╛ createSubdirectory рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рдЦреЛрдЬреЗрдВ рдФрд░ PsiDirectory рдмрдирд╛рдПрдВ
 val coreModuleDir = projectPsiDirectory.findSubdirectory("core") val newModulePsiDir = coreModuleDir.createSubdirectory(config.mainParams.moduleName) 

рдореИрдВ рдпрд╣ рднреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдПрдХ рдРрд╕рд╛ рдорд╛рдирдЪрд┐рддреНрд░ рдмрдирд╛рдПрдВ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдЖрдк рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреБрдВрдЬреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рднреА PsiDirectory рдлрд╝реЛрд▓реНрдбрд░ рд╕рдВрд░рдЪрдирд╛рдПрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЗрдирдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рднреА рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдмрдирд╛рдИ рдЧрдИ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред


рдПрдХ рдлрд╝реЛрд▓реНрдбрд░ рд╕рдВрд░рдЪрдирд╛ рдирдХреНрд╢рд╛ рдмрдирд╛рдПрдБ

рд╡рд╛рдкрд╕реА mutableMapOf <рд╕реНрдЯреНрд░рд┐рдВрдЧ, PsiDirectory?> () рд▓рд╛рдЧреВ рдХрд░реЗрдВред *
рдпрд╣ ["рд░реВрдЯ"] = рдореЙрдбреНрдпреВрд▓рдкрд╕реАрдбрд┐рд░
рдпрд╣ ["src"] = рдореЙрдбреНрдпреВрд▓PsiDir.createSubdirectory ("src")
рдпрд╣ ["рдореБрдЦреНрдп"] = рдпрд╣ ["src"]? createSubdirectory ("рдореБрдЦреНрдп")
рдпрд╣ ["рдЬрд╛рд╡рд╛"] = рдпрд╣ ["рдореБрдЦреНрдп"]? createSubdirectory ("рдЬрд╛рд╡рд╛")
рдпрд╣ ["рд░реЗрд╕"] = рдпрд╣ ["рдореБрдЦреНрдп"]? createSubdirectory ("рд░реЗрд╕")


 //   PsiDirectory   package name: // ru.hh.feature_worknear тЖТ ru / hh / feature_worknear createPackageNameFolder(config) // data this["data"] = this["package"]?.createSubdirectory("data") // ... 

}


рдлреЛрд▓реНрдбрд░ рдмрдирд╛рдпрд╛ред рд╣рдо PsiFile рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ PsiFiles рдмрдирд╛рдПрдВрдЧреЗ ред рдЗрд╕ рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╡рд┐рдзрд┐ рд╣реИ, рдЬрд┐рд╕реЗ createFileFromText рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рд┐рдзрд┐ рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рддреАрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреА рд╣реИ: рдирд╛рдо (рд╕реНрдЯреНрд░рд┐рдВрдЧ рдлрд╝рд╛рдЗрд▓рдирд╛рдо), рдкрд╛рда (рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкрд╛рда) рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдкреНрд░рдХрд╛рд░ (рдлрд╝рд╛рдЗрд▓ рдЯрд╛рдЗрдк рдлрд╝рд╛рдЗрд▓ рдЯрд╛рдЗрдк)ред рддреАрди рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рд╕реЗ рджреЛ рд╕реНрдкрд╖реНрдЯ рд╣реИрдВ рдХрд┐ рдЗрд╕реЗ рдХрд╣рд╛рдБ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рдП: рд╣рдо рд╕реНрд╡рдпрдВ рдирд╛рдо рдЬрд╛рдирддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рдлреНрд░реАрдорд╛рд░реНрдХрд░ рд╕реЗ рдкрд╛рда рдорд┐рд▓рддрд╛ рд╣реИред рдФрд░ рдХрд╣рд╛рдБ FileType рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП? рдФрд░ рдпрд╣ рд╕рдм рдХреНрдпрд╛ рд╣реИ?


рдлрд╝рд╛рдЗрд▓-рдкреНрд░рдХрд╛рд░


FileType рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╡рд░реНрдЧ рд╣реИ рдЬреЛ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИред "рдмреЙрдХреНрд╕" рд╕реЗ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреЗрд╡рд▓ рджреЛ FileType рдЙрдкрд▓рдмреНрдз рд╣реИрдВ: Java-files рдФрд░ XML-files рдХреЗ рд▓рд┐рдП рдХреНрд░рдорд╢рдГ JavaFileType рдФрд░ XmlFileTypeред рд▓реЗрдХрд┐рди рд╕рд╡рд╛рд▓ рдпрд╣ рдЙрдарддрд╛ рд╣реИ: рдмрд┐рд▓реНрдб рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рдХрд╣рд╛рдБ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рдХреЛрдЯрд▓рд┐рди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рдХреЛрд╕реНрдЯрдЧрд┐рд▓ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рдкреНрд░рд┐рдЯрдЧреЙрд░ рдХреЗ рд▓рд┐рдП, рдЖрдЦрд┐рд░рдХрд╛рд░ !?


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЗрдирдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдлрд╝рд╛рдЗрд▓ рдЯрд╛рдЗрдк рдХреЛ рдЕрдиреНрдп рдкреНрд▓рдЧрдЗрдиреНрд╕ рд╕реЗ рд▓рд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд┐рд╕реА рдХреЗ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВред GroovyFileType рдХреЛ Groovy plugin , KotlinFileType рд╕реЗ Kotlin рдкреНрд▓рдЧрдЗрди , рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд▓рдЧрдЗрди рд╕реЗ рдкреНрд░реЛрдЧрд╛рд░реНрдб рд╕реЗ рд▓рд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рд╣рдо рдЕрдкрдиреЗ рд▓рд┐рдП рджреВрд╕рд░реЗ рдкреНрд▓рдЧрдЗрди рдХреА рдирд┐рд░реНрднрд░рддрд╛ рдХреИрд╕реЗ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ? рд╣рдо gradle-intellij-plugin рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдкреНрд▓рдЧрдЗрди рдХреЗ build.gradle рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЗрдВрдЯреЗрд▓реАрдЬ рдмреНрд▓реЙрдХ рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдЕрдВрджрд░ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЧреБрдг рд╣реИ - рдкреНрд▓рдЧрдЗрдиреНрд╕ ред рдЗрд╕ рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ, рдЖрдк рдкреНрд▓рдЧрдЗрди рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХреА рд╕реВрдЪреА рд╕реВрдЪреАрдмрджреНрдз рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕ рдкрд░ рд╣рдо рдирд┐рд░реНрднрд░ рд░рд╣рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред


рдЕрдиреНрдп рдкреНрд▓рдЧрдЗрдиреНрд╕ рдкрд░ рдирд┐рд░реНрднрд░рддрд╛ рдЬреЛрдбрд╝реЗрдВ
 // build.gradle  intellij { тАж plugins = ['android', 'Groovy', 'kotlin'] } 

рд╣рдо рдЖрдзрд┐рдХрд╛рд░рд┐рдХ JetBrains рдкреНрд▓рдЧрдЗрди рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рдЪрд╛рдмреА рд▓реЗрддреЗ рд╣реИрдВред рдЖрдИрдбреАрдИрдП (рдЬреЛ рдЧреНрд░реВрд╡реА, рдХреЛрдЯрд▓рд┐рди рдФрд░ рдПрдВрдбреНрд░реЙрдЗрдб рд╣реИрдВ) рдореЗрдВ рдирд┐рд░реНрдорд┐рдд рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреЗ рд▓рд┐рдП, рдЖрдИрдбреАрдИрдП рдХреЗ рдЕрдВрджрд░ рдкреНрд▓рдЧрдЗрди рдлрд╝реЛрд▓реНрдбрд░ рдХрд╛ рдирд╛рдо рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рдмрд╛рдХреА рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ JetBrains рдкреНрд▓рдЧрдЗрди рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд▓рдЧрдЗрди рдХреЗ рдкреГрд╖реНрда рдкрд░ рдЬрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдкреНрд▓рдЧрдЗрди рдПрдХреНрд╕рдПрдордПрд▓ рдЖрдИрдбреА рд╕рдВрдкрддреНрддрд┐ рдХреЛ рд╡рд╣рд╛рдВ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд╕рд╛рде рд╣реА рд╕рдВрд╕реНрдХрд░рдг (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдВ рдбреЙрдХрд░ рдкреНрд▓рдЧрдЗрди рдХрд╛ рдкреЗрдЬ рд╣реИ )ред GitHub рдкрд░ рдЕрдиреНрдп рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдкрдврд╝реЗрдВред


рджреВрд╕рд░реЗ, рдЖрдкрдХреЛ plugin.xml рдлрд╝рд╛рдЗрд▓ рдкрд░ рдирд┐рд░реНрднрд░рддрд╛ рд╡рд┐рд╡рд░рдг рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣ рдЯреИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ред

рд╣рдо plugin.xml рдореЗрдВ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХрдиреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВ
 <idea-plugin> ... <depends>org.jetbrains.android</depends> <depends>org.jetbrains.kotlin</depends> <depends>org.intellij.groovy</depends> </idea-plugin> 

рд╣рдо рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЕрдиреНрдп рдкреНрд▓рдЧрдЗрдиреНрд╕ рд╕реЗ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдХрд╕ рд▓реЗрдВрдЧреЗ, рдФрд░ рд╣рдо рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдВрдЧреЗред


рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рд╣рдо рдЕрдиреНрдп рдкреНрд▓рдЧрдЗрдиреНрд╕ рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ? рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдЬрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдлрд╝рд╛рдЗрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЙрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдЯрдм рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд╣рд▓реЗ рдПрдХ рд╡рд░реНрдЧ рдмрдирд╛рдПрдВ рдЬреЛ рднрд╛рд╖рд╛ рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдЖрдПрдЧрд╛ред рд╣рдорд╛рд░реА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд▓реИрдВрдЧреНрд╡реЗрдЬ рдХреА рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ рдЗрд╕ рд╡рд░реНрдЧ (рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ - "ru.hh.plugins.Ignore ) рдкрд░ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред "


GitIgnore рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рднрд╛рд╖рд╛ рдмрдирд╛рдПрдБ
 class IgnoreLanguage private constructor() : Language("ru.hh.plugins.Ignore", "ignore", null), InjectableLanguage { companion object { val INSTANCE = IgnoreLanguage() } override fun getDisplayName(): String { return "Ignore() ($id)" } } 

рдпрд╣рд╛рдВ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ: рдХреБрдЫ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдЧреИрд░-рдЕрджреНрд╡рд┐рддреАрдп рд░реЗрдЦрд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдХрд╛рд░рдг, рдЕрдиреНрдп рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреЗ рд╕рд╛рде рдЖрдкрдХреЗ рдкреНрд▓рдЧрдЗрди рдХрд╛ рдПрдХреАрдХрд░рдг рдЯреВрдЯ рд╕рдХрддрд╛ рд╣реИред рд╣рдо рдорд╣рд╛рди рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЕрдиреЛрдЦреА рд░реЗрдЦрд╛ рд╣реИред


рднрд╛рд╖рд╛ рдмрдирд╛рдиреЗ рдХреЗ рдмрд╛рдж рдЕрдЧрд▓реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдПрдХ рдлрд╝рд╛рдЗрд▓ рдЯрд╛рдЗрдк рдмрдирд╛рдПрдБред рд╣рдо LanguageFileType рд╡рд░реНрдЧ рд╕реЗ рдЗрдирд╣реЗрд░рд┐рдЯ рдХрд░рддреЗ рд╣реИрдВ, рднрд╛рд╖рд╛ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рд╣рдордиреЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдерд╛, рдХреБрдЫ рдмрд╣реБрдд рд╣реА рд╕рд░рд▓ рддрд░реАрдХреЛрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд┐рдпрд╛ред рд╣реЛ рдЧрдпрд╛ред рдЕрдм рд╣рдо рдирдИ рдмрдирд╛рдИ рдЧрдИ рдлрд╝рд╛рдЗрд▓ рдЯрд╛рдЗрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


.Gitignore рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдЦреБрдж рдХреА FileType рдмрдирд╛рдПрдБ
 class IgnoreFileType(language: Language) : LanguageFileType(language) { companion object { val INSTANCE = IgnoreFileType(IgnoreLanguage.INSTANCE) } override fun getName(): String = "gitignore file" override fun getDescription(): String = "gitignore files" override fun getDefaultExtension(): String = "gitignore" override fun getIcon(): Icon? = null } 

рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдирд╛ рд╕рдорд╛рдкреНрдд рдХрд░реЗрдВ


рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдлрд╝рд╛рдЗрд▓ рдЯрд╛рдЗрдк рдЦреЛрдЬрдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдХрдВрдЯреЗрдирд░ рдмрдирд╛рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ, рдЬрд┐рд╕реЗ рдЯреЗрдореНрдкреНрд▓реЗрдЯрдбреЗрдЯрд╛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ - рдЗрд╕рдореЗрдВ рдЙрд╕ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рднреА рдбреЗрдЯрд╛ рд╣реЛрдВрдЧреЗ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдЖрдк рдХреЛрдб рдЬрдирд░реЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЗрд╕рдореЗрдВ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо, рдЖрдЙрдЯрдкреБрдЯ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо рд╣реЛрдЧрд╛ рдЬреЛ рдЖрдкрдХреЛ рдХреЛрдб, рд╡рд╛рдВрдЫрд┐рдд рдлрд╝рд╛рдЗрд▓ рдЯрд╛рдЗрдк, рдФрд░ рдЕрдВрдд рдореЗрдВ PsiDirectory , рдЬрд╣рд╛рдВ рдЖрдк рдмрдирд╛рдИ рдЧрдИ рдлрд╝рд╛рдЗрд▓ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдХреЗ рдмрд╛рдж рдорд┐рд▓рддреА рд╣реИ ред


TemplateData
 data class TemplateData( val templateFileName: String, val outputFileName: String, val outputFileType: FileType, val outputFilePsiDirectory: PsiDirectory? ) 

рдлрд┐рд░ рд╣рдо FreeMarker рдкрд░ рд▓реМрдЯрддреЗ рд╣реИрдВ - рд╣рдо рдЗрд╕реЗ рд╕реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдлрд╝рд╛рдЗрд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, StringWriter рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╣рдо рдкрд╛рда рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, PsiFileFactory рдореЗрдВ рд╣рдо рд╡рд╛рдВрдЫрд┐рдд рдкрд╛рда рдФрд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде PsiFile рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВред рдмрдирд╛рдИ рдЧрдИ рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╡рд╛рдВрдЫрд┐рдд рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред


рдЗрдЪреНрдЫрд┐рдд рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ PsiFile рдмрдирд╛рдПрдБ
 fun createFromTemplate(data: FileTemplateData, properties: Map<String, Any>): PsiFile { val template = freeMarkerConfig.getTemplate(data.templateFileName) val text = StringWriter().use { writer -> template.process(properties, writer) writer.buffer.toString() } return psiFileFactory.createFileFromText(data.outputFileName, data.outputFileType, text) } 

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдкреАрдПрд╕рдЖрдИ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЖрдИрдбреАрдИрдП, рд╕рд╛рде рд╣реА рдЕрдиреНрдп рдкреНрд▓рдЧрдЗрдиреНрд╕, рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рд╣рдордиреЗ рдХреНрдпрд╛ рдХрд┐рдпрд╛ рд╣реИред рдЗрд╕рд╕реЗ рдПрдХ рд▓рд╛рдн рд╣реЛ рд╕рдХрддрд╛ рд╣реИ: рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ Git рдХреЗ рд▓рд┐рдП рдкреНрд▓рдЧрдЗрди рджреЗрдЦрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдиреЗ рдПрдХ рдирдИ рдлрд╝рд╛рдЗрд▓ рдЬреЛрдбрд╝реА рд╣реИ, рддреЛ рдпрд╣ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рдбрд╛рдпрд▓реЙрдЧ рдмреЙрдХреНрд╕ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рдкреВрдЫрд╛ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рдЖрдк рдЗрди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ Git рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?


рдХреЛрдб рдкреАрдврд╝реА рдХреЗ рдирд┐рд╖реНрдХрд░реНрд╖


  • рдкрд╛рда рдлрд╝рд╛рдЗрд▓реЗрдВ FreeMarker рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИрдВред рдмрд╣реБрдд рд╕рд╣рдЬ рд╣реИред
  • рдлрд╛рдЗрд▓реЗрдВ рдмрдирд╛рддреЗ рд╕рдордп, рдЖрдкрдХреЛ рдкреАрдПрд╕рдЖрдИ рд╕рдВрд░рдЪрдирд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЕрдиреНрдпрдерд╛ рд╕рдм рдХреБрдЫ рдЧрд▓рдд рд╣реЛ рдЬрд╛рдПрдЧрд╛ред
  • рдпрджрд┐ рдЖрдк PsiFileFactory рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдлрд╝рд╛рдЗрд▓реЗрдВ рдЬрдирд░реЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдХрд╣реАрдВ-рдХрд╣реАрдВ FileType рдвреВрдВрдврдирд╛ рд╣реЛрдЧрд╛ред

рдЦреИрд░, рдЕрдм рд╣рдо рдЖрдЦрд┐рд░реА, рд╕рдмрд╕реЗ рд╕реНрд╡рд╛рджрд┐рд╖реНрдЯ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рднрд╛рдЧ рдХреА рдУрд░ рдореБрдбрд╝рддреЗ рд╣реИрдВ - рдпрд╣ рдХреЛрдб рдХрд╛ рдПрдХ рд╕рдВрд╢реЛрдзрди рд╣реИред


рдХреЛрдб рд╕рдВрд╢реЛрдзрди


рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдХреЗрд╡рд▓ рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд▓рдЧрдЗрди рдмрдирд╛рдирд╛ рдмрдХрд╡рд╛рд╕ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдЕрдиреНрдп рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдПрдХ рд╣реА FreeMarker ред рд▓реЗрдХрд┐рди FreeMarker рдХреНрдпрд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рдХреЛрдб рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддрд╛ рд╣реИред


рд╣рдорд╛рд░реА рдЪреЗрдХрд▓рд┐рд╕реНрдЯ рдореЗрдВ рдХреЛрдб рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХрдИ рдХрд╛рд░реНрдп рд╣реИрдВ, рдЖрдЗрдП рд╕рдмрд╕реЗ рд╕рд░рд▓ рдПрдХ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ - settings.gradle рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░реЗрдВред


рд╕рдВрд╢реЛрдзрди рд╕реЗрдЯрд┐рдВрдЧреНрд╕


рдореИрдВ рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛рддрд╛ рд╣реВрдВ рдХрд┐ рд╣рдо рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ: рд╣рдореЗрдВ рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреБрдЫ рд▓рд╛рдЗрдиреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдирдП рдмрдирд╛рдП рдЧрдП рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рдкрде рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВрдЧреЗ:


рдореЙрдбреНрдпреВрд▓ рдХреЗ рдкрде рдХрд╛ рд╡рд┐рд╡рд░рдг
 // settings.gradle include ':analytics project(':analytics').projectDir = new File(settingsDir, 'core/framework-metrics/analytics) ... include ':feature-worknear' project(':feature-worknear').projectDir = new File(settingsDir, 'feature/feature-worknear') 

рдореИрдВрдиреЗ рдЖрдкрдХреЛ рдереЛрдбрд╝рд╛ рдкрд╣рд▓реЗ рдбрд░рд╛ рджрд┐рдпрд╛ рдерд╛ рдХрд┐ рдЖрдкрдХреЛ рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рд╣рдореЗрд╢рд╛ рдкреАрдПрд╕рдЖрдИ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЕрдиреНрдпрдерд╛ рд╕рдм рдХреБрдЫ рдЬрд▓ рдЬрд╛рдПрдЧрд╛ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕рд░рд▓ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ, рдЬреИрд╕реЗ рдХрд┐рд╕реА рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЕрдВрдд рдореЗрдВ рдХреБрдЫ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛, рдЗрд╕реЗ рдЫреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЖрдк рд╕рд╛рдорд╛рдиреНрдп java.io.File рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреБрдЫ рд▓рд╛рдЗрдиреЗрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдкрде рдвреВрдВрдврддреЗ рд╣реИрдВ, java.io.File рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддреЗ рд╣реИрдВ, рдФрд░ рдХреЛрдЯрд▓рд┐рди рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдлрд╝рдВрдХреНрд╢рди рдХреА рдорджрдж рд╕реЗ рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЕрдВрдд рдореЗрдВ рджреЛ рд▓рд╛рдЗрдиреЗрдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдЖрдк рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, IDEA рдЖрдкрдХреЗ рдмрджрд▓рд╛рд╡реЛрдВ рдХреЛ рджреЗрдЦреЗрдЧрд╛ред


Settings.gradle рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд▓рд╛рдЗрдиреЗрдВ рдЬреЛрдбрд╝рдирд╛

val projectBaseDirPath = project.basePath ?: рд╡рд╛рдкрд╕реА
рд╡реИрд▓ рд╕реЗрдЯрд┐рдВрдЧреНрд╕рдкрдердлрд╛рдЗрд▓ = рдкреНрд░реЛрдЬреЗрдХреНрдЯрдмреЗрд╕ рдбреАрдкрдкреИрде + "/ рд╕реЗрдЯрд┐рдВрдЧреНрд╕.рдЧреНрд░реЗрдб"


рд╡реИрд▓ рд╕реЗрдЯрд┐рдВрдЧреНрд╕рдлрд╝рд┐рд▓ = рдлрд╝рд╛рдЗрд▓ (рд╕реЗрдЯрд┐рдВрдЧреНрд╕рдкрд╛рдк рдлрд╝рд╛рдЗрд▓)


settingsFile.appendText ("рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВ: $ рдореЙрдбреНрдпреВрд▓рдирд╛рдо" ")
settingsFile.appendText (
"рдкреНрд░реЛрдЬреЗрдХреНрдЯ (': $ рдореЙрдбреНрдпреВрд▓рдирд╛рдо')ред рдкреНрд░реЛрдЬреЗрдХреНрдЯрдбрд┐рд░ = рдирдИ рдлрд╝рд╛рдЗрд▓ (рд╕реЗрдЯрд┐рдВрдЧреНрд╕рдбрд╛рдпрд░, '$ рдлреЛрд▓реНрдбрд░рдкрд╛рде)"
)


рдЦреИрд░, рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдпрд╣ рдкреАрдПрд╕рдЖрдИ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмреЗрд╣рддрд░ рд╣реИ - рдпрд╣ рдЕрдзрд┐рдХ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд╣реИред


рдЯреВрдердкрд┐рдХ рдХреЗ рд▓рд┐рдП рдХреЗрдкреНрдЯ рдЯреНрдпреВрдирд┐рдВрдЧ


рдПрдХ рдмрд╛рд░ рдлрд┐рд░, рдореИрдВ рдЖрдкрдХреЛ рд╕рдорд╕реНрдпрд╛ рдХреА рдпрд╛рдж рджрд┐рд▓рд╛рддрд╛ рд╣реВрдВ: рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдмрд┐рд▓реНрдб.рдЧреНрд░реЗрдб рдлрд╝рд╛рдЗрд▓ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдЕрдВрджрд░ рдПрдиреЛрдЯреЗрд╢рди рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рд╣реИрдВред рдФрд░ рд╣рдо рдЕрдкрдиреЗ рдмрдирд╛рдП рдЧрдП рдореЙрдбреНрдпреВрд▓ рдХреЗ рдкреИрдХреЗрдЬ рдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реНрдерд╛рди рдкрд░ рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред


рдХрд╣рд╛рдБ рд╕реЗ рдХрд╣рд╛рдБ рддрдХ? редред

рдЫрд╡рд┐


рд╣рдорд╛рд░рд╛ рд▓рдХреНрд╖реНрдп рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ PsiElement рдХреА рдЦреЛрдЬ рдХрд░рдирд╛ рд╣реИ , рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рд╣рдо рдЕрдкрдиреА рд▓рд╛рдЗрди рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рддреЗ рд╣реИрдВред рддрддреНрд╡ рдХреА рдЦреЛрдЬ PsiFile рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ, рдЬреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЙрдбреНрдпреВрд▓ рдХреА рдмрд┐рд▓реНрдб.рдЧреНрд░реЗрдб рдлрд╝рд╛рдЗрд▓ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИред рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдЙрд╕ рдореЙрдбреНрдпреВрд▓ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рдЕрдВрджрд░ рд╣рдо рдлрд╝рд╛рдЗрд▓ рдХреА рддрд▓рд╛рд╢ рдХрд░реЗрдВрдЧреЗред


рд╣рдо рдирд╛рдо рд╕реЗ рдПрдХ рдореЙрдбреНрдпреВрд▓ рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ
 val appModule = ModuleManager.getInstance(project) .modules.toList() .first { it.name == "headhunter-applicant" } 

рдЕрдЧрд▓рд╛, рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд╡рд░реНрдЧ FilenameIndex рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ , рдЖрдк рдЦреЛрдЬ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рдП рдЧрдП рдореЙрдбреНрдпреВрд▓ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реБрдП, рдЗрд╕рдХреЗ рдирд╛рдо рд╕реЗ PsiFile рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред


рдирд╛рдо рд╕реЗ PsiFile рдХреА рддрд▓рд╛рд╢ рд╣реИ
 val buildGradlePsiFile = FilenameIndex.getFilesByName( appModule.project, "build.gradle", appModule.moduleContentScope ).first() 

рд╣рдо PsiFile рдЦреЛрдЬрдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо PsiElement рдХреА рдЦреЛрдЬ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред , тАУ PSI Viewer . IDEA , PSI- .


рдЫрд╡рд┐


- (, build.gradle) , PSI- .


рдЫрд╡рд┐


тАУ , PsiFile -.


. PsiFile . .


PsiElement
 val toothpickRegistryPsiElement = buildGradlePsiFile.originalFile .collectDescendantsOfType<GrAssignmentExpression>() .firstOrNull { it.text.startsWith("arguments") } ?.lastChild ?.children?.firstOrNull { it.text.startsWith("toothpick_registry_children_package_names") } ?.collectDescendantsOfType<GrListOrMap>() ?.first() ?: return 

?.. ? PSI-. GrAssignmentExpression , , arguments = [ тАж ] . , toothpick_registry_children_package_names = [...] , Groovy-.


PsiElement , . . .


PSI- , PsiElementFactory , . Java-? Java-. Groovy? GroovyPsiElementFactory . рдФрд░ рдЗрд╕реА рддрд░рд╣ред


PsiElementFactory . Groovy Kotlin , .


PsiElement package name
 val factory = GroovyPsiElementFactory.getInstance(buildGradlePsiFile.project) val packageName = config.mainParams.packageName val newArgumentItem = factory.createStringLiteralForReference(packageName) 

PsiElement .


Map-
 targetPsiElement.add(newArgumentItem) 

kapt- Moxy application


-, , тАУ kapt- Moxy application . : @RegisterMoxyReflectorPackages .


-?

рдЫрд╡рд┐


, : PsiFile , PsiElement , тАж , PsiElement -.


: , @RegisterMoxyReflectorPackages , value , .


, . , PsiManager , PsiClass .


PsiClass @RegisterMoxyReflectorPackages
 val appModule = ModuleManager.getInstance(project) .modules.toList() .first { it.name == "headhunter-applicant" } val psiManager = PsiManager.getInstance(appModule.project) val annotationPsiClass = ClassUtil.findPsiClass( psiManager, "com.arellomobile.mvp.RegisterMoxyReflectorPackages" ) ?: return 

AnnotatedMembersSearch , .


,
 val annotatedPsiClass = AnnotatedMembersSearch.search( annotationPsiClass, appModule.moduleContentScope ).findAll() ?.firstOrNull() ?: return 

, PsiElement , value. , .


 val annotationPsiElement = (annotatedPsiClass .annotations .first() as KtLightAnnotationForSourceEntry ).kotlinOrigin val packagesPsiElements = annotationPsiElement .collectDescendantsOfType<KtValueArgumentList>() .first() .collectDescendantsOfType<KtValueArgument>() val updatedPackagesList = packagesPsiElements .mapTo(mutableListOf()) { it.text } .apply { this += "\"${config.packageName}\"" } val newAnnotationValue = updatedPackagesList.joinToString(separator = ",\n") 

KtPsiFactory PsiElement тАУ .


 val kotlinPsiFactory = KtPsiFactory(project) val newAnnotationPsiElement = kotlinPsiFactory.createAnnotationEntry( "@RegisterMoxyReflectorPackages(\n$newAnnotationValue\n)" ) val replaced = annotationPsiElement.replace(newAnnotationPsiElement) 

.


? code style. , IDEA : CodeStyleManager.


code style
 CodeStyleManager.getInstance(module.project).reformat(replacedElement) 

- , .



  • , PSI-, .
  • , PSI , , PsiElement-.

?


.


  • тАУ , .
  • . . : .
  • ? . , IDEA , . , . тАФ - , GitHub . , , .
  • - тАУ IntelliJ IDEA . , Util Manager , , , .
  • : . , runIde , IDEA, . , hh.ru, .

рд╡рд╣ рд╕рдм рд╣реИред , , тАУ .


рдкреВрдЫреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рд╢реНрди


  • ?

, . , 2 3 .


  • IDEA , - ?

, IDEA IDEA SDK , deprecated, , . SDK- , , .


  • ?

тАУ gitignore . - .


  • ?

Android Studio Mac OS, Ubuntu, . , Windows, .

Source: https://habr.com/ru/post/hi463611/


All Articles