Prime Programming Proficiency, Part 2: VS.NET Macros, Page 2
Stating the Problem
Your primary problem is building a solution that performs the following tasks:
- Iterate over the current solution loaded into VS.NET.
- Examine every project, sub-project, and file.
- Track and print solution, project, and file names and sizes as lines of code.
The secondary problem is to accumulate totals for these same elements. (Don't you wish all project statements were so straightforward?) The final requirement is to print the element information and totals in the VS.NET Output window.
Having a statement of work, you now can begin defining a solution. The first thing you might do is extend your sample code from Listing 1 and just keep adding inner, nested loops to handle sub-projects and files. I will submit, with some caution, that this will work fine—and it reflects how a lot of code is written. However, that's not how this article is going to do it.
Designing a Solution
Although the statement of work guides the solution, it does not guide how you design your solution. To recap, the following is the statement of work listed as a set of imperatives (I really wish all projects were articulated this clearly. Oh, sorry, just daydreaming a bit.):
- The system shall be implemented as a VB.NET macro and callable from VS.NET.
- The system shall examine the currently open solution in VS.NET and fail miserably if no solution is open. (Hey, as long as we are being clear, we can be clear about failure states too.)
- The system shall examine all elements in the solution, including projects, sub-projects, source code elements, and non-source code elements.
- The system shall use the VS.NET Output window as the results pane.
- The system shall display the name of each project, sub-project, and file element as each element is examined.
- The system shall display the file name and line count for files with a .vb extension and a ProjectItem.Kind of EnvDTE.Constants.vsProjectItemKindPhysicalFile.
- The system shall keep a running count of the number of projects, total number of files, and total line count of all source files. (A file is considered to be a source file if it has a .vb extension and its ProjectItem.Kind is defined as EnvDTE.Constants.vsProjectItemKindPhysicalFile.)
- The final process shall display the total line count, total file count, and total project count.
Pretty easy, huh? Interestingly, most projects can be defined at this level of granularity using something as simple as an outline and word processor. Equally interesting is that very few projects have anything even remotely approaching this kind of definition statement.
At this point, your problem is defined and the solution is stated as a list of unambiguous imperatives. (If one were negotiating this problem and solution statement as a fixed-price contract, all that would be left to do is have a lawyer examine the language for problematic loopholes in verbiage. I would also include a good change management clause in the contract.)
Having the problem and solution statements, all you have left to do is implement and test the solution. In the final part of this series will do just that. As mentioned, you could hack out a bunch of nested loops, conditional statements, and the like, but using the Visitor behavior pattern will result in code that you can be proud to exhibit.
Don't Work in Ignorance
Lines of code are a heuristic that is akin to drawing a line in the sand. Unfortunately, measuring lines of code is only the first step in a journey of a thousand miles. You must isolate newly produced code and evaluate it relative to the schedule, complexity of the problem, and qualitative aspects of the code. Failing to do so is working in ignorance of measurable productivity and quality.
Part 3 of this article series will discuss the design pattern that makes the line counter utility more manageable. In addition to providing a team with a starting point for productivity improvement, all of these skills can be used collectively to solve other problems, which can improve a team's software development skill.
If you want to read more about the CodeDOM, project templates, or macros (other than what I cover here or in Part 3), check out some of my other articles or books. A Google search of my name and the subject you are interested in should do the trick.
Written by Paul Kimmel. Pkimmel@softconcepts.com
Copyright © 2004. All Rights Reserved.
Prepared for codeguru.com
Paul Kimmel is the VB Today columnist, has written several books on .NET programming, and is a software architect. You may contact him at Pkimmel@softconcepts.com if you need assistance or are interested in joining the Lansing Area .NET Users Group (glugnet.org).