embox

Форк
0
/
model_impl.mk 
405 строк · 9.6 Кб
1
#
2
# Builtins for generated implementations of modeled objects
3
# and runtime support for managing object references.
4
#
5
#   Date: Feb 17, 2012
6
# Author: Eldar Abusalimov
7
#
8

9
ifndef __model_eobject_mk
10
__model_eobject_mk := 1
11

12
# Param:
13
#   1. Meta class ID.
14
#   2. Instance class name.
15
#   3. Super classes.
16
#   4. Flags, which may contain:
17
#        abstract, interface
18
define builtin_func-eobject
19
	$(call __def_do,
20

21
		# Extends implementations of each super class.
22
		$(foreach s,$(or $3,EObject),
23
			$$(super $s))
24

25
		$$(getter eMetaClassId,
26
			$1)
27
		# A little optimization.
28
		$$(getter eMetaClass,
29
			$$($1))
30
	)
31
endef
32

33
# Param:
34
#   1. Meta feature ID.
35
#   2. Instance property name.
36
#   3. Flags, which may contain:
37
#        changeable many
38
define builtin_func-eobject-attribute
39
	$(call __def_do,
40
		$(if $(filter changeable,$3),
41
			# Changeable attributes are just property-fields.
42
			$$(property-field $2$(if $(filter many,$3),...)),
43

44
			# Otherwise, only getter should be defined.
45
			$$(property $2$(if $(filter many,$3),...))
46
			$$(field $2$(if $(filter many,$3),...))
47
			$$(getter $2,
48
				$$(get-field $2))
49
		)
50
	)
51
endef
52

53
# Param:
54
#   1. Meta feature ID.
55
#   2. Instance property name.
56
#   3. Reference class.
57
#   4. Opposite property name (if any).
58
#   5. Flags, which may contain:
59
#        changeable many containment container linkable
60
define builtin_func-eobject-reference
61
	$(call __def_do,
62

63
		# Declare a propery (though it has already been declared in API class).
64
		$$(property $2$(if $(filter many,$5),...) : $3)
65

66
		# Generate getter.
67
		$(if $(filter contain%,$5),
68
			# Container and containment references share the same field.
69
			$$(getter $2,
70
				$$(suffix $$(filter $2/%,$$(get-field \
71
					$(if $(filter container,$5),__eContainer,__eContents))))),
72

73
			# Otherwise define a new field.
74
			# Cross references are stored in raw fields.
75
			$$(field $2$(if $(filter many,$5),...))
76
			# There is also a custom serializer for such fields.
77
			$$(method __serialize_field-$2,
78
				$$(call __eObjectSerializeCrossReference,$2,$1))
79

80
			$$(getter $2,
81
				# Linkable references also support on-demand linkage.
82
				$(if $(filter linkable,$5),
83
					$$(call __eObjectResolveLinks,
84
						$$(filter %./,$$(get-field $2)),$1))
85
				# Getting suffix is mandatory here!
86
				$$(suffix $$(get-field $2)))
87
		)
88

89
		$(for fn_suffix <-
90
			$(if $(filter containment,$5),Containment,
91
				$(if $(filter container,$5),Container,
92
					$(if $4,Bidirectional,Unidirectional))),
93
			property <- $2,
94

95
			$(__eobject_ref_setter)
96

97
			$(if $(filter linkable,$5),
98
				$(for property <- $(property)_link$(if $(filter many,$5),s),
99
					fn_suffix <- $(fn_suffix)_link,
100

101
					# Declare a propery for links.
102
					$$(property $(property)$(if $(filter many,$5),...) : $3)
103

104
					$$(getter $(property),
105
						$$(subst ./,,$$(dir $$(get-field $2))))
106

107
					$(__eobject_ref_setter)
108
				)
109
			)
110
		)
111
	)
112
endef
113

114
# Param:
115
#   Same as to 'eobject-reference' builtin.
116
# Context:
117
#   'property'
118
#   'fn_suffix'
119
define __eobject_ref_setter
120
	$(if $(filter changeable,$5),
121
		$$(setter $(property),
122
			$(if $(not $(filter many,$5)),
123
				$$(assert $$(not $$2),
124
					Set '$$2' invoked for a non-list EReference $1)
125
			)
126
			$$(call __eObjectSet$(fn_suffix)$$2,$2,$$(suffix $$1),$4,$1))
127
	)
128
endef
129

130
# Params:
131
#   1. Property name.
132
#   2. Meta reference ID.
133
define __eObjectSerializeCrossReference
134
	$(assert $(not $(or $(get $2->isContainment),$(get $2->isContainer))),
135
		$0: Can't handle non-cross references)
136
	# '.link./.target'
137
	# '.link./'
138
	#        '.target'
139
	# '.oplink.target'
140
	$(for r <- $(get-field $1),
141
		$(for l <- $(subst ./,,$(dir $r)),# Link.
142
			$($l.__serial_id__)./)
143
		$(for t <- $(suffix $r),# Target.
144
			$(for l <- $(basename $(notdir $r)),# Opposite link.
145
				$($l.__serial_id__))
146
			$($t.__serial_id__)))
147
endef
148

149
#
150
# Container and containment references.
151
#
152

153
# Params:
154
#   1. Property name.
155
#   2. New container.
156
#   3. Containment property in the container.
157
define __eObjectSetContainer
158
	$(assert $(not $(multiword $2)))
159

160
	$(for oldContainer <- $(get-field __eContainer),
161
		$(if $(basename $(oldContainer)),
162
			# Regular containment.
163
			$(set-field- oldContainer->__eContents,
164
				$(notdir $(basename $(oldContainer)))/$(this)),
165
			# Resource containment.
166
			$(set oldContainer->contentsRoot,)
167
		)
168
	)
169

170
	$(set-field __eContainer,$1/$3$2)
171

172
	$(set-field+ 2->__eContents,$3/$(this))
173
endef
174

175
# Params:
176
#   1. Property name.
177
#   2. What to add.
178
#   3. Opposite property.
179
define __eObjectSetContainment+
180
	$(silent-for this <- $2,
181
		# XXX Using '__this'. -- Eldar
182
		$(call __eObjectSetContainer,$3,$(__this),$1))
183
endef
184

185
# Params:
186
#   1. Property name.
187
#   2. What to add.
188
#   3. Opposite property.
189
__eObjectSetContainment* = \
190
	$(__eObjectSetContainment+)
191

192
# Params:
193
#   1. Property name.
194
#   2. What to remove.
195
#   3. Opposite property.
196
__eObjectSetContainment- = \
197
	$(foreach ,$2,$(warning $0: NIY))
198

199
# Params:
200
#   1. Property name.
201
#   2. New value.
202
#   3. Opposite property.
203
define __eObjectSetContainment
204
	$(call __eObjectSetContainment-,$1,$(get $1),$3)
205
	$(call __eObjectSetContainment+,$1,$2,$3)
206
endef
207

208
#
209
# Unidirectional cross-references.
210
#
211

212
# Params:
213
#   1. Property name.
214
#   2. What to add.
215
__eObjectSetUnidirectional+ = \
216
	$(set-field+ $1,$2)
217

218
# Params:
219
#   1. Property name.
220
#   2. What to add.
221
#   3. Empty.
222
#   4. Meta reference ID.
223
define __eObjectSetUnidirectional_link+
224
	$(set-field+ $1,
225
		$(for link <- $2,
226
			$(assert $(not $(get-field link->eSource)),
227
				Link $(link) has already got a source)
228
			$(set-field link->eSource,$4$(this))
229
			# 'link./target' for resolved links, 'link./' otherwise.
230
			$(link)./$(get-field link->eTarget))
231
	)
232
endef
233

234
# Params:
235
#   1. Property name.
236
#   2. What to add.
237
__eObjectSetUnidirectional* = \
238
	$(set-field* $1,$2)
239

240
# Params:
241
#   1. Property name.
242
#   2. What to add.
243
#   3. Empty.
244
#   4. Meta reference ID.
245
__eObjectSetUnidirectional_link* = \
246
	$(call __eObjectSetUnidirectional_link+,$1, \
247
		$(filter-out $(get-field $1),$2),,$4)
248

249
# Params:
250
#   1. Property name.
251
#   2. What to remove.
252
__eObjectSetUnidirectional- = \
253
	$(foreach ,$2,$(warning $0: NIY))
254

255
# Params:
256
#   1. Property name.
257
#   2. What to remove.
258
__eObjectSetUnidirectional_link- = \
259
	$(foreach ,$2,$(warning $0: NIY))
260

261
# Params:
262
#   1. Property name.
263
#   2. New value.
264
define __eObjectSetUnidirectional
265
	$(set-field $1,)#TODO Deresolve of link before removing not implemented
266
	$(call __eObjectSetUnidirectional+,$1,$2)
267
endef
268

269
# Params:
270
#   1. Property name.
271
#   2. New value.
272
#   3. Empty.
273
#   4. Meta reference ID.
274
define __eObjectSetUnidirectional_link
275
	$(call __eObjectSetUnidirectional_link-,$1,$(get-field $1))
276
	$(call __eObjectSetUnidirectional_link+,$1,$2,,$4)
277
endef
278

279
#
280
# Bidirectional cross-references.
281
#
282

283
# Params:
284
#   1. Property name.
285
#   2. What to add.
286
#   3. Opposite property.
287
define __eObjectSetBidirectional+
288
	$(set-field+ $1,$2)
289
	$(set-field+ 2->$3,$(this))
290
endef
291

292
# Params:
293
#   1. Property name.
294
#   2. What to add.
295
#   3. Opposite property.
296
#   4. Meta reference ID.
297
define __eObjectSetBidirectional_link+
298
	$(set-field+ $1,
299
		$(for link <- $2,
300
			$(assert $(not $(get-field link->eSource)),
301
				Link $(link) has already got a source)
302
			$(set-field link->eSource,$4$(this))
303
			# 'link./target' for resolved links, 'link./' otherwise.
304
			$(link)./$(for target <- $(get-field link->eTarget),
305
						$(set-field+ target->$3,$(link)$(this))
306
						$(target)))
307
	)
308
endef
309

310
# Params:
311
#   1. Property name.
312
#   2. What to add.
313
#   3. Opposite property.
314
__eObjectSetBidirectional* = \
315
	$(call __eObjectSetBidirectional+,$1,$(filter-out $(get-field $1),$2),$3)
316

317
# Params:
318
#   1. Property name.
319
#   2. What to add.
320
#   3. Opposite property.
321
#   4. Meta reference ID.
322
__eObjectSetBidirectional_link* = \
323
	$(call __eObjectSetBidirectional_link+,$1, \
324
		$(filter-out $(get-field $1),$2),$3,$4)
325

326
# Params:
327
#   1. Property name.
328
#   2. What to remove.
329
#   3. Opposite property.
330
__eObjectSetBidirectional- = \
331
	$(foreach ,$2,$(warning $0: NIY))
332

333
# Params:
334
#   1. Property name.
335
#   2. What to remove.
336
#   3. Opposite property.
337
__eObjectSetBidirectional_link- = \
338
	$(foreach ,$2,$(warning $0: NIY))
339

340
# Params:
341
#   1. Property name.
342
#   2. New value.
343
#   3. Opposite property.
344
define __eObjectSetBidirectional
345
	$(call __eObjectSetBidirectional-,$1,$(get-field $1),$3)
346
	$(call __eObjectSetBidirectional+,$1,$2,$3)
347
endef
348

349
# Params:
350
#   1. Property name.
351
#   2. New value.
352
#   3. Opposite property.
353
#   4. Meta reference ID.
354
define __eObjectSetBidirectional_link
355
	$(call __eObjectSetBidirectional_link-,$1,$(get-field $1),$3)
356
	$(call __eObjectSetBidirectional_link+,$1,$2,$3,$4)
357
endef
358

359
#
360
# On-demand linkage and link target resolution.
361
#
362

363
# Params:
364
#   1. List of unresolved (at the call time) references with './' at their ends.
365
#   2. Meta reference ID.
366
define __eObjectResolveLinks
367
	$(and $1,$(for resource <- $(get this->eResource),
368
#		$(for link <- $(subst ./,,$1),
369
#			$(warning on-demand linkage: \
370
#				[$(get link->eMetaReference)] '$(get link->name)'))
371
		$(invoke resource->resourceSet>linker>resolveLinksGroup,
372
			$(subst ./,,$1),$($2))
373
	),)
374
endef
375

376
# Params:
377
#   1. New value of 'eTarget' property of this link.
378
define __eLinkSetTarget
379
	$(assert $(not $(multiword $1)))
380
	$(assert $(invoke eSource),
381
		Can't set a target on the link with no source)
382

383
	$(for oldTarget <- $(get-field eTarget),
384
		$(warning $0: NIY; (old target: '$(oldTarget)')))
385

386
	$(set-field eTarget,$1)
387

388
	$(for newTarget <- $1,
389
		source <- $(invoke eSource),
390
		metaReference <- $(get eMetaReference),
391
		referenceProperty <- $(get metaReference->instanceProperty),
392

393
		$(set-field source->$(referenceProperty),
394
			$(patsubst $(this)./,$(this)./$(newTarget),
395
				$(get-field source->$(referenceProperty))))
396

397
		$(for opposite <- $(get metaReference->eOpposite),
398
			$(set-field+ newTarget->$(get opposite->instanceProperty),
399
				$(this)$(source)))
400
	)
401
endef
402

403
$(def_all)
404

405
endif # __model_eobject_mk
406

407

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.