/* Ċ Ġ* ĠSource ++, Ġthe Ġopen - source Ġlive Ġcoding Ġplatform . Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 2 2 ĠCode B rig , ĠInc . Ċ Ġ* Ċ Ġ* ĠThis Ġprogram Ġis Ġfree Ġsoftware : Ġyou Ġcan Ġredistribute Ġit Ġand / or Ġmodify Ċ Ġ* Ġit Ġunder Ġthe Ġterms Ġof Ġthe ĠGNU ĠAffero ĠGeneral ĠPublic ĠLicense Ġas Ġpublished Ċ Ġ* Ġby Ġthe ĠFree ĠSoftware ĠFoundation , Ġeither Ġversion Ġ 3 Ġof Ġthe ĠLicense , Ġor Ċ Ġ* Ġ( at Ġyour Ġoption ) Ġany Ġlater Ġversion . Ċ Ġ* Ċ Ġ* ĠThis Ġprogram Ġis Ġdistributed Ġin Ġthe Ġhope Ġthat Ġit Ġwill Ġbe Ġuseful , Ċ Ġ* Ġbut ĠWITHOUT ĠANY ĠWARRANTY ; Ġwithout Ġeven Ġthe Ġimplied Ġwarranty Ġof Ċ Ġ* ĠMERCHANTABILITY Ġor ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE . Ġ ĠSee Ġthe Ċ Ġ* ĠGNU ĠAffero ĠGeneral ĠPublic ĠLicense Ġfor Ġmore Ġdetails . Ċ Ġ* Ċ Ġ* ĠYou Ġshould Ġhave Ġreceived Ġa Ġcopy Ġof Ġthe ĠGNU ĠAffero ĠGeneral ĠPublic ĠLicense Ċ Ġ* Ġalong Ġwith Ġthis Ġprogram . Ġ ĠIf Ġnot , Ġsee Ġ< https :// www . gnu . org / licenses />. Ċ Ġ*/ Ċ package Ġs pp . jetbrains . marker . jvm . psi Ċ Ċ import Ġcom . intellij . openapi . application . Application Manager Ċ import Ġcom . intellij . openapi . editor . Editor Ċ import Ġcom . intellij . openapi . editor . Logical Position Ċ import Ġcom . intellij . openapi . util . Text Range Ċ import Ġcom . intellij . psi .* Ċ import Ġcom . intellij . refactor ing . suggest ed . end Offset Ċ import Ġcom . intellij . refactor ing . suggest ed . start Offset Ċ import Ġio . vertx . core . Future Ċ import Ġio . vertx . core . Promise Ċ import Ġio . vertx . core . Vert x Ċ import Ġio . vertx . kotlin . coroutines . await Ċ import Ġio . vertx . kotlin . coroutines . dispatcher Ċ import Ġkotlinx . coroutines . Global Scope Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlinx . coroutines . run Blocking Ċ import Ġorg . jetbrains . u ast . U Method Ċ import Ġorg . jetbrains . u ast . to U Element Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġs pp . jetbrains . marker . source . SourceFile Marker Ċ import Ġs pp . jetbrains . marker . source . mark . api . Method Source Mark Ċ import Ġs pp . jetbrains . marker . source . mark . api . key . Source Key Ċ import Ġs pp . jetbrains . marker . source . mark . in lay . In lay Mark Ċ Ċ /** Ċ Ġ* ĠDetect s Ġthe Ġpresence Ġof Ġlog Ġstatements Ġwithin Ġmethods Ġand Ġsaves Ġlog Ġpatterns . Ċ Ġ* Ċ Ġ* Ġ@ since Ġ 0 . 2 . 0 Ċ Ġ* Ġ@ author Ġ[ Brand on ĠF erg erson ]( mailto : b fer g erson @ apache . org ) Ċ Ġ*/ Ċ class ĠLogger Detector ( val Ġvert x : ĠVert x ) Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġlog Ġ= ĠLoggerFactory . getLogger ( Logger Detector :: class . java ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠLOGGER _ STATE MENTS Ġ= ĠSource Key < List < Detected Logger >> (" LOGGER _ STATE MENTS ") ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠLOGGER _ CLASSES Ġ= Ġset Of ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" org . apache . logging . log 4 j . spi . Abstract Logger ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" ch . qos . log back . classic . Logger ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" org . slf 4 j . Logger " ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠLOGGER _ METHO DS Ġ= Ġset Of ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" trace ", Ġ" debug ", Ġ" info ", Ġ" warn ", Ġ" error " ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Live Log ( editor : ĠEditor , Ġin lay Mark : ĠIn lay Mark , Ġlog Pattern : ĠString , Ġline Location : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// todo : Ġbetter Ġway Ġto Ġhandle Ġlogger Ġdetector Ġwith Ġin lay Ġmarks ĊĠĠĠĠĠĠĠ ĠApplication Manager . getApplication (). run Read Action Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmethod Source Mark Ġ= Ġfind Method Source Mark ( editor , Ġin lay Mark . source File Marker , Ġline Location ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( method Source Mark Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Or Find Logger Statements ( method Source Mark ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlogger Statements Ġ= Ġmethod Source Mark . getUser Data ( LOGGER _ STATE MENTS ) !! Ġas ĠMutable List < Detected Logger > ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger Statements . add ( Detected Logger ( log Pattern , Ġ" live ", Ġline Location )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlogger Statements Ġ= Ġin lay Mark . getUser Data ( LOGGER _ STATE MENTS ) Ġas ĠMutable List ? ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( logger Statements Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin lay Mark . put UserData ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOGGER _ STATE MENTS , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmutable ListOf ( Detected Logger ( log Pattern , Ġ" live ", Ġline Location )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger Statements . add ( Detected Logger ( log Pattern , Ġ" live ", Ġline Location )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġget Or Find Logger Statements ( source Mark : ĠMethod Source Mark ): ĠList < Detected Logger > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlogger Statements Ġ= Ġsource Mark . getUser Data ( LOGGER _ STATE MENTS ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( logger Statements Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . trace (" Found Ġlogger Ġstatements : Ġ$ logger Statements ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger Statements ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġu Method Ġ= Ġsource Mark . get Psi Method (). to U Element () Ġas ĠU Method ? ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( u Method Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfound Logger Statements Ġ= Ġget Or Find Logger Statements ( u Method ). await () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsource Mark . put UserData ( LOGGER _ STATE MENTS , Ġfound Logger Statements ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfound Logger Statements ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ Ġ// todo : Ġpython Ġfunctions Ġdon 't Ġhave ĠU Method ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġempty List () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Or Find Logger Statements ( u Method : ĠU Method ): ĠFuture < List < Detected Logger >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpromise Ġ= ĠPromise . promise < List < Detected Logger >>() ĊĠĠĠĠĠĠĠ ĠGlobal Scope . launch ( vertx . dispatcher ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlogger Statements Ġ= Ġmutable ListOf < Detected Logger >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger Statements . addAll ( determine Logger Statements ( u Method ). await ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( throwable : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpromise . fail ( throwable ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpromise . try Complete ( logger Statements ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġpromise . future () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdetermine Logger Statements ( u Method : ĠU Method ): ĠFuture < List < Detected Logger >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpromise Ġ= ĠPromise . promise < List < Detected Logger >>() ĊĠĠĠĠĠĠĠ Ġval Ġlogger Statements Ġ= Ġmutable ListOf < Detected Logger >() ĊĠĠĠĠĠĠĠ ĠApplication Manager . getApplication (). run Read Action Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġu Method . java Psi . accept ( object Ġ: ĠJava Recursive Element Visitor () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit MethodCall Expression ( expression : ĠPsi MethodCall Expression ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠmethodName Ġ= Ġexpression . method Expression . reference Name ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( methodName Ġ!= Ġnull Ġ&& ĠLOGGER _ METHO DS . contains ( methodName )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresolved Method Ġ= Ġexpression . resolve Method () Ġ?: Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( LOGGER _ CLASSES . contains ( resolved Method . containing Class ?. qualified Name . or Empty ())) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Template Ġ= Ġ( expression . argument List . expressions . first OrNull ()?. run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( this Ġas ? ĠPsi Literal )?. value Ġas ? ĠString ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( log Template Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger Statements . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDet ected Logger ( log Template , ĠmethodName , Ġget LineNumber ( expression ) Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . debug (" Found Ġlog Ġstatement : Ġ$ log Template ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . warn (" No Ġlog Ġtemplate Ġargument Ġavailable Ġfor Ġexpression : Ġ$ expression ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpromise . complete ( logger Statements ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġpromise . future () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget LineNumber ( element : ĠPsi Element , Ġstart : ĠBoolean Ġ= Ġtrue ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdocument Ġ= Ġelement . containing File . view Provider . document ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠPsi Document Manager . getInstance ( element . project ). getDocument ( element . containing File ) ĊĠĠĠĠĠĠĠ Ġval Ġindex Ġ= Ġif Ġ( start ) Ġelement . start Offset Ġelse Ġelement . end Offset ĊĠĠĠĠĠĠĠ Ġif Ġ( index Ġ> Ġ( document ?. text Length Ġ?: Ġ 0 )) Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠ Ġreturn Ġdocument ?. get LineNumber ( index ) Ġ?: Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind Method Source Mark ( editor : ĠEditor , Ġfile Marker : ĠSource File Marker , Ġline : ĠInt ): ĠMethod Source Mark ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġfile Marker . getSource Marks (). find Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġis ĠMethod Source Mark ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . configuration . activate On Keyboard Shortcut ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// + 1 Ġon Ġend Ġoffset Ġso Ġmatch Ġis Ġmade Ġeven Ġright Ġafter Ġmethod Ġend ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinc Text Range Ġ= ĠText Range ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . get Psi Method (). text Range . start Offset , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . get Psi Method (). text Range . end Offset Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinc Text Range . contains ( editor . logical Position To Offset ( Logical Position ( line Ġ- Ġ 1 , Ġ 0 ))) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġas ĠMethod Source Mark ? ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġtodo : Ġdescription . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ since Ġ 0 . 2 . 1 ĊĠĠĠĠ Ġ* Ġ@ author Ġ[ Brand on ĠF erg erson ]( mailto : b fer g erson @ apache . org ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġdata Ġclass ĠDet ected Logger ( ĊĠĠĠĠĠĠĠ Ġval Ġlog Pattern : ĠString , ĊĠĠĠĠĠĠĠ Ġval Ġlevel : ĠString , ĊĠĠĠĠĠĠĠ Ġval Ġline Location : ĠInt ĊĠĠĠ Ġ) Ċ } Ċ