Предыдущая серия была тут - Минимальный пример того, что мы можем сделать с описанной моделью.
Теперь расширим наш пример:
https://bitbucket.org/lulinalex/mindstream/src/1993baa5f2b16ac3f3e1bca85658740b3df8eb60/Examples/Scripts/CodeGeneration/CodeGen39.ms.script?at=B284
Теперь расширим наш пример:
https://bitbucket.org/lulinalex/mindstream/src/1993baa5f2b16ac3f3e1bca85658740b3df8eb60/Examples/Scripts/CodeGeneration/CodeGen39.ms.script?at=B284
USES
metaMACRO.ms.dict
;
Test CodeGen
REMARK
'
CodeGen - это функция в которой мы будем тестировать наш функционал
'
REMARK
'
%SUMMARY это мета-информация, которая позволяет привязывать документацию
к элементам кода. Эта документация доступна потом из скриптовой машины.
'
%SUMMARY '
Тут будем тестировать построение сначала мета-модели, потом модели, а потом и
кодогенерации
'
; // %SUMMARY
// ---------------------------------------------------------------------------
meta-meta-model-begin
'Тут будем определять аксиоматику мета-мета-модели, а потом вынесем её
в отдельный словарь.
'
StereotypeStereotypeProducer meta
%SUMMARY '
Определяем базовый элемент мета-модели
Тот самый который позволяет тащить всё остальное "за волосы из болота"
Через этот примитив выводятся все остальные
'
; // %SUMMARY
; // meta
meta-meta-model-end
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
meta-model-begin
'Тут будем определять аксиоматику мета-модели, а потом вынесем её
в отдельный словарь.
Дальше будем определять понятия из UML - https://ru.wikipedia.org/wiki/UML
Там бывают КАТЕГОРИИ и КЛАССЫ (Category и Class)
На самом деле разница между ними - "призрачна", но раз умные дяди так решили,
то так тому и быть
Вот с них и начнём:
'
<<@meta>> UMLCategory
%SUMMARY '
Категория в терминах UML
'
; // %SUMMARY
; // UMLCategory
<<@meta>> UMLClass
%SUMMARY '
Класс в терминах UML
'
; // %SUMMARY
; // UMLClass
meta-model-end
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
concrete-model-begin 'Модель шаблонов'
'Тут будем определять аксиоматику конкретной модели.
Пока - "модели шаблонов".
А потом вынесем её
в отдельный словарь.
'
<<UMLCategory>> Project
%SUMMARY '
Наверное у нас при разработке встречаются проекты.
Так вот Project это стереотип, который описывает наши проекты.
'
; // %SUMMARY
; // Project
<<UMLCategory>> Library
%SUMMARY '
Наверное у нас при разработке встречаются проектные библиотеки.
Так вот Library это стереотип, который описывает наши библиотеки.
'
; // %SUMMARY
; // Library
<<UMLCategory>> Programm
%SUMMARY '
Наверное у нас при разработке встречаются программы.
Так вот Programm это стереотип, который описывает наши программы.
'
; // %SUMMARY
; // Programm
<<UMLClass>> Class
%SUMMARY '
Наверное у нас при разработке встречаются проектные классы.
Так вот Class это стереотип, который описывает наши проектные классы.
'
; // %SUMMARY
; // Class
REMARK
'
Могут ли Library вкладываться в Project, а Project в Library
Или могут ли Programm вкладываться в Class, а Class в Programm
И прочие отношения между стереотипами - мы определим несколько позже.
Когда начнём использовать их.
'
model-end
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
concrete-model-begin 'Модель конкретного проекта'
'Тут будем определять аксиоматику конкретной модели конкретного проекта.
А потом вынесем её
в отдельный словарь.
'
<<Project>> Project1
%SUMMARY '
Это наш первый проект - Project1
'
; // %SUMMARY
<<Library>> Library1
%SUMMARY '
Наверное наш проект содержит какие-то проектные библиотеки.
Так вот Library1 - это наша первая проектная библиотека
'
; // %SUMMARY
; // Library1
<<Library>> Library2
%SUMMARY '
Наверное наш проект достаточно серьёзен и содержит НЕ ОДНУ библиотеку.
Так вот Library2 - это наша вторая проектная библиотека.
'
; // %SUMMARY
; // Library2
<<Library>> Library3
%SUMMARY '
Наверное наш проект НАСТОЛЬКО серьёзен, что содержит даже НЕ ДВЕ библиотеки.
Так вот Library3 - это наша третья проектная библиотека.
'
; // %SUMMARY
; // Library3
<<Programm>> Programm1
%SUMMARY '
Наверное наш проект реализует какую-то программу.
Иначе - зачем бы он нам был бы нужен?
Так вот Programm1 - это программа внутри нашего проекта Project1.
'
; // %SUMMARY
<<Class>> Class1
%SUMMARY '
Наверное наша программа содержит какие-то классы реализации.
Иначе - кто будет реализовывать наш функционал?
Так вот Class1 - это наш ПЕРВЫЙ класс реализации внутри нашей программы Programm1.
'
; // %SUMMARY
; // Class1
<<Class>> Class2
%SUMMARY '
Наверное наша программа достаточно серьёзна и содержит НЕ ОДИН классы реализации.
Так вот Class2 - это наш ВТОРОЙ класс реализации внутри нашей программы Programm1.
'
; // %SUMMARY
; // Class2
; // Programm1
; // Project1
REMARK
'
РЕМАРКА.
Все эти слова "наверное" вообще говоря должны проистекать из требований, ТЗ и UseCase
Но мы про это позже поговорим.
'
model-end
// ---------------------------------------------------------------------------
USES
CodeDump.ms.dict
// - тут подключаем словарь CodeDump.ms.dict, чтобы "увидеть" слово DumpElement
;
@SELF DumpElement
REMARK
'
- тут дампим элемент CodeGen и его содержимое
в стандартное устройство вывода.
Чисто для отладки того, что мы сейчас написали.
'
help
REMARK
'
Выводим всю доступную аксиоматику в стандартное устройство вывода.
Чисто для отладки того, что мы сейчас написали.
'
REMARK
'
Теперь, что мы можем сделать с нашим проектом?
Ну для начала выведем его содержимое на стандартное устройство вывода.
'
TtfwWord TYPE ModelElement
REMARK 'Элемент модели'
BOOLEAN FUNCTION IsSummary
ModelElement IN aWord
%SUMMARY
'
Определяет тот факт, что aWord является документацией к элементу
'
; // %SUMMARY
( aWord |N ) = '%SUM' >>> Result
; // IsSummary
BOOLEAN FUNCTION IsModelElement
ModelElement IN aWord
%SUMMARY
'
Определяет тот факт, что aWord является "элементом модели"
'
; // %SUMMARY
aWord IsSummary ! >>> Result
; // IsModelElement
ARRAY FUNCTION Children
ModelElement IN aWord
%SUMMARY
'
Возвращает итератор детей aWord в "терминах определённой модели"
'
;
( aWord MembersIterator ) >filter> IsModelElement >>> Result
; // Children
INTEGER VAR g_Indent
REMARK 'Текущий отступ'
g_Indent := 0
BOOLEAN FUNCTION IsElementNeedIndent
ModelElement IN anElement
%SUMMARY 'Определяет тот факт, что элементу нужен отступ' ;
true >>> Result
; // IsElementNeedIndent
PROCEDURE EnterElement
ModelElement IN anElement
%SUMMARY 'Начинает вывод элемента' ;
anElement IsElementNeedIndent ? INC g_Indent
; // EnterElement
PROCEDURE LeaveElement
ModelElement IN anElement
%SUMMARY 'Заканчивает вывод элемента' ;
anElement IsElementNeedIndent ? DEC g_Indent
; // LeaveElement
FILE VAR g_OutFile
g_OutFile := nil
PROCEDURE OutToFile
STRING IN aString
%SUMMARY
'
Выводит строку в текущий файл вывода.
С переводом каретки.
'
; // %SUMMARY
[ g_Indent ' ' char:Dupe aString ] strings:Cat g_OutFile File:WriteLn
REMARK '- выводим элементы модели в файл, а не в стандартный вывод.'
; //OutToFile
FORWARD DumpModelElement
REMARK 'FORWARD DumpModelElement используем для того, чтобы можно было вызывать DumpModelElement рекурсивно'
PROCEDURE DumpModelElement
ModelElement IN aWord
%SUMMARY
'
Процедура печатающая содержимое элемента модели.
Рекурсивно.
'
; // %SUMMARY
aWord |S OutToFile
REMARK 'Выводим стереотип элемента'
aWord |N OutToFile
REMARK 'Выводим имя элемента'
TRY
for ( aWord Children ) (
REMARK 'Выводим детей элемента'
ModelElement IN aWord
aWord EnterElement
TRY
aWord DumpModelElement
REMARK 'Вызываем рекурсивно сами себя'
FINALLY
aWord LeaveElement
END
)
FINALLY
'; // ' (+) ( aWord |N ) OutToFile
REMARK 'Выводим закрывающую скобку элемента'
END
; // DumpModelElement
STRING FUNCTION OutFileName
%SUMMARY 'Имя файла для вывода' ;
script:FileName sysutils:ExtractFileName (+) '.dump' >>> Result
; // OutFileName
g_OutFile := ( OutFileName File:OpenWrite )
TRY
@ Project1 DumpModelElement
REMARK 'Выводим содержимое элемента'
FINALLY
g_OutFile := nil
END
OutFileName Print
REMARK 'Выводим имя файла скрипта в тестовых целях'
; // CodeGen
CodeGen
Комментариев нет:
Отправить комментарий