DSL Tools

En este apartado indicamos los pasos, uno a uno, para realizar un ejercicio mínimo ilustrativo de DSLs. Antes es necesario que tengamos instalado Visual Studio 2005 o superior en la versión profesional mínimo. Además de haber instalado los agregados de DSLTools necesarios.



Para crear un nuevo Domain Specific Language: Crear nuevo proyecto: Archivo -> Nuevo -> Proyecto



Otros Tipos de Proyecto -> Extensibilidad -> Domain Specific Language Designer


Poner nombre al proyecto








  • Seleccionar tipo de lenguaje: Minimal Language
  • Poner nombre al DSL








  • Definir extensión para programas del lenguaje (los programas visuales se almacenan en un archivo que tendrá la extensión indicada)


    • Poner nombre de Compañía

    • Dejar el default de Strong Name Key File 

    • Revisar y hacer clic en Finalizar si todo es correcto


    Como resultado del proceso que hemos seguido se obtiene un lenguaje de ejemplo. Le borraremos para ilustrar paso a paso la forma de construir el DSL.

    Borrar todas las clases de dominio del lenguaje mínimo (en Classes and Relationships), excepto la principal (la principal es la que está en la raíz del modelo), lo mismo con los Diagram Elements borrar todas excepto la que es de tipo Diagram (que es la principal)




    • Cambiar nombre a Clase Principal y al Diagrama Principal ambos en propiedad Name (seleccionamos la clase y en la ventana properties hacemos los cambios),
    • Al dar Validate All (botón derecho del ratón sobre el área de DslDefinition.dsl y valídate all), genera error.
    • Borrar las tools asociadas a los nodos del lenguaje recién eliminado (ir a la ventana DSL Explorer, Editor, Toolbox Tabs, DSLPagsWeb, Tools) 

    • Otra vez Validate All y listo, se puede hacer un Transform templates (Explorador de soluciones, botón Transform All Templates), e iniciar depuración (Menú Depurar, Iniciar Depuración). Habrá un lenguaje vacío

    COMENZAR LA REALIZACIÓN DEL domain model

    Agregar del cuadro de htas: Named Domain Class y cambiar su nombre a Pagina. Así mismo, arrastrar Embedding Relationship de SitioWeb a Pagina

    haciendo botón derecho sobre Pagina (la ligada), seleccionar Bring Tree Here para evitar una doble ilustración


    Agregar una nueva propiedad a la página (botón derecho sobre la leyenda Domain Properties, add new domain property), a la que llamaremos Descripcion empleando la ventana properties


     Cambiar nombre a relación de SitioWebHas hacia SitioTienePags


    Cambiar nombre del Source Role (a la izquierda de la relación SitioTienePags, arriba de la multiplicidad) a Pags, para ello, seleccionar el rol y en la ventana propiedades cambiar las propiedades: Name y PropertyName. Al target role (a la derecha de la relación SitioTienePags, arriba de la multiplicidad), nombrarlo Sitio del mismo modo. La multiplicidad no se cambió




    En el área de diseño, botón derecho -> Validate All. Transformar templates para probar que todo vaya bien


    Agregar una Reference Relationship (tomada del cuadro de htas) partiendo de Pagina y llegando a Pagina

    Renombrar roles,  el source (a la izq de la relación) como: PagDest y el target (a la derecha de la relación) como PagOri. Rrecordar hacerlo tanto en property name, como en name. La relación renombrarla a PagEnlacePag. La multiplicidad se conserva.

    Validate All-> Transform Templates -> Depurar –>Iniciar depuración
    Vamos a tener un IDE del DSL pero sin herramientas



    Cerrar la ventana Visual Studio de depuración


    Agregar (del cuadro de herramientas de Visual Studio) un Geometry Shape, cambiarle el nombre a PagShape,

    Después agregar un Diagram Element Map entre la clase Pagina y el elemento de diagrama PagShape


    Agregar un decorador a PagShape con botón derecho Add New Text Decorator


    y llamarlo NameDecorator


    Seccionar el map de diagrama 


    Activar Ver->Otras ventanas -> DSL Details e ir a pestaña Decorator Maps, para indicar que NameDecorator (activar casilla) está relacionado en el combobox Display property con Name, es decir, ese decorador va a estar enlazado con la propiedad name que va a obtener del modelo



    Crear a partir del cuadro de htas. un Connector, y renombrarlo como LinkShape,
    Enseguida agregar un DiagramElementMap partiendo de la relación de referencia llamada PagEnlacePag hasta LinkShape


    Agregar htas en DSL Explorer -> Editor  -> Toolbox Tabs -> DSL Pags Web -> boton derecho


    Agregar un ElementTool y un ConnectionTool


    Seleccionar el ElementTool1 agregado y en la ventana de propiedades modificar las props:

    Class –> debe apuntar a la clase que se va a modelar, en este caso Pagina

    Name -> El nombre de la tool (Pagina)
    Caption -> Lo que va a decir en el cuadro de htas (Crear una Pagina)
    Toolbox icon->  directorio de proyecto, DSL\Resources\ExampleShapeToolBitmap.bmp
    Tooltip -> Para las pistas de ayuda



    Seleccionar el ConnectionTool1 agregado y en la ventana de propiedades modificar las props:
    Connection Builder –> debe apuntar a la clase relación que se va a modelar, en este caso PagEnlacePag
    Name -> Conexion
    Caption -> Lo que va a decir en el cuadro de htas (crear enlace)
    Toolbox icon-> directorio de proyecto, DSL\ Resources\ExampleConnectorToolBitmap.bmp
    Tooltip -> Para la ayuda

    Validate All -> Transform Templates -> Start Debug F5

    Por default con el proyecto se crean dos archivos de ejemplo Test y Sample, se puede hacer doble click en ellos para abrirlos y a continuación modificarlos agregando nuevas clases de dominio y enlazarlas con relaciones.

    En ocasiones no carga el panel de herramientas de nuestro DSL, eso se debe a que el modo de depuración está usando una "imágen" de proyecto no actualizada con los últimos cambios a la configuración, si ese es el caso, cerrar depuración, ir al menú Build, hacer un Rebuild, nuevamente Transform All Templates y volver a arrancer el modo de depuración de nuestro DSL.




    El siguiente es un programa válido


    Generar -> Volver a generar solucion ->
    Depurar ->  Iniciar depuracion


    CREACION DE LAS PLANTILLAS GENERADORAS DE CODIGO

    • Asegurarnos que estamos en el modo de depuración, es decir, ahorita tenemos el nuevo lenguaje en ejecución

    Seleccionar Explorador de soluciones -> (botón derecho del ratón sobre debugging) ->Agregar -> Nuevo elemento


    Escoger archivo de texto y renombrar a plantilla.generador

    Seleccionar en el Explorador de soluciones el archivo recién generado: Plantilla.generador
    Y establecer la propiedad herramienta personalizada en propiedades: TextTemplatingFileGenerator

    Agregar el código que sigue al archivo plantilla.generador  (las dos primeras instrucciones las debe llevar toda plantilla)


    <#@ template inherits=
          "Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>

    <#@ DSLPagsWeb processor="DSLPagsWebDirectiveProcessor" requires="fileName='Test.dslpw'"   #>
                              Filename es el archivo que contiene el modelo(programa
                                 del nuevo lenguaje)
                                NOTESE EL NOMBRE DEL DSL INDICADO AL CREAR EL LENGUAJE
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;


    class Programitas
        {
            public void crear()
            {
              TextWriter tw;
              string a;
                               
              Mediante un foreach haremos un recorrido sobre el conjunto de paginas
                 Pagina es la clase del dominio que modela las páginas web
                 SitioWeb es la clase principal (la raiz) de las clases del dominio
                 (classes and relationships)
                 Pags es el source role de la clase raiz

    <#   foreach(Pagina p in this.SitioWeb.Pags)
        {
    #>                                                    LA PROPIEDAD DEL OBJETO
                                         
          Console.WriteLine("Creando archivo: <#=p.Name#>.html");
         TextWriter tw = new StreamWriter("<#=p.Name#>.html");
             tw.WriteLine("<html> hola que tal, estoy en archivo <#=p.Name#>.html </html>");
             tw.Close();
        Console.WriteLine("Se ha generado el archivo <#=p.Name#>.html...");
              a = Console.ReadLine(); 
               
         
         
         
    <#
        }
    #>


    }
    }



    Otro ejemplo de generación de código, para otro lenguajes es:

    <#@ template inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>
    <#@ output extension=".txt" #>
    <#@ PLenguajePaginasWeb processor="PLenguajePaginasWebDirectiveProcessor" requires="fileName='Test2.dslwebpages'"  #>


    <#
       foreach(PaginaWWW pag in this.SitioTec.webpages)
       {
    #>                                                   
       //----------------- <#= pag.Name #> --------------------
      
       <html> 
           <body>
                <bold> Esta es la página de: <#= pag.Name #> </bold>
            
                <# //verifica que exista un encabezado
                   if (pag.heads2!=null)
                    {   #>                                                   
                      <h1> <#= pag.heads2.Text #> </h1>
                <#  }   #>  
               
                <# foreach(PaginaWWW pagdest in pag.destino)
    {  #>                                                    
                  <A href="<#=pagdest.Name#>.html">Ir a pag  <#=pagdest.Name#> </A>
                <# } #>  

           </body>  
       </html> 
       //----------------------------------------------------
    <#
       }
    #>                                                    

    Donde se verifica que exista o no un elemento (if pag.heads2!=null), cuando la multiplicidad es 0..1 no se genera  un arreglo y por tanto debemos verificar si existe o no un elemento.



    Para invocar la ejecución de la plantilla
    Dar  botón derecho del ratón sobre el nombre de la plantilla.generador, en el explorador de soluciones, y hacer clic en Ejecutar Herramienta Personalizada



    Abajo del nombre de la plantilla, en el Explorador de Soluciones, aparece el nombre de un archivo, que si no indicamos otra cosa, se llamará igual que el nombre de la plantilla pero con la extensión cs (c Sharp), la extensión se puede indicar incluyendo una macroinstrucción en la plantilla. En dicho archivo estará el código generado


    El código generado es: