
Code Generation Approaches
In a previous article, we examined how code generation is used in real products.
In this article, we will look at how which approaches to code generation can make our life easier.
Code generation is the process of generating code based on certain data.
I would like to highlight some areas:
This approach allows us to obtain based on a simple intuitive code - lower-level code. This approach helps maintain the abstraction. The language in which the source code is written may not coincide with the language of the code to be generated.
For example, we write a site in some language of our own. And on the server we have PHP. Let's see what generation is theoretically possible.
We configured the site to use MySQL and we can get similar code in the output:
And if the code generator is smart, then it can generate something like this:
Suddenly we decided not to use MySQL, but to use, for example, direct writing to files, then the code may be like this:
One more example. We write in our own language:
In the case of using MySQL, we could get this code:
In the case of using files, we could get the following code:
Code examples are not perfect, but they do the job of demonstrating code generation.
I also want to give an example of the operation of a real code generator that works on this principle. This is the LINQ code generator.
Source:
Resulting Code:
A delegate is also generated:
And the method:
This approach allows us to create data manipulation code based on the description of the data structure (metadata). For example, we have a MySQL database. I want to generate entities for working with a database. The simplest data on the database structure is easy to obtain:
From this, a primitive user information storage class can be generated.
If you think about it, you can still implement the select, update, insert, delete methods. In the future we will encounter similar code generators and even consider the development of such.
This is one of the simple and everyday approaches to code generation. An example of such a system is Smarty. This system is mainly used for generating HTML code based on templates. During the experiments, I generated PHP and C # code.
For example, we have a list of fields in a certain source $ source , and we need to create a class with properties on their basis.
The template can be taken as follows:
And with $ source = array ('width', 'height', 'name') we get:
In the next article, we will look at how you can manage complexity using code generation.
In this article, we will look at how which approaches to code generation can make our life easier.
Code Generation
Code generation is the process of generating code based on certain data.
I would like to highlight some areas:
Higher-Level Code Generation
This approach allows us to obtain based on a simple intuitive code - lower-level code. This approach helps maintain the abstraction. The language in which the source code is written may not coincide with the language of the code to be generated.
For example, we write a site in some language of our own. And on the server we have PHP. Let's see what generation is theoretically possible.
user = Users.find (5);
user.lastActivity = DateTime.Now;
user.save ();
We configured the site to use MySQL and we can get similar code in the output:
$ user_query = mysql_query ('SELECT * FROM `users` WHERE` id` = 5', $ mysql_connection );
$ user = mysql_fetch_assoc ( $ user_query );
mysql_query ('UPDATE` users` SET `lastActivity` ='. time (). 'WHERE` id` ='. $ page ['id'], $ mysql_connection );
And if the code generator is smart, then it can generate something like this:
mysql_query ('UPDATE` users` SET `lastActivity` ='. time (). 'WHERE` id` = 5', $ mysql_connection );
Suddenly we decided not to use MySQL, but to use, for example, direct writing to files, then the code may be like this:
$ user_list = unserialize (file_get_contents ('users.txt'));
foreach ( $ user_list as $ current_user )
{
if ( $ current_user -> id == 5)
{
$ user = $ current_user ;
break ;
}
}
$ user -> lastActivity = time ();
file_put_contents ('users.txt', serialize ( $ user_list ));
One more example. We write in our own language:
deletedRowsCount = query: delete from myTable where id> 5;
In the case of using MySQL, we could get this code:
$ query = mysql_query ('DELETE FROM `myTable` WHERE` id`> 5', $ mysql_connection );
$ deletedRowsCount = mysql_affected_rows ( $ mysql_connection );
In the case of using files, we could get the following code:
$ deletedRowsCount = 0;
$ myTable_list = unserialize (file_get_contents ('myTable.txt'));
foreach ( $ myTable_list as $ key_myTable => $ current_myTable )
{
if ( $ current_myTable -> id> 5)
{
unset ( $ myTable_list [ $ key_myTable ]);
$ deletedRowsCount ++;
}
}
file_put_contents ('myTable.txt', serialize ( $ myTable_list ));
Code examples are not perfect, but they do the job of demonstrating code generation.
I also want to give an example of the operation of a real code generator that works on this principle. This is the LINQ code generator.
Source:
byte [] source = new byte [] {1, 5, 7, 4, 3, 9, 8, 2, 6};
var dest = from n in source where n> 5 select n;
Resulting Code:
IEnumerable < byte > dest = Enumerable.Where < byte > ( new byte [] {1, 5, 7, 4, 3, 9, 8, 2, 6}, new CS $ <> 9__CachedAnonymousMethodDelegate1 (Main_b__0));
A delegate is also generated:
[CompilerGenerated]
private static Func < byte , bool > CS $ <> 9__CachedAnonymousMethodDelegate1;
And the method:
[CompilerGenerated]
private static bool Main_b__0 ( byte n)
{
return (n> 5);
}
Metadata Generation
This approach allows us to create data manipulation code based on the description of the data structure (metadata). For example, we have a MySQL database. I want to generate entities for working with a database. The simplest data on the database structure is easy to obtain:
show tables;
+---------------+
| Tables_in_gen |
+---------------+
| users |
+---------------+
describe users;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(100) | YES | | NULL | |
+-------+--------------+------+-----+---------+----------------+
From this, a primitive user information storage class can be generated.
class User
{
public $ id ;
public $ name ;
}
If you think about it, you can still implement the select, update, insert, delete methods. In the future we will encounter similar code generators and even consider the development of such.
Pattern Based Code Generation
This is one of the simple and everyday approaches to code generation. An example of such a system is Smarty. This system is mainly used for generating HTML code based on templates. During the experiments, I generated PHP and C # code.
For example, we have a list of fields in a certain source $ source , and we need to create a class with properties on their basis.
The template can be taken as follows:
class MyClass
{
{{foreach from = $ source item = name}}
public $ {{$ $}};
{{/ foreach}}
}
And with $ source = array ('width', 'height', 'name') we get:
class MyClass
{
public $ width ;
public $ height ;
public $ name ;
}
In the next article, we will look at how you can manage complexity using code generation.