// ĠCopyright Ġ 2 0 0 0 - 2 0 1 8 Ġ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 . code Insight . completion Ċ Ċ import Ġcom . google . common . annotations . Visible ForTesting Ċ import Ġcom . intellij . code Insight . lookup . Lookup Ċ import Ġcom . intellij . code Insight . lookup . Lookup Element Ċ import Ġcom . intellij . code Insight . lookup . Lookup Event Ċ import Ġcom . intellij . feature Statistics . Feature Usage Tracker Ċ import Ġcom . intellij . feature Statistics . Feature Usage Tracker Impl Ċ import Ġcom . intellij . openapi . Disposable Ċ import Ġcom . intellij . openapi . application . Application Manager Ċ import Ġcom . intellij . openapi . editor . event . Document Event Ċ import Ġcom . intellij . openapi . editor . event . Document Listener Ċ import Ġcom . intellij . openapi . util . Dis poser Ċ import Ġcom . intellij . openapi . util . text . StringUtil Ċ import Ġcom . intellij . psi . statistics . Statistics Info Ċ import Ġcom . intellij . util . Alarm Ċ Ċ /** Ċ Ġ* Ġ@ author Ġp eter Ċ Ġ*/ Ċ class ĠStatistics Update ĊĠĠĠ Ġprivate Ġconstructor ( private Ġval Ġmy Info : ĠStatistics Info ) Ġ: ĠDis posable Ġ{ ĊĠ Ġprivate Ġvar Ġmy Sp ared : ĠInt Ġ= Ġ 0 ĊĊĠ Ġoverride Ġfun Ġdispose () Ġ{} ĊĊĠ Ġfun Ġadd Sp ared Chars ( lookup : ĠLookup , Ġitem : ĠLookup Element , Ġcontext : ĠInsert ion Context ) Ġ{ ĊĠĠĠ Ġval Ġtext Inserted : ĠString ĊĠĠĠ Ġif Ġ( context . offset Map . contains Offset ( Completion Initialization Context . START _ OFFSET ) Ġ&& ĊĠĠĠĠĠĠĠ Ġcontext . offset Map . contains Offset ( Insertion Context . TAIL _ OFFSET ) Ġ&& ĊĠĠĠĠĠĠĠ Ġcontext . tail Offset Ġ>= Ġcontext . start Offset ) Ġ{ ĊĠĠĠĠĠ Ġtext Inserted Ġ= Ġcontext . document . immutable CharSequence . sub Sequence ( context . start Offset , Ġcontext . tail Offset ). toString () ĊĠĠĠ Ġ} ĊĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠ Ġtext Inserted Ġ= Ġitem . lookup String ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġwithout Spaces Ġ= ĠString Util . replace ( text Inserted , ĠlistOf (" Ġ", Ġ"\ t ", Ġ"\ n "), ĠlistOf ("", Ġ"", Ġ"")) ĊĠĠĠ Ġvar Ġsp ared Ġ= Ġwithout Spaces . length Ġ- Ġlookup . item Pattern ( item ). length ĊĠĠĠ Ġval Ġcompletion Char Ġ= Ġcontext . completion Char ĊĠĠĠ Ġif Ġ(! Lookup Event . is Special Completion Char ( completion Char ) Ġ&& Ġwithout Spaces . contains ( completion Char . toString ())) Ġ{ ĊĠĠĠĠĠ Ġsp ared -- ĊĠĠĠ Ġ} ĊĠĠĠ Ġif Ġ( sp ared Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠ Ġmy Sp ared Ġ+= Ġsp ared ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġtrack Statistics ( context : ĠInsert ion Context ) Ġ{ ĊĠĠĠ Ġif Ġ( our Pending Update Ġ!== Ġthis ) Ġ{ ĊĠĠĠĠĠ Ġreturn ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ(! context . offset Map . contains Offset ( Completion Initialization Context . START _ OFFSET )) Ġ{ ĊĠĠĠĠĠ Ġreturn ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġdocument Ġ= Ġcontext . document ĊĠĠĠ Ġval Ġstart Offset Ġ= Ġcontext . start Offset ĊĠĠĠ Ġval Ġtail Offset Ġ= ĊĠĠĠĠĠ Ġif Ġ( context . editor . selection Model . has Selection ()) Ġcontext . editor . selection Model . selection Start ĊĠĠĠĠĠ Ġelse Ġcontext . editor . caret Model . offset ĊĠĠĠ Ġif Ġ( start Offset Ġ< Ġ 0 Ġ|| Ġtail Offset Ġ<= Ġstart Offset ) Ġ{ ĊĠĠĠĠĠ Ġreturn ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġmarker Ġ= Ġdocument . create Range Marker ( start Offset , Ġtail Offset ) ĊĠĠĠ Ġval Ġlistener Ġ= Ġobject Ġ: ĠDocument Listener Ġ{ ĊĠĠĠĠĠ Ġoverride Ġfun Ġbefore Document Change ( e : ĠDocument Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! marker . isValid Ġ|| Ġe . offset Ġ> Ġmarker . start Offset Ġ&& Ġe . offset Ġ< Ġmarker . end Offset ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġcancel Last Completion Statistics Update () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġour Stats Alarm . add Request ({ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( our Pending Update Ġ=== Ġthis ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapply Last Completion Statistics Update () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, Ġ 2 0 Ġ* Ġ 1 0 0 0 ) ĊĊĠĠĠ Ġdocument . add Document Listener ( listener ) ĊĠĠĠ ĠDis poser . register ( this , ĠDis posable Ġ{ ĊĠĠĠĠĠ Ġdocument . remove Document Listener ( listener ) ĊĠĠĠĠĠ Ġmarker . dispose () ĊĠĠĠĠĠ Ġour Stats Alarm . cancel All Requests () ĊĠĠĠ Ġ}) ĊĠ Ġ} ĊĊĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠ Ġprivate Ġval Ġour Stats Alarm Ġ= ĠAlarm ( Application Manager . getApplication ()) ĊĠĠĠ Ġprivate Ġvar Ġour Pending Update : ĠStatistics Update ? Ġ= Ġnull ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠ ĠDis poser . register ( Application Manager . getApplication (), ĠDis posable Ġ{ Ġcancel Last Completion Statistics Update () Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġfun Ġcollect Statistic Changes ( item : ĠLookup Element ): ĠStatistics Update Ġ{ ĊĠĠĠĠĠ Ġapply Last Completion Statistics Update () ĊĊĠĠĠĠĠ Ġval Ġbase Ġ= ĠStatistics We igh er . getBase Statistics Info ( item , Ġnull ) ĊĠĠĠĠĠ Ġif Ġ( base Ġ=== ĠStatistics Info . EMPTY ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠStatistics Update ( Statistics Info . EMPTY ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġval Ġupdate Ġ= ĠStatistics Update ( base ) ĊĠĠĠĠĠ Ġour Pending Update Ġ= Ġupdate ĊĠĠĠĠĠ ĠDis poser . register ( update , ĠDis posable Ġ{ Ġour Pending Update Ġ= Ġnull Ġ}) ĊĊĠĠĠĠĠ Ġreturn Ġupdate ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġfun Ġcancel Last Completion Statistics Update () Ġ{ ĊĠĠĠĠĠ Ġour Pending Update ?. let Ġ{ ĠDis poser . dispose ( it ) Ġ} ĊĠĠĠĠĠ Ġassert ( our Pending Update Ġ== Ġnull ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġfun Ġapply Last Completion Statistics Update () Ġ{ ĊĠĠĠĠĠ Ġour Pending Update ?. let Ġ{ ĊĠĠĠĠĠĠĠ Ġit . my Info . inc Use Count () ĊĠĠĠĠĠĠĠ Ġ( Feature Usage Tracker . getInstance () Ġas ĠFeature Usage Tracker Impl ). completion Statistics . register Invocation ( it . my Sp ared ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġcancel Last Completion Statistics Update () ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ