GFunk911-rubytypeassert 0.0.1 → 0.0.2

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 (4) hide show
  1. data/aspect.rb +67 -0
  2. data/core_ext.rb +156 -0
  3. data/intel.rb +149 -0
  4. metadata +4 -2
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+ require 'ostruct'
3
+
4
+ class MethodRuns
5
+ attr_accessor :method_name, :method_class
6
+ def initialize(c,n)
7
+ @method_name = n.to_s
8
+ @method_class = c.to_s
9
+ end
10
+ #:return: => Object
11
+ def runs
12
+ @runs ||= []
13
+ end
14
+ def log_run!(r)
15
+ raise 'wrong' unless method_name == r.method_name.to_s and method_class = r.method_class.to_s
16
+ runs << r
17
+ end
18
+ #:return: => Object
19
+ def arg_classes
20
+ runs.map { |r| r.args.map { |x| x.class } }.uniq
21
+ end
22
+ def return_classes
23
+ runs.map { |r| r.return.class }.uniq
24
+ end
25
+ #:return: => Object
26
+ def to_s
27
+ "#{method_class} / #{method_name}"
28
+ end
29
+ #:return: => Object
30
+ def summary
31
+ "#{method_class}##{method_name}, returns: #{return_classes.inspect}, args: #{arg_classes.inspect}"
32
+ end
33
+ #:return: => Object
34
+ def self.run_hash
35
+ @run_hash ||= Hash.new { |h,k| h[k] = new(*k) }
36
+ end
37
+ #:return: => Object
38
+ def self.runs
39
+ run_hash.values
40
+ end
41
+ #:return: => Object
42
+ def self.log_run!(r)
43
+ run_hash[[r.method_class.to_s,r.method_name.to_s]].log_run!(r)
44
+ end
45
+ #:return: => Object
46
+ def self.get(c,n)
47
+ run_hash[[c.to_s,n.to_s]]
48
+ end
49
+ end
50
+
51
+ def add_advice!(*advised_classes)
52
+ require 'aquarium'
53
+ advised_classes.flatten.each do |cls|
54
+ Aquarium::Aspects::Aspect.new :around, :calls_to => cls.uniq_instance_methods, :on_types => cls do |jp, object, *args|
55
+ #p "Entering: #{join_point.target_type.name}##{join_point.method_name} for object #{object}"
56
+ result = jp.proceed
57
+ #p "Leaving: #{join_point.target_type.name}##{join_point.method_name} for object #{object}"
58
+ MethodRuns.log_run! OpenStruct.new(:method_class => jp.target_type.name, :method_name => jp.method_name, :args => args, :return => result)
59
+ result # block needs to return the result of the "proceed"!
60
+ end
61
+ end
62
+ end
63
+
64
+ at_exit do
65
+ File.create("method_runs.txt",MethodRuns.runs.map { |x| x.summary }.join("\n"))
66
+ end
67
+
@@ -0,0 +1,156 @@
1
+ #!/usr/bin/env ruby
2
+ require 'facets/file/write'
3
+ require 'facets/enumerable/collect'
4
+ class Object
5
+ def common_methods
6
+ 7.methods + "".methods + 7.class.methods + "".class.methods + ActiveRecord::Base.instance_methods
7
+ end
8
+ def uniq_methods
9
+ (methods - common_methods).sort
10
+ end
11
+ def uniq_instance_methods(include_ar=true)
12
+ (instance_methods - common_methods - superclass.instance_methods - uniq_modules.map { |x| x.instance_methods }.flatten + (include_ar ? ar_methods : [])).sort
13
+ end
14
+ def uniq_modules
15
+ included_modules - superclass.included_modules
16
+ end
17
+ def ar_methods
18
+ return [] unless inherits_from?(ActiveRecord::Base)
19
+ columns.map { |x| x.name }.map { |x| [x,"#{x}="] }.flatten
20
+ end
21
+ def inherits_from?(x)
22
+ return true if superclass == x
23
+ return false unless superclass
24
+ superclass.inherits_from?(x)
25
+ end
26
+ end
27
+
28
+
29
+ class Object
30
+ def tap
31
+ yield(self)
32
+ self
33
+ end
34
+ end
35
+ class Hash
36
+ def summary
37
+ keys.sort_by { |x| x.to_s }.map { |k| "#{k}: #{self[k]}" }.join("\n")
38
+ end
39
+ end
40
+
41
+
42
+ class Class
43
+ def cond_accessor(*names)
44
+ names.flatten.each do |name|
45
+ define_method(name) do |*args|
46
+ instance_variable_set("@#{name}",args.first) unless args.empty?
47
+ instance_variable_get("@#{name}")
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ class Object
54
+ def klass
55
+ self.class
56
+ end
57
+ end
58
+
59
+ def eat_exceptions
60
+ yield
61
+ rescue
62
+ return nil
63
+ end
64
+
65
+ class Object
66
+ def from_hash(ops)
67
+ ops.each { |k,v| send("#{k}=",v) unless (v == :UNSET_FIELD) }
68
+ self
69
+ end
70
+ end
71
+
72
+ class Class
73
+ def from_hash(ops)
74
+ new.from_hash(ops)
75
+ end
76
+ end
77
+
78
+ class Object
79
+ def lazy_method(sym,&b)
80
+ send(:define_method,sym) do
81
+ instance_variable_set("@#{sym}",instance_eval(&b)) if instance_variable_get("@#{sym}").nil?
82
+ instance_variable_get("@#{sym}")
83
+ end
84
+ end
85
+ end
86
+
87
+ class Object
88
+ #attr_accessor :system
89
+ end
90
+
91
+ def log(x)
92
+ puts x
93
+ File.append(File.dirname(__FILE__) + "/output.log",x.to_s+"\n")
94
+ end
95
+
96
+ def debug(x)
97
+ end
98
+
99
+ class WIN32OLE
100
+ include Enumerable
101
+ def first
102
+ each { |x| return x }
103
+ end
104
+ def size
105
+ self.Count
106
+ end
107
+ def pruned_methods
108
+ ole_methods.map { |x| x.to_s.gsub(/\d/,"") }.uniq.sort
109
+ end
110
+ end
111
+
112
+ module ForwardableExtension
113
+ def delegate_to(object, new_method, *args)
114
+ options = args.last.is_a?(Hash) ? args.pop : {}
115
+ args.each do |element|
116
+ def_delegator object, element, new_method.to_sym
117
+ if options[:writer]
118
+ def_delegator object, :"#{element}=", :"#{new_method}="
119
+ end
120
+ end
121
+ end
122
+
123
+ protected
124
+ def name_with_prefix(element, options)
125
+ "#{options[:prefix] + "_" unless options[:prefix].nil? }#{element}"
126
+ end
127
+ end
128
+
129
+ require 'forwardable'
130
+ Forwardable.send :include, ForwardableExtension
131
+
132
+ module Enumerable
133
+ def propagate_to!(target)
134
+ each { |x| x.propagate_to!(target) }
135
+ end
136
+ end
137
+
138
+ def tm(str,num=1)
139
+ t = Time.now
140
+ res = nil
141
+ num.times { res = yield }
142
+ sec = Time.now - t
143
+ puts "#{str} took #{sec} seconds (#{res})"
144
+ end
145
+
146
+ class Object
147
+ def to_is
148
+ self ? to_i.to_s : nil
149
+ end
150
+ end
151
+
152
+ class Object
153
+ def nvl(x)
154
+ self || x
155
+ end
156
+ end
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env ruby
2
+ class Object
3
+ def lazy_method(sym,&b)
4
+ send(:define_method,sym) do
5
+ instance_variable_set("@#{sym}",instance_eval(&b)) if instance_variable_get("@#{sym}").nil?
6
+ instance_variable_get("@#{sym}")
7
+ end
8
+ end
9
+ end
10
+
11
+ class OS
12
+ def each(&b)
13
+ ObjectSpace.each_object(&b)
14
+ end
15
+ include Enumerable
16
+ def self.method_missing(sym,*args,&b)
17
+ new.send(sym,*args,&b)
18
+ end
19
+ end
20
+
21
+ def current_classes
22
+ OS.select { |x| x.is_a?(Class) }.uniq
23
+ end
24
+
25
+ def local_class_names
26
+ $local_class_names ||= Dir["**/*.rb"].map do |filename|
27
+ File.new(filename).read.scan(/^\s*class (\S+)(?: |$)/).flatten
28
+ end.flatten.map { |x| x.split(":")[-1] }.sort
29
+ end
30
+
31
+ def init_classes
32
+ $init_classes ||= current_classes
33
+ end
34
+
35
+ def generate_local_class_defs!(req_file)
36
+ init_classes
37
+ load req_file
38
+ str = local_class_defs.map { |x| x.class_str }.join("\n")
39
+ File.create("local_class_defs.rb",str)
40
+ end
41
+
42
+ def local_class_defs
43
+ $local_class_defs ||= (current_classes - init_classes).select { |x| local_class_names.include?(x.to_s.split(":")[-1]) }.map { |x| ClassDef.new(x) }
44
+ end
45
+
46
+ class String
47
+ def prefix_each_line(pre)
48
+ pre + self[0..-2].gsub(/\n/,"\n#{pre}") + self[-1..-1]
49
+ end
50
+ end
51
+
52
+ module DefModule
53
+ def modules
54
+ cls.to_s.split(":")[0..-2].select { |x| x != '' }
55
+ end
56
+ def class_spaces
57
+ " "*2*modules.size
58
+ end
59
+ end
60
+
61
+ class ClassDef
62
+ include DefModule
63
+ attr_accessor :cls
64
+ def initialize(c)
65
+ @cls = c
66
+ end
67
+ def bare_cls
68
+ cls.to_s.split(':')[-1]
69
+ end
70
+ def class_str
71
+ str = ''
72
+ modules.each_with_index { |x,i| str << " "*i*2 + "module #{x}\n" }
73
+ str << class_spaces + "class #{bare_cls}"
74
+ str << " < #{cls.superclass}" unless [Object,nil].include?(cls.superclass)
75
+ str << "\n"
76
+ cls.uniq_modules.each { |x| str << "#{class_spaces} include #{x}\n" }
77
+ str << methods_str
78
+ str << class_spaces + "end\n"
79
+ modules.each_with_index { |x,i| str << " "*i*2 + "end\n" }
80
+ str
81
+ end
82
+ lazy_method(:methods) do
83
+ cls.uniq_instance_methods.map { |x| MethodDef.new(cls,x) }
84
+ end
85
+ def methods_str
86
+ methods.map { |x| x.method_str }.join("")
87
+ end
88
+ end
89
+
90
+ class MethodDef
91
+ include DefModule
92
+ attr_accessor :cls, :name
93
+ def initialize(c,n)
94
+ @cls = c
95
+ @name = n.to_s.downcase
96
+ end
97
+ def method_obj
98
+ eat_exceptions { cls.instance_method(m) }
99
+ end
100
+ def arity
101
+ method_obj ? method_obj.arity : 0
102
+ end
103
+ def arg_str
104
+ (0...arity).map { |x| ("a"[0]+x).chr }.join(",")
105
+ end
106
+ def manual_method_str
107
+ str = "#{class_spaces} # manual meth def\n"
108
+ str << "#{class_spaces} def #{name}(#{arg_str})\n"
109
+ str << "#{class_spaces} end\n"
110
+ str
111
+ end
112
+ def runs
113
+ MethodRuns.get(cls,name)
114
+ end
115
+ def return_type
116
+ runs.return_classes.flatten.first || Object
117
+ end
118
+ def type_comments
119
+ "#{class_spaces} #:return: => #{return_type}\n"
120
+ end
121
+ lazy_method(:method_body) do
122
+ eat_exceptions { RubyToRuby.translate(cls,name).prefix_each_line(class_spaces+" ") + "\n" } || manual_method_str
123
+ end
124
+ def arg_names
125
+ return [] if method_body.strip =~ /^attr_/
126
+ arg_str = method_body.scan(/def.*#{name}(.*)$/).flatten.first
127
+ raise "no arg_str for #{cls} #{name} /def.*#{name}(.*)$/" unless arg_str
128
+ return [] if arg_str.strip == '' or arg_str.strip == '()'
129
+ arg_str[1..-2].split(",")
130
+ end
131
+ def arg_type(i)
132
+ (runs.arg_classes[i]||[]).first || Object
133
+ end
134
+ def arg_comments
135
+ arg_names.map_with_index do |arg,i|
136
+ "#{class_spaces} #:arg: #{arg} => #{arg_type(i)}\n"
137
+ end.join("")
138
+ end
139
+ def method_str
140
+ type_comments + arg_comments + method_body
141
+ end
142
+ end
143
+
144
+ def rta_run!(req_file)
145
+ require 'ruby2ruby'
146
+ generate_local_class_defs!(req_file)
147
+ add_advice!(ActiveRecord::Base)
148
+ generate_local_class_defs!(req_file)
149
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: GFunk911-rubytypeassert
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Harris
@@ -22,7 +22,9 @@ extensions: []
22
22
  extra_rdoc_files: []
23
23
 
24
24
  files:
25
- - "*.rb"
25
+ - aspect.rb
26
+ - core_ext.rb
27
+ - intel.rb
26
28
  has_rdoc: false
27
29
  homepage: http://github.com/GFunk911/RubyTypeAssert
28
30
  post_install_message: