xumlidot 0.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.
- 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
|