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

Commit26ff245

Browse files
committed
Add capability to auto-break on first executable line
1 parent675a272 commit26ff245

File tree

5 files changed

+203
-149
lines changed

5 files changed

+203
-149
lines changed

‎src/fsharp/fsi/fsi.fs‎

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,8 @@ type internal FsiDynamicCompilerState =
733733
tcState:Build.TcState
734734
ilxGenerator:Ilxgen.IlxAssemblyGenerator
735735
// Why is this not in FsiOptions?
736-
timing:bool}
736+
timing:bool
737+
debugBreak:bool}
737738

738739
letinternalWithImplicitHome(tcConfigB,dir)f=
739740
letold= tcConfigB.implicitIncludeDir
@@ -986,13 +987,22 @@ type internal FsiDynamicCompiler
986987
letmkBind pat expr= Binding(None, DoBinding,false,(*mutable*)false,[], PreXmlDoc.Empty, SynInfo.emptySynValData, pat, None, expr, m, NoSequencePointAtInvisibleBinding)
987988
letbindingA= mkBind(mkSynPatVar None itID) expr(* let it = <expr>*)// NOTE: the generalizability of 'expr' must not be damaged, e.g. this can't be an application
988989
letsaverPath=["Microsoft";"FSharp";"Compiler";"Interactive";"RuntimeHelpers";"SaveIt"]
989-
letdots= List.replicate(saverPath.Length-1)rangeStdin
990-
letbindingB= mkBind(SynPat.Wild m)(SynExpr.App(ExprAtomicFlag.NonAtomic,false, SynExpr.LongIdent(false, LongIdentWithDots(List.map(mkSynIdrangeStdin) saverPath,dots),None,m), itExp,m))(* let _ = saverPath it*)
990+
letdots= List.replicate(saverPath.Length-1)m
991+
letbindingB= mkBind(SynPat.Wild m)(SynExpr.App(ExprAtomicFlag.NonAtomic,false, SynExpr.LongIdent(false, LongIdentWithDots(List.map(mkSynIdm) saverPath,dots),None,m), itExp,m))(* let _ = saverPath it*)
991992
letdefA= SynModuleDecl.Let(false,[bindingA], m)
992993
letdefB= SynModuleDecl.Let(false,[bindingB], m)
993994

994995
[defA; defB]
995996

997+
// construct an invisible call to Debugger.Break(), in the specified range
998+
member__.CreateDebuggerBreak(m:range)=
999+
letbreakPath=["System";"Diagnostics";"Debugger";"Break"]
1000+
letdots= List.replicate(breakPath.Length-1) m
1001+
letmethCall= SynExpr.LongIdent(false, LongIdentWithDots(List.map(mkSynId m) breakPath, dots), None, m)
1002+
letargs= SynExpr.Const(SynConst.Unit, m)
1003+
letbreakStatement= SynExpr.App(ExprAtomicFlag.Atomic,false, methCall, args, m)
1004+
SynModuleDecl.DoExpr(SequencePointInfoForBinding.NoSequencePointAtDoBinding, breakStatement, m)
1005+
9961006
member__.EvalRequireReference istate m path=
9971007
if Path.IsInvalidPath(path)then
9981008
error(Error(FSIstrings.SR.fsiInvalidAssembly(path),m))
@@ -1080,6 +1090,7 @@ type internal FsiDynamicCompiler
10801090
tcState= tcState;
10811091
ilxGenerator= ilxGenerator;
10821092
timing=false;
1093+
debugBreak=false;
10831094
}
10841095

10851096

@@ -1619,7 +1630,10 @@ type internal FsiInteractionProcessor
16191630
| IHash(ParsedHashDirective("silentCd",[path],m),_)->
16201631
ChangeDirectory path m;
16211632
fsiConsolePrompt.SkipNext();(* "silent" directive*)
1622-
istate,Completed
1633+
istate,Completed
1634+
1635+
| IHash(ParsedHashDirective("dbgbreak",[],_),_)->
1636+
{istatewith debugBreak=true},Completed
16231637

16241638
| IHash(ParsedHashDirective("time",[],_),_)->
16251639
if istate.timingthen
@@ -1678,27 +1692,45 @@ type internal FsiInteractionProcessor
16781692
/// #directive comes through with other definitions as a SynModuleDecl.HashDirective.
16791693
/// We split these out for individual processing.
16801694
let recExecInteractions(exitViaKillThread,tcConfig,istate,action:ParsedFsiInteraction option)=
1681-
letaction,nextAction=
1695+
letaction,nextAction,istate=
16821696
match actionwith
1683-
| None-> None,None
1684-
| Some(IHash_)-> action,None
1685-
| Some(IDefns([],_))-> None,None
1697+
| None-> None,None,istate
1698+
| Some(IHash_)-> action,None,istate
1699+
| Some(IDefns([],_))-> None,None,istate
16861700
| Some(IDefns(SynModuleDecl.HashDirective(hash,mh)::defs,m))->
1687-
Some(IHash(hash,mh)),Some(IDefns(defs,m))
1701+
Some(IHash(hash,mh)),Some(IDefns(defs,m)),istate
16881702

16891703
| Some(IDefns(defs,m))->
16901704
letisDefHash=function SynModuleDecl.HashDirective(_,_)->true|_->false
1705+
letisBreakable def=
1706+
// only add automatic debugger breaks before 'let' or 'do' expressions with sequence points
1707+
match defwith
1708+
| SynModuleDecl.DoExpr(SequencePointInfoForBinding.SequencePointAtBinding_,_,_)
1709+
| SynModuleDecl.Let(_, SynBinding.Binding(_,_,_,_,_,_,_,_,_,_,_, SequencePointInfoForBinding.SequencePointAtBinding_)::_,_)->true
1710+
|_->false
16911711
letdefsA= Seq.takeWhile(isDefHash>>not) defs|> Seq.toList
16921712
letdefsB= Seq.skipWhile(isDefHash>>not) defs|> Seq.toList
16931713

1714+
// If user is debugging their script interactively, inject call
1715+
// to Debugger.Break() at the first "breakable" line.
1716+
// Update istate so that more Break() calls aren't injected when recursing
1717+
letdefsA,istate=
1718+
if istate.debugBreakthen
1719+
letpreBreak= Seq.takeWhile(isBreakable>>not) defsA|> Seq.toList
1720+
letpostBreak= Seq.skipWhile(isBreakable>>not) defsA|> Seq.toList
1721+
match postBreakwith
1722+
| h::_-> preBreak@(fsiDynamicCompiler.CreateDebuggerBreak(h.Range):: postBreak),{ istatewith debugBreak=false}
1723+
|_-> defsA, istate
1724+
else defsA,istate
1725+
16941726
// When the last declaration has a shape of DoExp (i.e., non-binding),
16951727
// transform it to a shape of "let it = <exp>", so we can refer it.
16961728
letdefsA=if defsA.Length<=1|| defsB.Length>0then defsAelse
16971729
match List.headAndTail(List.rev defsA)with
16981730
| SynModuleDecl.DoExpr(_,exp,_), rest->(rest|> List.rev)@(fsiDynamicCompiler.BuildItBinding exp)
16991731
|_-> defsA
17001732

1701-
Some(IDefns(defsA,m)),Some(IDefns(defsB,m))
1733+
Some(IDefns(defsA,m)),Some(IDefns(defsB,m)),istate
17021734

17031735
match actionwith
17041736
| None->assert(nextAction.IsNone); istate,Completed

‎src/fsharp/vs/ServiceLexing.fs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,7 @@ type internal LineTokenizer(text:string,
733733
|true,"I"
734734
|true,"load"
735735
|true,"time"
736+
|true,"dbgbreak"
736737
|true,"cd"
737738
#if DEBUG
738739
|true,"terms"

‎vsintegration/src/vs/FsPkgs/FSharp.LanguageService/FSharp.LanguageService.Base/ViewFilter.cs‎

Lines changed: 85 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,6 @@ private Microsoft.VisualStudio.Shell.Package GetProjectSystemPackage()
9595
returnthis.projectSystemPackage;
9696
}
9797

98-
privateboolDebuggerIsRunning()
99-
{
100-
vardebugger=this.service.GetIVsDebugger();
101-
returndebugger!=null&&this.mgr.LanguageService.IsDebugging;
102-
}
103-
10498
privateboolEditorSelectionIsEmpty()
10599
{
106100
stringselection;
@@ -222,16 +216,16 @@ public IVsTextView TextView {
222216
get{returnthis.textView;}
223217
}
224218

225-
/// <include file='doc\ExpansionProvider.uex' path='docs/doc[@for="ViewFilter.IsExpansionUIActive"]/*' />
226-
publicvirtualboolIsExpansionUIActive{
227-
get{
228-
IVsTextViewExtve=this.textViewasIVsTextViewEx;
229-
if(tve!=null&&tve.IsExpansionUIActive()==VSConstants.S_OK){
230-
returntrue;
231-
}
232-
returnfalse;
233-
}
234-
}
219+
/// <include file='doc\ExpansionProvider.uex' path='docs/doc[@for="ViewFilter.IsExpansionUIActive"]/*' />
220+
publicvirtualboolIsExpansionUIActive{
221+
get{
222+
IVsTextViewExtve=this.textViewasIVsTextViewEx;
223+
if(tve!=null&&tve.IsExpansionUIActive()==VSConstants.S_OK){
224+
returntrue;
225+
}
226+
returnfalse;
227+
}
228+
}
235229

236230
#region IVsTextViewFilter methods
237231
/// <include file='doc\ViewFilter.uex' path='docs/doc[@for="ViewFilter.GetWordExtent"]/*' />
@@ -362,76 +356,86 @@ public virtual void OnSetFocus(IVsTextView view) {
362356
/// OLECMDF_ENABLED | OLECMDF_SUPPORTED.
363357
/// Return E_FAIL if want to delegate to the next command target.
364358
/// </returns>
365-
protectedvirtualintQueryCommandStatus(refGuidguidCmdGroup,uintnCmdId){
359+
protectedvirtualintQueryCommandStatus(refGuidguidCmdGroup,uintnCmdId)
360+
{
366361
ExpansionProviderep=GetExpansionProvider();
367-
if(ep!=null&&ep.InTemplateEditingMode){
362+
if(ep!=null&&ep.InTemplateEditingMode)
363+
{
368364
inthr=0;
369365
if(ep.HandleQueryStatus(refguidCmdGroup,nCmdId,outhr))
370366
returnhr;
371367
}
372-
if(guidCmdGroup==typeof(VsCommands).GUID){
368+
if(guidCmdGroup==typeof(VsCommands).GUID)
369+
{
373370
VsCommandscmd=(VsCommands)nCmdId;
374371

375-
switch(cmd){
376-
caseVsCommands.GotoDefn:
377-
caseVsCommands.GotoDecl:
378-
caseVsCommands.GotoRef:
379-
caseVsCommands.Goto:
380-
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
372+
switch(cmd)
373+
{
374+
caseVsCommands.GotoDefn:
375+
caseVsCommands.GotoDecl:
376+
caseVsCommands.GotoRef:
377+
caseVsCommands.Goto:
378+
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
381379
}
382-
}elseif(guidCmdGroup==typeof(VsCommands2K).GUID){
380+
}
381+
elseif(guidCmdGroup==typeof(VsCommands2K).GUID)
382+
{
383383
VsCommands2Kcmd=(VsCommands2K)nCmdId;
384384

385-
switch(cmd){
386-
caseVsCommands2K.FORMATDOCUMENT:
387-
if(this.CanReformat())
388-
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
389-
break;
390-
caseVsCommands2K.FORMATSELECTION:
391-
if(this.CanReformat())
392-
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
393-
break;
385+
switch(cmd)
386+
{
387+
caseVsCommands2K.FORMATDOCUMENT:
388+
if(this.CanReformat())
389+
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
390+
break;
391+
caseVsCommands2K.FORMATSELECTION:
392+
if(this.CanReformat())
393+
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
394+
break;
394395

395-
caseVsCommands2K.COMMENT_BLOCK:
396-
caseVsCommands2K.UNCOMMENT_BLOCK:
397-
if(this.commentSupported)
398-
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
399-
break;
396+
caseVsCommands2K.COMMENT_BLOCK:
397+
caseVsCommands2K.UNCOMMENT_BLOCK:
398+
if(this.commentSupported)
399+
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
400+
break;
400401

401-
caseVsCommands2K.SHOWMEMBERLIST:
402-
caseVsCommands2K.COMPLETEWORD:
403-
caseVsCommands2K.PARAMINFO:
402+
caseVsCommands2K.SHOWMEMBERLIST:
403+
caseVsCommands2K.COMPLETEWORD:
404+
caseVsCommands2K.PARAMINFO:
405+
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
406+
407+
caseVsCommands2K.QUICKINFO:
408+
if(this.service.Preferences.EnableQuickInfo)
409+
{
404410
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
411+
}
412+
break;
405413

406-
caseVsCommands2K.QUICKINFO:
407-
if(this.service.Preferences.EnableQuickInfo){
408-
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
409-
}
410-
break;
414+
// case VsCommands2K.HANDLEIMEMESSAGE:
415+
// return 0;
411416

412-
// case VsCommands2K.HANDLEIMEMESSAGE:
413-
// return 0;
414-
415-
// Let the core editor handle this. Stop outlining also removes user
416-
// defined hidden sections so it is handy to keep this enabled.
417-
// case VsCommands2K.OUTLN_STOP_HIDING_ALL:
418-
// int rc = (int)OLECMDF.OLECMDF_SUPPORTED;
419-
// if (this.source.OutliningEnabled) {
420-
// rc |= (int)OLECMDF.OLECMDF_ENABLED;
421-
// }
422-
// return rc;
417+
// Let the core editor handle this. Stop outlining also removes user
418+
// defined hidden sections so it is handy to keep this enabled.
419+
// case VsCommands2K.OUTLN_STOP_HIDING_ALL:
420+
// int rc = (int)OLECMDF.OLECMDF_SUPPORTED;
421+
// if (this.source.OutliningEnabled) {
422+
// rc |= (int)OLECMDF.OLECMDF_ENABLED;
423+
// }
424+
// return rc;
423425

424-
caseVsCommands2K.OUTLN_START_AUTOHIDING:
425-
if(this.source.OutliningEnabled){
426-
return(int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
427-
}
428-
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
429-
430-
caseVsCommands2K.OUTLN_STOP_HIDING_ALL://"stop outlining" on context menu
431-
if(this.source.OutliningEnabled){
432-
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
433-
}
426+
caseVsCommands2K.OUTLN_START_AUTOHIDING:
427+
if(this.source.OutliningEnabled)
428+
{
434429
return(int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
430+
}
431+
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
432+
433+
caseVsCommands2K.OUTLN_STOP_HIDING_ALL://"stop outlining" on context menu
434+
if(this.source.OutliningEnabled)
435+
{
436+
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
437+
}
438+
return(int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
435439
}
436440
}
437441
elseif(guidCmdGroup==Microsoft.VisualStudio.VSConstants.VsStd11)
@@ -445,19 +449,21 @@ protected virtual int QueryCommandStatus(ref Guid guidCmdGroup, uint nCmdId) {
445449
{
446450
if(nCmdId==cmdIDDebugSelection)
447451
{
448-
if(DebuggerIsRunning())
452+
vardbgState=Interactive.Hooks.GetDebuggerState(GetProjectSystemPackage());
453+
454+
if(dbgState==Interactive.FsiDebuggerState.AttachedNotToFSI)
449455
return(int)OLECMDF.OLECMDF_INVISIBLE;
456+
elseif(EditorSelectionIsEmpty())
457+
return(int)OLECMDF.OLECMDF_SUPPORTED;
450458
else
451-
{
452-
if(EditorSelectionIsEmpty())
453-
return(int)OLECMDF.OLECMDF_SUPPORTED;
454-
else
455-
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
456-
}
459+
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
457460
}
461+
458462
elseif(nCmdId==cmdIDDebugLine)
459463
{
460-
if(DebuggerIsRunning())
464+
vardbgState=Interactive.Hooks.GetDebuggerState(GetProjectSystemPackage());
465+
466+
if(dbgState==Interactive.FsiDebuggerState.AttachedNotToFSI)
461467
return(int)OLECMDF.OLECMDF_INVISIBLE;
462468
else
463469
return(int)OLECMDF.OLECMDF_SUPPORTED|(int)OLECMDF.OLECMDF_ENABLED;
@@ -584,20 +590,15 @@ public virtual bool HandlePreExec(ref Guid guidCmdGroup, uint nCmdId, uint nCmde
584590
{
585591
if(nCmdId==(uint)Microsoft.VisualStudio.VSConstants.VSStd11CmdID.ExecuteSelectionInInteractive)
586592
{
587-
Microsoft.VisualStudio.FSharp.Interactive.Hooks.OnMLSend(GetProjectSystemPackage(),null,null);
593+
Interactive.Hooks.OnMLSend(GetProjectSystemPackage(),false,null,null);
588594
returntrue;
589595
}
590596
}
591597
elseif(guidCmdGroup==guidInteractive)
592598
{
593599
if(nCmdId==cmdIDDebugSelection)
594600
{
595-
Interactive.Hooks.OnMLSend(GetProjectSystemPackage(),false,true,null,null);
596-
returntrue;
597-
}
598-
elseif(nCmdId==cmdIDDebugLine)
599-
{
600-
Interactive.Hooks.OnMLSend(GetProjectSystemPackage(),true,true,null,null);
601+
Interactive.Hooks.OnMLSend(GetProjectSystemPackage(),true,null,null);
601602
returntrue;
602603
}
603604
}

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,21 @@ module internal Hooks =
5656
with e2->
5757
(System.Windows.Forms.MessageBox.Show(e2.ToString())|> ignore)
5858

59-
letprivatewithFSIToolWindow(this:Package)f=
59+
letprivatequeryFSIToolWindow(this:Package)(f:FsiToolWindow->'t)(dflt:'t)=
6060
try
6161
letwindow= this.FindToolWindow(typeof<FsiToolWindow>,0,true)
6262
letwindowFrame= window.Frame:?> IVsWindowFrame
6363
if windowFrame.IsVisible()<> VSConstants.S_OKthen
6464
windowFrame.Show()|> throwOnFailure0
6565
match windowwith
66-
|null->()
6766
|:? FsiToolWindowas window-> f window
68-
|_->()
67+
|_->dflt
6968
with e2->
7069
(System.Windows.Forms.MessageBox.Show(VFSIstrings.SR.exceptionRaisedWhenRequestingToolWindow(e2.ToString()))|> ignore)
70+
dflt
71+
72+
letprivatewithFSIToolWindow(this:Package)f=
73+
queryFSIToolWindow this f()
7174

7275
letOnMLSend(this:Package)(debug:bool)(sender:obj)(e:EventArgs)=
7376
withFSIToolWindow this(fun window->
@@ -78,6 +81,9 @@ module internal Hooks =
7881
letAddReferencesToFSI(this:Package)references=
7982
withFSIToolWindow this(fun window-> window.AddReferences references)
8083

84+
letGetDebuggerState(this:Package)=
85+
queryFSIToolWindow this(fun window-> window.GetDebuggerState()) FsiDebuggerState.AttachedNotToFSI
86+
8187
// FxCop request this function not be public
8288
letprivatesupportWhenFSharpDocument(sender:obj)(e:EventArgs)=
8389
letcommand= sender:?> OleMenuCommand

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp