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

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.

Related

Swap text blocks in Visual Studio

Is there any built-in way to swap two arbitrary text blocks in Visual Studio? (I happen to be using VS2015).
Example: you have a method such as FooBar(target, source) and you decide it would make more sense to be FooBar(source, target). If you've called FooBar in a lot of places you might need to run multiple operations to swap the various pairs of variable names.
Having this done also within comments could also be useful.
While obviously you could do this with multiple search & replaces, or multiple Edit->Refactor->Renames (^R^R), those approaches are somewhat prone to error, and are more tedious.
If this doesn't actually exist within Visual Studio but another tool like Notepad++ (for instance) has this capability, that is almost as good.
These questions are similar but for more specific scenarios:
Does anyone know a visual studio keyboard short cut to swap around two sides of a statement?
Invert assignment direction in Visual Studio
Visual Studio has the built in functionality to reorder parameters. You can select this by using Edit > Refactor > Reorder Parameters.... Changing parameters in this form will update all the method calls in addition to the method. You can also request to preview all the changes which will be made.
More information here.

Visual Studio - Is there any way to search a subset of code that can be executed?

Not sure if this is possible but given the way we can easily navigate to implementations of method calls (or at least a choice of possible implementations) and can even syntax highlight code coverage - is there any way to perform a 'search' or have an overview of all the code that CAN be run in a given highlighted section?
I.E if I highlight code
CallThirdParty(); // this function calls five other functions from classes X Y and Z
WriteToDatabase(); // no child function calls
PerformReconciliation(); // this function calls fourteen other functions from class A
Could I run a search on code that would be in classes X Y Z and A? Or at least get a view of all the code that would / could be run for that snippet?
Forgive me if it doesn't make much sense, but I think this would be absolutely awesome, especially when jumping into a project you aren't familiar with!
For Visual Studio for the question purposes but I'd be interested in any IDE / plugin that accomplishes this.
The Code Map might do what you're looking for. As the article says it can help you
Understand the overall architecture of a .NET application.
Analyze dependencies surfaced in that architecture by progressively drilling into the details.
Understand and analyze the impact of a proposed change to the code by building a dependency map from a specific code element.
The Call Hierarchy may help too. As the article says the
Call Hierarchy enables you to navigate through your code by displaying all calls to and from a selected method, property, or constructor. This enables you to better understand how code flows and to evaluate the effects of changes to code. You can examine several levels of code to view complex chains of method calls and additional entry points to the code, which enables you to explore all possible execution paths.
Additionally, you could always debug and step through the code to see what it does under different circumstances and then look at the call stack etc. to follow your calls and variables through.

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.

Macro expansion in Visual Studio macro or add in

I have a VS project with an IntermediateDirectory like this: "....\temp\$(SolutionName)\$(ProjectName)".
I can read this value using a macro or add in, however, I would need the actual directory to manipulate files there. Right now, I manually replace the "$(SolutionName)" and "$(ProjectName)" with the respective values, which works fine but might become complicated when different macros or even user macros from property sheets are used.
So my question is:
Does the Visual Studio API have a built in function to expand macros like these? Or is there some other elegant solution?
There is an elegant solution! But I only know the one that applies to C++ projects.
Assuming you're in a C# add-in:
// Get the main project from the first startup project
VCProject vcMainProject = (VCProject)(_applicationObject.Solution.SolutionBuild.StartupProjects as IVCCollection).Item(1);
Project mainProj = (Project)_vcMainProject .Object;
// Get the configuration we'll be using
IVCCollection cfgs = (IVCCollection)_vcMainProject .Configurations;
VCConfiguration vcCfg = (VCConfiguration) cfgs.Item(mainProj.ConfigurationManager.ActiveConfiguration.ConfigurationName + "|" + mainProj.ConfigurationManager.ActiveConfiguration.PlatformName);
string finalString = vcCfg.Evaluate("....\temp\$(SolutionName)\$(ProjectName)");
You can also check out this page:
http://msdn.microsoft.com/en-us/library/czt44k0x%28VS.71%29.aspx
If you're not using this for C++, there should be a similar interface for the Project, Configuration, and Solution classes provided for other languages (C# and VB).
As far as i know, there is no API available that will expand those macro values. Although it shouldn't be too hard to write a quick and dirty implementation that deals with only the values that you care about.
For instance, in this case you only care about 2 values (SolutionName and ProjectName). If these are the values you are primarily interested in use a simple search and replace with the best values.
Yes this is a sub-optimal solution. But it may help to unblock your progress.

How to debug a LINQ Statement

I have a Linq to objects statement
var confirm = from l in lines.Lines
where (l.LineNumber == startline.LineNumber) || (l.LineNumber == endline.LineNumber)
select l;
The confirm object is returning an 'Object Null or Not A Reference' at at System.Linq.Enumerable.WhereListIterator`1.MoveNext()
If the result of the query was empty, it would just return an empty enumerator. I know for a fact that there are no null objects in the statement. Is it possible to step through the LINQ statement to see where it is falling over?
EDIT When I said I know for a fact that there are no null objects it turns out I was lying :[, but the question remains, though I am asuming the answer will be 'you can't really'
LINQPad is a good idea, I used it to teach myself LINQ, but I may start looking at it again as a debug / slash and burn style tool
Yes it is indeed possible to pause execution midway through a linq query.
Convert your linq to query style using lambda expressions and insert a Select statement that returns itself somewhere after the point in the linq that you want to debug. Some sample code will make it clearer -
var query = dataset.Tables[0].AsEnumerable()
.Where (i=> i.Field<string>("Project").Contains("070932.01"))
// .Select(i =>
// {return i;}
// )
.Select (i=>i.Field<string>("City"));
Then uncomment the commented lines. Make sure the {return i;} is on its own line and insert a debug point there. You can put this select at any point in your long, complicated linq query.
I'm not sure if it's possible to debug from VS, but I find LINQPad to be quite useful. It'll let you dump the results of each part of the LINQ query.
You should be able to set a breakpoint on the expression in the where clause of your LINQ statement.
In this example, put the cursor anywhere in the following section of code:
(l.LineNumber == startline.LineNumber) || (l.LineNumber == endline.LineNumber)
Then press F9 or use the menu or context menu to add the breakpoint.
When set correctly, only the above code should have the breakpoint formatting in the editor rather than the entire LINQ statement. You can also look in the breakpoints window to see.
If you've set it correctly, you will stop each time at the function that implements the above part of the query.
I wrote a comprehensive article addressing this very question published on Simple-Talk.com (LINQ Secrets Revealed: Chaining and Debugging) back in 2010:
I talk about LINQPad (as mentioned earlier by OwenP) as a great tool external to Visual Studio. Pay particular attention to its extraordinary Dump() method. You can inject this at one or more points in a LINQ chain to see your data visualized in an amazingly clean and clear fashion. Though very useful, LINQPad is external to Visual Studio. So I also present several techniques available for use within Visual Studio because sometimes it is just not practical to migrate a chunk of code over to LINQPad:
(1) Inject calls to the Dump() extension method I present in my article to allow logging. I started with Bart De Smet's Watch() method in his informative article LINQ to Objects – Debugging and added some labeling and colorization to enhance the visualization, though still it pales in comparison to LINQPad's Dump output.
(2) Bring LINQPad's visualization right into Visual Studio with Robert Ivanc's LINQPad Visualizer add-in. Not sure if it was through my prodding :-), but the couple inconveniences present when I was writing my article have now all been admirably addressed in the latest release. It has full VS2010 support and lets you examine any object you like when debugging.
(3) Embed nop statements in the middle of your LINQ chain so you can set breakpoints, as described earlier by Amazing Pete.
2016.12.01 Update
And I just wrote the sequel to the above article, titled simply LINQ Debugging and Visualization, which reveals that true LINQ debugging capability has finally arrived in Visual Studio 2015 with the about-to-be-released new feature in OzCode. #Dror's answer to this question shows a tiny glimpse of it, but I encourage you to read my new article for an in-depth "how to". (And I do not work for OzCode.:-)
[Disclaimer: I work at OzCode]
The problem with LINQ is that it's hard to impossible to debug - even when dealing simple queries a developer is forced to refactor his/her query to a bunch of foreach loops, or use logging.
LINQ debugging is supported in a soon-to-be-released version of OzCode (currently available as an Early Access Preview) and it helps developers drill into their LINQ code as well and pinpoint those hard to catch exceptions inside queries
This is what your query would look like in OzCode:
It is possible to step inside the LINQ expression without setting any temporary breakpoints. You need to step into the function which evaluates the LINQ expression, e.g.:
var confirm = from l in lines.Lines
where (l.LineNumber == startline.LineNumber)
|| (l.LineNumber == endline.LineNumber)
select l;
confirm.ToArray(); // Press F11 ("Step into") when you reach this statement
foreach(var o in q) // Press F11 when "in" keyword is highlighted as "next statement"
// ...
Check the exception stack trace and see the last bit of your code that executed.
From the looks of the error I would suggest you take a look at line.Lines and make sure its enumerator is implemented properly. I think it's returning a null when it shouldn't.
Oh and just make sure the line and line.Lines objects aren't null or returning nulls as well.
While it isn't a way of debugging, I'd suggest using the following:
using (var db = new AppContext())
{
db.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
// Rest of code
}
You can then check the output window when debugging to see the SQL generated from your LINQ query.
To step through the LINQ statement just put a breakpoint on linq statement and then when it starts to debug that line then
Right click on it
click on Run To Cursor option
It will start to execute code line by line as we do normally.

Resources