/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 - 2 0 1 5 ĠJetBrains Ġs . r . o . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġorg . jetbrains . kotlin . j 2 k Ċ Ċ import Ġcom . intellij . psi .* Ċ import Ġorg . jetbrains . kotlin . j 2 k . ast .* Ċ import Ġcom . intellij . psi . util . Psi Util Ċ import Ġjava . util . HashMap Ċ import Ġjava . util . ArrayList Ċ import Ġjava . util . HashSet Ċ Ċ class ĠConstructor Converter ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġpsi Class : ĠPsi Class , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġconverter : ĠConverter , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġfield Corre ctions : ĠMap < Psi Field , ĠField Correction Info > Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġconstructors Ġ= Ġpsi Class . get Construct ors () ĊĠĠĠ Ġprivate Ġval Ġconstructors To Drop Ġ= ĠHashSet < Psi Method >() ĊĠĠĠ Ġprivate Ġval Ġlast Param Defaults Ġ= ĠArrayList < Psi Expression >() Ġ// Ġdefaults Ġfor Ġa Ġfew Ġlast Ġparameters Ġof Ġprimary Ġconstructor Ġin Ġreverse Ġorder ĊĠĠĠ Ġprivate Ġval Ġprimary Constructor : ĠPsi Method ? Ġ= Ġwhen Ġ( construct ors . size ()) Ġ{ ĊĠĠĠĠĠĠĠĠ 0 Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠ 1 Ġ-> Ġconstructors . single () ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġchoose Primary Constructor () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠTarget Constructor Info ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠTarget Ġconstructor Ġ( one Ġwhich Ġis Ġfinally Ġinvoked Ġby Ġthis Ġone ) ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconstructor : ĠPsi Method , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠIs Ġnot Ġnull Ġif Ġthis Ġconstructor Ġis Ġequivalent Ġto Ġthe Ġtarget Ġconstructor Ġwith Ġa Ġfew Ġlast Ġparameters Ġhaving Ġdefault Ġvalues ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparameter Defaults : ĠList < Psi Expression > ?) ĊĊĠĠĠ Ġprivate Ġfun Ġchoose Primary Constructor (): ĠPsi Method ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġto Target Constructor Map Ġ= Ġbuild To Target Constructor Map () ĊĊĠĠĠĠĠĠĠ Ġval Ġcandidates Ġ= Ġconstructors . filter Ġ{ Ġit Ġ! in Ġto Target Constructor Map Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( candidates . size () Ġ!= Ġ 1 ) Ġreturn Ġnull Ġ// Ġthere Ġshould Ġbe Ġonly Ġone Ġconstructor Ġwhich Ġdoes Ġnot Ġcall Ġother Ġconstructor ĊĠĠĠĠĠĠĠ Ġval Ġprimary Ġ= Ġcandidates . single () ĊĠĠĠĠĠĠĠ Ġif Ġ( to Target Constructor Map . values (). any () Ġ{ Ġit . constructor Ġ!= Ġprimary Ġ}) Ġreturn Ġnull Ġ// Ġall Ġother Ġconstructors Ġcall Ġour Ġcandidate Ġ( direct ly Ġor Ġindirect ly ) ĊĊĠĠĠĠĠĠĠ Ġdrop Construct ors For Default Values ( primary , Ġto Target Constructor Map ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġprimary ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġbuild To Target Constructor Map (): ĠMap < Psi Method , ĠTarget Constructor Info > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġto Target Constructor Map Ġ= ĠHashMap < Psi Method , ĠTarget Constructor Info >() ĊĠĠĠĠĠĠĠ Ġfor Ġ( constructor Ġin Ġconstructors ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfirst Statement Ġ= Ġconstructor . getBody ()?. getState ments ()?. first OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmethod Call Ġ= Ġ( first Statement Ġas ? ĠPsi Expression Statement )?. get Expression () Ġas ? ĠPsi MethodCall Expression ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( method Call Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġref Expr Ġ= Ġmethod Call . getMethod Expression () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ref Expr . getCanonical Text () Ġ== Ġ" this ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Ġ= Ġref Expr . resolve () Ġas ? ĠPsi Method ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( target Ġ!= Ġnull Ġ&& Ġtarget . is Constructor ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġparameter Defaults Ġ= Ġcalc Target Parameter Defaults ( constructor , Ġtarget , Ġmethod Call ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfinal Target Info Ġ= Ġto Target Constructor Map [ target ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( final Target Info Ġ!= Ġnull Ġ&& Ġparameter Defaults Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameter Defaults Ġ= Ġif Ġ( final Target Info . parameter Defaults Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameter Defaults !! Ġ+ Ġfinal Target Info . parameter Defaults ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfinal Target Ġ= Ġfinal Target Info ?. constructor Ġ?: Ġtarget ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Target Constructor Map [ constructor ] Ġ= ĠTarget Constructor Info ( final Target , Ġparameter Defaults ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( entry Ġin Ġto Target Constructor Map . entrySet ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( entry . value . constructor Ġ== Ġconstructor ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Parameter Defaults Ġ= Ġif Ġ( parameter Defaults Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry . value . parameter Defaults ?. plus ( parameter Defaults !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry . setValue ( Target Constructor Info ( final Target , Ġnew Parameter Defaults )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġto Target Constructor Map ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcalc Target Parameter Defaults ( constructor : ĠPsi Method , Ġtarget : ĠPsi Method , Ġtarget Call : ĠPsi MethodCall Expression ): ĠList < Psi Expression >? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( constructor . getBody () !!. getState ments (). size () Ġ!= Ġ 1 ) Ġreturn Ġnull Ġ// Ġconstructor 's Ġbody Ġshould Ġconsist Ġof Ġonly Ġ" this (... )" ĊĠĠĠĠĠĠĠ Ġval Ġparameters Ġ= Ġconstructor . getParameter List (). getParameters () ĊĠĠĠĠĠĠĠ Ġval Ġtarget Parameters Ġ= Ġtarget . getParameter List (). getParameters () ĊĠĠĠĠĠĠĠ Ġif Ġ( parameters . size () Ġ>= Ġtarget Parameters . size ()) Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġargs Ġ= Ġtarget Call . get ArgumentList (). get Expressions () ĊĠĠĠĠĠĠĠ Ġif Ġ( args . size () Ġ!= Ġtarget Parameters . size ()) Ġreturn Ġnull Ġ// Ġincorrect Ġcode ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġparameters . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparameter Ġ= Ġparameters [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Parameter Ġ= Ġtarget Parameters [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( parameter . getName () Ġ!= Ġtarget Parameter . getName () Ġ|| Ġparameter . getType () Ġ!= Ġtarget Parameter . getType ()) Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarg Ġ= Ġargs [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( arg Ġ! is ĠPsi Reference Expression Ġ|| Ġarg . resolve () Ġ!= Ġparameter ) Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġargs . drop ( parameters . size ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdrop Construct ors For Default Values ( primary : ĠPsi Method , Ġto Target Constructor Map : ĠMap < Psi Method , ĠTarget Constructor Info >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdrop Candidates Ġ= Ġto Target Constructor Map ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . value . parameter Defaults Ġ!= Ġnull Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . key Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . access Modifier () Ġ== Ġprimary . access Modifier () Ġ&& Ġit . get Modifier List (). get Annotations (). isEmpty () Ġ/* Ġdo Ġnot Ġdrop Ġconstructors Ġwith Ġannotations Ġ*/ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. sortBy Ġ{ Ġ- it . getParameter List (). getParameters Count () Ġ} Ġ// Ġwe Ġwill Ġtry Ġto Ġdrop Ġthem Ġstarting Ġfrom Ġones Ġwith Ġmore Ġparameters ĊĠĠĠĠĠĠĠ Ġval Ġprimary Param Count Ġ= Ġprimary . getParameter List (). getParameters Count () ĊĠĠĠĠĠĠĠ Ġ@ Drop Candidates Loop ĊĠĠĠĠĠĠĠ Ġfor Ġ( constructor Ġin Ġdrop Candidates ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparam Count Ġ= Ġconstructor . getParameter List (). getParameters Count () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert ( param Count Ġ< Ġprimary Param Count ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdefaults Ġ= Ġto Target Constructor Map [ constructor ] !!. parameter Defaults !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert ( defaults . size () Ġ== Ġprimary Param Count Ġ- Ġparam Count ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġdefaults . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdefault Ġ= Ġdefaults [ defaults . size () Ġ- Ġi Ġ- Ġ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( i Ġ< Ġlast Param Defaults . size ()) Ġ{ Ġ// Ġdefault Ġfor Ġthis Ġparameter Ġhas Ġalready Ġbeen Ġassigned ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( last Param Defaults [ i ]. getText () Ġ!= Ġdefault . getText ()) Ġcontinue @ Drop Candidates Loop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Param Defaults . add ( default ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġconstructors To Drop . add ( constructor ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġvar Ġbase Class Params : ĠList < Deferred Element < Expression >> Ġ= ĠlistOf () ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġpublic Ġfun Ġconvert Constructor ( constructor : ĠPsi Method , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġannotations : ĠAn notations , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodifiers : ĠMod ifiers , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmembers ToRemove : ĠMutable Set < Psi Member >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Process Body : Ġ( Block ) Ġ-> ĠBlock ): ĠMember ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( constructor Ġ== Ġprimary Constructor ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġconvert Primary Constructor ( annotations , Ġmodifiers , Ġmembers ToRemove , Ġpost Process Body ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( constructor Ġin Ġconstructors To Drop ) Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparams Ġ= Ġconverter . convert Parameter List ( constructor . getParameter List ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġthis Or Super Ġ= Ġfind This Or Super Call ( constructor ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġthis Or Super Deferred Ġ= Ġif Ġ( this Or Super Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconverter . deferred Element Ġ{ Ġit . convert Expression ( this Or Super . get Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġconvert Body ( code Converter : ĠCode Converter ): ĠBlock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpost Process Body ( code Converter . with Special Expression Converter ( object : ĠSpecial Expression Converter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġconvert Expression ( expression : ĠPsi Expression , Ġcode Converter : ĠCode Converter ): ĠExpression ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( expression . is This Constructor Call () Ġ|| Ġexpression . is Super Constructor Call ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠExpression . Empty Ġ// Ġskip Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}). convert Block ( constructor . getBody ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠSecondary Constructor ( annotations , Ġmodifiers , Ġparams , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconverter . deferred Element (:: convert Body ), Ġthis Or Super Deferred ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind This Or Super Call ( constructor : ĠPsi Method ): ĠPsi Expression Statement ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstatement Ġ= Ġconstructor . getBody ()?. getState ments ()?. first OrNull () Ġas ? ĠPsi Expression Statement Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġmethod Call Ġ= Ġstatement . get Expression () Ġas ? ĠPsi MethodCall Expression Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġtext Ġ= Ġmethod Call . getMethod Expression (). getText () ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( text Ġ== Ġ" this " Ġ|| Ġtext Ġ== Ġ" super ") Ġstatement Ġelse Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconvert Primary Constructor ( annotations : ĠAn notations , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodifiers : ĠMod ifiers , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmembers ToRemove : ĠMutable Set < Psi Member >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Process Body : Ġ( Block ) Ġ-> ĠBlock ): ĠPrimary Constructor Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġparams Ġ= Ġprimary Constructor !!. getParameter List (). getParameters () ĊĠĠĠĠĠĠĠ Ġval Ġparameter To Field Ġ= ĠHashMap < Psi Parameter , ĠPair < Psi Field , ĠType >>() ĊĠĠĠĠĠĠĠ Ġval Ġbody Ġ= Ġprimary Constructor . getBody () ĊĊĠĠĠĠĠĠĠ Ġval Ġparameter Usage Replacement Map Ġ= ĠHashMap < String , ĠString >() ĊĠĠĠĠĠĠĠ Ġval Ġcorrected Type Converter Ġ= Ġconverter . with Special Context ( psi Class ). type Converter Ġ/* Ġto Ġcorrect Ġnested Ġclass Ġreferences Ġ*/ ĊĊĠĠĠĠĠĠĠ Ġval Ġbody Generator : Ġ( Code Converter ) Ġ-> ĠBlock Ġ= Ġif Ġ( body Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstatements ToRemove Ġ= ĠHashSet < Psi Statement >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( parameter Ġin Ġparams ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( field , Ġinitialization Statement ) Ġ= Ġfind Backing Field For Constructor Parameter ( parameter , Ġprimary Constructor ) Ġ?: Ġcontinue ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠfieldType Ġ= Ġcorrected Type Converter . convert Variable Type ( field ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparameter Type Ġ= Ġcorrected Type Converter . convert Variable Type ( parameter ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtypes Ġcan Ġbe Ġdifferent Ġonly Ġin Ġnull ability ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtype Ġ= Ġif Ġ( fieldType Ġ== Ġparameter Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠfieldType ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġif Ġ( fieldType . to NotNull Type () Ġ== Ġparameter Type . to NotNull Type ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( fieldType . is Nullable ) ĠfieldType Ġelse Ġparameter Type Ġ// Ġprefer Ġnullable Ġone ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfield Correction Ġ= Ġfield Corre ctions [ field ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġcannot Ġspecify Ġdifferent Ġsetter Ġaccess Ġfor Ġconstructor Ġparameter ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( field Correction Ġ!= Ġnull Ġ&& Ġ! is Val ( converter . reference Searcher , Ġfield ) Ġ&& Ġfield Correction . access Ġ!= Ġfield Correction . setter Access ) Ġcontinue ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameter To Field . put ( parameter , Ġfield Ġto Ġtype ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatements ToRemove . add ( initialization Statement ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmembers ToRemove . add ( field ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠfieldName Ġ= Ġfield Correction ?. name Ġ?: Ġfield . getName () !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( fieldName Ġ!= Ġparameter . getName ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameter Usage Replacement Map . put ( parameter . getName () !! , ĠfieldName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġcode Converter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbody Converter Ġ= Ġcode Converter . with Special Expression Converter ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠRe pl acing Expression Converter ( parameter Usage Replacement Map ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġconvert Expression ( expression : ĠPsi Expression , Ġcode Converter : ĠCode Converter ): ĠExpression ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( expression . is Super Constructor Call ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠExpression . Empty Ġ// Ġskip Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsuper . convert Expression ( expression , Ġcode Converter ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Process Body ( body Converter . convert Block ( body , Ġfalse , Ġ{ Ġ! statements ToRemove . contains ( it ) Ġ})) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġit Ġ-> ĠBlock . Empty Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġwe Ġneed Ġto Ġreplace Ġrenamed Ġparameter Ġusage s Ġin Ġbase Ġclass Ġconstructor Ġarguments Ġand Ġin Ġdefault Ġvalues ĊĊĠĠĠĠĠĠĠ Ġval Ġcorrected Converter Ġ= Ġconverter . with Special Context ( psi Class ) Ġ/* Ġto Ġcorrect Ġnested Ġclass Ġreferences Ġ*/ ĊĊĠĠĠĠĠĠĠ Ġfun ĠCode Converter . correct () Ġ= Ġwith Special Expression Converter ( Repl acing Expression Converter ( parameter Usage Replacement Map )) ĊĊĠĠĠĠĠĠĠ Ġval Ġstatement Ġ= Ġprimary Constructor . getBody ()?. getState ments ()?. first OrNull () ĊĠĠĠĠĠĠĠ Ġval Ġmethod Call Ġ= Ġ( statement Ġas ? ĠPsi Expression Statement )?. get Expression () Ġas ? ĠPsi MethodCall Expression ĊĠĠĠĠĠĠĠ Ġif Ġ( method Call Ġ!= Ġnull Ġ&& Ġmethod Call . is Super Constructor Call ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbase Class Params Ġ= Ġmethod Call . get ArgumentList (). get Expressions (). map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcorrected Converter . deferred Element Ġ{ Ġcode Converter Ġ-> Ġcode Converter . correct (). convert Expression ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġparameter List Ġ= ĠParameter List ( params . indices . map Ġ{ Ġi Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparameter Ġ= Ġparams [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġindex From End Ġ= Ġparams . size () Ġ- Ġi Ġ- Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠdefaultValue Ġ= Ġif Ġ( index From End Ġ< Ġlast Param Defaults . size ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcorrected Converter . deferred Element Ġ{ Ġcode Converter Ġ-> Ġcode Converter . correct (). convert Expression ( last Param Defaults [ index From End ], Ġparameter . getType ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! parameter To Field . containsKey ( parameter )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcorrected Converter . convert Parameter ( parameter , ĠdefaultValue Ġ= ĠdefaultValue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( field , Ġtype ) Ġ= Ġparameter To Field [ parameter ] !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfield Correction Ġ= Ġfield Corre ctions [ field ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġfield Correction ?. identifier Ġ?: Ġfield . declaration Identifier () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaccess Modifiers Ġ= Ġif Ġ( field Correction Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMod ifiers ( listOf ()). with ( field Correction . access ). assign No Prototype () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconverter . convert Modifiers ( field ). filter Ġ{ Ġit Ġin ĠACCESS _ MODI FI ERS Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠParameter ( name , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtype , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Val ( converter . reference Searcher , Ġfield )) ĠParameter . Var Val Modifier . Val Ġelse ĠParameter . Var Val Modifier . Var , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconverter . convert Annotations ( parameter ) Ġ+ Ġconverter . convert Annotations ( field ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaccess Modifiers , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠdefaultValue ). assign Pro totypes ( listOf ( parameter , Ġfield ), ĠComments And Spaces Inheritance ( blank Lines Before Ġ= Ġfalse )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}). assign Prototype ( primary Constructor . getParameter List ()) ĊĠĠĠĠĠĠĠ Ġreturn ĠPrimary Constructor ( annotations , Ġmodifiers , Ġparameter List , Ġconverter . deferred Element ( body Generator )). assign Prototype ( primary Constructor ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind Backing Field For Constructor Parameter ( parameter : ĠPsi Parameter , Ġconstructor : ĠPsi Method ): ĠPair < Psi Field , ĠPsi Statement >? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbody Ġ= Ġconstructor . getBody () Ġ?: Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġval Ġrefs Ġ= Ġconverter . reference Searcher . find Variable Usage s ( parameter , Ġbody ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( refs . any Ġ{ ĠPsi Util . is Ac cessed For Writing ( it ) Ġ}) Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( ref Ġin Ġrefs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġassignment Ġ= Ġref . getParent () Ġas ? ĠPsi Assignment Expression Ġ?: Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( assignment . get Operation Sign (). get TokenType () Ġ!= ĠJava TokenType . EQ ) Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġassign ee Ġ= Ġassignment . get L Expression () Ġas ? ĠPsi Reference Expression Ġ?: Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! assign ee . is Qualifier Empty Or This ()) Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfield Ġ= Ġassign ee . resolve () Ġas ? ĠPsi Field Ġ?: Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( field . get Containing Class () Ġ!= Ġconstructor . get Containing Class ()) Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( field . has Modifier Property ( Psi Modifier . STATIC )) Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( field . get Initializer () Ġ!= Ġnull ) Ġcontinue ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġassignment Ġshould Ġbe Ġa Ġtop - level Ġstatement ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstatement Ġ= Ġassignment . getParent () Ġas ? ĠPsi Expression Statement Ġ?: Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( statement . getParent () Ġ!= Ġbody ) Ġcontinue ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġand Ġno Ġother Ġassignments Ġto Ġfield Ġshould Ġexist Ġin Ġthe Ġconstructor ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( converter . reference Searcher . find Variable Usage s ( field , Ġbody ). any Ġ{ Ġit Ġ!= Ġassign ee Ġ&& ĠPsi Util . is Ac cessed For Writing ( it ) Ġ&& Ġit . is Qualifier Empty Or This () Ġ}) Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// TODO : Ġcheck Ġaccess Ġto Ġfield Ġbefore Ġassignment ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfield Ġto Ġstatement ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠPsi Expression . is Super Constructor Call () Ġ= Ġ( this Ġas ? ĠPsi MethodCall Expression )?. getMethod Expression ()?. getText () Ġ== Ġ" super " ĊĠĠĠ Ġprivate Ġfun ĠPsi Expression . is This Constructor Call () Ġ= Ġ( this Ġas ? ĠPsi MethodCall Expression )?. getMethod Expression ()?. getText () Ġ== Ġ" this " ĊĊĠĠĠ Ġprivate Ġinner Ġopen Ġclass ĠRe pl acing Expression Converter ( val Ġparameter Usage Replacement Map : ĠMap < String , ĠString >) Ġ: ĠSpecial Expression Converter Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġconvert Expression ( expression : ĠPsi Expression , Ġcode Converter : ĠCode Converter ): ĠExpression ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( expression Ġis ĠPsi Reference Expression Ġ&& Ġexpression . get Qualifier () Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġreplacement Ġ= Ġparameter Usage Replacement Map [ expression . getReference Name ()] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( replacement Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Ġ= Ġexpression . getReference ()?. resolve () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( target Ġis ĠPsi Parameter ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġscope Ġ= Ġtarget . get Declaration Scope () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġdo Ġnot Ġcheck Ġfor Ġexactly Ġthis Ġconstructor Ġbecause Ġdefault Ġvalues Ġreference Ġparameters Ġin Ġother Ġconstructors ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scope . is Constructor () Ġ&& Ġscope . getParent () Ġ== Ġpsi Class ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠIdentifier ( replacement , Ġcode Converter . type Converter . variable Null ability ( target ). is Nullable ( code Converter . settings )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ