/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 - 2 0 1 9 ĠJetBrains Ġs . r . o . Ġand ĠKotlin ĠProgramming ĠLanguage Ġcontributors . Ċ Ġ* ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe Ġlicense / LICENSE . txt Ġfile . Ċ Ġ*/ Ċ Ċ package Ġorg . jetbrains . kotlin . k apt 3 . base . incremental Ċ Ċ import Ġjava . io . File Ċ import Ġjava . io . Object InputStream Ċ import Ġjava . io . Object OutputStream Ċ import Ġjava . io . Serializable Ċ import Ġjava . lang . IllegalArgumentException Ċ import Ġjava . lang . IllegalStateException Ċ import Ġjava . net . URI Ċ Ċ /** Ċ Ġ* ĠStores Ġtype Ġinformation Ġabout Ġprocessed Ġand Ġgenerated Ġsources . ĠFor Ġ. java Ġfiles Ġa Ġfine - gr ained Ġtype Ġinformation Ċ Ġ* Ġexists Ġi . e Ġwe Ġknow Ġall Ġreferenced Ġtypes . ĠFor Ġ. class Ġfiles Ġwe Ġonly Ġknow Ġwhich Ġtype Ġis Ġdefined Ġin Ġthe Ġ. class Ġfile . Ċ Ġ*/ Ċ class ĠJava Class Cache () Ġ: ĠSerializable Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġsource Cache Ġ= Ġmutable Map Of < URI , ĠJava File Structure >() ĊĊĠĠĠ Ġ/** ĠMap Ġfrom Ġtypes Ġto Ġfiles Ġthey Ġare Ġmentioned Ġin . Ġ*/ ĊĠĠĠ Ġ@ Transient ĊĠĠĠ Ġprivate Ġvar Ġdependency Cache Ġ= Ġmutable Map Of < String , ĠMutable Set < URI >>() ĊĊĠĠĠ Ġ@ Transient ĊĠĠĠ Ġprivate Ġvar Ġnon Trans itive Cache Ġ= Ġmutable Map Of < String , ĠMutable Set < URI >>() ĊĊĠĠĠ Ġfun Ġadd Source Structure ( source Structure : ĠJava File Structure ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsource Cache [ source Structure . source File ] Ġ= Ġsource Structure ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠReturns Ġall Ġtypes Ġdefined Ġin Ġthese Ġfiles . Ġ*/ ĊĠĠĠ Ġfun Ġget Types For Files ( files : ĠCollection < File >): ĠSet < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtypes From Files Ġ= ĠHashSet < String >( files . size ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( file Ġin Ġfiles ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsource Cache [ file . to URI ()] ?. declared Types ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtypes From Files . addAll ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtypes From Files ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġread Object ( input : ĠObject InputStream ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠĠĠĠĠ Ġsource Cache Ġ= Ġinput . read Object () Ġas ĠMutable Map < URI , ĠJava File Structure > ĊĊĠĠĠĠĠĠĠ Ġdependency Cache Ġ= ĠHashMap ( source Cache . size Ġ* Ġ 4 ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( source Info Ġin Ġsource Cache . values ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( source Info Ġ! is ĠSource File Structure ) Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( mention ed Type Ġin Ġsource Info . getM ention ed Types ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdepend ants Ġ= Ġdependency Cache [ mention ed Type ] Ġ?: Ġmutable Set Of () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdepend ants . add ( source Info . source File ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdependency Cache [ mention ed Type ] Ġ= Ġdepend ants ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠT reat Ġreferred Ġconstants Ġas ĠABI Ġdependencies Ġuntil Ġwe Ġstart Ġsupporting Ġper - constant Ġclasspath Ġupdates . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( mention ed Constants Ġin Ġsource Info . getM ention ed Constants (). keys ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdepend ants Ġ= Ġdependency Cache [ mention ed Constants ] Ġ?: Ġmutable Set Of () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdepend ants . add ( source Info . source File ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdependency Cache [ mention ed Constants ] Ġ= Ġdepend ants ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġnon Trans itive Cache Ġ= ĠHashMap ( source Cache . size Ġ* Ġ 2 ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( source Info Ġin Ġsource Cache . values ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( source Info Ġ! is ĠSource File Structure ) Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( private Type Ġin Ġsource Info . get Private Types ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdepend ants Ġ= Ġnon Trans itive Cache [ private Type ] Ġ?: Ġmutable Set Of () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdepend ants . add ( source Info . source File ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnon Trans itive Cache [ private Type ] Ġ= Ġdepend ants ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġwrite Object ( output : ĠObject OutputStream ) Ġ{ ĊĠĠĠĠĠĠĠ Ġoutput . write Object ( source Cache ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġis Already Processed ( source File : ĠURI ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! source File . is Absolute ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġnever Ġwant Ġto Ġprocess Ġnon - absolute ĠURIs , Ġsee Ġhttps :// yout rack . jetbrains . com / issue / KT - 3 3 6 1 7 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( source File . is Opaque ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġnever Ġwant Ġto Ġprocess Ġnon - hierarchical ĠURIs , Ġhttps :// yout rack . jetbrains . com / issue / KT - 3 3 6 1 7 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsource Cache . containsKey ( source File ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalArgumentException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġunable Ġto Ġcreate ĠFile Ġinstance , Ġavoid Ġprocessing Ġthese Ġfiles ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠUsed Ġfor Ġtesting Ġonly . Ġ*/ ĊĠĠĠ Ġinternal Ġfun Ġget Structure ( source File : ĠFile ) Ġ= Ġsource Cache [ source File . to URI ()] ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCompute Ġthe Ġlist Ġof Ġtypes Ġthat Ġare Ġimpact ed Ġby Ġsource Ġchanges Ġi . e Ġ[ Changes . source Changes ] Ġand Ġ[ Changes . dirty Fq Names From Classpath ] ĊĠĠĠĠ Ġ* Ġi . e Ġclasspath Ġchanges . ĠThe Ġsearch Ġis Ġtrans itive , Ġif Ġa Ġfile Ġis Ġimpact ed , Ġall Ġfiles Ġreferencing Ġtypes Ġdefined Ġin Ġthat Ġfile Ġare ĊĠĠĠĠ Ġ* Ġalso Ġconsidered Ġimpact ed . ĠOnly Ġoriginal Ġsources Ġand Ġgenerated Ġsources Ġare Ġreported Ġas Ġimpact ed Ġ( final Ġresult Ġdoes Ġnot Ġcontain ĊĠĠĠĠ Ġ* Ġclasspath Ġtypes ). ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun ĠgetAll Imp acted Types ( changes : ĠChanges ): ĠMutable Set < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġfind Imp acted Types ( changed Type : ĠString , Ġtrans itive Deps : ĠMutable Set < String >, Ġnon Trans itive Deps : ĠMutable Set < String >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdependency Cache [ changed Type ]?. let Ġ{ Ġimpact ed Sources Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimpact ed Sources . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrans itive Deps . addAll ( source Cache . getValue ( it ). declared Types ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnon Trans itive Cache [ changed Type ]?. let Ġ{ Ġimpact ed Sources Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimpact ed Sources . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnon Trans itive Deps . addAll ( source Cache . getValue ( it ). declared Types ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġall Dirty Types Ġ= Ġmutable Set Of < String >() ĊĠĠĠĠĠĠĠ Ġvar Ġcurrent Dirty Types Ġ= Ġget Types For Files ( changes . source Changes ). to Mutable Set () ĊĊĠĠĠĠĠĠĠ Ġchanges . dirty Fq Names From Classpath . forEach Ġ{ Ġclasspath Change Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfind Imp acted Types ( classpath Change , Ġcurrent Dirty Types , Ġall Dirty Types ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġwhile Ġ( current Dirty Types . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Round Ġ= Ġmutable Set Of < String >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( dirty Type Ġin Ġcurrent Dirty Types ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġall Dirty Types . add ( dirty Type ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfind Imp acted Types ( dirty Type , Ġnext Round , Ġall Dirty Types ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Dirty Types Ġ= Ġnext Round . filter To ( HashSet ()) Ġ{ Ġit Ġ! in Ġall Dirty Types Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġall Dirty Types ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġinvalidate All () Ġ{ ĊĠĠĠĠĠĠĠ Ġsource Cache . clear () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Source ForType ( type : ĠString ): ĠFile Ġ{ ĊĠĠĠĠĠĠĠ Ġsource Cache . forEach Ġ{ Ġ( file Uri , Ġtype Info ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( type Ġin Ġtype Info . declared Types ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠFile ( file Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Unable Ġto Ġfind Ġsource Ġfile Ġfor Ġtype Ġ$ type ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġinvalidate Data For Types ( imp acted Types : ĠMutable Set < String >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġall Sources Ġ= Ġmutable Set Of < URI >() ĊĠĠĠĠĠĠĠ Ġsource Cache . forEach Ġ{ Ġ( file Uri , Ġtype Info ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( type Info . declared Types . any Ġ{ Ġit Ġin Ġimpact ed Types Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġall Sources . add ( file Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġall Sources . forEach Ġ{ Ġsource Cache . remove ( it ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠReturns Ġtotal Ġnumber Ġof Ġdeclared Ġtypes Ġin Ġ. java Ġsource Ġfiles Ġthat Ġwere Ġprocessed . Ġ*/ ĊĠĠĠ Ġfun Ġget SourceFile Defined Types Count (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsource Cache . values . sum Of Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstructure Ġ= Ġit Ġas ? ĠSource File Structure Ġ?: Ġreturn @ sum Of Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( structure . declared Types . size Ġ== Ġ 1 Ġ&& Ġstructure . declared Types . single () Ġ== Ġ" error . Non Ex istent Class ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnever Ġreport Ġpackage Ġfor Ġerror . Non Ex istent Class , Ġas Ġit Ġis Ġnever Ġcompiled Ġby Ġjav ac / kotlin c ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ sum Of Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ sum Of Ġstructure . declared Types . size ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } ĊĊ Ċ private Ġval ĠIG NORE _ TYPES Ġ= Ġ{ Ġname : ĠString Ġ-> Ġname Ġ== Ġ" java . lang . Object " Ġ} Ċ Ċ interface ĠJava File Structure Ġ{ ĊĠĠĠ Ġval Ġsource File : ĠURI ĊĠĠĠ Ġval Ġdeclared Types : ĠSet < String > Ċ } Ċ Ċ class ĠClass File Structure ( ĊĠĠĠ Ġoverride Ġval Ġsource File : ĠURI , ĊĠĠĠ Ġdeclared Type : ĠString Ċ ) Ġ: ĠJava File Structure , ĠSerializable Ġ{ ĊĠĠĠ Ġoverride Ġval Ġdeclared Types : ĠSet < String > Ġ= Ġset Of ( declared Type ) Ċ } Ċ Ċ class ĠSource File Structure ( ĊĠĠĠ Ġoverride Ġval Ġsource File : ĠURI Ċ ) Ġ: ĠJava File Structure , ĠSerializable Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġ_ declared Types : ĠMutable Set < String > Ġ= Ġmutable Set Of () ĊĊĠĠĠ Ġprivate Ġval Ġmentioned Types : ĠMutable Set < String > Ġ= Ġmutable Set Of () ĊĠĠĠ Ġprivate Ġval Ġprivate Types : ĠMutable Set < String > Ġ= Ġmutable Set Of () ĊĊĠĠĠ Ġprivate Ġval Ġmentioned Annotations : ĠMutable Set < String > Ġ= Ġmutable Set Of () ĊĠĠĠ Ġprivate Ġval Ġmentioned Constants : ĠMutable Map < String , ĠMutable Set < String >> Ġ= Ġmutable Map Of () ĊĊĠĠĠ Ġoverride Ġval Ġdeclared Types : ĠSet < String > Ġ= Ġ_ declared Types ĊĠĠĠ Ġfun Ġget Mention ed Types (): ĠSet < String > Ġ= Ġmentioned Types ĊĠĠĠ Ġfun Ġget Private Types (): ĠSet < String > Ġ= Ġprivate Types ĊĠĠĠ Ġfun Ġget Mention ed Annotations (): ĠSet < String > Ġ= Ġmentioned Annotations ĊĠĠĠ Ġfun Ġget Mention ed Constants (): ĠMap < String , ĠSet < String >> Ġ= Ġmentioned Constants ĊĊĠĠĠ Ġfun Ġadd Declared Type ( declared Type : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ_ declared Types . add ( declared Type ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Mention ed Type ( mention ed Type : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmentioned Type . take Unless ( IGNORE _ TYPES )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmentioned Types . add ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Mention ed Annotations ( name : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmentioned Annotations . add ( name ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Private Type ( name : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Types . add ( name ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Mention ed Constant ( containing Class : ĠString , Ġname : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! declared Types . contains ( containing Class )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmentioned Constants . get Or Put ( containing Class ) Ġ{ ĠHashSet () Ġ}. add ( name ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } ĊĊ Ċ class ĠChanges ( val Ġsource Changes : ĠCollection < File >, Ġval Ġdirty Fq Names From Classpath : ĠSet < String >)