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
|
+
#<<Cambio>>: AUXILIAR AspectGen class that represents a Pointcut
|
|
4
|
+
class Pointcut < Regexp
|
|
5
|
+
#Pointcut name (a String)
|
|
6
|
+
attr_accessor :name
|
|
7
|
+
#Pointcut value (a Regexp)
|
|
8
|
+
attr_accessor :regExp
|
|
9
|
+
#Pointcut scope ('local' or 'global')
|
|
10
|
+
attr_accessor :scope
|
|
11
|
+
|
|
12
|
+
# * 'name' = Pointcut name (a String)
|
|
13
|
+
# * 'regExp' = Pointcut value (a Regexp)
|
|
14
|
+
# * 'scope' = Pointcut scope ('local' or 'global')
|
|
15
|
+
def initialize(name, regExp, scope='local')
|
|
16
|
+
raise "First argument of Pointcut constructor must be a String" if !name.kind_of?(String)
|
|
17
|
+
raise "Second argument of Pointcut constructor must be a Regular Expression" if !regExp.kind_of?(Regexp)
|
|
18
|
+
raise "Pointcut scope must be 'local' or 'global'" if (scope != 'local') and
|
|
19
|
+
(scope != 'global')
|
|
20
|
+
super(regExp)
|
|
21
|
+
@name = name
|
|
22
|
+
@regExp = regExp
|
|
23
|
+
@scope = scope
|
|
24
|
+
end #initialize
|
|
25
|
+
|
|
26
|
+
def clone
|
|
27
|
+
result = Pointcut.new(@name.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
|
+
raise "First argument of Pointcut#crash? must be a Pointcut" if !pointcut.kind_of?(Pointcut)
|
|
34
|
+
# crash? inner <<Cambio>>: 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 <<Cambio>>: 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
|
+
#<<Cambio>>: AUXILIAR AspectGen class that represents an Advice
|
|
81
|
+
class Advice
|
|
82
|
+
#Advice name (a String)
|
|
83
|
+
attr_accessor :name
|
|
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
|
+
# * 'name' = Advice name (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(name, pointcut, subText)
|
|
93
|
+
|
|
94
|
+
raise "Arguments of Advice constructor must be a String" if (!name.kind_of?(String)) or
|
|
95
|
+
(!pointcut.kind_of?(String)) or (!subText.kind_of?(String))
|
|
96
|
+
@name = name
|
|
97
|
+
@pointcut = pointcut
|
|
98
|
+
@subText = subText
|
|
99
|
+
end #initialize
|
|
100
|
+
|
|
101
|
+
def clone
|
|
102
|
+
result = Advice.new(@name.clone, @pointcut.clone, @subText.clone)
|
|
103
|
+
end #clone
|
|
104
|
+
|
|
105
|
+
end #Advice
|
|
106
|
+
|
|
107
|
+
#<<Cambio>>: AUXILIAR AspectGen class that represents a Generation
|
|
108
|
+
class Generation
|
|
109
|
+
#Generation name (a String)
|
|
110
|
+
attr_accessor :name
|
|
111
|
+
#Generation sterotype file (a String)
|
|
112
|
+
attr_accessor :fin
|
|
113
|
+
#Generation output file (a String)
|
|
114
|
+
attr_accessor :fout
|
|
115
|
+
#List of Advice names associated with the Generation (a String List)
|
|
116
|
+
attr_accessor :adviceList
|
|
117
|
+
|
|
118
|
+
# * 'name' = Generation name (a String)
|
|
119
|
+
# * 'fin' = Generation sterotype file (a String)
|
|
120
|
+
# * 'fout' = Generation output file (a String)
|
|
121
|
+
# * 'adviceList' = List of Advice names associated with the Generation (a String List)
|
|
122
|
+
def initialize(name, fin, fout, adviceList = [])
|
|
123
|
+
raise "First argument of Generation constructor must be a String" if !name.kind_of?(String)
|
|
124
|
+
raise "Fourth argument of Generation constructor must be a String List" if !adviceList.kind_of?(Array)
|
|
125
|
+
adviceList.each { |a|
|
|
126
|
+
raise "Fourth argument of Generation constructor must be a String List" if !a.kind_of?(String)
|
|
127
|
+
} #adviceList.each
|
|
128
|
+
@name = name
|
|
129
|
+
@fin = fin
|
|
130
|
+
@fout = fout
|
|
131
|
+
@adviceList = adviceList
|
|
132
|
+
end #initialize
|
|
133
|
+
|
|
134
|
+
def clone
|
|
135
|
+
result = Generation.new(@name, @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
|
+
# + <<Cambio>>: 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].name +=
|
|
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].name +=
|
|
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].name +=
|
|
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
|
+
# * 'name' = Pointcut name (a String)
|
|
209
|
+
# * 'regExp' = Pointcut value (a Regexp)
|
|
210
|
+
# * 'scope' = Pointcut scope ('local' or 'global')
|
|
211
|
+
def pointcut(name, regExp, scope = 'local')
|
|
212
|
+
@pointcutHash = {} unless @pointcutHash
|
|
213
|
+
@pointcutHash[name] = Pointcut.new(name, regExp, scope)
|
|
214
|
+
end #pointcut
|
|
215
|
+
|
|
216
|
+
# Adds a new Advice to 'self'
|
|
217
|
+
# * 'name' = Advice name (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(name, pointcut, subText)
|
|
221
|
+
raise "Pointcut referenced by AspectGen#advice doesn't exist" if pointcutHash[pointcut] == nil
|
|
222
|
+
@adviceHash = {} unless @adviceHash
|
|
223
|
+
@adviceHash[name] = Advice.new(name, pointcut, subText)
|
|
224
|
+
end #advice
|
|
225
|
+
|
|
226
|
+
# Adds a new Generation to 'self'
|
|
227
|
+
# * 'name' = Generation name (a String)
|
|
228
|
+
# * 'fin' = Generation sterotype file (a String)
|
|
229
|
+
# * 'fout' = Generation output file (a String)
|
|
230
|
+
# * 'adviceList' = List of Advice names associated with the Generation (a String List)
|
|
231
|
+
def generation(name, fin, fout, adviceList = [])
|
|
232
|
+
@generationHash = {} unless @generationHash
|
|
233
|
+
|
|
234
|
+
raise "Fourth argument of Generation constructor must be a String List" if !adviceList.kind_of?(Array)
|
|
235
|
+
adviceList.each { |a|
|
|
236
|
+
raise "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
|
+
raise 'several pointcuts are crashing'
|
|
244
|
+
end #if
|
|
245
|
+
} #adviceListAux.each
|
|
246
|
+
} #adviceList.each
|
|
247
|
+
generationHash.each { |k, g|
|
|
248
|
+
raise "There is another generation with the same output file" if (fout == g.fout) and (name != g.name)
|
|
249
|
+
} #generationHash.each
|
|
250
|
+
@generationHash[name] =
|
|
251
|
+
Generation.new(name, 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 raise 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
|
+
raise "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
|
+
raise "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
|
+
raise '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.id2name, @args)
|
|
319
|
+
eval "@#{id.id2name} = id_value"
|
|
320
|
+
end #for
|
|
321
|
+
yield if block_given?
|
|
322
|
+
end #interface
|
|
323
|
+
|
|
324
|
+
end #AspectGen
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import java.io.*;
|
|
2
|
+
import javagently.*;
|
|
3
|
+
|
|
4
|
+
public class Matriz {
|
|
5
|
+
|
|
6
|
+
private int[][] matriz;
|
|
7
|
+
private int numFilas, numOtrasCosas, numColumnas;
|
|
8
|
+
|
|
9
|
+
public Matriz (int numFilas, int numColumnas) {
|
|
10
|
+
numFilas = numFilas;
|
|
11
|
+
numColumnas = numColumnas;
|
|
12
|
+
numOtrasCosas = numOtrasCosas;
|
|
13
|
+
matriz = new int[numFilas][numColumnas];
|
|
14
|
+
} /* Matriz */
|
|
15
|
+
|
|
16
|
+
public void leerMatriz() throws IOException{
|
|
17
|
+
BufferedReader entradaTeclado = Text.open(System.in);
|
|
18
|
+
for (int i=0; i<numFilas; i++) {
|
|
19
|
+
for (int j=0; j<numColumnas; j++) {
|
|
20
|
+
System.out.print("\tElemento[" + i + "][" + j +"] ?: ");
|
|
21
|
+
mAtriz[i][j] = Text.readInt(entradaTeclado);
|
|
22
|
+
} /* for */
|
|
23
|
+
} /* for */
|
|
24
|
+
} /* leerMatriz */
|
|
25
|
+
|
|
26
|
+
public void escribirMatriz() {
|
|
27
|
+
System.out.print("\nLa matriz resultado es:\n");
|
|
28
|
+
for (int i=0; i<numFilas; i++) {
|
|
29
|
+
System.out.print("\n\t");
|
|
30
|
+
for (int j=0; j<numColumnas; j++) {
|
|
31
|
+
System.out.print(Text.writeInt(matriz[i][j], 2) + " ");
|
|
32
|
+
} /* for j */
|
|
33
|
+
} /* for i */
|
|
34
|
+
} /* leerMatriz */
|
|
35
|
+
|
|
36
|
+
public int obtenerNumFilas() {
|
|
37
|
+
return numFilas;
|
|
38
|
+
} /* obtenerNumFilas */
|
|
39
|
+
|
|
40
|
+
public int obtenerNumColumnas() {
|
|
41
|
+
return numColumnas;
|
|
42
|
+
} /* obtenerNumColumnas */
|
|
43
|
+
|
|
44
|
+
public int obtenerElemento(int i, int j) {
|
|
45
|
+
return matriz[i][j];
|
|
46
|
+
} /* obtenerElemento */
|
|
47
|
+
|
|
48
|
+
public void establecerElemento(int i, int j, int valor) {
|
|
49
|
+
matriz[i][j] = valor;
|
|
50
|
+
} /* establecerElemento */
|
|
51
|
+
|
|
52
|
+
public static boolean puedeRealizarseElProducto(Matriz matriz1, Matriz matriz2) {
|
|
53
|
+
// dice si es posible realizar el producto de matrices
|
|
54
|
+
return matriz1.obtenerNumColumnas() == matriz2.obtenerNumFilas();
|
|
55
|
+
} /* verificarProducto */
|
|
56
|
+
|
|
57
|
+
public static Matriz multiplicarMatrices(Matriz matriz1, Matriz matriz2) {
|
|
58
|
+
Matriz matrizResultado = new Matriz(matriz1.obtenerNumFilas(),
|
|
59
|
+
matriz2.obtenerNumColumnas());
|
|
60
|
+
int suma;
|
|
61
|
+
for (int i=0; i<matriz1.obtenerNumFilas(); i++) {
|
|
62
|
+
for (int j=0; j<matriz2.obtenerNumColumnasOtras(); j++) {
|
|
63
|
+
suma = 0;
|
|
64
|
+
for (int k=0; k<matriz1.obtenerNumColumnas(); k++) {
|
|
65
|
+
suma += matriz1.obtenerElemento(i,k) *
|
|
66
|
+
matriz2.obtenerElemento(k,j);
|
|
67
|
+
} /* for k */
|
|
68
|
+
matrizResultado.establecerElemento(i,j, suma);
|
|
69
|
+
} /* for j */
|
|
70
|
+
} /* for i */
|
|
71
|
+
return matrizResultado;
|
|
72
|
+
} /* multiplicarMatrices */
|
|
73
|
+
|
|
74
|
+
} /* Matriz */
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import java.io.*;
|
|
2
|
+
import javagently.*;
|
|
3
|
+
|
|
4
|
+
public class MatrizExterna {
|
|
5
|
+
|
|
6
|
+
private int[][] matriz;
|
|
7
|
+
private int numFilas, numOtrasCosas, numColumnas;
|
|
8
|
+
|
|
9
|
+
public MatrizInterna (int numFilas, int numColumnas) {
|
|
10
|
+
numFilas = numFilas;
|
|
11
|
+
numColumnas = numColumnas;
|
|
12
|
+
numOtrasCosas = numOtrasCosas;
|
|
13
|
+
matriz = new int[numFilas][numColumnas];
|
|
14
|
+
} /* MatrizInterna */
|
|
15
|
+
|
|
16
|
+
public void leerMatrizInterna() throws IOException{
|
|
17
|
+
BufferedReader entradaTeclado = Text.open(System.in);
|
|
18
|
+
for (int i=0; i<numFilas; i++) {
|
|
19
|
+
for (int j=0; j<numColumnas; j++) {
|
|
20
|
+
System.out.imprimePollo!("\tElemento[" + i + "][" + j +"] ?: ");
|
|
21
|
+
mAtriz[i][j] = Text.readInt(entradaTeclado);
|
|
22
|
+
} /* for */
|
|
23
|
+
} /* for */
|
|
24
|
+
} /* leerMatrizInterna */
|
|
25
|
+
|
|
26
|
+
public void escribirMatrizInterna() {
|
|
27
|
+
System.out.imprimePollo!("\nLa matriz resultado es:\n");
|
|
28
|
+
for (int i=0; i<numFilas; i++) {
|
|
29
|
+
System.out.imprimePollo!("\n\t");
|
|
30
|
+
for (int NuevaVariableee=0; j<numColumnas; j++) {
|
|
31
|
+
System.out.imprimePollo!(Text.writeInt(matriz[i][j], 2) + " ");
|
|
32
|
+
} /* for j */
|
|
33
|
+
} /* for i */
|
|
34
|
+
} /* leerMatrizInterna */
|
|
35
|
+
|
|
36
|
+
public int obtenerNumFilas() {
|
|
37
|
+
return numFilas;
|
|
38
|
+
} /* obtenerNumFilas */
|
|
39
|
+
|
|
40
|
+
public int obtenerNumColumnas() {
|
|
41
|
+
return numColumnas;
|
|
42
|
+
} /* obtenerNumColumnas */
|
|
43
|
+
|
|
44
|
+
public int obtenerElemento(int i, int j) {
|
|
45
|
+
return matriz[i][j];
|
|
46
|
+
} /* obtenerElemento */
|
|
47
|
+
|
|
48
|
+
public void establecerElemento(int i, int j, int valor) {
|
|
49
|
+
matriz[i][j] = valor;
|
|
50
|
+
} /* establecerElemento */
|
|
51
|
+
|
|
52
|
+
public static boolean puedeRealizarseElProducto(MatrizInterna matriz1, MatrizInterna matriz2) {
|
|
53
|
+
// dice si es posible realizar el producto de matrices
|
|
54
|
+
return matriz1.obtenerNumColumnas() == matriz2.obtenerNumFilas();
|
|
55
|
+
} /* verificarProducto */
|
|
56
|
+
|
|
57
|
+
public static MatrizInterna multiplicarMatrices(MatrizInterna matriz1, MatrizInterna matriz2) {
|
|
58
|
+
MatrizInterna matrizResultado = new MatrizInterna(matriz1.obtenerNumFilas(),
|
|
59
|
+
matriz2.obtenerNumColumnas());
|
|
60
|
+
int suma;
|
|
61
|
+
for (int i=0; i<matriz1.obtenerNumFilas(); i++) {
|
|
62
|
+
for (int j=0; j<matriz2.obtenerNumColumnasOtras(); j++) {
|
|
63
|
+
suma = 0;
|
|
64
|
+
for (int k=0; k<matriz1.obtenerNumColumnas(); k++) {
|
|
65
|
+
suma += matriz1.obtenerElemento(i,k) *
|
|
66
|
+
matriz2.obtenerElemento(k,j);
|
|
67
|
+
} /* for k */
|
|
68
|
+
matrizResultado.establecerElemento(i,j, suma);
|
|
69
|
+
} /* for j */
|
|
70
|
+
} /* for i */
|
|
71
|
+
return matrizResultado;
|
|
72
|
+
} /* multiplicarMatrices */
|
|
73
|
+
|
|
74
|
+
} /* Matriz */
|