maroon 0.6.1 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/Examples/Dijkstra/CalculateShortestDistance.rb +16 -12
  3. data/Examples/Dijkstra/calculate_shortest_path.rb +47 -27
  4. data/Examples/Dijkstra/data.rb +41 -14
  5. data/Examples/Dijkstra/dijkstra.rb +4 -3
  6. data/Examples/MoneyTransfer.rb +61 -60
  7. data/Examples/greeter.rb +8 -7
  8. data/Examples/meter.rb +35 -29
  9. data/Gemfile +9 -4
  10. data/LICENSE.txt +21 -21
  11. data/README.md +13 -0
  12. data/Rakefile +41 -1
  13. data/Test/Generate/method_info_test.rb +12 -0
  14. data/Test/{Greeter_test.rb → Greeter_test_disabled.rb} +24 -20
  15. data/Test/ImmutableQueue_test.rb +18 -0
  16. data/Test/MethodInfo_test.rb +65 -0
  17. data/Test/alltests.rb +1 -0
  18. data/Test/{source_assertions.rb → assertions.rb} +15 -7
  19. data/Test/bind_test.rb +13 -0
  20. data/Test/expression_test.rb +105 -0
  21. data/Test/method_call_test.rb +83 -0
  22. data/Test/self_test.rb +46 -0
  23. data/Test/stack_test.rb +17 -0
  24. data/Test/test_helper.rb +14 -0
  25. data/base/ImmutableStack.rb +32 -0
  26. data/base/MethodDefinition.rb +124 -0
  27. data/base/bind_rewriter.rb +58 -0
  28. data/base/immutable_queue.rb +50 -0
  29. data/base/maroon_base.rb +267 -0
  30. data/base/method_call.rb +78 -0
  31. data/base/method_info.rb +86 -0
  32. data/base/self.rb +60 -0
  33. data/generated/build.rb +13 -0
  34. data/generated/interpretation_context.rb +29 -0
  35. data/lib/Bind.rb +65 -0
  36. data/lib/Context.rb +187 -0
  37. data/lib/ImmutableQueue.rb +50 -0
  38. data/lib/ImmutableStack.rb +38 -0
  39. data/lib/MethodCall.rb +91 -0
  40. data/lib/MethodDefinition.rb +114 -0
  41. data/lib/MethodInfo.rb +78 -0
  42. data/lib/Self.rb +71 -0
  43. data/lib/build.rb +14 -0
  44. data/lib/interpretation_context.rb +30 -0
  45. data/lib/maroon/contracts.rb +43 -0
  46. data/lib/maroon/kernel.rb +2 -0
  47. data/lib/maroon/version.rb +3 -3
  48. data/maroon.gemspec +26 -26
  49. metadata +49 -31
  50. data/lib/Source_cleaner.rb +0 -34
  51. data/lib/maroon.rb +0 -165
  52. data/lib/rewriter.rb +0 -185
@@ -1,3 +1,5 @@
1
+ require_relative '../Context'
2
+
1
3
  module Kernel
2
4
  def context(*args, &b)
3
5
  Context::define *args, &b
@@ -1,3 +1,3 @@
1
- module Maroon
2
- VERSION = '0.6.1'
3
- end
1
+ module Maroon
2
+ VERSION = '0.6.5'
3
+ end
@@ -1,26 +1,26 @@
1
- # -*- encoding: utf-8 -*-
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'maroon/version'
5
-
6
- Gem::Specification.new do |gem|
7
- gem.name = 'maroon'
8
- gem.version = Maroon::VERSION
9
- gem.authors = ['Rune Funch Søltoft']
10
- gem.email = %w(funchsoltoft@gmail.com)
11
- gem.description = %q{maroon makes DCI a DSL for Ruby it's mainly based on the work gone into Marvin,
12
- the first language to support injectionless DCI.
13
-
14
- The performance of code written using maroon is on par with code using regular method invocation.
15
-
16
- For examples on how to use maroon look at the examples found at the home page}
17
- gem.summary = %q{maroon}
18
- gem.homepage = 'https://github.com/runefs/maroon'
19
-
20
- gem.files = `git ls-files`.split($/)
21
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
22
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
23
- gem.require_paths = ["lib"]
24
- gem.add_runtime_dependency 'sourcify', '~>0.3', '>=0.3.10'
25
- gem.add_runtime_dependency 'sorcerer'
26
- end
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'maroon/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'maroon'
8
+ gem.version = Maroon::VERSION
9
+ gem.authors = ['Rune Funch Søltoft']
10
+ gem.email = %w(funchsoltoft@gmail.com)
11
+ gem.description = %q{maroon makes DCI a DSL for Ruby it's mainly based on the work gone into Marvin,
12
+ the first language to support injectionless DCI.
13
+
14
+ The performance of code written using maroon is on par with code using regular method invocation.
15
+
16
+ For examples on how to use maroon look at the examples found at the home page}
17
+ gem.summary = %q{maroon}
18
+ gem.homepage = 'https://github.com/runefs/Moby'
19
+
20
+ gem.files = `git ls-files`.split($/)
21
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
22
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
23
+ gem.require_paths = ["lib"]
24
+ gem.add_runtime_dependency 'sourcify', '~>0.3', '>=0.3.10'
25
+ gem.add_runtime_dependency 'sorcerer'
26
+ end
metadata CHANGED
@@ -1,65 +1,56 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maroon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
5
- prerelease:
4
+ version: 0.6.5
6
5
  platform: ruby
7
6
  authors:
8
7
  - Rune Funch Søltoft
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-02-27 00:00:00.000000000 Z
11
+ date: 2013-04-09 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: sourcify
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0.3'
22
- - - ! '>='
20
+ - - '>='
23
21
  - !ruby/object:Gem::Version
24
22
  version: 0.3.10
25
23
  type: :runtime
26
24
  prerelease: false
27
25
  version_requirements: !ruby/object:Gem::Requirement
28
- none: false
29
26
  requirements:
30
27
  - - ~>
31
28
  - !ruby/object:Gem::Version
32
29
  version: '0.3'
33
- - - ! '>='
30
+ - - '>='
34
31
  - !ruby/object:Gem::Version
35
32
  version: 0.3.10
36
33
  - !ruby/object:Gem::Dependency
37
34
  name: sorcerer
38
35
  requirement: !ruby/object:Gem::Requirement
39
- none: false
40
36
  requirements:
41
- - - ! '>='
37
+ - - '>='
42
38
  - !ruby/object:Gem::Version
43
39
  version: '0'
44
40
  type: :runtime
45
41
  prerelease: false
46
42
  version_requirements: !ruby/object:Gem::Requirement
47
- none: false
48
43
  requirements:
49
- - - ! '>='
44
+ - - '>='
50
45
  - !ruby/object:Gem::Version
51
46
  version: '0'
52
- description: ! 'maroon makes DCI a DSL for Ruby it''s mainly based on the work gone
53
- into Marvin,
54
-
47
+ description: |-
48
+ maroon makes DCI a DSL for Ruby it's mainly based on the work gone into Marvin,
55
49
  the first language to support injectionless DCI.
56
50
 
51
+ The performance of code written using maroon is on par with code using regular method invocation.
57
52
 
58
- The performance of code written using maroon is on par with code using regular method
59
- invocation.
60
-
61
-
62
- For examples on how to use maroon look at the examples found at the home page'
53
+ For examples on how to use maroon look at the examples found at the home page
63
54
  email:
64
55
  - funchsoltoft@gmail.com
65
56
  executables: []
@@ -78,36 +69,63 @@ files:
78
69
  - LICENSE.txt
79
70
  - README.md
80
71
  - Rakefile
81
- - Test/Greeter_test.rb
82
- - Test/source_assertions.rb
83
- - lib/Source_cleaner.rb
84
- - lib/maroon.rb
72
+ - Test/Generate/method_info_test.rb
73
+ - Test/Greeter_test_disabled.rb
74
+ - Test/ImmutableQueue_test.rb
75
+ - Test/MethodInfo_test.rb
76
+ - Test/alltests.rb
77
+ - Test/assertions.rb
78
+ - Test/bind_test.rb
79
+ - Test/expression_test.rb
80
+ - Test/method_call_test.rb
81
+ - Test/self_test.rb
82
+ - Test/stack_test.rb
83
+ - Test/test_helper.rb
84
+ - base/ImmutableStack.rb
85
+ - base/MethodDefinition.rb
86
+ - base/bind_rewriter.rb
87
+ - base/immutable_queue.rb
88
+ - base/maroon_base.rb
89
+ - base/method_call.rb
90
+ - base/method_info.rb
91
+ - base/self.rb
92
+ - generated/build.rb
93
+ - generated/interpretation_context.rb
94
+ - lib/Bind.rb
95
+ - lib/Context.rb
96
+ - lib/ImmutableQueue.rb
97
+ - lib/ImmutableStack.rb
98
+ - lib/MethodCall.rb
99
+ - lib/MethodDefinition.rb
100
+ - lib/MethodInfo.rb
101
+ - lib/Self.rb
102
+ - lib/build.rb
103
+ - lib/interpretation_context.rb
104
+ - lib/maroon/contracts.rb
85
105
  - lib/maroon/kernel.rb
86
106
  - lib/maroon/version.rb
87
- - lib/rewriter.rb
88
107
  - maroon.gemspec
89
- homepage: https://github.com/runefs/maroon
108
+ homepage: https://github.com/runefs/Moby
90
109
  licenses: []
110
+ metadata: {}
91
111
  post_install_message:
92
112
  rdoc_options: []
93
113
  require_paths:
94
114
  - lib
95
115
  required_ruby_version: !ruby/object:Gem::Requirement
96
- none: false
97
116
  requirements:
98
- - - ! '>='
117
+ - - '>='
99
118
  - !ruby/object:Gem::Version
100
119
  version: '0'
101
120
  required_rubygems_version: !ruby/object:Gem::Requirement
102
- none: false
103
121
  requirements:
104
- - - ! '>='
122
+ - - '>='
105
123
  - !ruby/object:Gem::Version
106
124
  version: '0'
107
125
  requirements: []
108
126
  rubyforge_project:
109
- rubygems_version: 1.8.24
127
+ rubygems_version: 2.0.0
110
128
  signing_key:
111
- specification_version: 3
129
+ specification_version: 4
112
130
  summary: maroon
113
131
  test_files: []
@@ -1,34 +0,0 @@
1
- require 'sourcify'
2
- require 'sorcerer'
3
-
4
- module Source_cleaner
5
- private
6
-
7
- #cleans up the string for further processing and separates arguments from body
8
- def block2source(method_name, &block)
9
- source = block.to_sexp
10
- raise 'unknown format' unless source[0] == :iter or source.length != 4
11
- args = get_args source[2]
12
- body = source[3]
13
- return args, body
14
- end
15
-
16
- def get_args(sexp)
17
- return nil unless sexp
18
- return sexp[1] if sexp[0] == :lasgn
19
- sexp = sexp[1][1..-1] # array or arguments
20
- args = []
21
- sexp.each { |e|
22
- args << e[1]
23
- }
24
- args.join(',')
25
- end
26
-
27
- def lambda2method (method_name, method)
28
- arguments, body = method.arguments, method.body
29
- transform_ast body
30
- block = Ruby2Ruby.new.process(body)
31
- args = "(#{arguments})" if arguments
32
- "\ndef #{method_name} #{args}\n#{block} end\n"
33
- end
34
- end
@@ -1,165 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- require './lib/Source_cleaner.rb'
3
- require './lib/rewriter.rb'
4
-
5
-
6
- class Method_info
7
- def initialize(arguments,body)
8
- @arguments = arguments
9
- @body = body
10
- end
11
- attr_reader :arguments
12
- attr_reader :body
13
- end
14
-
15
- ##
16
- # The Context class is used to define a DCI context with roles and their role methods
17
- # to define a context call define with the name of the context (this name will become the name of the class that defines the context)
18
- # the name should be a symbol and since it's going to be used as a class name, use class naming conventions
19
- # follow the name with a block. With in this block you can define roles and interactions
20
- # and interaction is defined by write the name of the interaction (hello in the below example) followed by a block
21
- # the block will become the method body
22
- # a role can be defined much like a context. instead of calling the define method call the role method followed by the role name (as a symbol)
23
- # the role will be used for a private instance variable and the naming convention should match this
24
- # With in the block supplied to the role method you can define role methods the same way as you define interactions. See the method who
25
- # in the below example
26
- # = Example
27
- # Context::define :Greeter do
28
- # role :who do
29
- # say do
30
- # @who #could be self as well to refer to the current role player of the 'who' role
31
- # end
32
- # end
33
- # greeting do
34
- # p "Hello #{who.say}!"
35
- # end
36
- # end
37
- #
38
- # class Greeter
39
- # def initialize(player)
40
- # #@who = player
41
- # end
42
- # end
43
- #
44
- # Greeter.new('world').greeting #Will print "Hello world!"
45
- #maroon is base on Marvin which was the first injectionless language for DCI
46
- #being injectionless there's no runtime extend or anything else impacting the performance. There' only regular method invocation even when using role methods
47
- #Author:: Rune Funch Søltoft (funchsoltoft@gmail.com)
48
- #License:: Same as for Ruby
49
- ##
50
- class Context
51
- include Rewriter,Source_cleaner
52
- @roles
53
- @interactions
54
- @defining_role
55
- @role_alias
56
- @alias_list
57
- @cached_roles_and_alias_list
58
-
59
- #define is the only exposed method and can be used to define a context (class)
60
- #if maroon/kernel is required calling context of Context::define are equivalent
61
- #params
62
- #name:: the name of the context. Since this is used as the name of a class, class naming convetions should be used
63
- #block:: the body of the context. Can include definitions of roles (through the role method) or definitions of interactions
64
- #by simply calling a method with the name of the interaction and passing a block as the body of the interaction
65
- def self.define(*args, &block)
66
- name,base_class,default_interaction = *args
67
- #if there's two arguments and the second is not a class it must be an interaction
68
- if default_interaction && (!base_class.instance_of? Class) then base_class = eval(base_class.to_s) end
69
- base_class,default_interaction = default_interaction, base_class if base_class and !default_interaction and !base_class.instance_of? Class
70
- ctx = Context.new
71
- ctx.instance_eval &block
72
- return ctx.send(:finalize, name,base_class,default_interaction)
73
- end
74
-
75
- private
76
- ##
77
- #Defines a role with the given name
78
- #role methods can be defined inside a block passed to this method
79
- # = Example
80
- # role :who do
81
- # say do
82
- # p @who
83
- # end
84
- # end
85
- #The above code defines a role called 'who' with a role method called say
86
- ##
87
- def role(role_name)
88
- raise 'Argument role_name must be a symbol' unless role_name.instance_of? Symbol
89
-
90
- @defining_role = role_name
91
- @roles[role_name] = Hash.new
92
- yield if block_given?
93
- @defining_role = nil
94
- end
95
-
96
- def initialize
97
- @roles = Hash.new
98
- @interactions = Hash.new
99
- @role_alias = Array.new
100
- end
101
-
102
- def methods
103
- (@defining_role ? @roles[@defining_role] : @interactions)
104
- end
105
-
106
- def finalize(name, base_class, default)
107
- c = base_class ? (Class.new base_class) : Class.new
108
- Kernel.const_set name, c
109
- code = ''
110
- fields = ''
111
- getters = ''
112
- impl = ''
113
- interactions = ''
114
- @interactions.each do |method_name, method|
115
- @defining_role = nil
116
- interactions << " #{lambda2method(method_name, method)}"
117
- end
118
- if default
119
- interactions <<"
120
- def self.call(*args)
121
- arity =#{name}.method(:new).arity
122
- newArgs = args[0..arity-1]
123
- p \"new \#{newArgs}\"
124
- obj = #{name}.new *newArgs
125
- if arity < args.length
126
- methodArgs = args[arity..-1]
127
- p \"method \#{methodArgs}\"
128
- obj.#{default} *methodArgs
129
- else
130
- obj.#{default}
131
- end
132
- end
133
- "
134
- interactions <<"\ndef call(*args);#{default} *args; end\n"
135
- end
136
-
137
- @roles.each do |role, methods|
138
- fields << "@#{role}\n"
139
- getters << "def #{role};@#{role} end\n"
140
-
141
- methods.each do |method_name, method_source|
142
- @defining_role = role
143
- rewritten_method_name = "self_#{role}_#{method_name}"
144
- definition = lambda2method rewritten_method_name, method_source
145
- impl << " #{definition}" if definition
146
- end
147
- end
148
-
149
- code << "#{interactions}\n#{fields}\n private\n#{getters}\n#{impl}\n"
150
-
151
- complete = "class #{name}\r\n#{code}\r\nend"
152
- #File.open("#{name}_generated.rb", 'w') {|f| f.write(complete) }
153
- temp = c.class_eval(code)
154
- return (temp ||c),complete
155
- end
156
-
157
- def role_or_interaction_method(method_name,*args, &b)
158
- raise "method with out block #{method_name}" unless b
159
-
160
- args, body = block2source method_name, &b
161
- methods[method_name] = Method_info.new args,body
162
- end
163
-
164
- alias method_missing role_or_interaction_method
165
- end
@@ -1,185 +0,0 @@
1
- require 'Ripper'
2
-
3
- module Rewriter
4
- private
5
- def role_aliases
6
- @alias_list if @alias_list
7
- @alias_list = Hash.new
8
- @role_alias.each { |aliases|
9
- aliases.each { |k, v|
10
- @alias_list[k] = v
11
- }
12
- }
13
- @alias_list
14
- end
15
-
16
- def roles
17
- @cached_roles_and_alias_list if @cached_roles_and_alias_list
18
- @roles unless @role_alias and @role_alias.length
19
- @cached_roles_and_alias_list = Hash.new
20
- @roles.each { |k, v|
21
- @cached_roles_and_alias_list[k] = v
22
- }
23
- role_aliases.each { |k, v|
24
- @cached_roles_and_alias_list[k] = @roles[v]
25
- }
26
- @cached_roles_and_alias_list
27
- end
28
-
29
- def add_alias (a, role_name)
30
- @cached_roles_and_alias_list, @alias_list = nil
31
- @role_alias.last()[a] = role_name
32
- end
33
-
34
- def role_method_call(ast, method)
35
- is_call_expression = ast && ast[0] == :call
36
- self_is_instance_expression = is_call_expression && (!ast[1]) #implicit self
37
- is_in_block = ast && ast[0] == :lvar
38
- role_name_index = self_is_instance_expression ? 2 : 1
39
- role = (self_is_instance_expression || is_in_block) ? roles[ast[role_name_index]] : nil #is it a call to a role getter
40
- is_role_method = role && role.has_key?(method)
41
- role_name = is_in_block ? role_aliases[ast[1]] : (ast[2] if self_is_instance_expression)
42
- role_name if is_role_method #return role name
43
- end
44
-
45
- ##
46
- #Test if there's a block that needs to potentially be transformed
47
- ##
48
- def transform_block(exp)
49
- if exp && exp[0] == :iter
50
- (exp.length-1).times do |i|
51
- expr = exp[i+1]
52
- #find the block
53
- if expr && expr.length && expr[0] == :block
54
- transform_ast exp if rewrite_bind? expr, expr[1]
55
- end
56
- end
57
- end
58
- end
59
-
60
- ##
61
- #Calls rewrite_block if needed and will return true if the AST was changed otherwise false
62
- ##
63
- def rewrite_bind?(block, expr)
64
- changed = false
65
- #check if the first call is a bind call
66
- if expr && expr.length && (expr[0] == :call && expr[1] == nil && expr[2] == :bind)
67
- argument_list = expr[3]
68
- if argument_list && argument_list[0] == :arglist
69
- arguments = argument_list[1]
70
- if arguments && arguments[0] == :hash
71
- block.delete_at 1
72
- count = (arguments.length-1) / 2
73
- (1..count).each do |j|
74
- temp = j * 2
75
- local = arguments[temp-1][1]
76
- if local.instance_of? Sexp
77
- local = local[1]
78
- end
79
- raise 'invalid value for role alias' unless local.instance_of? Symbol
80
- #find the name of the role being bound to
81
- aliased_role = arguments[temp][1]
82
- if aliased_role.instance_of? Sexp
83
- aliased_role = aliased_role[1]
84
- end
85
- raise "#{aliased_role} used in binding is an unknown role #{roles}" unless aliased_role.instance_of? Symbol and @roles.has_key? aliased_role
86
- add_alias local, aliased_role
87
- #replace bind call with assignment of iteration variable to role field
88
- do_rewrite_bind(aliased_role, local, block)
89
- changed = true
90
- end
91
- end
92
- end
93
- end
94
- changed
95
- end
96
-
97
- ##
98
- #removes call to bind in a block
99
- #and replaces it with assignment to the proper role player local variables
100
- #in the end of the block the local variables have their original values reassigned
101
- def do_rewrite_bind(aliased_role, local, block)
102
- raise 'aliased_role must be a Symbol' unless aliased_role.instance_of? Symbol
103
- raise 'local must be a Symbol' unless local.instance_of? Symbol
104
- aliased_field = "@#{aliased_role}".to_sym
105
- assignment = Sexp.new
106
- assignment[0] = :iasgn
107
- assignment[1] = aliased_field
108
- load_arg = Sexp.new
109
- load_arg[0] = :lvar
110
- load_arg[1] = local
111
- assignment[2] = load_arg
112
- block.insert 1, assignment
113
-
114
- # assign role player to temp
115
- temp_symbol = "temp____#{aliased_role}".to_sym
116
- assignment = Sexp.new
117
- assignment[0] = :lasgn
118
- assignment[1] = temp_symbol
119
- load_field = Sexp.new
120
- load_field[0] = :ivar
121
- load_field[1] = aliased_field
122
- assignment[2] = load_field
123
- block.insert 1, assignment
124
-
125
- # reassign original player
126
- assignment = Sexp.new
127
- assignment[0] = :iasgn
128
- assignment[1] = aliased_field
129
- load_temp = Sexp.new
130
- load_temp[0] = :lvar
131
- load_temp[1] = temp_symbol
132
- assignment[2] = load_temp
133
- block[block.length] = assignment
134
- end
135
-
136
- # rewrites a call to self in a role method to a call to the role player accessor
137
- # which is subsequently rewritten to a call to the instance variable itself
138
- # in the case where no role method is called on the role player
139
- # It's rewritten to an instance call on the context object if a role method is called
140
- def rewrite_self (ast)
141
- ast.length.times do |i|
142
- raise 'Invalid argument. must be an expression' unless ast.instance_of? Sexp
143
- exp = ast[i]
144
- if exp == :self
145
- ast[0] = :call
146
- ast[1] = nil
147
- ast[2] = @defining_role
148
- arglist = Sexp.new
149
- ast[3] = arglist
150
- arglist[0] = :arglist
151
- elsif exp.instance_of? Sexp
152
- rewrite_self exp
153
- end
154
- end
155
- end
156
-
157
- #rewrites the ast so that role method calls are rewritten to a method invocation on the context object rather than the role player
158
- #also does rewriting of binds in blocks
159
- def transform_ast(ast)
160
- if ast
161
- if @defining_role
162
- rewrite_self ast
163
- end
164
- ast.length.times do |k|
165
- exp = ast[k]
166
- if exp
167
- method_name = exp[2]
168
- role = role_method_call exp[1], exp[2]
169
- if exp[0] == :iter
170
- @role_alias.push Hash.new
171
- transform_block exp
172
- @role_alias.pop()
173
- end
174
- if exp[0] == :call && role
175
- exp[1] = nil #remove call to attribute
176
- exp[2] = "self_#{role}_#{method_name}".to_sym
177
- end
178
- if exp.instance_of? Sexp
179
- transform_ast exp
180
- end
181
- end
182
- end
183
- end
184
- end
185
- end