-
Notifications
You must be signed in to change notification settings - Fork 0
/
FeatureLangGenerator.xtend
145 lines (132 loc) · 3.94 KB
/
FeatureLangGenerator.xtend
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
* generated by Xtext 2.30.0
*/
package de.tud.st.featurelang.generator
import de.tud.st.featurelang.featureLang.AssociationAction
import de.tud.st.featurelang.featureLang.AttributeAction
import de.tud.st.featurelang.featureLang.InheritanceAction
import de.tud.st.featurelang.featureLang.PriorityValue
import de.tud.st.featurelang.featureLang.UpdateAction
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.xtext.generator.AbstractGenerator
import org.eclipse.xtext.generator.IFileSystemAccess2
import org.eclipse.xtext.generator.IGeneratorContext
import de.tud.st.featurelang.featureLang.CreationStatement
import de.tud.st.featurelang.featureLang.ChangeStatement
import de.tud.st.featurelang.featureLang.Statement
/**
* Generates code from your model files on save.
*
* See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
*/
// @author Karl Kegel 2023
class FeatureLangGenerator extends AbstractGenerator {
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
val result = resource.allContents
.filter(Statement)
.map[compileStatement]
.join("&\n");
System.out.println(">>>")
System.out.println(result)
System.out.println("<<<")
fsa.generateFile("evolution.txt", result);
}
private def compileStatement(Statement s){
switch s {
ChangeStatement : s.compile
CreationStatement : s.compile
default : 'NOP'
}
}
private def compile(ChangeStatement s) '''
«val should = s.getPriority() !== null && s.getPriority().getPriority() === PriorityValue.SHOULD»
«IF should»
START OPTIONAL
«ENDIF»
OPEN CLASS «s.getTarget().name»
«IF s.getAction() !== null »
«s.getAction().getType().compileAction(s.isNegation())»
«ELSEIF s.getUpdate() !== null»
«s.getUpdate().compileUpdate()»
«ENDIF»
CLOSE CLASS «s.getTarget().name»
«IF should»
END OPTIONAL
«ENDIF»
'''
private def compile(CreationStatement s)'''
«val should = s.getPriority() !== null && s.getPriority().getPriority() === PriorityValue.SHOULD»
«val name = s.getClassElement().getName()»
«IF should»
START OPTIONAL
«ENDIF»
«IF s.isNegation() »
DELETE CLASS «name»
«ELSE»
CREATE CLASS «name»
«ENDIF»
«IF should»
END OPTIONAL
«ENDIF»
'''
private def compileAction(EObject a, boolean negation){
switch a {
AttributeAction : a.compileAttributeAction(negation)
AssociationAction : a.compileAssociationAction(negation)
InheritanceAction : a.compileInheritanceAction(negation)
default : 'NOP'
}
}
private def compileAttributeAction(AttributeAction a, boolean negation){
val attr = a.getAttribute()
val attrName = attr.getName()
'''
«IF negation»
DELETE ATTRIBUTE «attrName»
«ELSE»
ADD ATTRIBUTE «attrName»
OPEN ATTRIBUTE «attrName»
«IF a.getType() !== null»
SET TYPE «a.getType()»
«ELSE»
SET TYPE DEFAULT
«ENDIF»
CLOSE ATTRIBUTE «attrName»
«ENDIF»
'''
}
private def compileAssociationAction(AssociationAction a, boolean negation){
val targetClass = a.getTarget().getName()
val relation = a.getRelation()
'''
«IF negation»
DELETE ASSOCIATION «relation»
«ELSE»
ADD ASSOCIATION «relation» TARGET «targetClass»
«ENDIF»
'''
}
private def compileInheritanceAction(InheritanceAction a, boolean negation){
val targetClass = a.getParent().getName()
'''
«IF negation»
DELETE PARENT_RELATION «targetClass»
«ELSE»
ADD PARENT_RELATION «targetClass»
«ENDIF»
'''
}
private def compileUpdate(UpdateAction a) '''
«val should = a.getPriority() !== null && a.getPriority().getPriority() === PriorityValue.SHOULD»
«IF should»
START OPTIONAL
«ENDIF»
OPEN ATTRIBUTE «a.getAttribute().getName()»
SET TYPE «a.getType()»
CLOSE ATTRIBUTE «a.getAttribute().getName()»
«IF should»
END OPTIONAL
«ENDIF»
'''
}