@@ -8,8 +8,8 @@ import { satisfies } from 'semver';
88import { PlatformInformation } from '../platform' ;
99import * as path from 'path' ;
1010import * as vscode from 'vscode' ;
11- import * as util from '../common' ;
1211import { Options } from './options' ;
12+ import { LaunchInfo } from './OmnisharpManager' ;
1313
1414export enum LaunchTargetKind {
1515 Solution ,
@@ -201,12 +201,12 @@ function isCake(resource: vscode.Uri): boolean {
201201export interface LaunchResult {
202202 process : ChildProcess ;
203203 command : string ;
204- usingMono : boolean ;
204+ monoVersion ?: string ;
205205}
206206
207- export async function launchOmniSharp ( cwd : string , args : string [ ] , launchPath : string ) : Promise < LaunchResult > {
207+ export async function launchOmniSharp ( cwd : string , args : string [ ] , launchInfo : LaunchInfo ) : Promise < LaunchResult > {
208208 return new Promise < LaunchResult > ( ( resolve , reject ) => {
209- launch ( cwd , args , launchPath )
209+ launch ( cwd , args , launchInfo )
210210 . then ( result => {
211211 // async error - when target not not ENEOT
212212 result . process . on ( 'error' , err => {
@@ -222,50 +222,42 @@ export async function launchOmniSharp(cwd: string, args: string[], launchPath: s
222222 } ) ;
223223}
224224
225- async function launch ( cwd : string , args : string [ ] , launchPath : string ) : Promise < LaunchResult > {
226- return PlatformInformation . GetCurrent ( ) . then ( platformInfo => {
227- const options = Options . Read ( ) ;
228-
229- if ( options . useEditorFormattingSettings ) {
230- let globalConfig = vscode . workspace . getConfiguration ( ) ;
231- let csharpConfig = vscode . workspace . getConfiguration ( '[csharp]' ) ;
225+ async function launch ( cwd : string , args : string [ ] , launchInfo : LaunchInfo ) : Promise < LaunchResult > {
226+ const platformInfo = await PlatformInformation . GetCurrent ( ) ;
227+ const options = Options . Read ( ) ;
232228
233- args . push ( `formattingOptions:useTabs=${ ! getConfigurationValue ( globalConfig , csharpConfig , 'editor.insertSpaces' , true ) } ` ) ;
234- args . push ( `formattingOptions:tabSize=${ getConfigurationValue ( globalConfig , csharpConfig , 'editor.tabSize' , 4 ) } ` ) ;
235- args . push ( `formattingOptions:indentationSize=${ getConfigurationValue ( globalConfig , csharpConfig , 'editor.tabSize' , 4 ) } ` ) ;
236- }
229+ if ( options . useEditorFormattingSettings ) {
230+ let globalConfig = vscode . workspace . getConfiguration ( ) ;
231+ let csharpConfig = vscode . workspace . getConfiguration ( '[csharp]' ) ;
237232
238- // If the user has provided an absolute path or the specified version has been installed successfully, we'll use the path.
239- if ( launchPath ) {
240- if ( platformInfo . isWindows ( ) ) {
241- return launchWindows ( launchPath , cwd , args ) ;
242- }
233+ args . push ( `formattingOptions:useTabs=${ ! getConfigurationValue ( globalConfig , csharpConfig , 'editor.insertSpaces' , true ) } ` ) ;
234+ args . push ( `formattingOptions:tabSize=${ getConfigurationValue ( globalConfig , csharpConfig , 'editor.tabSize' , 4 ) } ` ) ;
235+ args . push ( `formattingOptions:indentationSize=${ getConfigurationValue ( globalConfig , csharpConfig , 'editor.tabSize' , 4 ) } ` ) ;
236+ }
243237
244- // If we're launching on macOS/Linux, we have two possibilities:
245- // 1. Launch using Mono
246- // 2. Launch process directly (e.g. a 'run' script)
247- return options . useMono
248- ? launchNixMono ( launchPath , cwd , args )
249- : launchNix ( launchPath , cwd , args ) ;
250- }
238+ if ( platformInfo . isWindows ( ) ) {
239+ return launchWindows ( launchInfo . LaunchPath , cwd , args ) ;
240+ }
251241
252- // If the user has not provided a path, we'll use the locally-installed OmniSharp
253- const basePath = path . resolve ( util . getExtensionPath ( ) , '.omnisharp ' ) ;
242+ let monoVersion = await getMonoVersion ( ) ;
243+ let isValidMonoAvailable = await satisfies ( monoVersion , '>=5.2.0 ' ) ;
254244
255- if ( platformInfo . isWindows ( ) ) {
256- return launchWindows ( path . join ( basePath , 'OmniSharp.exe' ) , cwd , args ) ;
245+ // If the user specifically said that they wanted to launch on Mono, respect their wishes.
246+ if ( options . useMono ) {
247+ if ( ! isValidMonoAvailable ) {
248+ throw new Error ( 'Cannot start OmniSharp because Mono version >=5.2.0 is required.' ) ;
257249 }
258250
259- // If it's possible to launch on a global Mono, we'll do that. Otherwise, run with our
260- // locally installed Mono runtime.
261- return canLaunchMono ( )
262- . then ( async ( ) => {
263- return launchNixMono ( path . join ( basePath , 'omnisharp' , 'OmniSharp.exe' ) , cwd , args ) ;
264- } )
265- . catch ( _ => {
266- return launchNix ( path . join ( basePath , 'run' ) , cwd , args ) ;
267- } ) ;
268- } ) ;
251+ return launchNixMono ( launchInfo . LaunchPath , monoVersion , cwd , args ) ;
252+ }
253+
254+ // If we can launch on the global Mono, do so; otherwise, launch directly;
255+ if ( isValidMonoAvailable && launchInfo . MonoLaunchPath ) {
256+ return launchNixMono ( launchInfo . MonoLaunchPath , monoVersion , cwd , args ) ;
257+ }
258+ else {
259+ return launchNix ( launchInfo . LaunchPath , cwd , args ) ;
260+ }
269261}
270262
271263function getConfigurationValue ( globalConfig : vscode . WorkspaceConfiguration , csharpConfig : vscode . WorkspaceConfiguration ,
@@ -303,7 +295,6 @@ function launchWindows(launchPath: string, cwd: string, args: string[]): LaunchR
303295 return {
304296 process,
305297 command : launchPath ,
306- usingMono : false
307298 } ;
308299}
309300
@@ -315,58 +306,41 @@ function launchNix(launchPath: string, cwd: string, args: string[]): LaunchResul
315306
316307 return {
317308 process,
318- command : launchPath ,
319- usingMono : true
309+ command : launchPath
320310 } ;
321311}
322312
323- async function launchNixMono ( launchPath : string , cwd : string , args : string [ ] ) : Promise < LaunchResult > {
324- return canLaunchMono ( )
325- . then ( ( ) => {
326- let argsCopy = args . slice ( 0 ) ; // create copy of details args
327- argsCopy . unshift ( launchPath ) ;
328- argsCopy . unshift ( "--assembly-loader=strict" ) ;
329-
330- let process = spawn ( 'mono' , argsCopy , {
331- detached : false ,
332- cwd : cwd
333- } ) ;
334-
335- return {
336- process,
337- command : launchPath ,
338- usingMono : true
339- } ;
340- } ) ;
341- }
313+ function launchNixMono ( launchPath : string , monoVersion : string , cwd : string , args : string [ ] ) : LaunchResult {
314+ let argsCopy = args . slice ( 0 ) ; // create copy of details args
315+ argsCopy . unshift ( launchPath ) ;
316+ argsCopy . unshift ( "--assembly-loader=strict" ) ;
342317
343- async function canLaunchMono ( ) : Promise < void > {
344- return new Promise < void > ( ( resolve , reject ) => {
345- hasMono ( '>=5.2.0' ) . then ( success => {
346- if ( success ) {
347- resolve ( ) ;
348- }
349- else {
350- reject ( new Error ( 'Cannot start Omnisharp because Mono version >=5.2.0 is required.' ) ) ;
351- }
352- } ) ;
318+ let process = spawn ( 'mono' , argsCopy , {
319+ detached : false ,
320+ cwd : cwd
353321 } ) ;
322+
323+ return {
324+ process,
325+ command : launchPath ,
326+ monoVersion,
327+ } ;
354328}
355329
356- export async function hasMono ( range ?: string ) : Promise < boolean > {
330+ async function getMonoVersion ( ) : Promise < string > {
357331 const versionRegexp = / ( \d + \. \d + \. \d + ) / ;
358332
359- return new Promise < boolean > ( ( resolve , reject ) => {
333+ return new Promise < string > ( ( resolve , reject ) => {
360334 let childprocess : ChildProcess ;
361335 try {
362336 childprocess = spawn ( 'mono' , [ '--version' ] ) ;
363337 }
364338 catch ( e ) {
365- return resolve ( false ) ;
339+ return resolve ( undefined ) ;
366340 }
367341
368342 childprocess . on ( 'error' , function ( err : any ) {
369- resolve ( false ) ;
343+ resolve ( undefined ) ;
370344 } ) ;
371345
372346 let stdout = '' ;
@@ -375,20 +349,14 @@ export async function hasMono(range?: string): Promise<boolean> {
375349 } ) ;
376350
377351 childprocess . stdout . on ( 'close' , ( ) => {
378- let match = versionRegexp . exec ( stdout ) ,
379- ret : boolean ;
352+ let match = versionRegexp . exec ( stdout ) ;
380353
381- if ( ! match ) {
382- ret = false ;
383- }
384- else if ( ! range ) {
385- ret = true ;
354+ if ( match && match . length > 1 ) {
355+ resolve ( match [ 1 ] ) ;
386356 }
387357 else {
388- ret = satisfies ( match [ 1 ] , range ) ;
358+ resolve ( undefined ) ;
389359 }
390-
391- resolve ( ret ) ;
392360 } ) ;
393361 } ) ;
394362}
0 commit comments