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.
- data/README.txt +36 -0
- data/lib/EFL.rb +494 -0
- data/lib/EFL_array.rb +20 -0
- data/lib/EFL_errors.rb +48 -0
- data/lib/EFL_hash.rb +18 -0
- data/lib/EFL_production.rb +49 -0
- data/lib/EFL_regexp.rb +112 -0
- data/lib/EFL_regexp_generator.rb +70 -0
- data/lib/EFL_substitution.rb +221 -0
- data/lib/EFL_syntactic_sugar.rb +67 -0
- data/lib/Hash Doc.doc +0 -0
- data/lib/Limitaciones.txt +3 -0
- data/lib/doc/classes/Generator.html +634 -0
- data/lib/doc/classes/Generator.src/M000008.html +18 -0
- data/lib/doc/classes/Generator.src/M000009.html +18 -0
- data/lib/doc/classes/Generator.src/M000010.html +18 -0
- data/lib/doc/classes/Generator.src/M000011.html +18 -0
- data/lib/doc/classes/Generator.src/M000012.html +18 -0
- data/lib/doc/classes/Generator.src/M000013.html +18 -0
- data/lib/doc/classes/Generator.src/M000014.html +18 -0
- data/lib/doc/classes/Generator.src/M000015.html +18 -0
- data/lib/doc/classes/Generator.src/M000016.html +28 -0
- data/lib/doc/classes/Generator.src/M000017.html +24 -0
- data/lib/doc/classes/Generator.src/M000018.html +157 -0
- data/lib/doc/classes/Generator.src/M000019.html +25 -0
- data/lib/doc/classes/Generator.src/M000020.html +30 -0
- data/lib/doc/classes/Generator.src/M000021.html +32 -0
- data/lib/doc/classes/Generator.src/M000022.html +22 -0
- data/lib/doc/classes/Generator.src/M000023.html +18 -0
- data/lib/doc/classes/Generator.src/M000024.html +27 -0
- data/lib/doc/classes/Generator.src/M000025.html +22 -0
- data/lib/doc/classes/Generator.src/M000026.html +18 -0
- data/lib/doc/classes/Generator.src/M000027.html +27 -0
- data/lib/doc/classes/Regexp.html +271 -0
- data/lib/doc/classes/Regexp.src/M000028.html +37 -0
- data/lib/doc/classes/Regexp.src/M000029.html +29 -0
- data/lib/doc/classes/Regexp.src/M000030.html +32 -0
- data/lib/doc/created.rid +1 -0
- data/lib/doc/files/EFL_rb.html +147 -0
- data/lib/doc/files/EFL_regexp_generator_rb.html +242 -0
- data/lib/doc/files/EFL_regexp_generator_rb.src/M000003.html +27 -0
- data/lib/doc/files/EFL_regexp_generator_rb.src/M000004.html +27 -0
- data/lib/doc/files/EFL_regexp_generator_rb.src/M000005.html +19 -0
- data/lib/doc/files/EFL_regexp_generator_rb.src/M000006.html +20 -0
- data/lib/doc/files/EFL_regexp_generator_rb.src/M000007.html +19 -0
- data/lib/doc/files/EFL_regexp_rb.html +139 -0
- data/lib/doc/files/EFL_syntactic_sugar_rb.html +208 -0
- data/lib/doc/files/EFL_syntactic_sugar_rb.src/M000001.html +29 -0
- data/lib/doc/files/EFL_syntactic_sugar_rb.src/M000002.html +19 -0
- data/lib/doc/fr_class_index.html +28 -0
- data/lib/doc/fr_file_index.html +30 -0
- data/lib/doc/fr_method_index.html +56 -0
- data/lib/doc/index.html +24 -0
- data/tests/Add_Sup_1.rb +223 -0
- data/tests/Add_Sup_1.rb.bak +223 -0
- data/tests/Add_Sup_1_NI.rb +25 -0
- data/tests/Add_Sup_2.rb +142 -0
- data/tests/Add_Sup_2.rb.bak +140 -0
- data/tests/All.rb +2 -0
- data/tests/All_1.rb +7 -0
- data/tests/All_2.rb +7 -0
- data/tests/All_2.rb.bak +5 -0
- data/tests/BeforeAfter.rb +83 -0
- data/tests/Bloques.rb +34 -0
- data/tests/Bloques.rb.bak +34 -0
- data/tests/Complementary.rb +144 -0
- data/tests/ComplementaryZoom.rb +78 -0
- data/tests/Del.rb +126 -0
- data/tests/Dup.rb +55 -0
- data/tests/Dup.rb.bak +54 -0
- data/tests/Error.rb +11 -0
- data/tests/ErrorArgClass.rb +169 -0
- data/tests/ErrorArgClass.rb.bak +158 -0
- data/tests/ErrorCollision.rb +218 -0
- data/tests/ErrorCollision.rb.bak +219 -0
- data/tests/ErrorWithoutDeclaration.rb +60 -0
- data/tests/ErrorWithoutDeclaration.rb.bak +60 -0
- data/tests/Extract.rb +56 -0
- data/tests/ExtractDollar.rb +17 -0
- data/tests/HashTest.rb +54 -0
- data/tests/HashTest.rb.bak +54 -0
- data/tests/Lista Czarnecki/AntiguaInterfaz/List.cpp +75 -0
- data/tests/Lista Czarnecki/AntiguaInterfaz/ListTransformer.rb +69 -0
- data/tests/Lista Czarnecki/AntiguaInterfaz/ListTransformer.rb.bak +100 -0
- data/tests/Lista Czarnecki/AntiguaInterfaz/ejecutame.bat +1 -0
- data/tests/Lista Czarnecki/AntiguaInterfaz/outDir/MyClassList.cpp +75 -0
- data/tests/Lista Czarnecki/AntiguaInterfaz/runme.bat +1 -0
- data/tests/Lista Czarnecki/AntiguaInterfaz/specification1.txt +5 -0
- data/tests/Lista Czarnecki/AntiguaInterfaz/specification2.txt +3 -0
- data/tests/Lista Czarnecki/AntiguaInterfaz/specification3.txt +5 -0
- data/tests/Lista Czarnecki/NuevaInterfaz/List.cpp +75 -0
- data/tests/Lista Czarnecki/NuevaInterfaz/ListTransformer.rb +58 -0
- data/tests/Lista Czarnecki/NuevaInterfaz/ListTransformer.rb.bak +57 -0
- data/tests/Lista Czarnecki/NuevaInterfaz/ejecutame.bat +1 -0
- data/tests/Lista Czarnecki/NuevaInterfaz/outDir/MyClassList.cpp +75 -0
- data/tests/Lista Czarnecki/NuevaInterfaz/outDir/NewClassList.cpp +75 -0
- data/tests/Lista Czarnecki/NuevaInterfaz/specification1.txt +5 -0
- data/tests/Lista Czarnecki/NuevaInterfaz/specification1.txt.bak +5 -0
- data/tests/Lista Czarnecki/NuevaInterfaz/specification2.txt +3 -0
- data/tests/Lista Czarnecki/NuevaInterfaz/specification3.txt +5 -0
- data/tests/Minus.rb +89 -0
- data/tests/Plus.rb.bak +48 -0
- data/tests/REVit.rb +84 -0
- data/tests/RenameTest.rb +46 -0
- data/tests/RenameTest.rb.bak +46 -0
- data/tests/SubCrash.rb +26 -0
- data/tests/SubList.rb.bak +43 -0
- data/tests/archAuxiliares/1.txt +328 -0
- data/tests/archAuxiliares/2.txt +328 -0
- data/tests/archAuxiliares/Bloques/s1.txt +328 -0
- data/tests/archAuxiliares/Copia de Matriz.java +19 -0
- data/tests/archAuxiliares/Gen/Tesis_156_1.lgi +10 -0
- data/tests/archAuxiliares/Gen/Tesis_156_2.lgi +10 -0
- data/tests/archAuxiliares/Gen/t01.txt +328 -0
- data/tests/archAuxiliares/Gen/t01.txt.bak +328 -0
- data/tests/archAuxiliares/Gen/t02.txt +328 -0
- data/tests/archAuxiliares/Gen/t02.txt.bak +328 -0
- data/tests/archAuxiliares/Gen/t03.txt +328 -0
- data/tests/archAuxiliares/Gen/t03.txt.bak +328 -0
- data/tests/archAuxiliares/Gen/t04.txt +328 -0
- data/tests/archAuxiliares/Gen/t04.txt.bak +328 -0
- data/tests/archAuxiliares/Gen/t1.txt +328 -0
- data/tests/archAuxiliares/Gen/t1.txt.bak +328 -0
- data/tests/archAuxiliares/Gen/t2.txt +328 -0
- data/tests/archAuxiliares/Gen/t2.txt.bak +328 -0
- data/tests/archAuxiliares/Gen/t5.txt +328 -0
- data/tests/archAuxiliares/Gen/t9.txt +328 -0
- data/tests/archAuxiliares/Gen/t9.txt.bak +328 -0
- data/tests/archAuxiliares/GenTesis_156_1.lgi +10 -0
- data/tests/archAuxiliares/Matriz.java +74 -0
- data/tests/archAuxiliares/MatrizOut.java +74 -0
- data/tests/archAuxiliares/MatrizOut10.java +68 -0
- data/tests/archAuxiliares/MatrizOut11.java +86 -0
- data/tests/archAuxiliares/MatrizOut2.java +74 -0
- data/tests/archAuxiliares/MatrizOut3.java +74 -0
- data/tests/archAuxiliares/MatrizOut4.java +74 -0
- data/tests/archAuxiliares/MatrizOut5.java +21 -0
- data/tests/archAuxiliares/MatrizOut6.java +21 -0
- data/tests/archAuxiliares/MatrizOut7.java +21 -0
- data/tests/archAuxiliares/MatrizOut8.java +16 -0
- data/tests/archAuxiliares/MatrizOut9.java +86 -0
- data/tests/archAuxiliares/MatrizOut_9.java +86 -0
- data/tests/archAuxiliares/Matriz_1.java +74 -0
- data/tests/archAuxiliares/Matriz_10.java +68 -0
- data/tests/archAuxiliares/Matriz_11.java +86 -0
- data/tests/archAuxiliares/Matriz_2.java +74 -0
- data/tests/archAuxiliares/Matriz_3.java +74 -0
- data/tests/archAuxiliares/Matriz_4.java +74 -0
- data/tests/archAuxiliares/Matriz_5.java +21 -0
- data/tests/archAuxiliares/Matriz_6.java +21 -0
- data/tests/archAuxiliares/Matriz_7.java +21 -0
- data/tests/archAuxiliares/Matriz_8.java +16 -0
- data/tests/archAuxiliares/Matriz_9.java +86 -0
- data/tests/archAuxiliares/Matriz_N_1.java +21 -0
- data/tests/archAuxiliares/Matriz_N_2.java +91 -0
- data/tests/archAuxiliares/N1.txt +18 -0
- data/tests/archAuxiliares/N1_EXPECTED.txt +18 -0
- data/tests/archAuxiliares/N1_OUT.txt +18 -0
- data/tests/archAuxiliares/N2_EXPECTED.txt +18 -0
- data/tests/archAuxiliares/N2_OUT.txt +18 -0
- data/tests/archAuxiliares/N3.txt +23 -0
- data/tests/archAuxiliares/N3_EXPECTED.txt +22 -0
- data/tests/archAuxiliares/N3_OUT.txt +22 -0
- data/tests/archAuxiliares/N4_EXPECTED.txt +10 -0
- data/tests/archAuxiliares/N4_OUT.txt +10 -0
- data/tests/archAuxiliares/N5_OUT.txt +18 -0
- data/tests/archAuxiliares/N6_OUT.txt +18 -0
- data/tests/archAuxiliares/PedidorTerceroWS.jsp +142 -0
- data/tests/archAuxiliares/Tesis_156.lgi +7 -0
- data/tests/archAuxiliares/aspectgen.rb +328 -0
- data/tests/archAuxiliares/aspectgenCopy.rb +328 -0
- data/tests/archAuxiliares/extract_dollar.txt +1 -0
- data/tests/archAuxiliares/minus.txt +26 -0
- data/tests/archAuxiliares/minus_expected_1.txt +26 -0
- data/tests/archAuxiliares/minus_expected_2.txt +26 -0
- data/tests/archAuxiliares/minus_out_1.txt +26 -0
- data/tests/archAuxiliares/minus_out_2.txt +26 -0
- data/tests/archAuxiliares/p1.txt +328 -0
- data/tests/archAuxiliares/p2.txt +328 -0
- data/tests/archAuxiliares/s1.txt +328 -0
- data/tests/archAuxiliares/s2.txt +328 -0
- data/tests/archAuxiliares/s3.txt +328 -0
- data/tests/archAuxiliares/s4.txt +328 -0
- data/tests/archAuxiliares/s5.txt +328 -0
- data/tests/archAuxiliares/s7.txt +328 -0
- data/tests/archAuxiliares/s8.txt +328 -0
- data/tests/archAuxiliares/s9.txt +328 -0
- data/tests/archAuxiliares/text.txt +1 -0
- data/tests/delay.rb +33 -0
- data/tests/delay.rb.bak +33 -0
- data/tests/satisfy.rb +44 -0
- data/tests/satisfy.rb.bak +34 -0
- 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
|
+
|