4.4. Supporting IntelliSense

Most people agree that one of the best features of Visual Studio is IntelliSense. Having contextual information about class members during development makes the process more efficient. It eliminates a lot of the need to jump back and forth between coding and documentation. Not only does IntelliSense give you information about what members are available, but it also provides abbreviated help about parameters and return values.

A big part of the IntelliSense feature is driven by the use of reflection by Visual Studio over the managed types referenced by the project. However, this does not work very well with a dynamic language like JavaScript. Even though, ASP.NET has worked out a way to provide IntelliSense with the JavaScript that you type.

You will only find this feature with the ASP.NET 3.5 release and when using Visual Studio 2008. When you start typing, you will immediately see IntelliSense for the JavaScript that you are working with. This is illustrated here in Figure 4-5.

Figure 4-5. Figure 4-5

IntelliSense with JavaScript simply works in Visual Studio, which uses inference when figuring out what to display. For instance, if you are working with a <div> tag through JavaScript, Visual Studio's IntelliSense will figure out through inference that it is an HTML element and provide you with the proper methods and properties in the IntelliSense drop-down.

For instance, suppose that you have the following code snippet in your <body> section:

<form id="form1" runat="server">
    <div>
        <div id="label1">abc</div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
    </div>
</form>

Here you can see that you have a <div> element called label1 with an initial value of abc. Through, typing in Visual Studio 2008, you will see that VS knows that this is an HTML element and will provide you with the appropriate list of options. This is illustrated in Figure 4-6.

Figure 4-6. Figure 4-6

Visual Studio even takes the extra steps of working with and understanding the files that are imported into your files and providing the IntelliSense options that these files might expose to the code you are working with. For example, suppose that you have a simple JavaScript file with a function to change passed in text to uppercase. You might want to keep this function in a separate JavaScript file. This .js file is illustrated in Listing 4-18.

Example 4-18. A separate .js file
function uppercaseItems(passInString)
{
    var returnValue = passInString.toString().toUpperCase();

    return returnValue;
}

Now that this function, uppercaseItems() is in a separate .js file. Include this file in your ASP.NET page as such:

<script src="MyFunctions.js" type="text/javascript"></script>

When you include this and you and you are working with items, you will have the uppercaseItems() method at your disposal as illustrated here in Figure 4-7.

Figure 4-7. Figure 4-7

You can also provide XML doc comments that then are presented in the IntelliSense. XML doc comments provide information about JavaScript code to let you know how to use it. The first item typically included is a summary statement, as shown in Listing 4-19. The Album object can proclaim to developers that it intends to be a repository for information about an album. This may seem obvious in this discussion, but as the number of classes grows and the use of intuitive names decreases, the need for an IntelliSense aid is more apparent.

Listing 4-19 repeats the Album class code from Listing 4-4 and includes XML doc comments. For each function, there is a summary statement. If a function takes parameters, they are described in param entries, and finally there is information about the return type.

Example 4-19. Providing documentation to your JavaScript
<%@ Page Language="C#" Debug="true" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>XML Documentation</title>

    <script type="text/javascript">

        function pageLoad(sender, args) {

            Type.registerNamespace('Wrox.AspAjax.Samples'),

            Wrox.AspAjax.Samples.Album = function(title, artist) {

                /// <summary>Use this method to create a new Album.</summary>

/// <param name="title" type="String" optional="false"
                ///  mayBeNull="false">The album title.</param>
                /// <param name="artist" type="String" optional="false"
                ///  mayBeNull="false">The album artist.</param>
                /// <returns type="Album">An Album object.</returns>
                this._title = title;
                this._artist = artist;
            }

            Wrox.AspAjax.Samples.Album.prototype = {
                get_title: function() {

                /// <summary>Album title accessor.</summary>
                /// <returns  type="String">Album title.</returns>
                    return this._title;
                },
                get_artist: function() {

                /// <summary>Album artist accessor.</summary>
                /// <returns type="String">Album artist.</returns.
                    return this._artist;
                }
            }

            Wrox.AspAjax.Samples.Album.registerClass
                    ('Wrox.AspAjax.Samples.Album'),
            var anAlbum = new Wrox.AspAjax.Samples.Album("Have a Nice Day",
               "Bon Jovi");
            alert(anAlbum.get_title());

        }

    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
    </div>
    </form>
</body>
</html>

The parameter doc comments indicate whether, including the parameter in the function call is optional and whether nulls are allowed. XML doc comments added to enums provide information about the individual fields. The album genre enum with comments is shown in Listing 4-20.

Example 4-20. XML documentation for enumerations
Wrox.AspAjax.Samples.MusicGenre = function() {
    /// <summary>Classifies types of music into a distinct genre.</summary>
    /// <field name="Blues" type="Number" integer="true" static="true" />
    /// <field name="Classical" type="Number" integer="true" static="true" />
    /// <field name="Electronic" type="Number" integer="true" static="true" />
    /// <field name="Folk" type="Number" integer="true" static="true" />
    /// <field name="Industrial" type="Number" integer="true" static="true" />
    /// <field name="Jazz" type="Number" integer="true" static="true" />
    /// <field name="NewAge" type="Number" integer="true" static="true" />
    /// <field name="HipHop" type="Number" integer="true" static="true" />
    /// <field name="Rock" type="Number" integer="true" static="true" />
    /// <field name="WorldFusion" type="Number" integer="true" static="true" />
    throw Error.invalidOperation();
}

Wrox.AspAjax.Samples.MusicGenre.prototype = {
    Blues: 1,
    Classical: 2,
    Electronic: 3,
    Folk: 4,
    Industrial: 5,
    Jazz: 6,
    NewAge: 7,
    HipHop: 8,
    Rock: 9,
    WorldFusion: 10
}

Wrox.AspAjax.Samples.MusicGenre.registerEnum('Wrox.ASPAJAX.Samples.MusicGenre'),

For enumerations, the information looks somewhat redundant, but for Visual Studio to consistently pick up and display the correct IntelliSense information, the comments should be complete. Another use of the XML doc comments is to include example usage. This can be helpful in providing the developer a quick sample without requiring him or her to switch to the more complete documentation. It is especially useful when working with complex functions for which some contextual information is needed to understand usage; seeing it used in one code snippet is often as helpful as many paragraphs of help information. Listing 4-21 is an example directly from the Error object of the ASP.NET AJAX Library. The popStackFrame() function merits an example to aid in its use.

Example 4-21. Commenting a function
Error.prototype.popStackFrame = function() {
    /// <summary>
    /// Updates the fileName and lineNumber fields based on the next frame in the
    /// stack trace. Call this method whenever an instance of Error is returned
    /// from a function. This makes the fileName and lineNumber reported in the
    /// FireFox console point to the location where the exception was thrown, not
    /// the location where the instance of Error was created.
    /// </summary>

/// <example>
    /// function checkParam(param, expectedType) {
    ///     if (!expectedType.isInstanceOfType(param)) {
    ///         var e = new Error("invalid type");
    ///         e.popStackFrame();
    ///         return e;
    ///     }
    /// }
    /// </example>

Returning back to the uppercaseItems() function presented in Listing 4-18, you can now add documentation to this method. This is presented here in Listing 4-22.

Example 4-22. Adding documentation to the uppercaseItems() function
function uppercaseItems(passInString)
{
    /// <summary>This method simply uppercases a passed-in string</summary>
    /// <param name="passInString">This is the string you pass in</param>
    /// <returns>A string in uppercase</returns>
    var returnValue = passInString.toString().toUpperCase();

    return returnValue;
}

However, now when you find the function reference through IntelliSense, you will see the comments as presented in Figure 4-8.

Also, after selecting the function and working to pass in the correct parameter, you are presented with the following assistance through IntelliSense as illustrated in Figure 4-9.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset