@@ -73,6 +73,36 @@ export class ServerDownloader {
7373
7474 status . update ( `Initializing ${ this . displayName } ...` ) ;
7575 }
76+
77+ /**
78+ * Checks if there are any duplicate libraries caused by an invalid language
79+ * server update by an older version of the extension, that would require
80+ * the server to be reinstalled.
81+ *
82+ * See https://github.com/fwcd/vscode-kotlin/issues/119#issuecomment-1567203029.
83+ */
84+ private async checkIfInstallationIsCorrupt ( ) : Promise < string | null > {
85+ if ( ! ( await fsExists ( this . installDir ) ) ) {
86+ // A missing installation is not corrupt, it's just missing
87+ return null ;
88+ }
89+
90+ const libDir = path . join ( this . installDir , this . extractedName , "lib" ) ;
91+ if ( ! ( await fsExists ( libDir ) ) ) {
92+ return `Missing library directory ${ libDir } ` ;
93+ }
94+
95+ const foundLibPrefixes = new Set < string > ( ) ;
96+ for ( const lib of await fs . promises . readdir ( libDir ) ) {
97+ const libPrefix = lib . split ( "-" ) . slice ( 0 , - 1 ) . join ( "-" ) ;
98+ if ( foundLibPrefixes . has ( libPrefix ) ) {
99+ return `The library '${ libPrefix } ' is installed twice, this would cause clashes at runtime` ;
100+ }
101+ foundLibPrefixes . add ( libPrefix ) ;
102+ }
103+
104+ return null ;
105+ }
76106
77107 async downloadServerIfNeeded ( status : Status ) : Promise < void > {
78108 const serverInfo = await this . installedServerInfo ( ) ;
@@ -104,8 +134,13 @@ export class ServerDownloader {
104134 const installedVersion = serverInfoOrDefault . version ;
105135 const serverNeedsUpdate = semver . gt ( latestVersion , installedVersion ) ;
106136 let newVersion = installedVersion ;
137+
138+ const installationCorruptReason = await this . checkIfInstallationIsCorrupt ( ) ;
139+ if ( installationCorruptReason ) {
140+ LOG . warn ( `The ${ this . displayName } installation is corrupt (${ installationCorruptReason } ), the server will be reinstalled...` ) ;
141+ }
107142
108- if ( serverNeedsUpdate ) {
143+ if ( serverNeedsUpdate || installationCorruptReason ) {
109144 const serverAsset = releaseInfo . assets . find ( asset => asset . name === this . assetName ) ;
110145 if ( serverAsset ) {
111146 const downloadUrl = serverAsset . browser_download_url ;
0 commit comments