// ĠCopyright Ġ 2 0 0 0 - 2 0 2 0 ĠJetBrains Ġs . r . o . ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ package Ġcom . intellij . refactor ing . extract Method . new Impl Ċ Ċ import Ġcom . intellij . code Insight . Code Insight Util Ċ import Ġcom . intellij . openapi . editor . Editor Ċ import Ġcom . intellij . openapi . editor . Selection Model Ċ import Ġcom . intellij . psi .* Ċ import Ġcom . intellij . refactor ing . intro duce Variable . Intro duce Variable Base Ċ import Ġcom . intellij . refactor ing . util . Ref actor ing Util Ċ Ċ class ĠExtract Selector Ġ{ ĊĊĠ Ġprivate Ġfun Ġfind Selected Elements ( editor : ĠEditor ): ĠList < Psi Element > Ġ{ ĊĠĠĠ Ġval Ġproject Ġ= Ġeditor . project Ġ?: Ġreturn Ġempty List () ĊĠĠĠ Ġval Ġfile Ġ= ĠPsi Document Manager . getInstance ( project ). get Psi File ( editor . document ) Ġ?: Ġreturn Ġempty List () ĊĠĠĠ Ġval Ġselection Model : ĠSelection Model Ġ= Ġeditor . selection Model ĊĠĠĠ Ġif Ġ( selection Model . has Selection ()) Ġ{ ĊĠĠĠĠĠ Ġval Ġstart Offset Ġ= Ġselection Model . selection Start ĊĠĠĠĠĠ Ġval Ġend Offset Ġ= Ġselection Model . selection End ĊĠĠĠĠĠ Ġvar Ġelements : ĠArray < Psi Element > ĊĠĠĠĠĠ Ġval Ġexpr Ġ= ĠCode Insight Util . find Expression InRange ( file , Ġstart Offset , Ġend Offset ) ĊĠĠĠĠĠ Ġif Ġ( expr Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġelements Ġ= ĠarrayOf ( expr ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġelements Ġ= ĠCode Insight Util . find Statements InRange ( file , Ġstart Offset , Ġend Offset ) ĊĠĠĠĠĠĠĠ Ġif Ġ( elements . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġexpression Ġ= ĠIntro duce Variable Base . getSelected Expression ( project , Ġfile , Ġstart Offset , Ġend Offset ) ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( expression Ġ!= Ġnull Ġ&& ĠIntro duce Variable Base . get ErrorMessage ( expression ) Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoriginal Type Ġ= ĠRefactor ing Util . getType By Expression With Expected Type ( expression ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( original Type Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelements Ġ= ĠarrayOf ( expression ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġreturn Ġelements . toList () ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn ĠIntro duce Variable Base . collect Expressions ( file , Ġeditor , Ġeditor . caret Model . offset ) ĊĠ Ġ} ĊĊĠ Ġfun Ġsuggest Elements To Extract ( editor : ĠEditor ): ĠList < Psi Element > Ġ{ ĊĠĠĠ Ġval Ġselected Elements Ġ= Ġfind Selected Elements ( editor ) ĊĠĠĠ Ġreturn Ġalign Elements ( selected Elements ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġalign Elements ( elements : ĠList < Psi Element >): ĠList < Psi Element > Ġ{ ĊĠĠĠ Ġval Ġsingle Element Ġ= Ġelements . single OrNull () ĊĠĠĠ Ġval Ġaligned Elements Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠ Ġelements . size Ġ> Ġ 1 Ġ-> Ġalign Statements ( elements ) ĊĠĠĠĠĠ Ġsingle Element Ġis ĠPsi Code Block Ġ-> Ġalign Code Block ( single Element ) ĊĠĠĠĠĠ Ġsingle Element Ġis ĠPsi Statement Ġ-> ĠlistOf NotNull ( align Statement ( single Element )) ĊĠĠĠĠĠ Ġsingle Element Ġis ĠPsi Expression Ġ-> ĠlistOf NotNull ( align Expression ( single Element )) ĊĠĠĠĠĠ Ġelse Ġ-> Ġelements ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠ Ġaligned Elements . isEmpty () Ġ-> Ġempty List () ĊĠĠĠĠĠ Ġaligned Elements . first () Ġ!== Ġelements . first () Ġ|| Ġaligned Elements . last () Ġ!== Ġelements . last () Ġ-> Ġalign Elements ( aligned Elements ) ĊĠĠĠĠĠ Ġelse Ġ-> Ġaligned Elements ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġalign Expression ( expression : ĠPsi Expression ?): ĠPsi Expression ? Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( expression ) Ġ{ ĊĠĠĠĠĠ Ġnull Ġ-> Ġreturn Ġnull ĊĠĠĠĠĠ Ġis ĠPsi Return Statement Ġ-> Ġalign Expression ( expression . returnValue ) ĊĠĠĠĠĠ Ġis ĠPsi Assignment Expression Ġ-> Ġalign Expression ( expression . r Expression ) ĊĠĠĠĠĠ Ġ// expression . parent Ġis ĠPsi Parent hesized Expression Ġ-> Ġalign Expression ( expression . parent Ġas ĠPsi Expression ) ĊĠĠĠĠĠ Ġ// ĠPsi Util . skip Parent hesized Expr Down (( Psi Expression ) elements [ 0 ]); ĊĠĠĠĠĠ Ġelse Ġ-> Ġexpression ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġalign Statements ( statements : ĠList < Psi Element >): ĠList < Psi Element > Ġ{ ĊĠĠĠ Ġval Ġfiltered Statements Ġ= Ġstatements . drop While Ġ{ Ġit Ġis ĠPsi Switch Label Statement Ġ}. drop Last While Ġ{ Ġit Ġis ĠPsi Switch Label Statement Ġ} ĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠ Ġfiltered Statements . any Ġ{ Ġit Ġis ĠPsi Switch Label Statement Ġ} Ġ-> Ġempty List () ĊĠĠĠĠĠ Ġelse Ġ-> Ġfiltered Statements ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġalign Code Block ( code Block : ĠPsi Code Block ): ĠList < Psi Element > Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( code Block . parent ) Ġ{ ĊĠĠĠĠĠ Ġis ĠPsi Switch Statement Ġ-> ĠlistOf ( code Block . parent ) ĊĠĠĠĠĠ Ġelse Ġ-> Ġcode Block . children . drop While Ġ{ Ġit Ġ!== Ġcode Block . first Body Element Ġ}. drop Last While Ġ{ Ġit Ġ!== Ġcode Block . last Body Element Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġalign Statement ( statement : ĠPsi Statement ): ĠPsi Element ? Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( statement ) Ġ{ ĊĠĠĠĠĠ Ġis ĠPsi Expression Statement Ġ-> Ġalign Expression ( statement . expression ) ĊĠĠĠĠĠ Ġis ĠPsi Declaration Statement Ġ-> Ġstatement . declared Elements . map NotNull Ġ{ Ġ( it Ġas ? ĠPsi Local Variable )?. initializer Ġ}. single OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġstatement ĊĠĠĠĠĠ Ġelse Ġ-> Ġstatement ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ }