Tools to understand new code: Go To

You’ve just started a new job and landed in front of a huge code base. Great! What a challenge! It would be nice to quickly get a general understanding of your project and be able to comfortably move around in the code. How do you do it?

In my series of articles as a guest contributor to this blog, you will learn about my favorite Visual Assist tools that help with code understanding. My tools are:

  • Go To
  • Find
  • Move
  • Additional tips

In this post, let’s take a look at Go To functionality.

As an example project, let’s take a look at Irrlicht Engine.

Go To

The feature in Visual Assist that I probably use most often is Go To. In short, it is an improvement for a very well-known tool from Visual Studio — Go to definition/declaration. But, we all know how this works (or actually doesn’t work) in VS. Sometimes you have to wait for a response from VS, or simply you cannot go anywhere.

With Visual Assist, you get a really nice, working version of the tool: just press Alt+G (the default keyboard shortcut), select where you want to go, and Visual Assist will go to it immediately!

Alt+G is especially useful when:

  • You are reading a class interface and you want to go to the implementation of some method. You can take a glance at the internal code, then quickly go back to the interface.
  • You want to check the declaration of a variable. Use Go To to see where the variable is declared (is it a local variable or maybe a member of a class).

Go To Example

I am in IParticleEmitter.h and I see the class IParticleEmitter interface declaration. There is an interesting method called emitt(...) — how is it implemented?

I can use Go To and get the following result:

goto_iparticleemit

Of course, Visual Assist sees that a method can have multiple polymorphic implementations. Go To allows one to select the desired implementation and jump into it. In the list, you can move via arrow keys, mouse, or assigned numbers/letters.

Now, I am in the implementation of this method: CParticleBoxEmitter::emitt. There is some code:

if (MaxAngleDegrees)
{
    core::vector3df tgt = Direction;
    tgt.rotateXYBy(os::Randomizer::frand() * MaxAngleDegrees);
    tgt.rotateYZBy(os::Randomizer::frand() * MaxAngleDegrees);
    tgt.rotateXZBy(os::Randomizer::frand() * MaxAngleDegrees);
    p.vector = tgt;
}

What is this MaxAngleDegrees? Is it a static constant or a class member? I can hover my mouse over it and get some basic information, but via Go To , I can go to the place where it is defined so I can see some more context.

When I want to return (to the interface that I was looking at initially), I can do it in several ways:

  • Ctrl+Tab to go to the previous window
  • Ctrl+- to go to the previous location
  • Navigate Back — a Visual Assist command that I will describe in another article

Tip: Additionally, Alt+G works in other situations; for instance, press Alt+G when the caret is in a line with the #include "#xyz" statement. You will simply move to the header!

Go To Related

Visual Assist goes even further than Go To with the implementation of another commend — Go To Related. If you use Shift+Alt+G instead of Alt+G, you will see a much more advanced version of Go To. For instance:

goto_related_iparticle

With Shift+Alt+G, I can see base classes, derived classes and even go to the definition a particular member!

Summary

Go To  and its related commands, Go To Related and Go To Member, are some of the most important tools in Visual Assist. The Go To commands enable us to move in the code quickly and jump among definition/use/declaration. The implementations in Visual Assist are very advanced and more efficient that the native Visual Studio solution.

Learn More

You can learn more about the Go To commands in the documentation for Visual Assist:

This article was contributed by Bartlomiej Filipek, who writes at Code And Graphics — a technical blog about C++ and OpenGL.

Organize VA Snippets with hashtags

For a user with a modest collection of VA Snippets, the built-in type filtering and auto-sorting of the VA Snippet Editor are sufficient tools to manage the collection. Type filtering divides VA Snippets by access method in the UI of Visual Assist, and auto-sorting within a type makes scrolling efficient. For the occasional VA Snippet that is hard to locate by type filter, the search capability in the VA Snippet Editor is an ample ancillary tool.

But for the user who has a massive collection of VA Snippets, built-in type filtering can fail to divide VA Snippets into manageable subsets. In these instances, hashtags in the descriptions of VA Snippets will tame the collection. You can add multiple hashtags to one VA Snippet, and tell the VA Snippet Editor to display only VA Snippets that include a specific hashtag(s).

If hashtags might help you stay organized, start with a reasonable set of hashtags for your collection. Remember, one VA Snippet can have multiple hashtags. For example, you can specify a language construct, custom type, and author for a single VA Snippet. With your hashtags in hand, scroll through your collection of VA Snippets and add the hashtags to your descriptions, separating your hashtags with commas or spaces.

Once you’ve added your hashtags, tell the VA Snippet Editor to display only entries containing a hashtag by:

  1. setting Type to “Search”
  2. entering a hashtag in the search field
  3. setting scope to “Search descriptions”

In the following example, I search for VA Snippets I’ve tagged as loop constructs. The editor shows only the five I’ve tagged:

blogHashtagLoop

Searches for VA Snippets that include any one of several tags requires you enable REs in searches and separate your hashtags with vertical bars—the symbol for “or” in an RE. For example, I can search for VA Snippets I’ve tagged as loop constructs or as switch statements:

blogHashtagLoopOrSwitch

Searches for VA Snippets that include multiple tags are a little trickier. The general pattern of an RE that finds VA Snippets with multiple tags is:

(?=.*#tag)(?=.*#tag)(?=.*#tag).+

In the following example, I find VA Snippets tagged as loop constructs AND authored by Jeff:

blogHashtagLoopAndJeff

If you have a large collection of VA Snippets, especially if you distribute the collection to other developers who browse through it, consider setting aside time to add hashtags. You may be more productive in the long run.

Filtering results of Find References

We regularly hear from C/C++ and C# users that Find References is their most-used feature of Visual Assist. Despite the existence of a similarly named feature in Visual Studio, the functionality and speed provided by our version appears to be a game changer. And Find References keeps getting better.

Beginning with Visual Assist build 2036, you can filter the results of Find References, in original and cloned windows. Although filtering is available via the context menu, keyboard access is the way to go.

I begin with a simple example that includes a reference to a quantity in a comment, its definition, one write access, and one read access.

findRefsExample

Find References (Shift+Alt+F) on quantity produces a results window with four entries, one of each type.

findRefsResultsAll

Although Find References has always differentiated read versus write references—blue and pink in my example—you can now use shortcuts R and W to filter by type. When focus is in the results, press W to remove the write reference(s).

findRefsResultsW

Press W again to make the write reference reappear, then R to remove the read reference(s).

findRefsResultsR

Initializations aren’t considered write references. Instead, they are included in definition references, which are filtered with the D shortcut. (In C/C++, declarations are also filtered with D.)

“References” in coMments and strings are filtered using M, and if my example had any, unknown/Guess hits would be filtered with G. Hence, pressing RDM immediately after my initial find would leave me with only the write reference.

findRefsResultsWOnly

Filter states aren’t sticky. Each Find References begins with all results, and each of the shortcuts initially removes references.

Additionally, filter states are specific to the window. You can show read references in one window and write references in a cloned window—to one or different symbols. If you can’t remember the state of a filter in a window, toggle it and look for a change in the vertical scroll bar.

Shortcuts for Highlight All (H) and Search All Projects (P) work similarly. H toggles the highlighting of references in source windows; P refreshes search results to include references from all projects, or restrict them to the current project. (Because quantity is a local variable in my example, my searches were always restricted to the current file.) .

Open the context menu of Find References if you forget the shortcuts. Only those that apply to your results are visible.

findRefsResultsMenu

Find References in Visual Assist is powerful and complex, and you need time and revisits to take full advantage of the command. Try the filtering described in this post, check out a previous post about using Find References to manage a task , then hit the documentation when you are ready for more.

Automatically add C++11 override to virtual methods

The C++11 standard has been approved and C++14 is around the corner. These new standards define a lot of interesting language features, one of them being support for the override identifier. You can append “override” to a virtual function declaration and tell the compiler that you want to override a virtual method inherited from a base class. If the virtual method does not exist in the base class, or has a different signature, the compiler raises an error and the compilation fails.

blogOverrideExample

Use of override is very useful for detecting errors, at compile time, caused by typos and bad copy-pastes.

Visual Studio has supported override since Visual Studio 2010, and so has Visual Assist. But if you want Visual Assist to insert “override” automatically—when using the code generation feature Implement Virtual Methods—you need to tell it via the Windows Registry.

Note: Beginning with Visual Assist build 2042, you can insert “override” automatically via the options dialog of Visual Assist. The following instructions apply to build 2036 and older.

Exit your IDE(s) so Visual Assist does not overwrite your changes, then using the registry editor, navigate to this key:

HKEY_CURRENT_USER\Software\Whole Tomato\Visual Assist X\<IDE_SPEC>

Change the value of UseOverrideKeywordInImplementInterface from 00 to 01.

blogOverrideRegistry

Restart you IDE, and from now on, Visual Assist will append override to the signatures of your virtual methods.

This article was contributed by Manuel Maier, student at Hochschule der Medien Stuttgart, Germany.

Implementing Virtual Methods with Visual Assist

Visual Assist has a feature—Implement Virtual Methods—that makes it easy to implement an interface, or abstract methods of a base class. You don’t need to create anything manually.

Move the caret to a base or interface class in the declaration of your derived class, or to the derived class if you want to implement methods from all bases classes.

Open a refactoring menu—via the context menu or Shift+Alt+Q—and select Implement Virtual Methods.

blogImplVirtual

A dialog will open, letting you choose the methods to implement.

blogImplVirtualDialog

Visual Assist updates the declaration of your class, and create stubs in its implementation. By default, an exception is placed in the body of each method.

blogImplVirtualMethodCreated

You can change the default by modifying the VA Snippet for “Create from Usage Method Body”.

blogImplVirtualSnippet

If you add methods to an interface, repeat the process and Visual Assist will automatically disable existing methods.

blogImplVirtualRerun

The declaration and implementation of your new method will be inserted in the correct locations, relative to the existing methods.

blogImplVirtualDeclCreated

That’s all there is to it.

This article was contributed by Lei Zhu, student at the College of San Mateo, CA.

Scope of Refactoring in Universal Solutions

At the Build 2014 conference in San Francisco, Microsoft announced availability of Universal Solutions in Visual Studio 2013 Update 2 RC. When you are ready to explore the functionality of this major improvement to the IDE, you’ll want to know how several often-used commands of Visual Assist operate in this new arena.

As a review, a simple Universal Solution is one that has at two or more platform-specific projects, and a shared project that is inherited by the platform-specific projects. The solution can include additional projects that may or many not inherit the shared project.

In a Universal Solution of multiple project types, Find References, Rename, and Change Signature behave as they normally do if you tell the commands to display references from, or search in, all projects. A find for Foo::Bar() in all projects locates the method wherever it’s referenced in your solution—in all project types.

But, the three commands assume new behavior in a Universal Solution when you search only the current project: the three commands assume you wish to search the current project plus those the project inherits, or are inherited by the current project. This slightly broader definition of current project prevents you from inadvertently refactoring code that will break a solution.

For example, if you rename MinPlayableWidth from a reference in a shared project—without telling Rename to search all projects—Visual Assist assumes you also need to rename references in the projects that inherit the shared project.

As another example, if you change signature of Foo::Bar() from a reference in a platform-specific project, Visual Assist assumes you also need to change the signature of Foo::Bar() in the shared project, plus other projects that inherit the shared project.

Even with the broader definition of the current project within a Universal Solution, you still have the opportunity to select/deselect project nodes before committing to a refactoring. If you exploit Rename or Change Signature to “refactor” your code so it references a difference object, e.g. Foo::Bar2(), you might initiate a Rename or Change Signature, then deselect nodes of projects that inherit, or are inherited by, your current project.

In summary, Visual Assist assumes you want your solution to build when you refactor in a Universal Solution. If you’re using refactoring commands for non-refactoring purposes, be mindful of the scope of your changes before you commit to them.

Scope of Refactoring in Multi-Project Solutions

There is a subtle connection among the Find References, Rename, and Change Signature commands of Visual Assist, and if you didn’t perceive the connection, you might believe something was awry—with your memory.

The three commands—Find References, Rename, and Change Signature—share a setting to display references from, or refactor in, the current project or all projects. The shared setting prevents you from inadvertently reviewing code with Find References in one scope, then refactoring your code in a broader or narrower scope.

If you restrict Find References to the current project, the default scope of the next Rename or Change Signature is also the current project. If you broaden the scope of Find References to all projects, the default scope of the next Rename or Change Signature is also all projects.

When the scope of Find References is set to all projects, multiple project nodes appear in the results.

blogMultiProjectFindAll

After a Find References whose scope was all projects, the Rename and Change Signature dialogs open with the same scope—all projects.

blogMultiProjectRename

The same holds for reverse use of the commands. If you set the scope in Rename or Change Signature, the next Find References opens with the same scope.

In short, Visual Assist assumes you’re working at the project or solution level, and holds the assumption until you say otherwise.

And remember, you can always fine tune the scope of any Rename or Change Signature by selecting/deselecting references, including entire project nodes, before a commit.

Finally, if you are working in a Universal Solution, there are more nuances to the scope of Find References, Rename, and Change Signature. I’ll touch on those nuances in the next post.