How do I invoke an F# function from the VS2010 immediate window - visual-studio

While debugging an F# application, I would like to be able to invoke an F# method from the VS2010 immediate window but it doesn't seem to work. The problem appears to be that F# methods are actually FSharpFunc objects. I tried using the "Invoke" method but the interactive window doesn't recognize it.

The F# integration for Visual Studio doesn't support F# expressions in immediate window (or watches), so the only option is to write C# code corresponding to the compiled representation that F# uses. I tried doing that and I'm having the same issue as you described - the Invoke method appears to be there (in Reflector), but Visual Studio doesn't want to call it directly. I tried it using the following example:
let foo f =
let n = f 1 2 // Breakpoint here
n + 1
However, there are other ways to call the function. In this case, the actual code generated by the F# compiler is a call to InvokeFast method. If you type the following to the immediate window, it works:
Microsoft.FSharp.Core.FSharpFunc<int, int>.InvokeFast<int>(f, 1, 2) |
It also appears that you can call the usual Invoke method using dynamic from C# 4.0 (proving that the method is actually there!):
((dynamic)f).Invoke(1, 2)
This works only if you add reference to Microsoft.CSharp.dll (and use some type defined in the assembly somewhere in your code - e.g. as an annotation - so that it gets loaded).

Related

Visual Studio - Discover if method is called by another method at some point

I was wondering, does visual studio have a feature such that I gave it a 2 method names and it then works out if at somewhere along the call stack the first method is called by the second (statically, without having to debug).
e.g.
Say I have a method FireBullet, and I want to see if IsOutsideWestBoundary can be invoked at some point
FireBullet()->HitTest()->CheckBoundaries()->IsOutsiteWestBoundary()
You can see that FireBullet can eventually cause IsOutsideWestBoundary to be invoked at some point.
I understand this can potentially become a very large problem, especially with deep call stacks and multiple methods called at each level, but still, for relatively small call stacks depths, this could be very useful.
Surely something like this must exist?
Thanks
Thomas
The Visual Studio extension NDepend can do that. It lets write code rules and code queries through C# LINQ queries. The following LINQ code query, executed live in Visual Studio, answers your need:
from m in Methods
where m.Name == "FireBullet()"
let depth0 = m.DepthOfIsUsing("MyNamespace.Program.IsOutsiteWestBoundary()")
where depth0 >= 0 orderby depth0
select new { m, depth0 }
Notice that the code query result also provides the depth of call. It can be stored in your NDepend project, and it can be transformed into a rule by adding the prefix warnif count > 0.
This query gets inspired from the query generated by NDepend when right clicking a method and Select Methods ... that call me (directly or indirectly).
If you click the button Export to Graph you get such call graph (more info on this here):
A 14-day full featured trial is available here.
Disclaimer: I work for NDepend.

In a Visual Studio Extension, get the line range of the function in which the debugger is stopped

I have a Visual Studio extension that hooks into debugging events. When the debugger stops at a line of code, my IDebugEventCallback2 callback gets called, and I can find out the filename and line number where the debugger has stopped via IDebugThread2::EnumFrameInfo.
I'd like to know the range of source code lines that the current function spans.
I'm hoping it's possible to derive the information I need from the debugger interfaces - the debugger must know the line range of functions. If that's not possible, I'm open to any other methods. In an ideal world the solution would work without the project system - many people, myself included, use Visual Studio as a stand-alone debugger without using the project system. (Also, I can't rely on Roslyn - it needs to work in existing versions of Visual Studio.)
Edit: Carlos's method of using FileCodeModel works well, as long as the file is part of a project. I'd still love to know whether there's a method that doesn't require the project system.
Given a FRAMEINFO retrieved with IEnumDebugFrameInfo2.Next, you can use the following code to get the file name, the first line of code of the current frame and the current line of code:
IDebugStackFrame2 stackFrame = frmInfo.m_pFrame;
if (stackFrame != null)
{
TEXT_POSITION[] begin = new TEXT_POSITION[1];
TEXT_POSITION[] end = new TEXT_POSITION[1];
IDebugDocumentContext2 debugDocumentContext2;
stackFrame.GetDocumentContext(out debugDocumentContext2);
if (debugDocumentContext2 != null)
{
string fileName;
debugDocumentContext2.GetName((uint)enum_GETNAME_TYPE.GN_FILENAME, out fileName);
debugDocumentContext2.GetSourceRange(begin, end);
}
}
FWIW, the IDebugDocumentContext2 interface has a Seek method that allows you to advance lines or statements of code in the stack frame. I guess you can advance until failure to get the end line of code of the stack frame.
To get info about code elements and start/end points using the project system (and without Roslyn) you have to use the automation model (EnvDTE.ProjectItem.FileCodeModel). Given a EnvDTE.ProjectItem and a line of code, you can use for example: HOWTO: Get the code element at the cursor from a Visual Studio .NET macro or add-in

How to tell type of indexing used from debugger

Following shows a C# console application stopped at a breakpoint. The sln variable is of type Solution2. From research, I determined that the Projects item in the solution uses 1-based indexing, so that's how I retrieve the only project in the Visual Studio solution (the line where the breakpoint is):
project = sln.Projects.Item(1);
What I was trying to do through the debugger was try to figure out if I could tell whether the collection was 0-based or 1-based, had I not had this information beforehand. But the debugger only shows that the Projects collection has a Count of 1. Is there a way (short of experimenting) to gain this knowledge by looking into the collection through the debugger?
Also, related questions:
What is the Dynamic View element?
Expanding the `[System.__ComObject] leads to a seemingly recursive display as below:
Why is this? What purpose does it serve?
To answer to your first question, there is no easy way to tell if COM based collection is 0 based or 1 based. Not, unless you are willing to disassemble the implementation of get_Item() method of the object that implements the COM interface. It could be either 0 or 1, and in general, it is not even guaranteed that indexes are expected to be integer values. In fact, the definition of your Projects.Item method takes System.Object as a parameter:
Project Item(
Object index
)
---
Parameters
indexType: System.Object
Required. The index of the item to return.
In your case, you can avoid using Item method, because Projects collection is IEnumerable, so you can just get the first element of the enumeration:
#using System.Linq;
---
var firstItem = sln.Projects.First();
Your last question is just a bug (or "feature") of Visual Studio debugger. COM interop in VS debugger is not the best area. If you find you need to debug COM interop on lower lever, it is best to use low level debugger, like WinDbg and manually walk through interface vtable's.

Inspect value of inline return during debug

I'm doing some mobile development and sometimes things are easiest to debug by attaching to the server. For the sake of brevity, I like to write something like this:
Public Function GetData(parameters) As FuzzBomb
Using data As New PersistentDataAccessLayer()
Return data.MakeStateChangingCall(parameters)
End Using
End Function
However, if you have a string of function calls written this way (i.e. Return GetValueFromSomeFunction), it's really hard to inspect the value being returned while debugging.
Since there are side effects, I can't simply copy/paste the function call into the watch window. I could assign the results to a temporary variable... but that seems ugly to me:
Using data As New PersistentDataAccessLayer()
Dim result = data.MakeStateChangingCall(parameters)
Return result
End Using
Is there a better way?
This features is supported in Visual Studio 2013, .NET 4.5.1. Needed values will be appear in Autos window. You can find feature description in Somasegar's blog.
In old version of Visual Studio and .NET you can use Immediate Window: just write data.MakeStateChangingCall(parameters) from debugged function and Visual Studio will evaluate target value (result of function).

Visual Studio refactoring: Remove method

Is there any Visual Studio Add-In that can do the remove method refactoring?
Suppose you have the following method:
Result DoSomething(parameters)
{
return ComputeResult(parameters);
}
Or the variant where Result is void.
The purpose of the refactoring is to replace all the calls to DoSomething with calls to ComputeResult or the expression that uses the parameters if ComputeResult is not a method call.
If I understand the question, then Resharper calls this 'inline method' - Ctrl - R + I
I would do it the simpliest way:
rename ComputeResult method to ComputeResultX
rename DoSomething method to ComputeResult
remove DoSomething method (which is now ComputeResult)
rename ComputeResultX method back to ComputeResult
Maybe VS will show some conflict because of the last rename, but ignore it.
By "rename" I mean: overwrite the name of the method and after it use the dropdown (Shift+Alt+F10) and select "rename". It will replace all occurences with the new name.
There are a few products available to add extra refactoring options to Visual Studio 2005 & 2008, a few of the better ones are Refactor! Pro and Resharper.
As far as remove method, there is a description in the canonical Refactoring book about how to do this incrementally.
Personally, I follow a pattern something along these lines (assume that compiling and running unit tests occurs between each step):
Create the new method
Remove the body of the old method, change it to call the new method
Search for all references to the old method (right click the method name and select "Find all Reference"), change them to calls to the new method
Mark the old method as [Obsolete] (calls to it will now show up as warnings during the build)
Delete the old method
When it comes to refactoring like that, try out ReSharper.
Just right click on the method name, click "Find usages", and refactor until it cannot find any references.
And as dlamblin mentioned, the newest version of ReSharper has the possibility to inline a method. That should do just what you need.
ReSharper is definitely the VS 2008 plug in to have for refactoring. However it does not do this form of refactoring in one step; you will have to Refactor->rename DoSomething to ComputeResult and ignore the conflict with the real ComputeResult. Then delete the definition which was DoSomething. It's almost one step.
However maybe it can do it one step. If I read that correctly.
You can also right click the method name and click "Find all References" in Visual Studio.
I personally would just do a CTRL + SHIFT + H to Find & Replace

Resources