xumlidot 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/xumlidot +39 -0
- data/lib/xumlidot.rb +10 -0
- data/lib/xumlidot/diagram.rb +18 -0
- data/lib/xumlidot/diagram/dot.rb +55 -0
- data/lib/xumlidot/diagram/dot/klass.rb +75 -0
- data/lib/xumlidot/diagram/dot/module.rb +11 -0
- data/lib/xumlidot/diagram/shared/naming.rb +19 -0
- data/lib/xumlidot/diagram/xmi.rb +190 -0
- data/lib/xumlidot/diagram/xmi/argument.rb +34 -0
- data/lib/xumlidot/diagram/xmi/attribute.rb +24 -0
- data/lib/xumlidot/diagram/xmi/constant.rb +16 -0
- data/lib/xumlidot/diagram/xmi/id.rb +39 -0
- data/lib/xumlidot/diagram/xmi/klass.rb +133 -0
- data/lib/xumlidot/diagram/xmi/method.rb +38 -0
- data/lib/xumlidot/diagram/xmi/superklass.rb +18 -0
- data/lib/xumlidot/directory_tree.rb +24 -0
- data/lib/xumlidot/options.rb +104 -0
- data/lib/xumlidot/parsers.rb +14 -0
- data/lib/xumlidot/parsers/args.rb +159 -0
- data/lib/xumlidot/parsers/call.rb +92 -0
- data/lib/xumlidot/parsers/file.rb +15 -0
- data/lib/xumlidot/parsers/generic.rb +106 -0
- data/lib/xumlidot/parsers/klass_definition.rb +76 -0
- data/lib/xumlidot/parsers/method_signature.rb +95 -0
- data/lib/xumlidot/parsers/module_definition.rb +55 -0
- data/lib/xumlidot/parsers/scope.rb +54 -0
- data/lib/xumlidot/parsers/stack.rb +96 -0
- data/lib/xumlidot/types.rb +18 -0
- data/lib/xumlidot/types/argument.rb +61 -0
- data/lib/xumlidot/types/arguments.rb +14 -0
- data/lib/xumlidot/types/attribute.rb +34 -0
- data/lib/xumlidot/types/attributes.rb +11 -0
- data/lib/xumlidot/types/constant.rb +49 -0
- data/lib/xumlidot/types/constants.rb +57 -0
- data/lib/xumlidot/types/inherited_module.rb +24 -0
- data/lib/xumlidot/types/instance_methods.rb +10 -0
- data/lib/xumlidot/types/klass.rb +60 -0
- data/lib/xumlidot/types/klass_definition.rb +61 -0
- data/lib/xumlidot/types/klass_methods.rb +10 -0
- data/lib/xumlidot/types/method.rb +10 -0
- data/lib/xumlidot/types/method_signature.rb +64 -0
- data/lib/xumlidot/types/methods.rb +10 -0
- data/lib/xumlidot/types/module.rb +11 -0
- data/lib/xumlidot/types/module_definition.rb +14 -0
- data/lib/xumlidot/types/superklass.rb +32 -0
- data/spec/spec_helper.rb +2 -0
- metadata +175 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'id'
|
4
|
+
|
5
|
+
module Xumlidot
|
6
|
+
class Diagram
|
7
|
+
class Xmi
|
8
|
+
module Attribute
|
9
|
+
include ::Xumlidot::Diagram::Xmi::ID
|
10
|
+
|
11
|
+
# TODO - public/private visibility on attributes
|
12
|
+
def draw
|
13
|
+
attribute_xmi = "<ownedAttribute aggregation=\"none\" isDerived=\"false\" isDerivedUnion=\"false\" isID=\"false\" isLeaf=\"false\" isReadOnly=\"false\" isStatic=\"false\" name=\"#{name_to_xmi}\" visibility=\"public\" xmi:id=\"#{id}\" xmi:type=\"uml:Property\">"
|
14
|
+
attribute_xmi += "</ownedAttribute>"
|
15
|
+
end
|
16
|
+
|
17
|
+
def name_to_xmi
|
18
|
+
name.encode(:xml => :text) if name
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
module Xumlidot
|
6
|
+
class Diagram
|
7
|
+
class Xmi
|
8
|
+
# Helper - everything needs an id and these ids need to be used in the
|
9
|
+
# Element section
|
10
|
+
module ID
|
11
|
+
def id
|
12
|
+
@_id ||= new_id
|
13
|
+
end
|
14
|
+
|
15
|
+
def force_id(id)
|
16
|
+
@_id = id
|
17
|
+
end
|
18
|
+
|
19
|
+
def gen_id
|
20
|
+
@gen_id ||= "#{new_id[0..5]}.#{new_id[0..5]}".upcase
|
21
|
+
end
|
22
|
+
|
23
|
+
def association_id
|
24
|
+
@association_id ||= "#{new_id[0..5]}.#{new_id[0..5]}".upcase
|
25
|
+
end
|
26
|
+
|
27
|
+
def association_end_id
|
28
|
+
@association_end_id ||= "#{new_id[0..5]}.#{new_id[0..5]}".upcase
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def new_id
|
34
|
+
SecureRandom.hex
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../types'
|
4
|
+
require_relative 'id'
|
5
|
+
require_relative 'constant'
|
6
|
+
require_relative 'superklass'
|
7
|
+
require_relative '../shared/naming'
|
8
|
+
|
9
|
+
module Xumlidot
|
10
|
+
class Diagram
|
11
|
+
class Xmi
|
12
|
+
# Draw the klass
|
13
|
+
module Klass
|
14
|
+
include ::Xumlidot::Diagram::Xmi::ID
|
15
|
+
include ::Xumlidot::Diagram::Shared::Naming
|
16
|
+
|
17
|
+
module Name
|
18
|
+
def to_xmi
|
19
|
+
map do |constant|
|
20
|
+
constant.extend(::Xumlidot::Diagram::Xmi::Constant) unless constant.respond_to?(:to_xmi)
|
21
|
+
constant.to_xmi
|
22
|
+
end.join
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# TODO: Split this into model and diagram classes
|
27
|
+
class Model
|
28
|
+
end
|
29
|
+
|
30
|
+
class Diagram
|
31
|
+
end
|
32
|
+
|
33
|
+
def draw_klass(options)
|
34
|
+
definition.name.extend(Name)
|
35
|
+
xmi = "<ownedMember isAbstract=\"false\" isActive=\"false\" isLeaf=\"false\" name=\"#{definition.name.to_xmi}\" visibility=\"public\" xmi:id=\"#{id}\" xmi:type=\"uml:Class\">"
|
36
|
+
xmi += draw_model_inheritance if options.inheritance
|
37
|
+
xmi += extend_and_draw(attributes)
|
38
|
+
xmi += extend_and_draw(class_methods)
|
39
|
+
xmi += extend_and_draw(instance_methods)
|
40
|
+
xmi += "</ownedMember>"
|
41
|
+
end
|
42
|
+
|
43
|
+
# Draws a diagram element i.e. the part which is rendered
|
44
|
+
def draw_diagram(options)
|
45
|
+
xml = %(<uml:DiagramElement preferredShapeType="Class" subject="#{id}" xmi:id="#{id}de">
|
46
|
+
</uml:DiagramElement>)
|
47
|
+
|
48
|
+
return xml if @definition.superklass.empty? && @definition.inherited_modules.empty?
|
49
|
+
return xml unless options.inheritance
|
50
|
+
|
51
|
+
xml += draw_diagram_generalisation
|
52
|
+
end
|
53
|
+
|
54
|
+
def draw_diagram_generalisation
|
55
|
+
xml = ''
|
56
|
+
|
57
|
+
if ! @definition.superklass.empty?
|
58
|
+
xml += %(<uml:DiagramElement fromDiagramElement="#{@definition.superklass.id}de" preferredShapeType="Generalization" subject="#{gen_id}" toDiagramElement="#{id}de">
|
59
|
+
</uml:DiagramElement>)
|
60
|
+
end
|
61
|
+
|
62
|
+
return xml if @definition.inherited_modules.empty?
|
63
|
+
|
64
|
+
@definition.inherited_modules.each do |m|
|
65
|
+
next if m.empty?
|
66
|
+
|
67
|
+
xml += %(<uml:DiagramElement fromDiagramElement="#{m.id}de" preferredShapeType="Generalization" subject="#{gen_id}" toDiagramElement="#{id}de">
|
68
|
+
</uml:DiagramElement>)
|
69
|
+
end
|
70
|
+
|
71
|
+
xml
|
72
|
+
end
|
73
|
+
|
74
|
+
# Inheritance has to be drawn both as part of the model
|
75
|
+
# and as a part of the diagram
|
76
|
+
#
|
77
|
+
# general =
|
78
|
+
# id = IMPORTANT; will be used to draw the lines in the diagram
|
79
|
+
#
|
80
|
+
def draw_model_inheritance
|
81
|
+
return '' if @definition.superklass.empty? && @definition.inherited_modules.empty?
|
82
|
+
|
83
|
+
xml = ''
|
84
|
+
|
85
|
+
if ! @definition.superklass.empty?
|
86
|
+
xml += %(<generalization general="#{@definition.superklass.id}" xmi:id="#{gen_id}" xmi:type="uml:Generalization">
|
87
|
+
</generalization>)
|
88
|
+
end
|
89
|
+
|
90
|
+
return xml if @definition.inherited_modules.empty?
|
91
|
+
|
92
|
+
@definition.inherited_modules.each do |m|
|
93
|
+
next if m.empty?
|
94
|
+
|
95
|
+
xml += %(<generalization general="#{m.id}" xmi:id="#{gen_id}" xmi:type="uml:Generalization">
|
96
|
+
</generalization>)
|
97
|
+
end
|
98
|
+
xml
|
99
|
+
end
|
100
|
+
|
101
|
+
def draw_model_composition(composee)
|
102
|
+
%(<ownedMember isAbstract="false" isDerived="false" isLeaf="false" xmi:id="#{association_id}" xmi:type="uml:Association">
|
103
|
+
<memberEnd xmi:idref="#{association_end_id}"/>
|
104
|
+
<ownedEnd aggregation="none" association="#{association_id}" isDerived="false" isDerivedUnion="false" isLeaf="false" isNavigable="true" isReadOnly="false" isStatic="false" type="#{id}" xmi:id="9JMZlYaD.AACASCI" xmi:type="uml:Property">
|
105
|
+
</ownedEnd>
|
106
|
+
<memberEnd xmi:idref="#{composee.association_end_id}"/>
|
107
|
+
<ownedEnd aggregation="composite" association="#{association_id}" isDerived="false" isDerivedUnion="false" isLeaf="false" isNavigable="true" isReadOnly="false" isStatic="false" type="#{composee.id}" xmi:id="9JMZlYaD.AACASCK" xmi:type="uml:Property">
|
108
|
+
</ownedEnd>
|
109
|
+
</ownedMember>)
|
110
|
+
end
|
111
|
+
|
112
|
+
def draw_diagram_composition(composee)
|
113
|
+
%(<uml:DiagramElement fromDiagramElement="#{id}de" preferredShapeType="Association" subject="#{association_id}" toDiagramElement="#{composee.id}de">
|
114
|
+
</uml:DiagramElement>)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Im not happy with this - xmi should not have to
|
118
|
+
# know about types and it should be a method
|
119
|
+
def extend_and_draw(collection)
|
120
|
+
collection.map do |member|
|
121
|
+
case member
|
122
|
+
when ::Xumlidot::Types::MethodSignature
|
123
|
+
member.extend(::Xumlidot::Diagram::Xmi::MethodSignature)
|
124
|
+
when ::Xumlidot::Types::Attribute
|
125
|
+
member.extend(::Xumlidot::Diagram::Xmi::Attribute)
|
126
|
+
end
|
127
|
+
member.draw
|
128
|
+
end.join(' ')
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../types'
|
4
|
+
require_relative 'id'
|
5
|
+
|
6
|
+
module Xumlidot
|
7
|
+
class Diagram
|
8
|
+
class Xmi
|
9
|
+
module MethodSignature
|
10
|
+
include ::Xumlidot::Diagram::Xmi::ID
|
11
|
+
|
12
|
+
# Ugh
|
13
|
+
def name_to_xmi
|
14
|
+
return '<<' if name == :<<
|
15
|
+
return '>>' if name == :>>
|
16
|
+
return '<=>' if name == :<=>
|
17
|
+
name
|
18
|
+
end
|
19
|
+
|
20
|
+
def draw
|
21
|
+
xmi = "<ownedOperation isAbstract=\"false\" isLeaf=\"false\" isOrdered=\"false\" isQuery=\"false\" isStatic=\"#{superclass_method}\" isUnique=\"true\" name=\"#{name_to_xmi}\" visibility=\"#{visibility}\" xmi:id=\"#{id}\" xmi:type=\"uml:Operation\">"
|
22
|
+
xmi += "<ownedParameter kind=\"return\" xmi:id=\"#{return_id}\" xmi:type=\"uml:Parameter\"/>"
|
23
|
+
args.each do |argument|
|
24
|
+
argument.extend(::Xumlidot::Diagram::Xmi::Argument)
|
25
|
+
xmi += argument.draw
|
26
|
+
end
|
27
|
+
xmi += "</ownedOperation>"
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def return_id
|
33
|
+
@_return_id ||= new_id
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../types'
|
4
|
+
require_relative 'id'
|
5
|
+
|
6
|
+
module Xumlidot
|
7
|
+
class Diagram
|
8
|
+
class Xmi
|
9
|
+
module Superklass
|
10
|
+
include ::Xumlidot::Diagram::Xmi::ID
|
11
|
+
|
12
|
+
def draw_identifier
|
13
|
+
[name, namespace.reverse].reverse.flatten.join('::')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'find'
|
2
|
+
|
3
|
+
module Xumlidot
|
4
|
+
# Recurse down a directory tree
|
5
|
+
class DirectoryTree
|
6
|
+
def initialize(directories, options)
|
7
|
+
@directories = directories
|
8
|
+
@options = options
|
9
|
+
@excluded = Regexp.new(@options.exclude)
|
10
|
+
end
|
11
|
+
|
12
|
+
def find_all_rb_files(&block)
|
13
|
+
@directories.each do |directory|
|
14
|
+
Find.find(directory) do |path|
|
15
|
+
next if path =~ @exluded
|
16
|
+
|
17
|
+
next unless path.end_with? '.rb'
|
18
|
+
|
19
|
+
yield path if block_given?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'optparse/time'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
module Xumlidot
|
6
|
+
OptionsError = Class.new(StandardError)
|
7
|
+
|
8
|
+
class Options
|
9
|
+
def self.method_missing(m, *args, &block)
|
10
|
+
if @options.respond_to?(m)
|
11
|
+
@options.send(m)
|
12
|
+
else
|
13
|
+
raise OptionsError.new("Unknown Option #{m}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.parse(args)
|
18
|
+
@options = OpenStruct.new
|
19
|
+
|
20
|
+
@options.title = 'Class Diagram'
|
21
|
+
@options.model_name = 'My Model'
|
22
|
+
@options.diagram_type = :dot
|
23
|
+
@options.rails = false
|
24
|
+
@options.debug = false
|
25
|
+
@options.inheritance = true
|
26
|
+
@options.composition = true
|
27
|
+
@options.usage = true
|
28
|
+
@options.split = 1
|
29
|
+
@options.sequence = ''
|
30
|
+
@options.exclude = ''
|
31
|
+
|
32
|
+
ENV.delete("XUMLIDOT_DEBUG")
|
33
|
+
|
34
|
+
opt_parser = OptionParser.new do |opts|
|
35
|
+
opts.banner = "Usage: xumlidot.rb [options]"
|
36
|
+
|
37
|
+
opts.separator ""
|
38
|
+
opts.separator "Specific options:"
|
39
|
+
|
40
|
+
opts.on("-t", "--title [TEXT]", "Title for the diagram") do |v|
|
41
|
+
@options.title = v
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on("-m", "--model [TEXT]", "Model Name for the diagram") do |v|
|
45
|
+
@options.model_name = v
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on("-d", "--dot", "Output diagram using dot (default)") do |v|
|
49
|
+
@options.diagram_type = :dot
|
50
|
+
end
|
51
|
+
|
52
|
+
opts.on("-x", "--xmi", "Output diagram using xmi") do |v|
|
53
|
+
@options.diagram_type = :xmi
|
54
|
+
end
|
55
|
+
|
56
|
+
opts.on("-d", "--debug", "Output debug information") do |v|
|
57
|
+
@options.debug = true
|
58
|
+
ENV["XUMLIDOT_DEBUG"] = '1'
|
59
|
+
end
|
60
|
+
|
61
|
+
opts.on("-i", "--no-inheritance", "Output inheritence links on the diagram") do |v|
|
62
|
+
@options.inheritance = false
|
63
|
+
end
|
64
|
+
|
65
|
+
opts.on("-c", "--no-composition", "Output composition links on the diagram") do |v|
|
66
|
+
@options.composition = false
|
67
|
+
end
|
68
|
+
|
69
|
+
opts.on("-r", "--rails", "Expect a Rails application") do |v|
|
70
|
+
@options.rails = v
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
opts.on("-e", "--exclude [TEXT[", "Output usage links on the diagram") do |v|
|
75
|
+
@options.exclude = v
|
76
|
+
end
|
77
|
+
|
78
|
+
opts.on("-u", "--[no-]usage", "Output usage links on the diagram") do |v|
|
79
|
+
@options.usage = v
|
80
|
+
end
|
81
|
+
opts.separator ""
|
82
|
+
|
83
|
+
opts.separator "Common options:"
|
84
|
+
|
85
|
+
# No argument, shows at tail. This will print an options summary.
|
86
|
+
# Try it and see!
|
87
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
88
|
+
puts opts
|
89
|
+
exit
|
90
|
+
end
|
91
|
+
|
92
|
+
# Another typical switch to print the version.
|
93
|
+
opts.on_tail("--version", "Show version") do
|
94
|
+
puts ::Version.join('.')
|
95
|
+
exit
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
opt_parser.parse!(args)
|
100
|
+
@options
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'ruby_parser'
|
2
|
+
require 'sexp_processor'
|
3
|
+
require 'ostruct'
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
require_relative 'parsers/generic'
|
7
|
+
require_relative 'parsers/args'
|
8
|
+
require_relative 'parsers/call'
|
9
|
+
require_relative 'parsers/file'
|
10
|
+
require_relative 'parsers/klass_definition'
|
11
|
+
require_relative 'parsers/method_signature'
|
12
|
+
require_relative 'parsers/module_definition'
|
13
|
+
require_relative 'parsers/scope'
|
14
|
+
require_relative 'parsers/stack'
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../parsers'
|
4
|
+
require_relative '../types'
|
5
|
+
|
6
|
+
module Xumlidot
|
7
|
+
module Parsers
|
8
|
+
# Parser for the arguments to a method
|
9
|
+
#
|
10
|
+
# e.g. formats def method(a, b = nil)
|
11
|
+
# to a string 'a, b = nil'
|
12
|
+
#
|
13
|
+
class Args < MethodBasedSexpProcessor
|
14
|
+
|
15
|
+
def initialize(exp)
|
16
|
+
super()
|
17
|
+
|
18
|
+
@arguments = ::Xumlidot::Types::Arguments.new
|
19
|
+
|
20
|
+
process(exp)
|
21
|
+
rescue => e
|
22
|
+
STDERR.puts " ** bug: unable to process args #{exp} "
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
@arguments.to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
def definition
|
30
|
+
@arguments
|
31
|
+
end
|
32
|
+
|
33
|
+
# Note - special case since a value of nil for default
|
34
|
+
# means we shouldn't display it and so we use the :nil
|
35
|
+
# symbol to represent an *actual assignment of nil* to
|
36
|
+
# a variable.
|
37
|
+
def process_nil(exp)
|
38
|
+
@argument.default = :nil
|
39
|
+
s()
|
40
|
+
end
|
41
|
+
|
42
|
+
def process_str(exp)
|
43
|
+
@argument.default = exp.value
|
44
|
+
s()
|
45
|
+
end
|
46
|
+
|
47
|
+
def process_hash(exp)
|
48
|
+
@argument.default = {}
|
49
|
+
s()
|
50
|
+
end
|
51
|
+
|
52
|
+
# const means that we have a constant assignment such as (a = Foo)
|
53
|
+
def process_const(exp)
|
54
|
+
@argument.default = exp.value.to_s
|
55
|
+
s()
|
56
|
+
end
|
57
|
+
|
58
|
+
# Colon2 means that we have a constant assignment such as (a = Foo::Bar)
|
59
|
+
def process_colon2(exp)
|
60
|
+
name = exp.flatten
|
61
|
+
name.delete :const
|
62
|
+
name.delete :colon2
|
63
|
+
|
64
|
+
leader = ''
|
65
|
+
if name.first == :colon3
|
66
|
+
leader = '::'
|
67
|
+
name.delete :colon3
|
68
|
+
end
|
69
|
+
|
70
|
+
# I'm not sure how best to proceed here.
|
71
|
+
#
|
72
|
+
# I can use const_set to start creating the constants heirachy
|
73
|
+
# but this is complex since it needs to be inserted into the right
|
74
|
+
# place and for that I need the namespace...which suggests this ISNT
|
75
|
+
# the place to do that. I possibly need a fake class ...
|
76
|
+
@argument.default = leader + name.map do |v|
|
77
|
+
v.to_s
|
78
|
+
end.to_a.join('::')
|
79
|
+
|
80
|
+
s()
|
81
|
+
end
|
82
|
+
|
83
|
+
# Colon2 means that we have a constant assignment such as (a = ::Foo::Bar)
|
84
|
+
# again see the note in colon2 about how to proceed
|
85
|
+
def process_colon3(exp)
|
86
|
+
process_colon2(exp)
|
87
|
+
@argument.default = "::#{argument.default}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def process_array(exp)
|
91
|
+
@argument.default = []
|
92
|
+
|
93
|
+
exp.shift # remove :array
|
94
|
+
exp.each { |element| process(element) }
|
95
|
+
s()
|
96
|
+
end
|
97
|
+
|
98
|
+
def process_lasgn(exp)
|
99
|
+
exp.shift # remove :lasgn
|
100
|
+
|
101
|
+
@argument.name = exp.shift.to_s
|
102
|
+
|
103
|
+
value = exp.shift
|
104
|
+
process(value)
|
105
|
+
s()
|
106
|
+
end
|
107
|
+
|
108
|
+
def process_lit(exp)
|
109
|
+
exp.shift # remove :lit
|
110
|
+
|
111
|
+
case @argument.default
|
112
|
+
when Array
|
113
|
+
@argument.default << exp.value
|
114
|
+
when nil
|
115
|
+
@argument.default = exp.value
|
116
|
+
when Symbol
|
117
|
+
@argument.default = exp.value.to_s
|
118
|
+
when String
|
119
|
+
@argument.default = exp.value.to_s
|
120
|
+
when Sexp
|
121
|
+
# binding.pry
|
122
|
+
when Hash
|
123
|
+
# binding.pry
|
124
|
+
else
|
125
|
+
# binding.pry
|
126
|
+
end
|
127
|
+
exp.shift
|
128
|
+
s()
|
129
|
+
end
|
130
|
+
|
131
|
+
def process_kwarg(exp)
|
132
|
+
exp.shift # remove :kwarg
|
133
|
+
@argument.name = "#{exp[0]}:"
|
134
|
+
process(exp)
|
135
|
+
s()
|
136
|
+
rescue => e
|
137
|
+
STDERR.puts " ** bug: unable to process kwarg #{exp}; failure to parse default value? "
|
138
|
+
s()
|
139
|
+
end
|
140
|
+
|
141
|
+
def process_args(exp)
|
142
|
+
exp.shift # remove :args
|
143
|
+
exp.each do |arg|
|
144
|
+
@argument = ::Xumlidot::Types::Argument.new
|
145
|
+
if arg.is_a? Sexp
|
146
|
+
@argument.assign = '='
|
147
|
+
process(arg)
|
148
|
+
else
|
149
|
+
@argument.name = arg.to_s
|
150
|
+
end
|
151
|
+
|
152
|
+
@arguments << @argument
|
153
|
+
end
|
154
|
+
rescue => e
|
155
|
+
STDERR.puts " ** bug: unable to process args #{exp}; failure to parse default value? "
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|