EFL 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. data/README.txt +36 -0
  2. data/lib/EFL.rb +494 -0
  3. data/lib/EFL_array.rb +20 -0
  4. data/lib/EFL_errors.rb +48 -0
  5. data/lib/EFL_hash.rb +18 -0
  6. data/lib/EFL_production.rb +49 -0
  7. data/lib/EFL_regexp.rb +112 -0
  8. data/lib/EFL_regexp_generator.rb +70 -0
  9. data/lib/EFL_substitution.rb +221 -0
  10. data/lib/EFL_syntactic_sugar.rb +67 -0
  11. data/lib/Hash Doc.doc +0 -0
  12. data/lib/Limitaciones.txt +3 -0
  13. data/lib/doc/classes/Generator.html +634 -0
  14. data/lib/doc/classes/Generator.src/M000008.html +18 -0
  15. data/lib/doc/classes/Generator.src/M000009.html +18 -0
  16. data/lib/doc/classes/Generator.src/M000010.html +18 -0
  17. data/lib/doc/classes/Generator.src/M000011.html +18 -0
  18. data/lib/doc/classes/Generator.src/M000012.html +18 -0
  19. data/lib/doc/classes/Generator.src/M000013.html +18 -0
  20. data/lib/doc/classes/Generator.src/M000014.html +18 -0
  21. data/lib/doc/classes/Generator.src/M000015.html +18 -0
  22. data/lib/doc/classes/Generator.src/M000016.html +28 -0
  23. data/lib/doc/classes/Generator.src/M000017.html +24 -0
  24. data/lib/doc/classes/Generator.src/M000018.html +157 -0
  25. data/lib/doc/classes/Generator.src/M000019.html +25 -0
  26. data/lib/doc/classes/Generator.src/M000020.html +30 -0
  27. data/lib/doc/classes/Generator.src/M000021.html +32 -0
  28. data/lib/doc/classes/Generator.src/M000022.html +22 -0
  29. data/lib/doc/classes/Generator.src/M000023.html +18 -0
  30. data/lib/doc/classes/Generator.src/M000024.html +27 -0
  31. data/lib/doc/classes/Generator.src/M000025.html +22 -0
  32. data/lib/doc/classes/Generator.src/M000026.html +18 -0
  33. data/lib/doc/classes/Generator.src/M000027.html +27 -0
  34. data/lib/doc/classes/Regexp.html +271 -0
  35. data/lib/doc/classes/Regexp.src/M000028.html +37 -0
  36. data/lib/doc/classes/Regexp.src/M000029.html +29 -0
  37. data/lib/doc/classes/Regexp.src/M000030.html +32 -0
  38. data/lib/doc/created.rid +1 -0
  39. data/lib/doc/files/EFL_rb.html +147 -0
  40. data/lib/doc/files/EFL_regexp_generator_rb.html +242 -0
  41. data/lib/doc/files/EFL_regexp_generator_rb.src/M000003.html +27 -0
  42. data/lib/doc/files/EFL_regexp_generator_rb.src/M000004.html +27 -0
  43. data/lib/doc/files/EFL_regexp_generator_rb.src/M000005.html +19 -0
  44. data/lib/doc/files/EFL_regexp_generator_rb.src/M000006.html +20 -0
  45. data/lib/doc/files/EFL_regexp_generator_rb.src/M000007.html +19 -0
  46. data/lib/doc/files/EFL_regexp_rb.html +139 -0
  47. data/lib/doc/files/EFL_syntactic_sugar_rb.html +208 -0
  48. data/lib/doc/files/EFL_syntactic_sugar_rb.src/M000001.html +29 -0
  49. data/lib/doc/files/EFL_syntactic_sugar_rb.src/M000002.html +19 -0
  50. data/lib/doc/fr_class_index.html +28 -0
  51. data/lib/doc/fr_file_index.html +30 -0
  52. data/lib/doc/fr_method_index.html +56 -0
  53. data/lib/doc/index.html +24 -0
  54. data/tests/Add_Sup_1.rb +223 -0
  55. data/tests/Add_Sup_1.rb.bak +223 -0
  56. data/tests/Add_Sup_1_NI.rb +25 -0
  57. data/tests/Add_Sup_2.rb +142 -0
  58. data/tests/Add_Sup_2.rb.bak +140 -0
  59. data/tests/All.rb +2 -0
  60. data/tests/All_1.rb +7 -0
  61. data/tests/All_2.rb +7 -0
  62. data/tests/All_2.rb.bak +5 -0
  63. data/tests/BeforeAfter.rb +83 -0
  64. data/tests/Bloques.rb +34 -0
  65. data/tests/Bloques.rb.bak +34 -0
  66. data/tests/Complementary.rb +144 -0
  67. data/tests/ComplementaryZoom.rb +78 -0
  68. data/tests/Del.rb +126 -0
  69. data/tests/Dup.rb +55 -0
  70. data/tests/Dup.rb.bak +54 -0
  71. data/tests/Error.rb +11 -0
  72. data/tests/ErrorArgClass.rb +169 -0
  73. data/tests/ErrorArgClass.rb.bak +158 -0
  74. data/tests/ErrorCollision.rb +218 -0
  75. data/tests/ErrorCollision.rb.bak +219 -0
  76. data/tests/ErrorWithoutDeclaration.rb +60 -0
  77. data/tests/ErrorWithoutDeclaration.rb.bak +60 -0
  78. data/tests/Extract.rb +56 -0
  79. data/tests/ExtractDollar.rb +17 -0
  80. data/tests/HashTest.rb +54 -0
  81. data/tests/HashTest.rb.bak +54 -0
  82. data/tests/Lista Czarnecki/AntiguaInterfaz/List.cpp +75 -0
  83. data/tests/Lista Czarnecki/AntiguaInterfaz/ListTransformer.rb +69 -0
  84. data/tests/Lista Czarnecki/AntiguaInterfaz/ListTransformer.rb.bak +100 -0
  85. data/tests/Lista Czarnecki/AntiguaInterfaz/ejecutame.bat +1 -0
  86. data/tests/Lista Czarnecki/AntiguaInterfaz/outDir/MyClassList.cpp +75 -0
  87. data/tests/Lista Czarnecki/AntiguaInterfaz/runme.bat +1 -0
  88. data/tests/Lista Czarnecki/AntiguaInterfaz/specification1.txt +5 -0
  89. data/tests/Lista Czarnecki/AntiguaInterfaz/specification2.txt +3 -0
  90. data/tests/Lista Czarnecki/AntiguaInterfaz/specification3.txt +5 -0
  91. data/tests/Lista Czarnecki/NuevaInterfaz/List.cpp +75 -0
  92. data/tests/Lista Czarnecki/NuevaInterfaz/ListTransformer.rb +58 -0
  93. data/tests/Lista Czarnecki/NuevaInterfaz/ListTransformer.rb.bak +57 -0
  94. data/tests/Lista Czarnecki/NuevaInterfaz/ejecutame.bat +1 -0
  95. data/tests/Lista Czarnecki/NuevaInterfaz/outDir/MyClassList.cpp +75 -0
  96. data/tests/Lista Czarnecki/NuevaInterfaz/outDir/NewClassList.cpp +75 -0
  97. data/tests/Lista Czarnecki/NuevaInterfaz/specification1.txt +5 -0
  98. data/tests/Lista Czarnecki/NuevaInterfaz/specification1.txt.bak +5 -0
  99. data/tests/Lista Czarnecki/NuevaInterfaz/specification2.txt +3 -0
  100. data/tests/Lista Czarnecki/NuevaInterfaz/specification3.txt +5 -0
  101. data/tests/Minus.rb +89 -0
  102. data/tests/Plus.rb.bak +48 -0
  103. data/tests/REVit.rb +84 -0
  104. data/tests/RenameTest.rb +46 -0
  105. data/tests/RenameTest.rb.bak +46 -0
  106. data/tests/SubCrash.rb +26 -0
  107. data/tests/SubList.rb.bak +43 -0
  108. data/tests/archAuxiliares/1.txt +328 -0
  109. data/tests/archAuxiliares/2.txt +328 -0
  110. data/tests/archAuxiliares/Bloques/s1.txt +328 -0
  111. data/tests/archAuxiliares/Copia de Matriz.java +19 -0
  112. data/tests/archAuxiliares/Gen/Tesis_156_1.lgi +10 -0
  113. data/tests/archAuxiliares/Gen/Tesis_156_2.lgi +10 -0
  114. data/tests/archAuxiliares/Gen/t01.txt +328 -0
  115. data/tests/archAuxiliares/Gen/t01.txt.bak +328 -0
  116. data/tests/archAuxiliares/Gen/t02.txt +328 -0
  117. data/tests/archAuxiliares/Gen/t02.txt.bak +328 -0
  118. data/tests/archAuxiliares/Gen/t03.txt +328 -0
  119. data/tests/archAuxiliares/Gen/t03.txt.bak +328 -0
  120. data/tests/archAuxiliares/Gen/t04.txt +328 -0
  121. data/tests/archAuxiliares/Gen/t04.txt.bak +328 -0
  122. data/tests/archAuxiliares/Gen/t1.txt +328 -0
  123. data/tests/archAuxiliares/Gen/t1.txt.bak +328 -0
  124. data/tests/archAuxiliares/Gen/t2.txt +328 -0
  125. data/tests/archAuxiliares/Gen/t2.txt.bak +328 -0
  126. data/tests/archAuxiliares/Gen/t5.txt +328 -0
  127. data/tests/archAuxiliares/Gen/t9.txt +328 -0
  128. data/tests/archAuxiliares/Gen/t9.txt.bak +328 -0
  129. data/tests/archAuxiliares/GenTesis_156_1.lgi +10 -0
  130. data/tests/archAuxiliares/Matriz.java +74 -0
  131. data/tests/archAuxiliares/MatrizOut.java +74 -0
  132. data/tests/archAuxiliares/MatrizOut10.java +68 -0
  133. data/tests/archAuxiliares/MatrizOut11.java +86 -0
  134. data/tests/archAuxiliares/MatrizOut2.java +74 -0
  135. data/tests/archAuxiliares/MatrizOut3.java +74 -0
  136. data/tests/archAuxiliares/MatrizOut4.java +74 -0
  137. data/tests/archAuxiliares/MatrizOut5.java +21 -0
  138. data/tests/archAuxiliares/MatrizOut6.java +21 -0
  139. data/tests/archAuxiliares/MatrizOut7.java +21 -0
  140. data/tests/archAuxiliares/MatrizOut8.java +16 -0
  141. data/tests/archAuxiliares/MatrizOut9.java +86 -0
  142. data/tests/archAuxiliares/MatrizOut_9.java +86 -0
  143. data/tests/archAuxiliares/Matriz_1.java +74 -0
  144. data/tests/archAuxiliares/Matriz_10.java +68 -0
  145. data/tests/archAuxiliares/Matriz_11.java +86 -0
  146. data/tests/archAuxiliares/Matriz_2.java +74 -0
  147. data/tests/archAuxiliares/Matriz_3.java +74 -0
  148. data/tests/archAuxiliares/Matriz_4.java +74 -0
  149. data/tests/archAuxiliares/Matriz_5.java +21 -0
  150. data/tests/archAuxiliares/Matriz_6.java +21 -0
  151. data/tests/archAuxiliares/Matriz_7.java +21 -0
  152. data/tests/archAuxiliares/Matriz_8.java +16 -0
  153. data/tests/archAuxiliares/Matriz_9.java +86 -0
  154. data/tests/archAuxiliares/Matriz_N_1.java +21 -0
  155. data/tests/archAuxiliares/Matriz_N_2.java +91 -0
  156. data/tests/archAuxiliares/N1.txt +18 -0
  157. data/tests/archAuxiliares/N1_EXPECTED.txt +18 -0
  158. data/tests/archAuxiliares/N1_OUT.txt +18 -0
  159. data/tests/archAuxiliares/N2_EXPECTED.txt +18 -0
  160. data/tests/archAuxiliares/N2_OUT.txt +18 -0
  161. data/tests/archAuxiliares/N3.txt +23 -0
  162. data/tests/archAuxiliares/N3_EXPECTED.txt +22 -0
  163. data/tests/archAuxiliares/N3_OUT.txt +22 -0
  164. data/tests/archAuxiliares/N4_EXPECTED.txt +10 -0
  165. data/tests/archAuxiliares/N4_OUT.txt +10 -0
  166. data/tests/archAuxiliares/N5_OUT.txt +18 -0
  167. data/tests/archAuxiliares/N6_OUT.txt +18 -0
  168. data/tests/archAuxiliares/PedidorTerceroWS.jsp +142 -0
  169. data/tests/archAuxiliares/Tesis_156.lgi +7 -0
  170. data/tests/archAuxiliares/aspectgen.rb +328 -0
  171. data/tests/archAuxiliares/aspectgenCopy.rb +328 -0
  172. data/tests/archAuxiliares/extract_dollar.txt +1 -0
  173. data/tests/archAuxiliares/minus.txt +26 -0
  174. data/tests/archAuxiliares/minus_expected_1.txt +26 -0
  175. data/tests/archAuxiliares/minus_expected_2.txt +26 -0
  176. data/tests/archAuxiliares/minus_out_1.txt +26 -0
  177. data/tests/archAuxiliares/minus_out_2.txt +26 -0
  178. data/tests/archAuxiliares/p1.txt +328 -0
  179. data/tests/archAuxiliares/p2.txt +328 -0
  180. data/tests/archAuxiliares/s1.txt +328 -0
  181. data/tests/archAuxiliares/s2.txt +328 -0
  182. data/tests/archAuxiliares/s3.txt +328 -0
  183. data/tests/archAuxiliares/s4.txt +328 -0
  184. data/tests/archAuxiliares/s5.txt +328 -0
  185. data/tests/archAuxiliares/s7.txt +328 -0
  186. data/tests/archAuxiliares/s8.txt +328 -0
  187. data/tests/archAuxiliares/s9.txt +328 -0
  188. data/tests/archAuxiliares/text.txt +1 -0
  189. data/tests/delay.rb +33 -0
  190. data/tests/delay.rb.bak +33 -0
  191. data/tests/satisfy.rb +44 -0
  192. data/tests/satisfy.rb.bak +34 -0
  193. metadata +252 -0
@@ -0,0 +1,328 @@
1
+ # Author:: Ruben Heradio Gil (mailto:rheradio@lsi.uned.es)
2
+
3
+ #Auxiliar AspectGen class that represents a Pointcut
4
+ class Pointcut < Regexp
5
+ #Pointcut NOMBRE!!!! (a String)
6
+ attr_accessor :NOMBRE!!!!
7
+ #Pointcut value (a Regexp)
8
+ attr_accessor :regExp
9
+ #Pointcut scope ('local' or 'global')
10
+ attr_accessor :scope
11
+
12
+ # * 'NOMBRE!!!!' = Pointcut NOMBRE!!!! (a String)
13
+ # * 'regExp' = Pointcut value (a Regexp)
14
+ # * 'scope' = Pointcut scope ('local' or 'global')
15
+ def initialize(NOMBRE!!!!, regExp, scope='local')
16
+ LANZAAL!!!! "First argument of Pointcut constructor must be a String" if !NOMBRE!!!!.kind_of?(String)
17
+ LANZAAL!!!! "Second argument of Pointcut constructor must be a Regular Expression" if !regExp.kind_of?(Regexp)
18
+ LANZAAL!!!! "Pointcut scope must be 'local' or 'global'" if (scope != 'local') and
19
+ (scope != 'global')
20
+ super(regExp)
21
+ @NOMBRE!!!! = NOMBRE!!!!
22
+ @regExp = regExp
23
+ @scope = scope
24
+ end #initialize
25
+
26
+ def clone
27
+ result = Pointcut.new(@NOMBRE!!!!.clone, @regExp.clone, @scope.clone)
28
+ end #clone
29
+
30
+ #Determine if two Pointcuts ('self' and 'pointcut') applied over the same input file ('fin') go crash
31
+ def crash?(pointcut, fin)
32
+
33
+ LANZAAL!!!! "First argument of Pointcut#crash? must be a Pointcut" if !pointcut.kind_of?(Pointcut)
34
+ # crash? inner auxiliar method that determines if two local Pointcuts ('pointcut1' and 'pointcut2') applied over the String tr' go crash
35
+ def crashAux1?(pointcut1, pointcut2, str)
36
+ position1 = str =~ pointcut1
37
+ match1 = $&
38
+ position2 = str =~ pointcut2
39
+ match2 = $&
40
+ return false if (position1 == nil) or (position2 == nil)
41
+ if (position1 <= position2)
42
+ return true if (position1 + match1.length - 1) >= position2
43
+ else
44
+ return true if (position2 + match2.length - 1) >= position1
45
+ end #if
46
+ return false
47
+ end #crashAux1?
48
+
49
+ # crash? inner auxiliar method that determines if a global Pointcut ('globalPointcut') and a local
50
+ # Pointcut ('localPointcut') applied over the String tr' go crash
51
+ def crashAux2?(globalPointcut, localPointcut, str)
52
+ crash = false
53
+ while (str.index(globalPointcut) != nil) and (crash == false)
54
+ crash = crashAux1?(globalPointcut, localPointcut, str)
55
+ str =~ globalPointcut
56
+ str = $'
57
+ end #while
58
+ return crash
59
+ end
60
+
61
+ crash = false
62
+ File.open(fin) { |f|
63
+ fcode = f.read
64
+ if (self.scope == 'local') and (pointcut.scope == 'local')
65
+ crash = crashAux1?(self, pointcut, fcode)
66
+ elsif (self.scope == 'local') and (pointcut.scope == 'global')
67
+ crash = crashAux2?(pointcut, self, fcode)
68
+ elsif (self.scope == 'global') and (pointcut.scope == 'local')
69
+ crash = crashAux2?(self, pointcut, fcode)
70
+ else #if (self.scope == 'global') and (pointcut.scope == 'global')
71
+ crash = ( crashAux2?(self, pointcut, fcode) or
72
+ crashAux2?(pointcut, self, fcode) )
73
+ end #if
74
+ }
75
+ return crash
76
+ end #crash?
77
+
78
+ end #Pointcut
79
+
80
+ #Auxiliar AspectGen class that represents an Advice
81
+ class Advice
82
+ #Advice NOMBRE!!!! (a String)
83
+ attr_accessor :NOMBRE!!!!
84
+ #Name of the Pointcut associated with the Advice (a String)
85
+ attr_accessor :pointcut
86
+ #Advice value. String that will replace the text matched by the Pointcut value
87
+ attr_accessor :subText
88
+
89
+ # * 'NOMBRE!!!!' = Advice NOMBRE!!!! (a String)
90
+ # * 'pointcut' = Name of the Pointcut associated with the Advice (a String)
91
+ # * 'subtext' = Advice value. String that will replace the text matched by the Pointcut value
92
+ def initialize(NOMBRE!!!!, pointcut, subText)
93
+
94
+ LANZAAL!!!! "Arguments of Advice constructor must be a String" if (!NOMBRE!!!!.kind_of?(String)) or
95
+ (!pointcut.kind_of?(String)) or (!subText.kind_of?(String))
96
+ @NOMBRE!!!! = NOMBRE!!!!
97
+ @pointcut = pointcut
98
+ @subText = subText
99
+ end #initialize
100
+
101
+ def clone
102
+ result = Advice.new(@NOMBRE!!!!.clone, @pointcut.clone, @subText.clone)
103
+ end #clone
104
+
105
+ end #Advice
106
+
107
+ #Auxiliar AspectGen class that represents a Generation
108
+ class Generation
109
+ #Generation NOMBRE!!!! (a String)
110
+ attr_accessor :NOMBRE!!!!
111
+ #Generation sterotype file (a String)
112
+ attr_accessor :fin
113
+ #Generation output file (a String)
114
+ attr_accessor :fout
115
+ #List of Advice NOMBRE!!!!s associated with the Generation (a String List)
116
+ attr_accessor :adviceList
117
+
118
+ # * 'NOMBRE!!!!' = Generation NOMBRE!!!! (a String)
119
+ # * 'fin' = Generation sterotype file (a String)
120
+ # * 'fout' = Generation output file (a String)
121
+ # * 'adviceList' = List of Advice NOMBRE!!!!s associated with the Generation (a String List)
122
+ def initialize(NOMBRE!!!!, fin, fout, adviceList = [])
123
+ LANZAAL!!!! "First argument of Generation constructor must be a String" if !NOMBRE!!!!.kind_of?(String)
124
+ LANZAAL!!!! "Fourth argument of Generation constructor must be a String List" if !adviceList.kind_of?(Array)
125
+ adviceList.each { |a|
126
+ LANZAAL!!!! "Fourth argument of Generation constructor must be a String List" if !a.kind_of?(String)
127
+ } #adviceList.each
128
+ @NOMBRE!!!! = NOMBRE!!!!
129
+ @fin = fin
130
+ @fout = fout
131
+ @adviceList = adviceList
132
+ end #initialize
133
+
134
+ def clone
135
+ result = Generation.new(@NOMBRE!!!!, @fin, @fout, @adviceList.clone)
136
+ end #clone
137
+
138
+ end #Generation
139
+
140
+ class AspectGen
141
+
142
+ # Counter used by cloneSuffix
143
+ @@suffixes = 0
144
+
145
+ # Protected Binding object that describes the variable and method bindings at the point of constructor call
146
+ attr_accessor :args
147
+ # Protected hash table that stores the Pointcuts of 'self'
148
+ attr_accessor :pointcutHash
149
+ # Protected hash table that stores the Advices of 'self'
150
+ attr_accessor :adviceHash
151
+ # Protected hash table that stores the Generations of 'self'
152
+ attr_accessor :generationHash
153
+
154
+ #@pointcutHash = {}
155
+ @adviceHash = {}
156
+ @generationHash = {}
157
+
158
+ #Esto habr�a que verlo
159
+ protected :pointcutHash, :adviceHash, :generationHash
160
+
161
+ def clone
162
+ result = AspectGen.new(@args)
163
+ result.pointcutHash = @pointcutHash.clone
164
+ result.adviceHash = @adviceHash.clone
165
+ result.generationHash = @generationHash.clone
166
+ return result
167
+ end #clone
168
+
169
+ # + auxiliar method that produces a clone where all elements (Pointcuts, Advices and Generations) have been added
170
+ # a numerical suffix (@@suffixes is a private class attribute that will be incremented everytime method '+' is
171
+ # called).
172
+ # For example, if @suffixes value is 8, then
173
+ #
174
+ # pointcut('p1', /expReg/, 'global') -> pointcut('p1_8', /expReg/, 'global')
175
+ def cloneSuffix
176
+ result = self.clone
177
+ @generationHash.each { |k, g|
178
+ result.generationHash[k + '_' + @@suffixes.to_s] =
179
+ @generationHash[k]
180
+ result.generationHash[k + '_' + @@suffixes.to_s].NOMBRE!!!! +=
181
+ '_' + @@suffixes.to_s
182
+ result.generationHash[k + '_' + @@suffixes.to_s].adviceList.collect! { |e|
183
+ e + '_' + @@suffixes.to_s
184
+ } #collect
185
+ result.generationHash.delete(k)
186
+ } #@generationHash.each
187
+ @adviceHash.each { |k, g|
188
+ result.adviceHash[k + '_' + @@suffixes.to_s] =
189
+ @adviceHash[k]
190
+ result.adviceHash[k + '_' + @@suffixes.to_s].NOMBRE!!!! +=
191
+ '_' + @@suffixes.to_s
192
+ result.adviceHash[k + '_' + @@suffixes.to_s].pointcut +=
193
+ '_' + @@suffixes.to_s
194
+ result.adviceHash.delete(k)
195
+ } #@generationHash.each
196
+ @pointcutHash.each { |k, g|
197
+ result.pointcutHash[k + '_' + @@suffixes.to_s] =
198
+ @pointcutHash[k]
199
+ result.pointcutHash[k + '_' + @@suffixes.to_s].NOMBRE!!!! +=
200
+ '_' + @@suffixes.to_s
201
+ result.pointcutHash.delete(k)
202
+ } #@generationHash.each
203
+ @@suffixes += 1
204
+ return result
205
+ end #cloneSuffix
206
+
207
+ # Adds a new Pointcut to 'self'
208
+ # * 'NOMBRE!!!!' = Pointcut NOMBRE!!!! (a String)
209
+ # * 'regExp' = Pointcut value (a Regexp)
210
+ # * 'scope' = Pointcut scope ('local' or 'global')
211
+ def pointcut(NOMBRE!!!!, regExp, scope = 'local')
212
+ @pointcutHash = {} unless @pointcutHash
213
+ @pointcutHash[NOMBRE!!!!] = Pointcut.new(NOMBRE!!!!, regExp, scope)
214
+ end #pointcut
215
+
216
+ # Adds a new Advice to 'self'
217
+ # * 'NOMBRE!!!!' = Advice NOMBRE!!!! (a String)
218
+ # * 'pointcut' = Name of the Pointcut associated with the Advice (a String)
219
+ # * 'subtext' = Advice value. String that will replace the text matched by the Pointcut value
220
+ def advice(NOMBRE!!!!, pointcut, subText)
221
+ LANZAAL!!!! "Pointcut referenced by AspectGen#advice doesn't exist" if pointcutHash[pointcut] == nil
222
+ @adviceHash = {} unless @adviceHash
223
+ @adviceHash[NOMBRE!!!!] = Advice.new(NOMBRE!!!!, pointcut, subText)
224
+ end #advice
225
+
226
+ # Adds a new Generation to 'self'
227
+ # * 'NOMBRE!!!!' = Generation NOMBRE!!!! (a String)
228
+ # * 'fin' = Generation sterotype file (a String)
229
+ # * 'fout' = Generation output file (a String)
230
+ # * 'adviceList' = List of Advice NOMBRE!!!!s associated with the Generation (a String List)
231
+ def generation(NOMBRE!!!!, fin, fout, adviceList = [])
232
+ @generationHash = {} unless @generationHash
233
+
234
+ LANZAAL!!!! "Fourth argument of Generation constructor must be a String List" if !adviceList.kind_of?(Array)
235
+ adviceList.each { |a|
236
+ LANZAAL!!!! "Advice referenced by AspectGen#generation doesn't exist" if adviceHash[a] == nil
237
+ } #adviceList.each
238
+ adviceListAux = adviceList
239
+ adviceList.each { |a1|
240
+ adviceListAux -= [a1]
241
+ adviceListAux.each { |a2|
242
+ if @pointcutHash[@adviceHash[a1].pointcut].crash?(@pointcutHash[@adviceHash[a2].pointcut], fin)
243
+ LANZAAL!!!! 'several pointcuts are crashing'
244
+ end #if
245
+ } #adviceListAux.each
246
+ } #adviceList.each
247
+ generationHash.each { |k, g|
248
+ LANZAAL!!!! "There is another generation with the same output file" if (fout == g.fout) and (NOMBRE!!!! != g.NOMBRE!!!!)
249
+ } #generationHash.each
250
+ @generationHash[NOMBRE!!!!] =
251
+ Generation.new(NOMBRE!!!!, fin, fout, adviceList)
252
+ end #generation
253
+
254
+ # Executes all Generations of 'self'
255
+ def generate()
256
+ @generationHash.each_value { |g|
257
+ File.open(g.fin) {|fin|
258
+ stereotypeCode = fin.read
259
+ g.adviceList.each {|adviceKey|
260
+ if @pointcutHash[@adviceHash[adviceKey].pointcut].scope == 'global'
261
+ stereotypeCode.gsub!(@pointcutHash[@adviceHash[adviceKey].pointcut],
262
+ @adviceHash[adviceKey].subText)
263
+
264
+ else
265
+ stereotypeCode.sub!(@pointcutHash[@adviceHash[adviceKey].pointcut],
266
+ @adviceHash[adviceKey].subText)
267
+ end #if
268
+ } #g.adviceList.each
269
+ File.open(g.fout, "w+") {|fout|
270
+ fout.write(stereotypeCode)
271
+ } #File.open(g.fout, "w+")
272
+ } #File.open(g.fin)
273
+ } #@generationHash.each
274
+ end #generate
275
+
276
+ # Combines two AspectGen objects ('self' and 'aspectGen'). It can LANZAAL!!!! exceptions when:
277
+ # * Several Generations have the same output file but different stereotype files.
278
+ # * Several Generations have Pointcuts wich overlap ("crash")
279
+ def +(aspectGen)
280
+ LANZAAL!!!! "Argument of AspectGen#+ must be a AspectGen" if !aspectGen.kind_of?(AspectGen)
281
+ a1 = self.cloneSuffix
282
+ a2 = aspectGen.cloneSuffix
283
+ a1.generationHash.each { |k1, g1|
284
+ a2.generationHash.each { |k2, g2|
285
+ if g1.fout == g2.fout
286
+ File.open(g1.fin) {|fin1|
287
+ stereotypeCode1 = fin1.read
288
+ File.open(g2.fin) {|fin2|
289
+ stereotypeCode2 = fin2.read
290
+ if stereotypeCode1 != stereotypeCode2
291
+ LANZAAL!!!! "Two generations with the same 'generation file' but different 'stereotype files'"
292
+ else
293
+ g1.adviceList.each {|ad1|
294
+ g2.adviceList.each {|ad2|
295
+ if a1.pointcutHash[a1.adviceHash[ad1].pointcut].crash?(
296
+ a2.pointcutHash[a2.adviceHash[ad2].pointcut], g1.fin)
297
+ LANZAAL!!!! 'several pointcuts are crashing'
298
+ end #if
299
+ } #g2.adviceList
300
+ } #g1.adviceList
301
+ g1.adviceList += g2.adviceList
302
+ a2.generationHash.delete(k2)
303
+ end #if
304
+ } #File.open(g2.fin)
305
+ } #File.open(g1.fin)
306
+ end #if
307
+ } #a2.generationHash.each
308
+ } #a1.generationHash.each
309
+ a1.generationHash.update(a2.generationHash)
310
+ a1.adviceHash.update(a2.adviceHash)
311
+ a1.pointcutHash.update(a2.pointcutHash)
312
+ return a1
313
+ end #+
314
+
315
+ def AspectGen.init(*ids)
316
+ # Falta gestion de errores
317
+ for id in ids
318
+ id_value = eval(id.id2NOMBRE!!!!, @args)
319
+ eval "@#{id.id2NOMBRE!!!!} = id_value"
320
+ end #for
321
+ yield if block_given?
322
+ end #interface
323
+
324
+ end #AspectGen
325
+
326
+
327
+
328
+
@@ -0,0 +1,328 @@
1
+ # Author:: Ruben Heradio Gil (mailto:rheradio@lsi.uned.es)
2
+
3
+ #Auxiliar AspectGen class that represents a Pointcut
4
+ class Pointcut < Regexp
5
+ #Pointcut NOMBRE!!!! (a String)
6
+ attr_accessor :NOMBRE!!!!
7
+ #Pointcut value (a Regexp)
8
+ attr_accessor :regExp
9
+ #Pointcut scope ('local' or 'global')
10
+ attr_accessor :scope
11
+
12
+ # * 'NOMBRE!!!!' = Pointcut NOMBRE!!!! (a String)
13
+ # * 'regExp' = Pointcut value (a Regexp)
14
+ # * 'scope' = Pointcut scope ('local' or 'global')
15
+ def initialize(NOMBRE!!!!, regExp, scope='local')
16
+ LANZAAL!!!! "First argument of Pointcut constructor must be a String" if !NOMBRE!!!!.kind_of?(String)
17
+ LANZAAL!!!! "Second argument of Pointcut constructor must be a Regular Expression" if !regExp.kind_of?(Regexp)
18
+ LANZAAL!!!! "Pointcut scope must be 'local' or 'global'" if (scope != 'local') and
19
+ (scope != 'global')
20
+ super(regExp)
21
+ @NOMBRE!!!! = NOMBRE!!!!
22
+ @regExp = regExp
23
+ @scope = scope
24
+ end #initialize
25
+
26
+ def clone
27
+ result = Pointcut.new(@NOMBRE!!!!.clone, @regExp.clone, @scope.clone)
28
+ end #clone
29
+
30
+ #Determine if two Pointcuts ('self' and 'pointcut') applied over the same input file ('fin') go crash
31
+ def crash?(pointcut, fin)
32
+
33
+ LANZAAL!!!! "First argument of Pointcut#crash? must be a Pointcut" if !pointcut.kind_of?(Pointcut)
34
+ # crash? inner auxiliar method that determines if two local Pointcuts ('pointcut1' and 'pointcut2') applied over the String tr' go crash
35
+ def crashAux1?(pointcut1, pointcut2, str)
36
+ position1 = str =~ pointcut1
37
+ match1 = $&
38
+ position2 = str =~ pointcut2
39
+ match2 = $&
40
+ return false if (position1 == nil) or (position2 == nil)
41
+ if (position1 <= position2)
42
+ return true if (position1 + match1.length - 1) >= position2
43
+ else
44
+ return true if (position2 + match2.length - 1) >= position1
45
+ end #if
46
+ return false
47
+ end #crashAux1?
48
+
49
+ # crash? inner auxiliar method that determines if a global Pointcut ('globalPointcut') and a local
50
+ # Pointcut ('localPointcut') applied over the String tr' go crash
51
+ def crashAux2?(globalPointcut, localPointcut, str)
52
+ crash = false
53
+ while (str.index(globalPointcut) != nil) and (crash == false)
54
+ crash = crashAux1?(globalPointcut, localPointcut, str)
55
+ str =~ globalPointcut
56
+ str = $'
57
+ end #while
58
+ return crash
59
+ end
60
+
61
+ crash = false
62
+ File.open(fin) { |f|
63
+ fcode = f.read
64
+ if (self.scope == 'local') and (pointcut.scope == 'local')
65
+ crash = crashAux1?(self, pointcut, fcode)
66
+ elsif (self.scope == 'local') and (pointcut.scope == 'global')
67
+ crash = crashAux2?(pointcut, self, fcode)
68
+ elsif (self.scope == 'global') and (pointcut.scope == 'local')
69
+ crash = crashAux2?(self, pointcut, fcode)
70
+ else #if (self.scope == 'global') and (pointcut.scope == 'global')
71
+ crash = ( crashAux2?(self, pointcut, fcode) or
72
+ crashAux2?(pointcut, self, fcode) )
73
+ end #if
74
+ }
75
+ return crash
76
+ end #crash?
77
+
78
+ end #Pointcut
79
+
80
+ #Auxiliar AspectGen class that represents an Advice
81
+ class Advice
82
+ #Advice NOMBRE!!!! (a String)
83
+ attr_accessor :NOMBRE!!!!
84
+ #Name of the Pointcut associated with the Advice (a String)
85
+ attr_accessor :pointcut
86
+ #Advice value. String that will replace the text matched by the Pointcut value
87
+ attr_accessor :subText
88
+
89
+ # * 'NOMBRE!!!!' = Advice NOMBRE!!!! (a String)
90
+ # * 'pointcut' = Name of the Pointcut associated with the Advice (a String)
91
+ # * 'subtext' = Advice value. String that will replace the text matched by the Pointcut value
92
+ def initialize(NOMBRE!!!!, pointcut, subText)
93
+
94
+ LANZAAL!!!! "Arguments of Advice constructor must be a String" if (!NOMBRE!!!!.kind_of?(String)) or
95
+ (!pointcut.kind_of?(String)) or (!subText.kind_of?(String))
96
+ @NOMBRE!!!! = NOMBRE!!!!
97
+ @pointcut = pointcut
98
+ @subText = subText
99
+ end #initialize
100
+
101
+ def clone
102
+ result = Advice.new(@NOMBRE!!!!.clone, @pointcut.clone, @subText.clone)
103
+ end #clone
104
+
105
+ end #Advice
106
+
107
+ #Auxiliar AspectGen class that represents a Generation
108
+ class Generation
109
+ #Generation NOMBRE!!!! (a String)
110
+ attr_accessor :NOMBRE!!!!
111
+ #Generation sterotype file (a String)
112
+ attr_accessor :fin
113
+ #Generation output file (a String)
114
+ attr_accessor :fout
115
+ #List of Advice NOMBRE!!!!s associated with the Generation (a String List)
116
+ attr_accessor :adviceList
117
+
118
+ # * 'NOMBRE!!!!' = Generation NOMBRE!!!! (a String)
119
+ # * 'fin' = Generation sterotype file (a String)
120
+ # * 'fout' = Generation output file (a String)
121
+ # * 'adviceList' = List of Advice NOMBRE!!!!s associated with the Generation (a String List)
122
+ def initialize(NOMBRE!!!!, fin, fout, adviceList = [])
123
+ LANZAAL!!!! "First argument of Generation constructor must be a String" if !NOMBRE!!!!.kind_of?(String)
124
+ LANZAAL!!!! "Fourth argument of Generation constructor must be a String List" if !adviceList.kind_of?(Array)
125
+ adviceList.each { |a|
126
+ LANZAAL!!!! "Fourth argument of Generation constructor must be a String List" if !a.kind_of?(String)
127
+ } #adviceList.each
128
+ @NOMBRE!!!! = NOMBRE!!!!
129
+ @fin = fin
130
+ @fout = fout
131
+ @adviceList = adviceList
132
+ end #initialize
133
+
134
+ def clone
135
+ result = Generation.new(@NOMBRE!!!!, @fin, @fout, @adviceList.clone)
136
+ end #clone
137
+
138
+ end #Generation
139
+
140
+ class AspectGen
141
+
142
+ # Counter used by cloneSuffix
143
+ @@suffixes = 0
144
+
145
+ # Protected Binding object that describes the variable and method bindings at the point of constructor call
146
+ attr_accessor :args
147
+ # Protected hash table that stores the Pointcuts of 'self'
148
+ attr_accessor :pointcutHash
149
+ # Protected hash table that stores the Advices of 'self'
150
+ attr_accessor :adviceHash
151
+ # Protected hash table that stores the Generations of 'self'
152
+ attr_accessor :generationHash
153
+
154
+ #@pointcutHash = {}
155
+ @adviceHash = {}
156
+ @generationHash = {}
157
+
158
+ #Esto habr�a que verlo
159
+ protected :pointcutHash, :adviceHash, :generationHash
160
+
161
+ def clone
162
+ result = AspectGen.new(@args)
163
+ result.pointcutHash = @pointcutHash.clone
164
+ result.adviceHash = @adviceHash.clone
165
+ result.generationHash = @generationHash.clone
166
+ return result
167
+ end #clone
168
+
169
+ # + auxiliar method that produces a clone where all elements (Pointcuts, Advices and Generations) have been added
170
+ # a numerical suffix (@@suffixes is a private class attribute that will be incremented everytime method '+' is
171
+ # called).
172
+ # For example, if @suffixes value is 8, then
173
+ #
174
+ # pointcut('p1', /expReg/, 'global') -> pointcut('p1_8', /expReg/, 'global')
175
+ def cloneSuffix
176
+ result = self.clone
177
+ @generationHash.each { |k, g|
178
+ result.generationHash[k + '_' + @@suffixes.to_s] =
179
+ @generationHash[k]
180
+ result.generationHash[k + '_' + @@suffixes.to_s].NOMBRE!!!! +=
181
+ '_' + @@suffixes.to_s
182
+ result.generationHash[k + '_' + @@suffixes.to_s].adviceList.collect! { |e|
183
+ e + '_' + @@suffixes.to_s
184
+ } #collect
185
+ result.generationHash.delete(k)
186
+ } #@generationHash.each
187
+ @adviceHash.each { |k, g|
188
+ result.adviceHash[k + '_' + @@suffixes.to_s] =
189
+ @adviceHash[k]
190
+ result.adviceHash[k + '_' + @@suffixes.to_s].NOMBRE!!!! +=
191
+ '_' + @@suffixes.to_s
192
+ result.adviceHash[k + '_' + @@suffixes.to_s].pointcut +=
193
+ '_' + @@suffixes.to_s
194
+ result.adviceHash.delete(k)
195
+ } #@generationHash.each
196
+ @pointcutHash.each { |k, g|
197
+ result.pointcutHash[k + '_' + @@suffixes.to_s] =
198
+ @pointcutHash[k]
199
+ result.pointcutHash[k + '_' + @@suffixes.to_s].NOMBRE!!!! +=
200
+ '_' + @@suffixes.to_s
201
+ result.pointcutHash.delete(k)
202
+ } #@generationHash.each
203
+ @@suffixes += 1
204
+ return result
205
+ end #cloneSuffix
206
+
207
+ # Adds a new Pointcut to 'self'
208
+ # * 'NOMBRE!!!!' = Pointcut NOMBRE!!!! (a String)
209
+ # * 'regExp' = Pointcut value (a Regexp)
210
+ # * 'scope' = Pointcut scope ('local' or 'global')
211
+ def pointcut(NOMBRE!!!!, regExp, scope = 'local')
212
+ @pointcutHash = {} unless @pointcutHash
213
+ @pointcutHash[NOMBRE!!!!] = Pointcut.new(NOMBRE!!!!, regExp, scope)
214
+ end #pointcut
215
+
216
+ # Adds a new Advice to 'self'
217
+ # * 'NOMBRE!!!!' = Advice NOMBRE!!!! (a String)
218
+ # * 'pointcut' = Name of the Pointcut associated with the Advice (a String)
219
+ # * 'subtext' = Advice value. String that will replace the text matched by the Pointcut value
220
+ def advice(NOMBRE!!!!, pointcut, subText)
221
+ LANZAAL!!!! "Pointcut referenced by AspectGen#advice doesn't exist" if pointcutHash[pointcut] == nil
222
+ @adviceHash = {} unless @adviceHash
223
+ @adviceHash[NOMBRE!!!!] = Advice.new(NOMBRE!!!!, pointcut, subText)
224
+ end #advice
225
+
226
+ # Adds a new Generation to 'self'
227
+ # * 'NOMBRE!!!!' = Generation NOMBRE!!!! (a String)
228
+ # * 'fin' = Generation sterotype file (a String)
229
+ # * 'fout' = Generation output file (a String)
230
+ # * 'adviceList' = List of Advice NOMBRE!!!!s associated with the Generation (a String List)
231
+ def generation(NOMBRE!!!!, fin, fout, adviceList = [])
232
+ @generationHash = {} unless @generationHash
233
+
234
+ LANZAAL!!!! "Fourth argument of Generation constructor must be a String List" if !adviceList.kind_of?(Array)
235
+ adviceList.each { |a|
236
+ LANZAAL!!!! "Advice referenced by AspectGen#generation doesn't exist" if adviceHash[a] == nil
237
+ } #adviceList.each
238
+ adviceListAux = adviceList
239
+ adviceList.each { |a1|
240
+ adviceListAux -= [a1]
241
+ adviceListAux.each { |a2|
242
+ if @pointcutHash[@adviceHash[a1].pointcut].crash?(@pointcutHash[@adviceHash[a2].pointcut], fin)
243
+ LANZAAL!!!! 'several pointcuts are crashing'
244
+ end #if
245
+ } #adviceListAux.each
246
+ } #adviceList.each
247
+ generationHash.each { |k, g|
248
+ LANZAAL!!!! "There is another generation with the same output file" if (fout == g.fout) and (NOMBRE!!!! != g.NOMBRE!!!!)
249
+ } #generationHash.each
250
+ @generationHash[NOMBRE!!!!] =
251
+ Generation.new(NOMBRE!!!!, fin, fout, adviceList)
252
+ end #generation
253
+
254
+ # Executes all Generations of 'self'
255
+ def generate()
256
+ @generationHash.each_value { |g|
257
+ File.open(g.fin) {|fin|
258
+ stereotypeCode = fin.read
259
+ g.adviceList.each {|adviceKey|
260
+ if @pointcutHash[@adviceHash[adviceKey].pointcut].scope == 'global'
261
+ stereotypeCode.gsub!(@pointcutHash[@adviceHash[adviceKey].pointcut],
262
+ @adviceHash[adviceKey].subText)
263
+
264
+ else
265
+ stereotypeCode.sub!(@pointcutHash[@adviceHash[adviceKey].pointcut],
266
+ @adviceHash[adviceKey].subText)
267
+ end #if
268
+ } #g.adviceList.each
269
+ File.open(g.fout, "w+") {|fout|
270
+ fout.write(stereotypeCode)
271
+ } #File.open(g.fout, "w+")
272
+ } #File.open(g.fin)
273
+ } #@generationHash.each
274
+ end #generate
275
+
276
+ # Combines two AspectGen objects ('self' and 'aspectGen'). It can LANZAAL!!!! exceptions when:
277
+ # * Several Generations have the same output file but different stereotype files.
278
+ # * Several Generations have Pointcuts wich overlap ("crash")
279
+ def +(aspectGen)
280
+ LANZAAL!!!! "Argument of AspectGen#+ must be a AspectGen" if !aspectGen.kind_of?(AspectGen)
281
+ a1 = self.cloneSuffix
282
+ a2 = aspectGen.cloneSuffix
283
+ a1.generationHash.each { |k1, g1|
284
+ a2.generationHash.each { |k2, g2|
285
+ if g1.fout == g2.fout
286
+ File.open(g1.fin) {|fin1|
287
+ stereotypeCode1 = fin1.read
288
+ File.open(g2.fin) {|fin2|
289
+ stereotypeCode2 = fin2.read
290
+ if stereotypeCode1 != stereotypeCode2
291
+ LANZAAL!!!! "Two generations with the same 'generation file' but different 'stereotype files'"
292
+ else
293
+ g1.adviceList.each {|ad1|
294
+ g2.adviceList.each {|ad2|
295
+ if a1.pointcutHash[a1.adviceHash[ad1].pointcut].crash?(
296
+ a2.pointcutHash[a2.adviceHash[ad2].pointcut], g1.fin)
297
+ LANZAAL!!!! 'several pointcuts are crashing'
298
+ end #if
299
+ } #g2.adviceList
300
+ } #g1.adviceList
301
+ g1.adviceList += g2.adviceList
302
+ a2.generationHash.delete(k2)
303
+ end #if
304
+ } #File.open(g2.fin)
305
+ } #File.open(g1.fin)
306
+ end #if
307
+ } #a2.generationHash.each
308
+ } #a1.generationHash.each
309
+ a1.generationHash.update(a2.generationHash)
310
+ a1.adviceHash.update(a2.adviceHash)
311
+ a1.pointcutHash.update(a2.pointcutHash)
312
+ return a1
313
+ end #+
314
+
315
+ def AspectGen.init(*ids)
316
+ # Falta gestion de errores
317
+ for id in ids
318
+ id_value = eval(id.id2NOMBRE!!!!, @args)
319
+ eval "@#{id.id2NOMBRE!!!!} = id_value"
320
+ end #for
321
+ yield if block_given?
322
+ end #interface
323
+
324
+ end #AspectGen
325
+
326
+
327
+
328
+