@@ -31,6 +31,7 @@ import { alsCommandExecutor } from './alsExecuteCommand';
3131import GnatTaskProvider , { getEnclosingSymbol } from './gnatTaskProvider' ;
3232import GprTaskProvider from './gprTaskProvider' ;
3333import { getEvaluatedCustomEnv } from './helpers' ;
34+ import { existsSync } from 'fs' ;
3435
3536export let contextClients : ContextClients ;
3637export let mainLogChannel : vscode . OutputChannel ;
@@ -114,6 +115,8 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
114115 mainLogChannel = vscode . window . createOutputChannel ( 'Ada Extension' ) ;
115116 mainLogChannel . appendLine ( 'Starting Ada extension' ) ;
116117
118+ assertSupportedEnvironments ( ) ;
119+
117120 context . subscriptions . push (
118121 vscode . commands . registerCommand ( 'ada.showExtensionOutput' , ( ) => mainLogChannel . show ( ) )
119122 ) ;
@@ -182,8 +185,38 @@ function createClient(
182185 extra : string [ ] ,
183186 pattern : string
184187) {
185- let serverModule = context . asAbsolutePath ( process . platform + '/ada_language_server' ) ;
186- if ( process . env . ALS ) serverModule = process . env . ALS ;
188+ let serverExecPath : string ;
189+
190+ if ( process . arch == 'arm64' && process . platform == 'darwin' ) {
191+ // On arm64 darwin use the x64 darwin executable thanks to Apple Rosetta.
192+ serverExecPath = context . asAbsolutePath ( `x64/darwin/ada_language_server` ) ;
193+ } else {
194+ serverExecPath = context . asAbsolutePath (
195+ `${ process . arch } /${ process . platform } /ada_language_server`
196+ ) ;
197+ }
198+
199+ // If the ALS environment variable is specified, use it as the path of the
200+ // server executable.
201+ if ( process . env . ALS ) {
202+ serverExecPath = process . env . ALS ;
203+ if ( ! existsSync ( serverExecPath ) ) {
204+ logErrorAndThrow (
205+ `The Ada language server given in the ALS environment ` +
206+ `variable does not exist: ${ serverExecPath } `
207+ ) ;
208+ }
209+ } else {
210+ if ( ! existsSync ( serverExecPath ) ) {
211+ logErrorAndThrow (
212+ `This installation of the Ada extension does not have the Ada ` +
213+ `language server for your architecture (${ process . arch } ) ` +
214+ `and platform (${ process . platform } ) ` +
215+ `at the expected location: ${ serverExecPath } `
216+ ) ;
217+ }
218+ }
219+
187220 // The debug options for the server
188221 // let debugOptions = { execArgv: [] };
189222 // If the extension is launched in debug mode then the debug server options are used
@@ -203,8 +236,8 @@ function createClient(
203236
204237 // Options to control the server
205238 const serverOptions : ServerOptions = {
206- run : { command : serverModule , args : extra } ,
207- debug : { command : serverModule , args : extra } ,
239+ run : { command : serverExecPath , args : extra } ,
240+ debug : { command : serverExecPath , args : extra } ,
208241 } ;
209242
210243 // Options to control the language client
@@ -352,3 +385,32 @@ async function checkSrcDirectories(alsClient: LanguageClient) {
352385 } ) ;
353386 }
354387}
388+
389+ function assertSupportedEnvironments ( ) {
390+ type Env = {
391+ arch : 'arm' | 'arm64' | 'x64' ;
392+ platform : 'win32' | 'linux' | 'darwin' ;
393+ } ;
394+ const supportedEnvs : Env [ ] = [
395+ { arch : 'x64' , platform : 'linux' } ,
396+ { arch : 'x64' , platform : 'win32' } ,
397+ { arch : 'x64' , platform : 'darwin' } ,
398+ { arch : 'arm64' , platform : 'darwin' } ,
399+ ] ;
400+
401+ if (
402+ ! supportedEnvs . some ( ( val ) => {
403+ return val . arch == process . arch && val . platform == process . platform ;
404+ } )
405+ ) {
406+ const msg =
407+ `The Ada extension is not supported on ` +
408+ `architecture '${ process . arch } ' and platform '${ process . platform } '` ;
409+ logErrorAndThrow ( msg ) ;
410+ }
411+ }
412+
413+ function logErrorAndThrow ( msg : string ) {
414+ mainLogChannel . appendLine ( '[Error] ' + msg ) ;
415+ throw new Error ( msg ) ;
416+ }
0 commit comments