sbuilder-al 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.org +217 -0
- data/VERSION +1 -0
- data/design/al-language-bnf.org +216 -0
- data/lib/meta/etc.rb +265 -0
- data/lib/meta/meta.rb +106 -0
- data/lib/model/api.rb +678 -0
- data/lib/model/builders.rb +603 -0
- data/lib/model/constants.rb +24 -0
- data/lib/model/model.rb +534 -0
- data/lib/model/module.rb +25 -0
- data/lib/plugin/controller.rb +247 -0
- data/lib/plugin/module.rb +2 -0
- data/lib/plugin/plugin.rb +352 -0
- data/lib/sbuilder-al.rb +30 -0
- data/lib/translator/alrules.rb +424 -0
- data/lib/translator/module.rb +31 -0
- data/lib/translator/producer.rb +580 -0
- data/lib/translator/renderer.rb +159 -0
- data/lib/translator/sexp.rb +57 -0
- data/lib/translator/tlagenerator.rb +1348 -0
- data/lib/translator/translator.rb +210 -0
- data/lib/util/exception.rb +16 -0
- data/lib/util/logger.rb +90 -0
- data/lib/util/module.rb +16 -0
- data/lib/util/script_eval.rb +41 -0
- data/sbuilder-al.gemspec +45 -0
- metadata +153 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6f8c4a390b98790cf7eebeae8c39af57fff98657
|
4
|
+
data.tar.gz: f89df2d19fb85e6f1ccdbb6c19caa8ad38a87f61
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 69fe015460b662fc1e07f7b7e6cf6d308dcf4bc0062243b1cabed7e22a96774d5556f29e0a83e5c73022762d552e261e7c23a36fa6c026e5d827dceaa30da10b
|
7
|
+
data.tar.gz: 30d6f16c6884da322c0cd63b62b241d2c8c3b5687ebcd39c43b20136704e10fe55a91b45b9813bfddeebc0e17e4766c575425e6f8574fa43f633a237bb66bfb7
|
data/README.org
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
* =sbuilder-al=: an API Language Interface to =tla-sbuilder= -Tool
|
2
|
+
|
3
|
+
=tla-sbuilder= is tool to generate runnable formal models in [[http://research.microsoft.com/en-us/um/people/lamport/tla/book.html][TLA+
|
4
|
+
language]] for [[https://github.com/jarjuk/tla-sbuilder#TARGET-SYSTEM][business IT systems]]. A formal model can be [[https://en.wikipedia.org/wiki/Model_checking][model
|
5
|
+
checked]] using [[http://research.microsoft.com/en-us/um/people/lamport/tla/tools.html][TLA+ Tools]].
|
6
|
+
|
7
|
+
=sbuillder-al= defines an [[design/al-language-bnf.org][API Language]] (AL), which it maps to [[https://github.com/jarjuk/tla-sbuilder#API_LOADER][API
|
8
|
+
Loader]] and [[https://github.com/jarjuk/tla-sbuilder#SNIPPET_LOADER][Snippet Loader]] extension points in =tla-sbuilder=.
|
9
|
+
|
10
|
+
Normally, there is no need to install =sbuilder-al= separately
|
11
|
+
because =sbuilder-al= is included as dependency for higher level
|
12
|
+
interfaces. For example, [[https://github.com/jarjuk/sbuilder-eth][sbuilder-eth]] GEM, Ethereum Solidity
|
13
|
+
interface to =tla-sbuilder=, uses =sbuilder-al= to interface with
|
14
|
+
=tla-sbuilder=.
|
15
|
+
|
16
|
+
* Development
|
17
|
+
|
18
|
+
** Run Rspec Unit Tests
|
19
|
+
|
20
|
+
To run =rspec= unit tests
|
21
|
+
|
22
|
+
#+name rspec
|
23
|
+
#+BEGIN_SRC sh :eval no-export :results output :exports code
|
24
|
+
bundle exec rspec
|
25
|
+
#+END_SRC
|
26
|
+
|
27
|
+
#+RESULTS:
|
28
|
+
#+begin_example
|
29
|
+
...................*.......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
|
30
|
+
|
31
|
+
Pending: (Failures listed here are expected and do not affect your suite's status)
|
32
|
+
|
33
|
+
1) Sbuilder::Al::Meta::Etc.alObject2ApiString domain
|
34
|
+
# causes dump
|
35
|
+
# ./spec/meta/etc_spec.rb:113
|
36
|
+
|
37
|
+
Finished in 0.4775 seconds (files took 0.49587 seconds to load)
|
38
|
+
1659 examples, 0 failures, 1 pending
|
39
|
+
|
40
|
+
#+end_example
|
41
|
+
|
42
|
+
|
43
|
+
** Run Cucumber Tests
|
44
|
+
|
45
|
+
To run =cucumber= tests
|
46
|
+
|
47
|
+
#+name cucumber
|
48
|
+
#+BEGIN_SRC sh :eval no-export :results output :exports code
|
49
|
+
bundle exec cucumber
|
50
|
+
#+END_SRC
|
51
|
+
|
52
|
+
#+RESULTS:
|
53
|
+
: Using the default profile...
|
54
|
+
: ...........................................................................
|
55
|
+
:
|
56
|
+
: 6 scenarios (6 passed)
|
57
|
+
: 75 steps (75 passed)
|
58
|
+
: 0m8.028s
|
59
|
+
|
60
|
+
|
61
|
+
* Usage (Normally not needed)
|
62
|
+
:PROPERTIES:
|
63
|
+
:CUSTOM_ID: MANUAL-USAGE
|
64
|
+
:END:
|
65
|
+
|
66
|
+
Following short steps demonstrate, how =sbuilder-al= loads AL snippets
|
67
|
+
to =tla-sbuilder= context.
|
68
|
+
|
69
|
+
** Create Gemfile
|
70
|
+
|
71
|
+
Configure =sbuilder-al= into =Gemfile=
|
72
|
+
|
73
|
+
#+BEGIN_SRC ruby :eval no
|
74
|
+
source "https://rubygems.org"
|
75
|
+
gem "sbuilder-al"
|
76
|
+
#+END_SRC
|
77
|
+
|
78
|
+
and install it together with dependencies:
|
79
|
+
|
80
|
+
#+BEGIN_SRC sh :eval no
|
81
|
+
bundle install
|
82
|
+
#+END_SRC
|
83
|
+
|
84
|
+
** Initialize =tla-sbuilder= directory structure
|
85
|
+
|
86
|
+
Command
|
87
|
+
|
88
|
+
#+name: sbuilder-init
|
89
|
+
#+BEGIN_SRC sh :eval no-export :results output :exports code
|
90
|
+
bundle exec sbuilder.rb init
|
91
|
+
#+END_SRC
|
92
|
+
|
93
|
+
creates directory structure for running tla-sbuilder.
|
94
|
+
|
95
|
+
#+RESULTS: sbuilder-init
|
96
|
+
#+begin_example
|
97
|
+
Directory cnf - created
|
98
|
+
Directory cache - already exists - no need to create
|
99
|
+
Directory src - created
|
100
|
+
Directory src/extend - created
|
101
|
+
Directory gen - created
|
102
|
+
File cnf/sbuilder.yaml.example - created
|
103
|
+
File cnf/resolver_customer.yaml.example - created
|
104
|
+
File cnf/extend_customer_doms.yaml.example - created
|
105
|
+
File cnf/extend_customer_if.yaml.example - created
|
106
|
+
File cnf/extend_customer_run1.yaml.example - created
|
107
|
+
File cnf/extend_customer_run2.yaml.example - created
|
108
|
+
File cnf/interface_customer.yaml.example - created
|
109
|
+
#+end_example
|
110
|
+
|
111
|
+
|
112
|
+
** Create Configuration File =cnf/sbuider.yaml=
|
113
|
+
|
114
|
+
Create a configuration file =cnf/sbuilder.yaml= with the following YAML content
|
115
|
+
|
116
|
+
#+BEGIN_SRC yaml :eval no :tangle cnf/sbuilder.yaml
|
117
|
+
|
118
|
+
# Define 'sbuilder-al' extension point
|
119
|
+
extend:
|
120
|
+
loaders:
|
121
|
+
- className: Sbuilder::Al::Plugin::Plugin
|
122
|
+
gem: sbuilder-al
|
123
|
+
objects:
|
124
|
+
# define object 'alLoader' and configure it
|
125
|
+
- objectName: alLoader
|
126
|
+
configuration:
|
127
|
+
metatypes:
|
128
|
+
example:
|
129
|
+
description: Example metatype using ex prefix
|
130
|
+
prefix: ex
|
131
|
+
rubypaths:
|
132
|
+
- src/al.rb
|
133
|
+
|
134
|
+
# Run as API loader extension point
|
135
|
+
interfaces:
|
136
|
+
- objectName: alLoader
|
137
|
+
|
138
|
+
# Run as Snippet loader extension point
|
139
|
+
snippets:
|
140
|
+
- objectName: alLoader
|
141
|
+
|
142
|
+
|
143
|
+
# Define setup with name 'setup1'
|
144
|
+
setups:
|
145
|
+
- setupDirectory: setup1
|
146
|
+
|
147
|
+
#+END_SRC
|
148
|
+
|
149
|
+
** Create Api Langauage file =src/al=
|
150
|
+
|
151
|
+
Create a simple AL language module, which defines an API object
|
152
|
+
=alApi= to construct AL language objects in an array
|
153
|
+
|
154
|
+
#+BEGIN_SRC ruby eval :no exports :code :tangle src/al.rb
|
155
|
+
|
156
|
+
# Include GEM
|
157
|
+
require('sbuilder-al')
|
158
|
+
|
159
|
+
# Define api interface to tla-sbuilder
|
160
|
+
class AlApi
|
161
|
+
include Sbuilder::Al::Model::Api
|
162
|
+
end
|
163
|
+
|
164
|
+
nameSpaces = { "example" => { :description=>"Example namespace", :prefix=>"ex_" } }
|
165
|
+
alApi = AlApi.start( nameSpaces )
|
166
|
+
|
167
|
+
|
168
|
+
# Application is an array of AL elements
|
169
|
+
[
|
170
|
+
alApi.variable( "example") do
|
171
|
+
name "var1"
|
172
|
+
init alApi.constantExpression { value "Hello World" }
|
173
|
+
end,
|
174
|
+
|
175
|
+
]
|
176
|
+
|
177
|
+
|
178
|
+
#+END_SRC
|
179
|
+
|
180
|
+
** Generate sbuilder
|
181
|
+
|
182
|
+
Running
|
183
|
+
|
184
|
+
#+name: sbuilder-gen
|
185
|
+
#+BEGIN_SRC sh :eval no-export :results output :exports code
|
186
|
+
bundle exec sbuilder.rb generate setup1
|
187
|
+
#+END_SRC
|
188
|
+
|
189
|
+
#+RESULTS: sbuilder-gen
|
190
|
+
|
191
|
+
creates a file
|
192
|
+
|
193
|
+
#+name: sbuilder-ls
|
194
|
+
#+BEGIN_SRC sh :eval no-export :results output :exports code
|
195
|
+
ls -l gen/setup1/tla/model.tla
|
196
|
+
#+END_SRC
|
197
|
+
|
198
|
+
#+RESULTS: sbuilder-ls
|
199
|
+
: -rw-rw-r-- 1 jj jj 16242 joulu 18 10:36 gen/setup1/tla/model.tla
|
200
|
+
|
201
|
+
which defines variable =ev_var1=
|
202
|
+
|
203
|
+
#+name: sbuilder-grep
|
204
|
+
#+BEGIN_SRC sh :eval no-export :results output :exports code
|
205
|
+
grep 'Hello' gen/setup1/tla/model.tla
|
206
|
+
#+END_SRC
|
207
|
+
|
208
|
+
#+RESULTS: sbuilder-grep
|
209
|
+
: ex_var1 = "Hello World";
|
210
|
+
|
211
|
+
|
212
|
+
for the AL snippet created in =src/al.rb= module.
|
213
|
+
|
214
|
+
|
215
|
+
* License
|
216
|
+
|
217
|
+
MIT
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.8
|
@@ -0,0 +1,216 @@
|
|
1
|
+
#+BEGIN_EXAMPLE
|
2
|
+
|
3
|
+
# Top level application
|
4
|
+
<application> :: <snippet>*
|
5
|
+
<snippet> :: <apiSnippet> | <tlaSnippet>
|
6
|
+
|
7
|
+
# Api snippets
|
8
|
+
<apiSnippet> :: <transaction> | <definition> | <domain>
|
9
|
+
|
10
|
+
<domain> :: =domain= { =name= STRING,
|
11
|
+
[
|
12
|
+
=value= STRING |
|
13
|
+
=value= INT |
|
14
|
+
=value= true |
|
15
|
+
=value= false |
|
16
|
+
=literal= STRING
|
17
|
+
]*
|
18
|
+
}
|
19
|
+
|
20
|
+
<definition> :: =definition= {
|
21
|
+
=name= STRING
|
22
|
+
<property>*
|
23
|
+
}
|
24
|
+
|
25
|
+
|
26
|
+
<property> :: =property= {
|
27
|
+
=name= STRING
|
28
|
+
=domain= STRING
|
29
|
+
=isArray= BOOLEAN
|
30
|
+
} |
|
31
|
+
=property= {
|
32
|
+
=name= STRING
|
33
|
+
=definition= STRING
|
34
|
+
=isArray= BOOLEAN
|
35
|
+
}
|
36
|
+
|
37
|
+
# TLA & API snippets
|
38
|
+
<transaction> :: =transaction= <meta> {
|
39
|
+
=name= STRING
|
40
|
+
(=local= STRING)*
|
41
|
+
=interfaceOption= <booleanExpression>
|
42
|
+
=returnOption= <booleanExpression>
|
43
|
+
=request= <request>
|
44
|
+
=response= <response>
|
45
|
+
=operation= STRING
|
46
|
+
=block= <block>
|
47
|
+
}
|
48
|
+
|
49
|
+
<request> :: =request= {
|
50
|
+
<reqResponseParam>*
|
51
|
+
}
|
52
|
+
<response> :: =response= {
|
53
|
+
<reqResponseParam>*
|
54
|
+
}
|
55
|
+
<reqResponseParam> :: =parameter= <name> <isArray> [ <domainName> ] |
|
56
|
+
=reference= <name> <isArray> <definitionName>
|
57
|
+
<isArray> :: true | false
|
58
|
+
|
59
|
+
|
60
|
+
# TLA snippets
|
61
|
+
<tlaSnippet> :: <transaction> | <macro> | <operator> | <variable> | <alias>
|
62
|
+
<macro> :: =macro= <meta> {
|
63
|
+
=name= STRING
|
64
|
+
(=parameter= <STRING>)*
|
65
|
+
=block= <block>
|
66
|
+
}
|
67
|
+
|
68
|
+
<alias> :: =aliased=(<meta> ) {
|
69
|
+
=name= STRING
|
70
|
+
=specName= STRING
|
71
|
+
}
|
72
|
+
|
73
|
+
<operator> :: =operator= <meta> {
|
74
|
+
=name= STRING
|
75
|
+
(=parameter= <STRING>)*
|
76
|
+
<operatorParameter>*
|
77
|
+
=expression= <expression>
|
78
|
+
}
|
79
|
+
|
80
|
+
# Block && statements
|
81
|
+
<block> :: <statement>*
|
82
|
+
<statement> :: <outputStmt> | <skipStmt> | <labelStmt> |
|
83
|
+
<callService> | <callMacro> | <conditionalStmt> | <assignTo> |
|
84
|
+
<ReturnValue> | <Return> | <jump> | <aborted> | <done> | <failure>
|
85
|
+
|
86
|
+
<skipStmt> :: =nop=
|
87
|
+
<labelStmt> :: =label=
|
88
|
+
<outputStmt> :: =output= <expression>*
|
89
|
+
|
90
|
+
<assignTo> :: =assignTo= {
|
91
|
+
=variable= <parameterRVal>
|
92
|
+
=rval= <expression>
|
93
|
+
} |
|
94
|
+
=assignTo= {
|
95
|
+
=variable= <reference>
|
96
|
+
=rval= <expression>
|
97
|
+
}
|
98
|
+
|
99
|
+
<reference> :: <referenceLocation> ('.' STRING)*
|
100
|
+
<referenceLocation> :: <txParameterRef> | <simpleRef> | <variableRef>
|
101
|
+
<simpleRef> :: STRING
|
102
|
+
<variableRef> :: <meta> STRING
|
103
|
+
<txParameterRef> :: <meta> STRING STRING
|
104
|
+
|
105
|
+
<lval> :: <parameterReference> | <variableReference>
|
106
|
+
|
107
|
+
<callService> :: =callService= <meta> <name> <operation> {
|
108
|
+
(=parameter= <expression>)*
|
109
|
+
}
|
110
|
+
<callMacro> :: =callMacro= <meta> <name> {
|
111
|
+
(=parameter= <expression>)*
|
112
|
+
}
|
113
|
+
<conditionalStmt> :: =ifThen= <expression> <block> ( =elseThen <block> )?
|
114
|
+
|
115
|
+
|
116
|
+
<jump> :: =jump= STRING
|
117
|
+
|
118
|
+
<aborted> :: =aborted= <interfaceOpration>
|
119
|
+
<done> :: =done= <interfaceOpration>
|
120
|
+
<failure> :: =done= <interfaceOpration>
|
121
|
+
|
122
|
+
<return> :: =ret= <booleanExpression>
|
123
|
+
|
124
|
+
<ReturnValue> :: =returnValue= STRING <expression>
|
125
|
+
|
126
|
+
# expressions
|
127
|
+
<expression> :: <constantExpression> |
|
128
|
+
<referenceExpression> |
|
129
|
+
<tlaExpression> |
|
130
|
+
<operatorCall> |
|
131
|
+
<binaryExpression>
|
132
|
+
<unaryExpression>
|
133
|
+
|
134
|
+
<operatorCall> :: *TBD*
|
135
|
+
|
136
|
+
<referenceExpression>:: =reference= <reference>
|
137
|
+
|
138
|
+
|
139
|
+
<operatorExpression> :: =parameterReference= STRING
|
140
|
+
|
141
|
+
<tlaExpression> :: =tlaExpression= {
|
142
|
+
=template= <tlaTemplate>
|
143
|
+
=args= <expression>*
|
144
|
+
}
|
145
|
+
<tlaTemplate> :: =:set= | =:sequence= | =:nil= | =:parenthesis=
|
146
|
+
|
147
|
+
<binaryExpression> :: =binaryExpression= {
|
148
|
+
=lval= <expression>
|
149
|
+
=op= <binaryOp>
|
150
|
+
=rval= <expression>
|
151
|
+
}
|
152
|
+
|
153
|
+
<unaryExpression> :: =unaryExpression= {
|
154
|
+
=op= <unaryOp>
|
155
|
+
=expr= <expression>
|
156
|
+
}
|
157
|
+
|
158
|
+
<binaryOp> :: =:plus= | =:minus= | =:equal= | =:mult= | =:div= | =:lt= | =:le=
|
159
|
+
<unaryOp> :: =:not
|
160
|
+
|
161
|
+
<constantExpression> :: <integerExpression> | <stringExpression> | <booleanExpression>
|
162
|
+
<booleanExpression> :: <trueExpression> | <falseExpression>
|
163
|
+
<trueExpression> :: TRUE
|
164
|
+
<falseExpression> :: FALSE
|
165
|
+
<stringExpression> :: STRING
|
166
|
+
<integerExpression> :: INT
|
167
|
+
|
168
|
+
|
169
|
+
# Namespace meta
|
170
|
+
<meta> :: <sbuilderMetatype> | STRING
|
171
|
+
<name> :: STRING
|
172
|
+
<domainName> :: STRING
|
173
|
+
<definitionName> :: STRING
|
174
|
+
<sbuilderMetatype> :: 'domains' | 'service_implementation' | 'service_completion' | 'framework-svc'
|
175
|
+
|
176
|
+
#+END_EXAMPLE
|
177
|
+
|
178
|
+
TLA-templates
|
179
|
+
|
180
|
+
#+BEGIN_EXAMPLE
|
181
|
+
tlaSet(expression) :: tlaExpression {
|
182
|
+
tempalate :tlaSet
|
183
|
+
args expr
|
184
|
+
}
|
185
|
+
|
186
|
+
|
187
|
+
tlaNil :: tlaExpression {
|
188
|
+
tempalate :nil
|
189
|
+
}
|
190
|
+
|
191
|
+
tlaSequence(expr) :: =tlaExpression= {
|
192
|
+
tempalate :sequence
|
193
|
+
arg= expr
|
194
|
+
}
|
195
|
+
tlaParenthesis(expr) :: =tlaExpression= {
|
196
|
+
tempalate :parenthesis
|
197
|
+
arg= expr
|
198
|
+
}
|
199
|
+
|
200
|
+
tlaPlainname :: =tlaPlainname= STRING
|
201
|
+
tlaRecodrIndex :: =tlaRecordIndex= STRING <tlaExpression>
|
202
|
+
tlaIF :: =tlaIF= <tlaExpression> <tlaExpression> <tlaExpression>
|
203
|
+
tlaEXCEPT :: =tlaEXCEPT= STRING <tlaExpression>
|
204
|
+
tlaSetGenerator :: =tlaEXCEPT= <tlaExpression> STRING <tlaExpression>
|
205
|
+
tlaSetIterate(v,set) :: tlaExpression {
|
206
|
+
tempalate :set_iterate
|
207
|
+
args v
|
208
|
+
args set
|
209
|
+
}
|
210
|
+
|
211
|
+
=plus=(l,r) :: =binaryExpression= { =lval= l; =op= :plus; =rval= r }
|
212
|
+
=minus(l,r) :: =binaryExpression= { =lval= l; =op= :minus; =rval r }
|
213
|
+
=equal(l,r) :: =binaryExpression= { =lval= l; =op= :equal; =rval= r }
|
214
|
+
=unequal(l,r) :: =binaryExpression= { =lval= l; =op= :unequal; =rval= r }
|
215
|
+
|
216
|
+
#+END_EXAMPLE
|
data/lib/meta/etc.rb
ADDED
@@ -0,0 +1,265 @@
|
|
1
|
+
require "sbuilder"
|
2
|
+
module Sbuilder
|
3
|
+
module Al
|
4
|
+
module Meta
|
5
|
+
module Etc
|
6
|
+
|
7
|
+
## Define lambdas for plantUml strings
|
8
|
+
STR_CLASSNODE =
|
9
|
+
lambda do |kl, attributes=false|
|
10
|
+
"
|
11
|
+
class #{kl.respond_to?(:demodulize) ? kl.demodulize : kl } {
|
12
|
+
#{ kl.attributes.join("\n") if (attributes && kl.respond_to?(:attributes) ) }
|
13
|
+
}
|
14
|
+
"
|
15
|
+
end
|
16
|
+
|
17
|
+
STR_MODULENODE =
|
18
|
+
lambda do |modu, attributes=false|
|
19
|
+
"
|
20
|
+
package #{modu.to_s.split("::").last } {
|
21
|
+
}
|
22
|
+
"
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
STR_EDGE =
|
27
|
+
lambda do |kl, chld|
|
28
|
+
"#{kl.respond_to?(:demodulize) ? kl.demodulize : kl } <|-- #{chld.respond_to?(:demodulize) ? chld.demodulize : chld}"
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
# @return [Array<class>] Class hierarchy recursable using
|
34
|
+
# 'descendants' method without classess below array 'prune'
|
35
|
+
#
|
36
|
+
# @param klass [class] to start of hierarchy collection
|
37
|
+
#
|
38
|
+
# @param classes [Array<class>] collected so far
|
39
|
+
#
|
40
|
+
# @param prune [Array<class>] hierarchy pruned away below the
|
41
|
+
# classes in 'prune' - array
|
42
|
+
def self.hierarchy( klass, prune=[], classes=[] )
|
43
|
+
classes += klass.descendants.map { |kl| hierarchy( kl, prune, classes ) }.flatten if klass.respond_to?( :descendants ) && !prune.include?(klass)
|
44
|
+
classes = classes << klass
|
45
|
+
classes.uniq
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Array<class>] of ancestor classes defining
|
49
|
+
# ':descendants' method
|
50
|
+
def self.ancestors( klass, classes=[] )
|
51
|
+
if klass.superclass.respond_to?( :descendants )
|
52
|
+
classes += ancestors( klass.superclass, classes )
|
53
|
+
classes.unshift( klass.superclass)
|
54
|
+
end
|
55
|
+
classes
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [Array<[Class,Class]>] Array of child, parent arrays
|
59
|
+
def self.parentEdges( klasses )
|
60
|
+
klasses.reduce([] ) do |memo, kl|
|
61
|
+
# puts "kl.class.ancestors=#{kl.class.ancestors}"
|
62
|
+
#memo = memo + ((klasses - [kl]) & kl.class.ancestors ).map{ |kl2| [kl,kl2]}
|
63
|
+
memo << [kl,kl.superclass] if klasses.include?(kl.superclass)
|
64
|
+
memo
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [Array<Class>] of classes in myModule, excluding
|
69
|
+
# classes in 'excluded'
|
70
|
+
def self.moduleClasses( myModule, excluded=[] )
|
71
|
+
myModule.
|
72
|
+
# acces module constants
|
73
|
+
constants.
|
74
|
+
# select not excluded classes
|
75
|
+
select do |c|
|
76
|
+
klass = myModule.const_get(c, inherit=false)
|
77
|
+
klass.is_a?(Class) && ( klass.ancestors & excluded ).empty?
|
78
|
+
end.
|
79
|
+
# map 'em class symbols to Class objects
|
80
|
+
map { |c| myModule.const_get(c, inherit=false) }
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
# @return [Array<Module>] of Module in myModule, excluding
|
85
|
+
# classes in 'excluded'
|
86
|
+
def self.moduleSubModules( myModule, excluded=[] )
|
87
|
+
myModule.constants.
|
88
|
+
map { |c| myModule.const_get(c, inherit=false) }.
|
89
|
+
select { |c| c.class == Module } # && !excluded.include?( c ) }
|
90
|
+
# # map 'em class symbols to Class objects
|
91
|
+
# map { |c| myModule.const_get(c, inherit=false) }
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
##
|
96
|
+
# Render 'alObject' as a string
|
97
|
+
#
|
98
|
+
# @param alObject [AlObject] AL language object to render as atring
|
99
|
+
#
|
100
|
+
def self.snippetString( alObject )
|
101
|
+
Sbuilder::Al::Plugin::Controller.start.alObject2tlaString( alObject )
|
102
|
+
end
|
103
|
+
|
104
|
+
# Class overriding configuration reader for Sbuilder
|
105
|
+
class MyController < Sbuilder::Controller
|
106
|
+
def initialize( factory, sbuilderConfigs )
|
107
|
+
@sbuilderConfigs = sbuilderConfigs
|
108
|
+
super( factory )
|
109
|
+
end
|
110
|
+
# Method to reaturn 'sbuilder.yaml' sbuilder overridden
|
111
|
+
def getConfigSbuilder
|
112
|
+
@sbuilderConfigs
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
##
|
119
|
+
# Render 'apiElement' as a string
|
120
|
+
#
|
121
|
+
# @param apiElement [Hash] A hash to define api element
|
122
|
+
#
|
123
|
+
def self.alObject2ApiString( alObject, alObjectCtx = [])
|
124
|
+
|
125
|
+
|
126
|
+
# Configure
|
127
|
+
apiType2Config = {
|
128
|
+
:domain => {
|
129
|
+
"modelData" => "domains",
|
130
|
+
"template" => "domains.mustache",
|
131
|
+
},
|
132
|
+
:definition => {
|
133
|
+
"modelData" => "definitions",
|
134
|
+
"template" => "definition_types.mustache",
|
135
|
+
},
|
136
|
+
}
|
137
|
+
|
138
|
+
# Init sbuilder factory & controller & define configuration
|
139
|
+
sbuilderConfigs = {
|
140
|
+
"setups" => [
|
141
|
+
{
|
142
|
+
"setupDirectory": "example"
|
143
|
+
}
|
144
|
+
]
|
145
|
+
}
|
146
|
+
factory = Sbuilder::Factory.getFactory()
|
147
|
+
sbuilderController = MyController.new( factory, sbuilderConfigs )
|
148
|
+
|
149
|
+
# use sbuilder factory to instantiate API plugin && configure it
|
150
|
+
apiFacade = factory.getApiFacade(sbuilderController)
|
151
|
+
plugin = factory.getLoaderPlugin( Sbuilder::Al::Plugin::Plugin )
|
152
|
+
plugin.setFacade(apiFacade)
|
153
|
+
|
154
|
+
# Add translated element of interest to plugin 'application'
|
155
|
+
# (=state kept in controller)
|
156
|
+
apiElement = plugin.controller.alObject2tlaSexp( alObject )
|
157
|
+
raise "Expect :apiType property in #{apiElement}" unless apiElement.has_key?( :apiType )
|
158
|
+
|
159
|
+
apiElementCtx = alObjectCtx.map{ |o| plugin.controller.alObject2tlaSexp( alObject ) }
|
160
|
+
|
161
|
+
plugin.controller.addAlObjects( apiElementCtx )
|
162
|
+
plugin.controller.addAlObjects( apiElement )
|
163
|
+
|
164
|
+
# sbuilderController.load
|
165
|
+
|
166
|
+
sbuilderController.baseExtensionDefine
|
167
|
+
|
168
|
+
# invoke plugin API loader interface to pass data to sbuilder
|
169
|
+
plugin.load( nil )
|
170
|
+
|
171
|
+
# After load prepare for snippets stuff
|
172
|
+
sbuilderController.resolve
|
173
|
+
sbuilderController.initializeSymbolTableMetaModel
|
174
|
+
sbuilderController.initializeSymbolTable
|
175
|
+
|
176
|
+
|
177
|
+
# render template in sbuilder
|
178
|
+
setupName = "example"
|
179
|
+
outputPath = "output"
|
180
|
+
# choose template && data which to show
|
181
|
+
raise "Unknown apiType '#{apiElement[:apiType]}', valid apitype #{apiType2Config.keys.join(',')}" if apiType2Config[apiElement[:apiType]].nil?
|
182
|
+
generateDef = { "template" => apiType2Config[apiElement[:apiType]]["template"],
|
183
|
+
"desc"=>"example",
|
184
|
+
"modelData" => apiType2Config[apiElement[:apiType]]["modelData"],
|
185
|
+
}
|
186
|
+
mustache = sbuilderController.prepareRender( setupName )
|
187
|
+
sbuilderController.generateTemplateString( setupName, outputPath, generateDef, mustache)
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
|
192
|
+
# @return [Array<String>] Class hierarchy edges and nodes for
|
193
|
+
# class 'klass' with classes in 'prune'
|
194
|
+
#
|
195
|
+
# @param attributes [Boolean] true when include attributes to class default
|
196
|
+
#
|
197
|
+
# @param parents [Boolean] true when include also parent to hierarchy
|
198
|
+
def self.plantUmlClassHierarchy( klass, prune=[], attributes=false, parents=false )
|
199
|
+
klass = [klass] unless klass.is_a?( Array )
|
200
|
+
|
201
|
+
# Find all classes in hierarchy 'klass'
|
202
|
+
klassesInHierarchy =
|
203
|
+
klass.map do |kl|
|
204
|
+
hierarchy( kl, prune )
|
205
|
+
end.flatten
|
206
|
+
|
207
|
+
## Create edge strings for hierarch down
|
208
|
+
hierarchyEdges =
|
209
|
+
klassesInHierarchy.
|
210
|
+
# do not look into descendants of a pruned class
|
211
|
+
select{ |kl| !prune.include?(kl) }.
|
212
|
+
map do |kl|
|
213
|
+
# kl.descendants.map { |chld| "#{kl.demodulize} <|-- #{chld.demodulize}" }
|
214
|
+
kl.descendants.map { |chld| STR_EDGE.call( kl, chld ) }
|
215
|
+
end.flatten
|
216
|
+
|
217
|
+
## Create node string
|
218
|
+
hierarchyNodes =
|
219
|
+
klassesInHierarchy.map do |kl|
|
220
|
+
STR_CLASSNODE.call( kl, attributes )
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
parentNodes = []
|
225
|
+
parentEdges = []
|
226
|
+
|
227
|
+
if ( parents ) then
|
228
|
+
|
229
|
+
# string for all parent nodes
|
230
|
+
parentNodes = klass.map do |kl|
|
231
|
+
# find all ancestors for all classes
|
232
|
+
ancestors( kl )
|
233
|
+
end.flatten.uniq.map do |kl|
|
234
|
+
# and a node for them
|
235
|
+
STR_CLASSNODE.call( kl, attributes )
|
236
|
+
end
|
237
|
+
|
238
|
+
parentEdges = klass.reduce([]) do |memo,kl|
|
239
|
+
|
240
|
+
klWithAncestors = [kl] + ancestors( kl )
|
241
|
+
# puts( "klWithAncestors=#{klWithAncestors.join(',')}")
|
242
|
+
memo << (0..(klWithAncestors.length-2)).map do |i|
|
243
|
+
# puts( "i=#{i}, klWithAncestors.length=#{klWithAncestors.length}, klWithAncestors[i]=#{klWithAncestors[i]}, #{klWithAncestors[i+1]}")
|
244
|
+
# template 'strEdge' produces parent/sub-class edge
|
245
|
+
# [ klWithAncestors[i+1], klWithAncestors[i] ]
|
246
|
+
STR_EDGE.call(klWithAncestors[i+1], klWithAncestors[i])
|
247
|
+
end
|
248
|
+
memo
|
249
|
+
end.reject{ |arr| arr.empty? }
|
250
|
+
# puts( "parentEdges=#{parentEdges.length}=#{parentEdges.join(',')},#{parentEdges}")
|
251
|
+
|
252
|
+
|
253
|
+
end # parents
|
254
|
+
|
255
|
+
# make edges unique
|
256
|
+
parentEdges = parentEdges.flatten.uniq
|
257
|
+
hierarchyEdges = hierarchyEdges.flatten.uniq
|
258
|
+
|
259
|
+
hierarchyNodes + parentNodes + parentEdges + hierarchyEdges
|
260
|
+
end
|
261
|
+
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end # Al
|
265
|
+
end # Sbuilder
|