Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc339e26

Browse files
committed
Add some basic UI to help configure FSI for script debugging
closesdotnet#314commit3ad1b86Author: latkin <latkin@microsoft.com>Date: Fri Mar 20 09:26:45 2015 -0700 Use different dialog box API for VS 2013/2015+commit07d5abdAuthor: latkin <latkin@microsoft.com>Date: Thu Mar 19 17:33:55 2015 -0700 Use warning dialog that can be suppressedcommit3bf5251Author: latkin <latkin@microsoft.com>Date: Thu Mar 19 12:32:29 2015 -0700 Update warning dialog textcommit9a51b9eAuthor: latkin <latkin@microsoft.com>Date: Wed Mar 18 17:37:12 2015 -0700 Add some basic UI to help configure FSI for script debugging
1 parentf8ba1dd commitc339e26

File tree

7 files changed

+153
-9
lines changed

7 files changed

+153
-9
lines changed

‎vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/Properties.resx‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@
128128
<value>F# Interactive options</value>
129129
</data>
130130
<dataname="FSharpInteractiveOptionsDescr"xml:space="preserve">
131-
<value>The command line arguments passed to the F# Interactive executable by Visual Studio.</value>
131+
<value>Additional command line arguments passed to the F# Interactive executable by Visual Studio. (optimization and debug flags are ignored if script debugging is enabled)</value>
132132
</data>
133133
<dataname="FSharpInteractiveMisc"xml:space="preserve">
134134
<value>Misc</value>
@@ -139,4 +139,13 @@
139139
<dataname="FSharpInteractiveShadowCopyDescr"xml:space="preserve">
140140
<value>Prevents referenced assemblies from being locked by the F# Interactive process.</value>
141141
</data>
142+
<dataname="FSharpInteractiveDebugMode"xml:space="preserve">
143+
<value>Enable script debugging</value>
144+
</data>
145+
<dataname="FSharpInteractiveDebugModeDescr"xml:space="preserve">
146+
<value>Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive)</value>
147+
</data>
148+
<dataname="FSharpInteractiveDebugging"xml:space="preserve">
149+
<value>Debugging</value>
150+
</data>
142151
</root>

‎vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/VFSIstrings.txt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ sessionTerminationDetected,"Session termination detected. Press Enter to restart
88
fsharpInteractive,"F# Interactive"
99
couldNotFindFsiExe,"Could not find fsi.exe, the F# Interactive executable.\nThis file does not exist:\n\n%s\n"
1010
killingProcessRaisedException,"Killing process raised exception:\n%s"
11+
sessionIsNotDebugFriendly,"The current F# Interactive session is not configured for debugging. For the best experience, enable debugging in F# Interactive settings, then reset the session.\n\nAttempt debugging with current settings?"
12+
doNotShowWarningInFuture,"Don't show this warning again"

‎vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/fsiBasis.fs‎

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ open System
2121
openSystem.IO
2222
openSystem.Diagnostics
2323
openSystem.Globalization
24+
openSystem.Text.RegularExpressions
2425
openSystem.Windows.Forms
2526
openSystem.Runtime.InteropServices
2627
openSystem.ComponentModel.Design
@@ -103,7 +104,51 @@ module internal Util =
103104
letthrowOnFailure2(res,a,b)= Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure res|> ignore;(a,b)
104105
letthrowOnFailure3(res,a,b,c)= Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure res|> ignore;(a,b,c)
105106
letthrowOnFailure4(res,a,b,c,d)= Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure res|> ignore;(a,b,c,d)
106-
107+
108+
moduleRegistryHelpers=
109+
/// returns Some(value) if key/value exists, None otherwise
110+
lettryReadHKCU<'t>subkey valueName=
111+
use key= Registry.CurrentUser.OpenSubKey(subkey)
112+
if key=nullthen Noneelse
113+
match key.GetValue(valueName)with
114+
|:? 'tas valTyped-> Some(valTyped)
115+
|_-> None
116+
117+
/// write value to HKCU subkey, uses default .NET/registry type conversions
118+
letwriteHKCU subkey valueName value=
119+
use key= Registry.CurrentUser.OpenSubKey(subkey,true)
120+
key.SetValue(valueName, value)
121+
122+
moduleArgParsing=
123+
letprivatelastIndexOfPattern s patt=
124+
letpatt'= sprintf@"(\s|^)%s(\s|$)" patt
125+
match Regex.Matches(s, patt')|> Seq.cast<Match>|> Seq.tryLastwith
126+
| None->-1
127+
| Some(m)-> m.Index
128+
129+
/// checks if combined arg string results in debug info on/off
130+
letdebugInfoEnabled(args:string)=
131+
// FSI default is --debug:pdbonly, so disabling must be explicit
132+
match lastIndexOfPattern args@"(--|/)debug-"with
133+
|-1->true
134+
| idxDisabled->
135+
// check if it's enabled by later args
136+
letafterDisabled= args.Substring(idxDisabled+5)
137+
letidxEnabled=
138+
[lastIndexOfPattern afterDisabled@"(--|/)debug(\+|:full|:pdbonly)?"
139+
lastIndexOfPattern afterDisabled@"(--|/)g"]|> List.max
140+
idxEnabled> idxDisabled
141+
142+
/// checks if combined arg string results in optimizations on/off
143+
letoptimizationsEnabled(args:string)=
144+
// FSI default is --optimize+, so disabling must be explicit
145+
match lastIndexOfPattern args@"(--|/)optimize-"with
146+
|-1->true
147+
| idxDisabled->
148+
// check if it's enabled by later args
149+
letafterDisabled= args.Substring(idxDisabled+5)
150+
letidxEnabled= lastIndexOfPattern afterDisabled@"(--|/)optimize\+?"
151+
idxEnabled> idxDisabled
107152

108153
// History buffer.
109154
// For now, follows the cmd.exe model.

‎vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/fsiLanguageService.fs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@ module SP = Microsoft.VisualStudio.FSharp.Interactive.Session.SessionsProperties
3232
[<Guid("4489e9de-6ac1-3cd6-bff8-a904fd0e82d4")>]
3333
typeFsiPropertyPage()=
3434
inherit DialogPage()
35+
3536
[<SRProperties.Category(SRProperties.FSharpInteractiveMisc)>]
3637
[<SRProperties.DisplayName(SRProperties.FSharpInteractive64Bit)>]
3738
[<SRProperties.Description(SRProperties.FSharpInteractive64BitDescr)>]
3839
memberthis.FsiPreferAnyCPUVersionwith get()= SP.useAnyCpuVersionandset(x:bool)= SP.useAnyCpuVersion<- x
40+
3941
[<SRProperties.Category(SRProperties.FSharpInteractiveMisc)>]
4042
[<SRProperties.DisplayName(SRProperties.FSharpInteractiveOptions)>]
4143
[<SRProperties.Description(SRProperties.FSharpInteractiveOptionsDescr)>]
@@ -45,6 +47,12 @@ type FsiPropertyPage() =
4547
[<SRProperties.DisplayName(SRProperties.FSharpInteractiveShadowCopy)>]
4648
[<SRProperties.Description(SRProperties.FSharpInteractiveShadowCopyDescr)>]
4749
memberthis.FsiShadowCopywith get()= SP.fsiShadowCopyandset(x:bool)= SP.fsiShadowCopy<- x
50+
51+
[<SRProperties.Category(SRProperties.FSharpInteractiveDebugging)>]
52+
[<SRProperties.DisplayName(SRProperties.FSharpInteractiveDebugMode)>]
53+
[<SRProperties.Description(SRProperties.FSharpInteractiveDebugModeDescr)>]
54+
memberthis.FsiDebugModewith get()= SP.fsiDebugModeandset(x:bool)= SP.fsiDebugMode<- x
55+
4856
// CompletionSet
4957
typeinternalFsiCompletionSet(imageList,source:Source)=
5058
inherit CompletionSet(imageList, source)

‎vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/fsiSessionToolWindow.fs‎

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ type internal ITestVFSI =
3535
#nowarn"47"
3636
moduleinternalLocals=
3737
letfsiFontsAndColorsCategory=new Guid("{00CCEE86-3140-4E06-A65A-A92665A40D6F}")
38+
letdefaultVSRegistryRoot=@"Software\Microsoft\VisualStudio\14.0"
39+
letsettingsRegistrySubKey=@"General"
40+
letdebugPromptRegistryValue="FSharpHideScriptDebugWarning"
41+
3842
letfixServerPrompt(str:string)=
3943
// Prompts come through as "SERVER-PROMPT>\n" (when in "server mode").
4044
// In fsi.exe, the newline is needed to get the output send through to VS.
@@ -487,9 +491,52 @@ type internal FsiToolWindow() as this =
487491
|_->()
488492
with_->()
489493

494+
// checks if current session is configured such that debugging will work well
495+
// if not, pops a dialog warning the user
496+
letcheckDebuggability()=
497+
// debug experience is good when optimizations are off and debug info is produced
498+
if ArgParsing.debugInfoEnabled sessions.ProcessArgs&&not(ArgParsing.optimizationsEnabled sessions.ProcessArgs)then
499+
true
500+
else
501+
match RegistryHelpers.tryReadHKCU(defaultVSRegistryRoot+"\\"+ settingsRegistrySubKey) debugPromptRegistryValuewith
502+
| Some(1)->true// warning dialog suppressed
503+
|_->
504+
#if VS_VERSION_DEV12
505+
letresult=
506+
VsShellUtilities.ShowMessageBox(
507+
serviceProvider= provider,
508+
message= VFSIstrings.SR.sessionIsNotDebugFriendly(),
509+
title= VFSIstrings.SR.fsharpInteractive(),
510+
icon= OLEMSGICON.OLEMSGICON_WARNING,
511+
msgButton= OLEMSGBUTTON.OLEMSGBUTTON_YESNO,
512+
defaultButton= OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST
513+
)
514+
515+
// if user picks YES, allow debugging anyways
516+
result=6
517+
518+
#else
519+
let mutablesuppressDiag=false
520+
letresult=
521+
Microsoft.VisualStudio.PlatformUI.MessageDialog.Show(
522+
VFSIstrings.SR.fsharpInteractive(),
523+
VFSIstrings.SR.sessionIsNotDebugFriendly(),
524+
Microsoft.VisualStudio.PlatformUI.MessageDialogCommandSet.YesNo,
525+
VFSIstrings.SR.doNotShowWarningInFuture(),
526+
&suppressDiag
527+
)
528+
529+
if suppressDiag&& result<> Microsoft.VisualStudio.PlatformUI.MessageDialogCommand.Abortthen
530+
RegistryHelpers.writeHKCU(defaultVSRegistryRoot+"\\"+ settingsRegistrySubKey) debugPromptRegistryValue1
531+
532+
// if user picks YES, allow debugging anyways
533+
result= Microsoft.VisualStudio.PlatformUI.MessageDialogCommand.Yes
534+
#endif
535+
490536
letonAttachDebugger(sender:obj)(args:EventArgs)=
491-
attachDebugger()
492-
showNoActivate()
537+
if checkDebuggability()then
538+
attachDebugger()
539+
showNoActivate()
493540

494541
letonDetachDebugger(sender:obj)(args:EventArgs)=
495542
detachDebugger()

‎vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/sessions.fs‎

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ module SessionsProperties =
6666
let mutableuseAnyCpuVersion=false
6767
let mutablefsiArgs="--optimize"
6868
let mutablefsiShadowCopy=true
69+
let mutablefsiDebugMode=false
6970

7071
// This code pre-dates the events/object system.
7172
// Later: Tidy up.
@@ -140,6 +141,7 @@ type Session =
140141
abstractExited :IObservable<EventArgs>
141142
abstractAlive :bool
142143
abstractProcessID :int
144+
abstractProcessArgs :string
143145
abstractKill :unit->unit
144146
#if FSI_SERVER_INTELLISENSE
145147
abstractCompletions :string->string[]
@@ -226,11 +228,26 @@ let fsiStartInfo channelName =
226228
// Send codepage preferences to the FSI.
227229
// We also need to send fsi.exe the locale of the VS process
228230
letinCP,outCP= System.Text.Encoding.UTF8.CodePage,System.Text.Encoding.UTF8.CodePage
229-
letprocArgs= sprintf"--fsi-server-output-codepage:%d --fsi-server-input-codepage:%d --fsi-server-lcid:%d --fsi-server:%s%s" outCP inCP(System.Threading.Thread.CurrentThread.CurrentUICulture.LCID) channelName(!settings).startupFlags
230-
letshadowCopy=
231-
letstate=if SessionsProperties.fsiShadowCopythen"+"else"-"
232-
sprintf"--shadowcopyreferences%s" state
233-
procInfo.Arguments<- procArgs+""+ SessionsProperties.fsiArgs+""+ shadowCopy// procArgs + user settable args
231+
232+
letaddBoolOption name value args= sprintf"%s --%s%s" args name(if valuethen"+"else"-")
233+
letaddStringOption name value args= sprintf"%s --%s:%O" args name value
234+
235+
letprocArgs=
236+
""
237+
|> addStringOption"fsi-server-output-codepage" outCP
238+
|> addStringOption"fsi-server-input-codepage" inCP
239+
|> addStringOption"fsi-server-lcid" System.Threading.Thread.CurrentThread.CurrentUICulture.LCID
240+
|> addStringOption"fsi-server" channelName
241+
|>(+)<| sprintf"%s"(!settings).startupFlags
242+
|>(+)<| sprintf"%s" SessionsProperties.fsiArgs
243+
|> addBoolOption"shadowcopyreferences" SessionsProperties.fsiShadowCopy
244+
|>(fun args->if SessionsProperties.fsiDebugModethen
245+
// for best debug experience, need optimizations OFF and debug info ON
246+
// tack these on the the end, they will override whatever comes earlier
247+
args|> addBoolOption"optimize"false|> addBoolOption"debug"true
248+
else args)
249+
250+
procInfo.Arguments<- procArgs
234251
procInfo.CreateNoWindow<-true;
235252
procInfo.UseShellExecute<-false;
236253
procInfo
@@ -367,6 +384,7 @@ let createSessionProcess () =
367384
memberx.Exited= exitedE
368385
memberx.Alive=not proc.HasExited
369386
memberx.ProcessID= proc.Id
387+
memberx.ProcessArgs= procInfo.Arguments
370388
memberx.Kill()= killProcess outW proc
371389
#if FSI_SERVER_INTELLISENSE
372390
memberx.Completions(s)= completions(s:string)
@@ -420,6 +438,11 @@ let createSessions () =
420438
match!sessionRwith
421439
| None->-1(* -1 assumed to never be a valid process ID*)
422440
| Some session-> session.ProcessID
441+
442+
letprocessArgs()=
443+
match!sessionRwith
444+
| None->""
445+
| Some session-> session.ProcessArgs
423446

424447
letinterrupt()=
425448
match!sessionRwith
@@ -445,6 +468,7 @@ let createSessions () =
445468
memberx.Error=upcast errE
446469
memberx.Alive= alive()
447470
memberx.ProcessID= processId()
471+
memberx.ProcessArgs= processArgs()
448472
memberx.Kill()= kill()
449473
memberx.Restart()= restart()
450474
memberx.Exited=upcast exitedE

‎vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/srProperties.fs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,18 @@ let FSharpInteractiveShadowCopyDescr = "FSharpInteractiveShadowCopyDescr"
3030
[<Literal>]
3131
letFSharpInteractiveShadowCopy="FSharpInteractiveShadowCopy"
3232

33+
[<Literal>]
34+
letFSharpInteractiveDebugMode="FSharpInteractiveDebugMode"
35+
36+
[<Literal>]
37+
letFSharpInteractiveDebugModeDescr="FSharpInteractiveDebugModeDescr"
38+
3339
[<Literal>]
3440
letFSharpInteractiveMisc="FSharpInteractiveMisc"
3541

42+
[<Literal>]
43+
letFSharpInteractiveDebugging="FSharpInteractiveDebugging"
44+
3645
typeDisplayNameAttribute(resName)=
3746
inherit System.ComponentModel.DisplayNameAttribute(GetString(resName))
3847

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp