The CodeDOM
In LayerD is called CodeDOM to all classes declared within the namespace LayerD::CodeDOM (depending the Zoe compiler implementation can be contained within another namespace DotNET::LayerD::CodeDOM, Java::LayerD::CodeDOM, etc.).
Classes within CodeDOM represents portions of Zoe source code in memory, eg classes, functions, expressions, types, etc.. All classes that represent some portion of source code are derived from XplNode which is the base class for all nodes that represent a Zoe source. In memory a Zoe source is represented with a tree structure and the classes within the CodeDOM represent the branches and leaves in the tree. As the most important classes within the CodeDOM can be mention the followings:
| Class | Description |
| XplNode | It is the base class for all classes that are part of a Zoe document in memory. |
| XplDocument | Represents the initial node of a Zoe document in memory. Contains a DocumentData that contains metadata and configuration information. Another section DocumentBody where the functional part of the source code is located. |
| XplNamespace | Represents a Zoe namespace, to set or get the name is used set_name or get_name. |
| XplClass | Represents a class, interface, enumeration, or Zoe structure. By default represents a class. |
| XplFunction | Represents a member function of a Zoe class. |
| XplProperty | Represents a member property of a Zoe class. |
| XplField | Represents a Zoe member field. |
| XplType | Represents a data type, is a recursive structure. It is used to represent the data type type. |
| XplFunctionBody | Represents a function body, contains instructions. It is used to represent the type of data block. |
| XplIName | Represents an iname or identifier for the purpose of being used by the Zoe compiler, but is not itself a portion of source code. |
| XplClassMembersList | Not used as part of a Zoe program, but to group class members in memory. |
| XplExpression | Represents a container of some kind of expression. For example, can contain a literal expression, unary, binary, etc. It's the data type used to represent the expressions data types exp. |
| XplNodeList | This is a list of nodes used to store any type of node derived from XplNode. |
As XplNode is the base class of all nodes in the CodeDOM its functionality is shared with most of the data types within the CodeDOM. You can think an instance of XplNode as the representation of a xml node of the Zoe source, then every derived class represents a different portion of Zoe source code in memory. The core functionality of XplNode is detailed in the following table:
| Member | Description |
| get_ElementName() and set_ElementName (string ^) | Gets or sets the XML element name. |
| Children() | Returns a XplNodeList with the child nodes. Only for elements that might contains a variable list of child nodes as classes, blocks, etc. If the element can not contains a variable list of children as an expression, returns null. |
| get_Parent() | Returns the parent of the node, null if it doesn't has a parent. |
| get_Content() | Returns the content of the node for nodes that holds a content like XplExpression which returns the specific expression node. Null if node doesn't contains any element. |
| set_Value(string^) | Sets as content of the node the string passed as argument (only used for simple nodes of XplNode type). |
| get_StringValue() | Gets the string value stored in the node. Only serves for XplNode nodes that contain a string value (simple nodes can contain other types of values such as integers, floating or dates). |
| FindNodes("/n") | Returns a list of nodes (XplNodeList) that match the search string passed as argument. |
| FindNode("/n(id)") | Returns the first node found that matches with the pattern passed as an argument or null if it doesn't find a node. |
| CurrentNamespace | Returns the immediate namespace that contains the current node or null if the current node is not within a namespace. |
| CurrentClass | Returns the most immediate class that contains the current node or null if the current node is not found within a class. |
| CurrentFunction | Returns the most immediate function containing the current node or null if is not found within a function. |
| CurrentStatement | Returns the most immediate statement or null if current node is not child of one statement. |
| CurrentProperty | Returns the most immediate property containing the current node or null if is not found within a property. |
| CurrentBlock | Returns the closest block that contains the current node or null if is not found within a block. |
| CurrentExpression | Returns the most immediate expression containing the current node or null if is not found within an expression. |
| ZoeXmlString | Return the XML representation of current node. |
| ReadableString | Returns an "human readable" string representation of current node. By default it renders to Meta D++ code. |
| ChildNodes() | Returns a collection with all child nodes. If the element has no child nodes returns an empty collection. |
| string^[] Attributes() | Returns an array with all XML attributes of the element type. |
| string^ AttributeValue(string^) | Returns the value of the attribute specified in the parameter converted to string as represented in XML when a Zoe document is stored . |
| set_doc(string^) and get_doc() | Sets and returns a simple comment associated with the element. |
| string^ get_ldsrc() | Returns a string that represents the lines/columns of beginning and/or ending in the original source. Can returns an empty string. This means that the node does not have information about the origin source, in this case, the closer parents nodes should be examined. |
| CodeDOMTypes get_TypeName() | Returns an enumeration value containing the name of the node type, eg XplNode, XplClass, etc. You can optionally use the identification of types supported by the high-level language. |
| IsA(CodeDOMTypes nodeType) | Returns a boolean pointing out if the node is or not of the same type as the passed argument. |
| XplNode^ Clone() | Gets a deep copy of a node. |
| Write(XplWriter^) | Save the node and all its childrens using the instance of XplWriter received as an argument. |
| XplNode^ Read(XplReader^) | Load in Memory the node from the instance of XplReader received as an argument. |
XplNodeList class is used by CodeDOM classes where you need a list nodes of any length and where in general that list can have several types of nodes of the CodeDOM. The most important members of XplNodeList are:
| Member | Description |
| InsertAtEnd(XplNode^) | Insert a node at the end of the list. There is also an overload method that accepts a XplNodeList as an argument, in which case inserts all nodes contained in the received list. |
| InsertAtBegin(XplNode^) | Insert a node at the beginning of the list. There is another overload method that accepts a XplNodeList. |
| InsertBefore(XplNode^ newNode, XplNode^ reference) | Insert newNode before the reference node. If the reference node does not exist newNode is not inserted. There is another overload method that accepts a XplNodeList. |
| InsertAfter(XplNode^ newNode, XplNode^ reference) | Insert newNode after the reference node. If the reference node does not exist newNode is not inserted. There is another overload method that accepts a XplNodeList. |
| FirstNode() | Returns the first node of the list and initializes the internal iterator on the list. |
| NextNode() | Gets the next node in the current iteration, if there are no more nodes (this at the end of the list) returns null. |
| GetLength() | Returns the number of nodes in the list. |
| XplNodeList::CopyNodesAtEnd(XplNodeList^ source, XplNodeList^ target) | Copy the nodes in the source list at the end of the target list. |
Using instances of CodeDOM classes is possible to create in memory portions of source code and even entire programs. Is necessary to clear that any Zoe code represented in memory as a document is implemented with CodeDOM classes, because of this it is very useful for all classfactories programmers know the CodeDOM.
Classification of CodeDOM classes regarding the possibility of having children nodes
The CodeDOM classes can be classified regarding the possibility of having children- nodes in the followings types:
- The ones that can have multiple children of different types. For example: XplFunctionBody, XplExpressionlist, XplClass, XplNamespace, XplDocumentBody, XplParameters, XplInherits. If .Children() method is invoked (the one which is inherited from XplNode) a list with the children nodes that the class has is returned. This is because is permitted to this kind of class to has a variable number of children nodes.
- The ones that can have only one child-node of some specific types. For example: XplExpression, XplCatchinit that uses the get_Content() and set_Content() methods to get or set its content. For an expression, for example, there are specific types of nodes that are valid as content. If .Children() method is invoked a null value is returned. This is because for this kind of class that manages a content the methods get and set content are supposed to be used.
- The ones that can have a limited number of children nodes of specific types. For example: XplFunction that uses the get_Parameters() and get_FunctionBody() for getting the parameters and function body of a function.If .Children() method is invoked, a null value is returned. This is because the special methods for handling the specific properties (as arguments or body in a function) are supposed to be used.
Of course that, in all the cases, the children nodes of every class must be coherent with the type of class and what it represents. Type 1, for example, can has a multiple number of children nodes of different types but not of any type. For example, a if-statement inside a DocumentBody won't work because is not a valid construction.
Examples of Use
Checking if a Block of Code contains only a Try-Catch statement inside
Let's suppose we want to check if a certain block of code passed as an argument has or not only one try-catch statement inside. The method implemented in a classfactory should look like this:
/*Checks if a block contains only a "try-catch" statement inside*/
static bool checkTryStatementOnly(XplFunctionBody^ tryBlock)
{
/*#1: Let's obtain all the children nodes of the block of code.
This is valid for a block of code as it could has a variable quantity of children nodes.*/
XplNodeList^ childrensOfBlock = tryBlock.Children();
/*#2: The block must contains only one child node and it must be "XplTryStatement" type.
Let's check this in a condition and we'll return a boolean to point out if it has or not a try-catch block*/
bool hasTryCatch;
if(childrensOfBlock.GetLength()!=1 || !childrensOfBlock.FirstNode().IsA(CodeDOMTypes::XplTryStatement))
{
hasTryCatch=false;
}
else
{
hasTryCatch=true;
}
return hasTryCatch;
}
In this example we have used:
- XplFunctionBody instead of block to deal with blocks of codes. (Let's remember it's the same)
- The .Children() method that is common to all derived nodes from XplNode. Lets's remember that, however, this method is valid for nodes that could has a variable number of nodes inside, not valid for an expression node for example.
- The .GetLength() method of XplNodeList to return the number of children nodes in the list.
- The .FirstNode() which is a searching method to look for the first node of a list.
- The .IsA(CodeDOMType::SOME_TYPE) which is a method for checking if a Node is of a certain type. This is another common method for all nodes as it's a method of XplNode.