Walkthrough: Generating and Compiling Source Code Dynamically in the Java LanguageĀ 

Visual J# provides a CodeDOM implementation for the Java language. The class Microsoft.VJSharp.VJSharpCodeProvider in the assembly VJSharpCodeProvider.dll provides methods for retrieving instances of the Visual J# implementation of the ICodeGenerator and ICodeCompiler interfaces for the Java language.

Note

The dialog boxes and menu commands you see might differ from those described in Help depending on your active settings or edition. To change your settings, choose Import and Export Settings on the Tools menu. For more information, see Visual Studio Settings.

Including the Visual J# Code Provider in a Project

To include the Visual J# code provider in a project

  • Right-click the project in Solution Explorer, point to Add Reference, and select VJSharpCodeProvider from the list of .NET Framework components.

CodeDOM and the throws Clause

CodeDOM elements can be used to model source code in a language-independent manner. The language-specific implementation of ICodeGenerator and ICodeCompiler can be used to generate and compile code dynamically.

For more information about CodeDOM, see Generating and Compiling Source Code Dynamically and in Multiple Languages.

The CodeDOM supports the common types of code elements found in common language runtime programming languages. However, it was not designed to provide elements to represent all possible programming language features.

The following are ways to provide support for Visual J# specific features like the throws clause, distinguishing between extends and implements, and specifying a cast involving a value type.

Note

Other language implementations of ICodeGenerator, if passed the same CodeDOM object graph, will ignore the UserData information that is not relevant to the language.

The CodeDOM does not provide a way to represent the exceptions declared in the throws clause of a method.

To represent throws clause

  1. Set a key-value pair in the CodeObject.UserData member of the CodeMemberMethod object that represents the method with the throws clause.

    The member is interpreted appropriately by the Visual J# implementation of ICodeGenerator.

  2. Name the key throwsCollection. Its value should be a CodeTypeReferenceCollection object that represents a collection of CodeTypeReference objects describing the exceptions thrown by the method.

  3. The Visual J# code generator uses throwsCollection to generate the throws clause for the method.

    For more information, see the CodeDOM Sample.

Generating a Class Declaration

The CodeDOM does not provide a way to represent the base class of a class separately from the base interface. By default, the Visual J# code generator interprets CodeTypeDeclaration.BaseTypes as follows:

  • The first type in the BaseTypes collection is the base class of the class, and corresponds to the extends clause.

  • The remaining types in the BaseTypes collection are the interfaces implemented by the class, and correspond to the implements clause.

To generate a class declaration that has no explicit extends clause, the Visual J# code generator requires additional information.

To distinguish between the extends and implements clauses

  1. Set a key-pair in the UserData member of the CodeTypeDeclaration object that represents the class you are generating.

  2. Name the key hasExtendsClause. Its value should be a Boolean object.

  3. The code generator interprets the value as follows:

    • If hasExtendsClause is true, the first type in the BaseTypes collection is the base class of the class, and corresponds to the extends clause. The remaining types in the BaseTypes collection are the interfaces implemented by the class by using the implements clause.

    • If hasExtendsClause is false, then all the types in the BaseTypes collection are interpreted as interfaces implemented by the class.

For more information, see CodeDOM Sample.

Casts in J# must be more explicit than in other .NET languages since J# does not support automatic boxing and unboxing of value types. In J#, you must explicitly specify boxing by casting to the appropriate wrapper type, such as System.Int32 for int. Casts in J# may have to be done in more than one step, using a a double cast. For example, if you are casting from a floating point value to a boxed System.Int32, you first cast to int and then to System.Int32 to box the integer. The CodeCastExpression object in J# now allows you to specify the exact type of cast required by using its UserData member. The UserData member supplies two Boolean keys which may be used to specify the various types of cast available.

To specify a cast involving a value type

  1. Set two key-pairs in the UserData member of the CodeCastExpression object that represents the cast expression you are generating.

  2. Name one of the keys CastIsBoxing, and the other DoubleCast.

  3. Assign Boolean objects as the value of each of these keys. The values of the Boolean variables will determine the type of cast generated according to the following table.

CastIsBoxing DoubleCast Cast Generated

false

true

(int) (System.Int32)

true

false

(System.Int32)

true

true

(System.Int32) (int)

false

false

(int)

  1. The actual types will be as specified in the CodeCastExpression object's TargetType property. The types int and System.Int32 are used for illustrative purposes only.

See Also

Tasks

CodeDOM Sample (Use CodeDomProvider)

Other Resources

Language Support
Dynamic Source Code Generation and Compilation