xumlidot 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d57e014e5a04129a7ca8bfcc0cc8dae7e2b4db752de4bf5ad7643db37251de91
4
- data.tar.gz: 5fa6e4b9c7004a2078a12123d5d506bd2d6479271285cd868fb87ba61a67b319
3
+ metadata.gz: '08c6d11a210e378f99226f1933944c6023d2bb3b0b5a8eeaba85050fe6e8b3cb'
4
+ data.tar.gz: d8a37ae51f5d1dbc416d05241b456e614f56f82d23b972d9a8e1507dc84835d1
5
5
  SHA512:
6
- metadata.gz: e3dc0e126cb359825379197fb3537881156436db6b65667c2c96cbfe31468e1ad406e78c485125ee334236cd7c9b018e717fd9a2dc29136b376b544adbbff537
7
- data.tar.gz: 5d7f6a45fdd7b7f847581991b67e4dee05b0c3aa518ce176c886d898a19a59e729f0d9f3e122ab09dbbf66e2af62c673f122819fa75e6149c315adb3a5f3997f
6
+ metadata.gz: bae461d270a21d92c15ff2694b955fc1972e43d6b973da8620032d96533bbfcb02c426793286a0a044b1eeb2f6a01c072e19bb2184a7c1908f596df3f7e6532c
7
+ data.tar.gz: '08f435ea1c0dddbcf49c53ab6c18820a6aceb67d2f504cbbe315203f9ea9f465dd1c378384bd70abe1202c83aede6f64793f0a7840a321af1052696bf477d203'
data/bin/xumlidot CHANGED
@@ -5,35 +5,6 @@ require_relative '../lib/xumlidot'
5
5
  options = ::Xumlidot::Options.parse(ARGV)
6
6
 
7
7
  # TODO: user input
8
- directories = [ARGV[0]]
8
+ directories = ARGV
9
9
 
10
- dt = Xumlidot::DirectoryTree.new(directories, options)
11
-
12
- # This is our tree of klasses/modules etc
13
- # since we can't assume rails conventions for naming
14
- # in a Ruby program.
15
- constants = ::Xumlidot::Parsers::Stack::Constants.new
16
-
17
- # TODO: move into directory tree
18
- dt.find_all_rb_files do |path|
19
- STDERR.puts path if ::Xumlidot::Options.debug == true
20
- file_contents = File.read(path)
21
-
22
- @parser = Xumlidot::Parsers::File.new(file_contents, constants)
23
- @parser.parse
24
- end
25
-
26
- # If a class is inherited from but does not exist in the constants
27
- # we will create a dummy class.
28
- #
29
- # if a class is inherited from, we want to find it using the constant lookup
30
- # rules definind in the resolver
31
- #
32
- # and what ... we want to add a reference too it?
33
- #
34
- # This REALLY should be done whenever we add a superklass
35
- # i.e. yeah, its a hack
36
- constants.resolve_inheritance()
37
-
38
- diagram = ::Xumlidot::Diagram.new(constants, options)
39
- diagram.draw
10
+ ::Xumlidot::Loader.new(directories, options).load
@@ -6,8 +6,16 @@ module Xumlidot
6
6
  class Diagram
7
7
  class Dot
8
8
  module Method
9
+ CHARACTER_SUBSTITUTIONS = {
10
+ '>' => '\>',
11
+ '<' => '\<',
12
+ '{' => '\{',
13
+ '}' => '\}',
14
+ '|' => '\|'
15
+ }.freeze
16
+
9
17
  def to_dot
10
- to_s.gsub('{}', '\{\}')
18
+ to_s.gsub(/[#{CHARACTER_SUBSTITUTIONS.keys.join}]/, CHARACTER_SUBSTITUTIONS)
11
19
  end
12
20
  end
13
21
 
@@ -29,22 +37,29 @@ module Xumlidot
29
37
  end
30
38
 
31
39
  def draw_composition(composee)
32
- "\"#{draw_identifier(composee.definition)}\" -> \"#{draw_identifier(@definition)}\" [label=\"\", arrowhead=\"diamond\", arrowtail=\"diamond\"]"
40
+ "\"#{draw_identifier(composee.definition)}\"" \
41
+ " -> \"#{draw_identifier(@definition)}\"" \
42
+ ' [label="", arrowhead="diamond", arrowtail="diamond"]'
33
43
  end
34
44
 
35
- def draw_inheritence
45
+ def draw_inheritance # rubocop:disable Metrics/AbcSize
36
46
  return nil if @definition.superklass.empty? && @definition.inherited_modules.empty?
37
47
 
38
- dot = ""
39
- if !@definition.superklass.empty?
40
- dot += "\"#{draw_identifier(@definition)}\" -> \"#{draw_ancestor(@definition.superklass)}\" [label=\"\", arrowhead=\"empty\", arrowtail=\"onormal\"]\n"
48
+ dot = ''
49
+ unless @definition.superklass.empty?
50
+ dot += "\"#{draw_identifier(@definition)}\"" \
51
+ " -> \"#{draw_ancestor(@definition.superklass)}\"" \
52
+ " [label=\"\", arrowhead=\"empty\", arrowtail=\"onormal\"]\n"
41
53
  end
42
54
 
43
55
  return dot if @definition.inherited_modules.empty?
44
56
 
45
57
  @definition.inherited_modules.each do |m|
46
58
  next if m.empty?
47
- dot += "\"#{draw_identifier(@definition)}\" -> \"#{draw_ancestor(m)}\" [label=\"#{m.type.to_s}s\", arrowhead=\"empty\", arrowtail=\"onormal\"]\n"
59
+
60
+ dot += "\"#{draw_identifier(@definition)}\"" \
61
+ " -> \"#{draw_ancestor(m)}\"" \
62
+ " [label=\"#{m.type}s\", arrowhead=\"empty\", arrowtail=\"onormal\"]\n"
48
63
  end
49
64
 
50
65
  dot
@@ -52,19 +67,19 @@ module Xumlidot
52
67
 
53
68
  private
54
69
 
55
- def draw_methods
70
+ def draw_methods # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
56
71
  @attributes.each { |a| a.extend(Attribute) }
57
72
  @class_methods.each { |a| a.extend(Method) }
58
73
  @instance_methods.each { |a| a.extend(Method) }
59
74
 
60
75
  km = ''
61
76
  km += @attributes.map(&:to_dot).join('\l')
62
- km += '\\l' unless km.end_with?('\\l')
77
+ km += '\\l' if @attributes.any?
63
78
 
64
79
  km += @class_methods.map(&:to_dot).join('\l')
65
80
  km += '\\l' unless km.end_with?('\\l')
66
- km += '|' if instance_methods.size.positive?
67
81
 
82
+ km += '|' if instance_methods.any?
68
83
  km += @instance_methods.map(&:to_dot).join('\l')
69
84
  km += '\\l' unless km.end_with?('\\l')
70
85
  km
@@ -1,19 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'dot/klass'
2
4
  require_relative 'dot/module'
3
5
 
4
6
  module Xumlidot
5
7
  class Diagram
6
8
  class Dot
7
-
8
- def initialize(stack, options = nil)
9
+ def initialize(stack)
9
10
  @stack = stack
10
- @options = options
11
11
  @output = []
12
12
  end
13
13
 
14
14
  # We have to draw any connecting labels AFTER we have drawn the klasses
15
15
  # in order to have something to connect.
16
- def draw
16
+ def draw # rubocop:disable Metrics/AbcSize
17
17
  @output << header
18
18
  @stack.traverse do |klass|
19
19
  klass.extend(::Xumlidot::Diagram::Dot::Klass)
@@ -21,15 +21,15 @@ module Xumlidot
21
21
  end
22
22
 
23
23
  @stack.traverse do |klass|
24
- # Check - i shouldnt need to extend twice
24
+ # Check - i shouldn't need to extend twice
25
25
  klass.extend(::Xumlidot::Diagram::Dot::Klass)
26
26
 
27
- if @options.inheritance
28
- output = klass.draw_inheritence
27
+ if ::Xumlidot::Options.inheritance
28
+ output = klass.draw_inheritance
29
29
  @output << output unless output.nil?
30
30
  end
31
31
 
32
- if @options.composition
32
+ if ::Xumlidot::Options.composition
33
33
  klass.constants.each do |k|
34
34
  @output << klass.draw_composition(k)
35
35
  end
@@ -1,17 +1,18 @@
1
+ # frozen_string_literal: true
1
2
  module Xumlidot
2
3
  class Diagram
3
4
  module Shared
4
5
  module Naming
5
- def draw_identifier(d = @definition)
6
- [d.name.name, d.name.namespace.reverse].reverse.flatten.join('::')
6
+ def draw_identifier(definition = @definition)
7
+ [definition.name.name, definition.name.namespace.reverse].reverse.flatten.join('::')
7
8
  end
8
9
 
9
10
  def draw_name
10
11
  @definition.name.name.join('::')
11
12
  end
12
13
 
13
- def draw_ancestor(d = @definition)
14
- [d.name, d.namespace.reverse].reverse.flatten.join('::')
14
+ def draw_ancestor(definition = @definition)
15
+ [definition.name, definition.namespace.reverse].reverse.flatten.join('::')
15
16
  end
16
17
  end
17
18
  end
@@ -10,19 +10,22 @@ module Xumlidot
10
10
 
11
11
  def draw
12
12
  xmi = "<ownedParameter kind=\"inout\" name=\"#{name_to_xmi}\" xmi:id=\"#{id}\" xmi:type=\"uml:Parameter\">"
13
- xmi += "<defaultValue value=\"#{default_to_xmi}\" xmi:id=\"#{default_id}\" xmi:type=\"uml:LiteralString\"/>" if default
14
- xmi += "</ownedParameter>"
13
+ if default
14
+ xmi += "<defaultValue value=\"#{default_to_xmi}\" xmi:id=\"#{default_id}\" xmi:type=\"uml:LiteralString\"/>"
15
+ end
16
+ "#{xmi}</ownedParameter>"
15
17
  end
16
18
 
17
19
  private
18
20
 
19
21
  def name_to_xmi
20
- name.encode(:xml => :text) if name
22
+ name&.encode(xml: :text)
21
23
  end
22
24
 
23
25
  def default_to_xmi
24
26
  return default unless default.is_a?(String)
25
- default.encode(:xml => :text)
27
+
28
+ default.encode(xml: :text)
26
29
  end
27
30
 
28
31
  def default_id
@@ -8,16 +8,16 @@ module Xumlidot
8
8
  module Attribute
9
9
  include ::Xumlidot::Diagram::Xmi::ID
10
10
 
11
- # TODO - public/private visibility on attributes
11
+ # TODO: - public/private visibility on attributes
12
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>"
13
+ '<ownedAttribute aggregation="none" isDerived="false" isDerivedUnion="false" isID="false"' \
14
+ " isLeaf=\"false\" isReadOnly=\"false\" isStatic=\"false\" name=\"#{name_to_xmi}\"" \
15
+ " visibility=\"public\" xmi:id=\"#{id}\" xmi:type=\"uml:Property\"></ownedAttribute>"
15
16
  end
16
17
 
17
18
  def name_to_xmi
18
- name.encode(:xml => :text) if name
19
+ name&.encode(xml: :text)
19
20
  end
20
-
21
21
  end
22
22
  end
23
23
  end
@@ -3,6 +3,46 @@
3
3
  require 'securerandom'
4
4
 
5
5
  module Xumlidot
6
+ class ID
7
+ class << self
8
+ # rubocop:disable Layout/LineLength
9
+ PREGENERATED = %w[ 915803defa2bd0509fc1ff7a652081d4 e891fc71118502b95030b5e15d887622 2cf60373a8305b3f64bb93a5fa0e786c 35cd5b04a0ab4542aede1e37046fab5e
10
+ e1521c43130d064474e1585be1d69c6f 59975b5d607a197e676e2534e3dce454 9e52022530441f1688dfab381bba4069 f84f7b576ba1ab5929b4208cebfe7935
11
+ 37e5d86bb891a70011261ad861118a73 09646c77f8dfd088487c91f75c387a4c 9a064273fb75db2d41ad146063940862 ecc9ae948a23543ad23e61b0f907ae6b
12
+ b922777242d6e4d182e979a19b6b8fd9 b7f1299975494da9811c061f008cacba c906375f1de4be9d3dd3ea56e7917ea6 4265f6134237c7d0c9a4f12b838d1849
13
+ 2d75d4762aa997551f95c76ff23a1e52 fe32489778ddc04b5b2e29a69a25c44e 8e89af98ee73225cac65ade347f5d653 70668faf589fcdd1034db5e8e38c0b8c
14
+ 5b4d3919edab18b46790dc2af405982e bb35181dc1d23696cb914287fb3073da 1adca3c4c42e345682e0abe24dee32fb 611e830b410e4216c80b5fb62f0f0d20
15
+ 648b5d6b3d87b62a3fd34620c391c6e5 bd0747fa99c86e03dd6bbeec3989f859 52653ebf9f0c0930523f583ca3a54476 52e2bdc77cba152a5f8a1e7703893b13
16
+ 08b98d56e4b3e9dd7415cd0174550e01 63de406c477145edb70df08e1fe3d3e9 93f7b64cbd8e96ac5b54e0b83cfef84b cae3e7e7fc79276237aecaf68ab1bdc3
17
+ d2bde85b6c67f2c4e4f21f4eb24a9e11 b6239715d7b6dfbe845bf6218ffa9267 d018d840347248a3da9989cd56f10532 1fc72578fa0f6820991a2068aac595b0
18
+ f200b2bf3d28ce99cadeb505fe2a13f9 aba7ec911338260e448768655f9f7f62 e5019785cc3b2db9866887002aab0e82 a9490aac41fa641bf17595f5adc014e2
19
+ 85917936118146692ec4ebaff9bffa25 13fe8089229ff0a7a824a11683e1afa4 8f4dcf8694457f5d09b69513034eb896 aa841e2dda7b46f397dfee83ebebfcb3
20
+ e84c823e04f190a46b92c7e96d39d802 8dc5d1471bda113d37134e6e457be7f3 ee0989ea42bd2a2e06b0b923bc27aac7 b21b9efefa95229940367caa25d7c7b6
21
+ 7f32d97647fa4d3bb1cb0f8842f6280c 65864053fcd398271fd0482e4b8d6291 22c52a000c617293244d2346679bbcc7 f745cfcd9617f0ee9e8b7a609ccce424
22
+ 85ee520fa2e905d454ccdbf94d789e81 f260df13675880d30ff85dd6713b3df8 afdbe21f7540febe19e2dd2efb1770fe 9c6e6b915115f94f74777e1fe3683805
23
+ 8517f315cc89778e32d62b0e2ee0c01e 2303ed4f97dd09d24427400e3ed9dbaf 72549f0fe322198493927ff113bb9841 c27b2914926e6c8c7406199b0532ba00
24
+ 79940b95278e119378da6e15eea86a90 cd3ee7977ead372f732a8c586ea566a7 ea6370883b3de89a8b38a03c1ec9d591 92ed3a3d54ac7c28e7544ea22f6bfe97
25
+ 8c2302bf6185908b24798f359a2e4838 bef733b51d12963d596f5ecfd5197201 3fa6ac50361036266b73bca0ad3dee57 a5545b87d99a3b7c9533085498ff460e
26
+ dc3115e7ced845fc6303b2b294a42437 027b8863405ce601db60d685af987dee 71ac366b83d49ca62c3f7c0c7c101f43 6647027529522180e0ae96a176e5766d
27
+ 22e2726ab1b3df71e314f8145180f1c8 b800ccd5d685adac614624ffd5abb098 6c395e62f19d0f5b04f7cea5dd616a24 e2bbe604833cc15c393450d215008306
28
+ 7fa0acb9786d57b2ef4d9027f6cc7992 73d5302aedef54fb51cd08173c1f1829 01cef3c8b0d5ef6cae8574d1a5044b2b c695a6a12c418bb56699b2f5c6559da3
29
+ a14c60d2210dfea6e625208b72aa79e9 1c60dc02eece351995820d7436e7752e d2a2b30eecceb9f453697103b01b203a 3ae847a28c2248460a37e24686860479
30
+ 354982e26fd1da65403c9e70866e14f7 66485373131b4d5e02261f9d085be072 2e3e154c3ec06e401f48c7f444583d45 e57c33100b8f66813ee9265e4f023e03
31
+ 5afa58ca1c74f449d1b18cc3cb39b19f d5775ea87353bb12f31318533ed17382 c55778698f7c896c6f7e1a35f8698a06 178d5cdabad7e9f82f326a9ebbd01737
32
+ 31cf106e33c94b139f8c8c4820b46524 50a49cf6d0b9bedcbcef845917889a62 cc8aa4100a6f3855df3518a0a4474b74 c98c57ab3db339c74d44d6da5b2e0e62
33
+ a04e46e4a1f5fea64b3a47a3cc8ca0de 750156c36b6990f2a4763949775ea6a1 423cb15b7efee4800449579ce561a58e 424041648b3414d67743957b9e2ad66c ].freeze
34
+ # rubocop:enable Layout/LineLength
35
+
36
+ def reset
37
+ @fixed = nil
38
+ end
39
+
40
+ def fixed
41
+ @fixed ||= PREGENERATED.dup
42
+ end
43
+ end
44
+ end
45
+
6
46
  class Diagram
7
47
  class Xmi
8
48
  # Helper - everything needs an id and these ids need to be used in the
@@ -31,7 +71,11 @@ module Xumlidot
31
71
  private
32
72
 
33
73
  def new_id
34
- SecureRandom.hex
74
+ if ::Xumlidot::Options.use_debug_ids
75
+ ::Xumlidot::ID.fixed.shift
76
+ else
77
+ SecureRandom.hex
78
+ end
35
79
  end
36
80
  end
37
81
  end
@@ -24,39 +24,38 @@ module Xumlidot
24
24
  end
25
25
 
26
26
  # TODO: Split this into model and diagram classes
27
- class Model
28
- end
29
-
30
- class Diagram
31
- end
27
+ # class Model
28
+ # end
29
+ # class Diagram
30
+ # end
32
31
 
33
- def draw_klass(options)
32
+ def draw_klass # rubocop:disable Metrics/AbcSize
34
33
  definition.name.extend(Name)
35
34
  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
35
+ xmi += draw_model_inheritance if ::Xumlidot::Options.inheritance
37
36
  xmi += extend_and_draw(attributes)
38
37
  xmi += extend_and_draw(class_methods)
39
38
  xmi += extend_and_draw(instance_methods)
40
- xmi += "</ownedMember>"
39
+ "#{xmi}</ownedMember>"
41
40
  end
42
41
 
43
42
  # Draws a diagram element i.e. the part which is rendered
44
- def draw_diagram(options)
43
+ def draw_diagram
45
44
  xml = %(<uml:DiagramElement preferredShapeType="Class" subject="#{id}" xmi:id="#{id}de">
46
45
  </uml:DiagramElement>)
47
46
 
48
47
  return xml if @definition.superklass.empty? && @definition.inherited_modules.empty?
49
- return xml unless options.inheritance
48
+ return xml unless ::Xumlidot::Options.inheritance
50
49
 
51
- xml += draw_diagram_generalisation
50
+ xml + draw_diagram_generalisation
52
51
  end
53
52
 
54
53
  def draw_diagram_generalisation
55
54
  xml = ''
56
55
 
57
- if ! @definition.superklass.empty?
56
+ unless @definition.superklass.empty?
58
57
  xml += %(<uml:DiagramElement fromDiagramElement="#{@definition.superklass.id}de" preferredShapeType="Generalization" subject="#{gen_id}" toDiagramElement="#{id}de">
59
- </uml:DiagramElement>)
58
+ </uml:DiagramElement>)
60
59
  end
61
60
 
62
61
  return xml if @definition.inherited_modules.empty?
@@ -65,7 +64,7 @@ module Xumlidot
65
64
  next if m.empty?
66
65
 
67
66
  xml += %(<uml:DiagramElement fromDiagramElement="#{m.id}de" preferredShapeType="Generalization" subject="#{gen_id}" toDiagramElement="#{id}de">
68
- </uml:DiagramElement>)
67
+ </uml:DiagramElement>)
69
68
  end
70
69
 
71
70
  xml
@@ -77,12 +76,12 @@ module Xumlidot
77
76
  # general =
78
77
  # id = IMPORTANT; will be used to draw the lines in the diagram
79
78
  #
80
- def draw_model_inheritance
79
+ def draw_model_inheritance # rubocop:disable Metrics/AbcSize
81
80
  return '' if @definition.superklass.empty? && @definition.inherited_modules.empty?
82
81
 
83
82
  xml = ''
84
83
 
85
- if ! @definition.superklass.empty?
84
+ unless @definition.superklass.empty?
86
85
  xml += %(<generalization general="#{@definition.superklass.id}" xmi:id="#{gen_id}" xmi:type="uml:Generalization">
87
86
  </generalization>)
88
87
  end
@@ -101,11 +100,11 @@ module Xumlidot
101
100
  def draw_model_composition(composee)
102
101
  %(<ownedMember isAbstract="false" isDerived="false" isLeaf="false" xmi:id="#{association_id}" xmi:type="uml:Association">
103
102
  <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">
103
+ <ownedEnd aggregation="none" association="#{association_id}" isDerived="false" isDerivedUnion="false" isLeaf="false" isNavigable="true" isReadOnly="false" isStatic="false" type="#{id}" xmi:id="#{association_end_id}" xmi:type="uml:Property">
105
104
  </ownedEnd>
106
105
  <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>
106
+ <ownedEnd aggregation="composite" association="#{association_id}" isDerived="false" isDerivedUnion="false" isLeaf="false" isNavigable="true" isReadOnly="false" isStatic="false" type="#{composee.id}" xmi:id="#{composee.association_end_id}" xmi:type="uml:Property">
107
+ </ownedEnd>
109
108
  </ownedMember>)
110
109
  end
111
110
 
@@ -14,17 +14,20 @@ module Xumlidot
14
14
  return '&lt;&lt;' if name == :<<
15
15
  return '&gt;&gt;' if name == :>>
16
16
  return '&lt;=&gt;' if name == :<=>
17
+
17
18
  name
18
19
  end
19
20
 
20
21
  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 = '<ownedOperation isAbstract="false" isLeaf="false" isOrdered="false" isQuery="false"' \
23
+ " isStatic=\"#{superclass_method}\" isUnique=\"true\" name=\"#{name_to_xmi}\"" \
24
+ " visibility=\"#{visibility}\" xmi:id=\"#{id}\" xmi:type=\"uml:Operation\">"
22
25
  xmi += "<ownedParameter kind=\"return\" xmi:id=\"#{return_id}\" xmi:type=\"uml:Parameter\"/>"
23
26
  args.each do |argument|
24
27
  argument.extend(::Xumlidot::Diagram::Xmi::Argument)
25
28
  xmi += argument.draw
26
29
  end
27
- xmi += "</ownedOperation>"
30
+ "#{xmi}</ownedOperation>"
28
31
  end
29
32
 
30
33
  private
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'xmi/argument'
2
4
  require_relative 'xmi/attribute'
3
5
  require_relative 'xmi/klass'
@@ -8,16 +10,9 @@ require 'rexml/document'
8
10
  module Xumlidot
9
11
  class Diagram
10
12
  class Xmi
11
-
12
13
  include REXML
13
14
 
14
15
  class Elements < Array
15
-
16
- def initialize(options)
17
- super()
18
- @options = options
19
- end
20
-
21
16
  def draw
22
17
  xml = header
23
18
  uniq.each { |de| xml += de }
@@ -46,7 +41,7 @@ module Xumlidot
46
41
  private
47
42
 
48
43
  def header
49
- %(<uml:Model name="#{@options[:model_name]}" xmi:id="jcBKnwaFYHEAAQV_">)
44
+ %(<uml:Model name="#{::Xumlidot::Options.model_name}" xmi:id="jcBKnwaFYHEAAQV_">)
50
45
  end
51
46
 
52
47
  def footer
@@ -58,12 +53,13 @@ module Xumlidot
58
53
  private
59
54
 
60
55
  def header
61
- %(<uml:Diagram diagramType="ClassDiagram" documentation="" name="#{@options[:title]}" toolName="Visual Paradigm" xmi:id="QfZKnwaFYHEAAQj3">
62
- <uml:Diagram.element>)
56
+ %(<uml:Diagram diagramType="ClassDiagram" documentation=""
57
+ name="#{::Xumlidot::Options.title}" toolName="Visual Paradigm" xmi:id="QfZKnwaFYHEAAQj3">
58
+ <uml:Diagram.element>)
63
59
  end
64
60
 
65
61
  def footer
66
- %( </uml:Diagram.element>
62
+ %(</uml:Diagram.element>
67
63
  </uml:Diagram>)
68
64
  end
69
65
  end
@@ -76,7 +72,7 @@ module Xumlidot
76
72
  end
77
73
 
78
74
  # reverse lookup
79
- def has_value?(id)
75
+ def has_value?(id) # rubocop:disable Naming/PredicateName
80
76
  @id_to_namespace[id] != nil
81
77
  end
82
78
 
@@ -94,20 +90,19 @@ module Xumlidot
94
90
  end
95
91
  end
96
92
 
97
- def initialize(stack, options = nil)
93
+ def initialize(stack)
98
94
  @stack = stack
99
- @options = options
100
95
 
101
96
  @namespace_to_id = NamespaceToId.new
102
97
 
103
- @model = ModelElements.new(options)
104
- @diagram = DiagramElements.new(options)
98
+ @model = ModelElements.new
99
+ @diagram = DiagramElements.new
105
100
 
106
- @model_associations = ModelAssociationElements.new(options)
107
- @diagram_associations = DiagramAssociationElements.new(options)
101
+ @model_associations = ModelAssociationElements.new
102
+ @diagram_associations = DiagramAssociationElements.new
108
103
  end
109
104
 
110
- def draw
105
+ def draw # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
111
106
  # First traversal we're just assigning ids to everything so that when
112
107
  # we come to draw things we can do a lookup on the ids for any composition
113
108
  # aggregation or subclass relationships.
@@ -117,10 +112,12 @@ module Xumlidot
117
112
 
118
113
  klass.definition.inherited_modules.each do |m|
119
114
  next if m.empty?
115
+
120
116
  m.extend(::Xumlidot::Diagram::Xmi::Superklass)
121
- end #unless klass.definition.inherited_modules.empty?
117
+ end
122
118
 
123
119
  next if @namespace_to_id.has?(klass.draw_identifier)
120
+
124
121
  @namespace_to_id[klass.draw_identifier] = klass.id
125
122
  end
126
123
 
@@ -136,22 +133,24 @@ module Xumlidot
136
133
  # do the same with the inherited modules
137
134
  klass.definition.inherited_modules.each do |m|
138
135
  next if m.empty?
136
+
139
137
  id = @namespace_to_id[m.draw_identifier]
140
138
  m.force_id(id)
141
- end #unless klass.definition.inherited_modules.empty?
139
+ end
142
140
 
143
141
  # if we have not added an id for this element it is likely a duplicate
144
142
  # so do not draw it.
145
- next unless @namespace_to_id.has_value?(klass.id)
143
+ next unless @namespace_to_id.has_value?(klass.id) # rubocop:disable Style/PreferredHashMethods
146
144
 
147
- @model << klass.draw_klass(@options)
148
- @diagram << klass.draw_diagram(@options)
145
+ @model << klass.draw_klass
146
+ @diagram << klass.draw_diagram
149
147
 
150
- if @options.composition
148
+ if ::Xumlidot::Options.composition
151
149
  klass.constants.each do |k|
152
150
  # Likewise to the above, unless we have an id for the class
153
151
  # we don't want to draw the relationships
154
- next unless @namespace_to_id.has_value?(k.id)
152
+ next unless @namespace_to_id.has_value?(k.id) # rubocop:disable Style/PreferredHashMethods
153
+
155
154
  @model_associations << klass.draw_model_composition(k)
156
155
  @diagram_associations << klass.draw_diagram_composition(k)
157
156
  end
@@ -1,13 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'diagram/dot'
2
4
  require_relative 'diagram/xmi'
3
5
 
4
6
  module Xumlidot
5
7
  class Diagram
6
- def initialize(stack, options)
7
- @diagram = if options[:diagram_type] == :dot
8
- ::Xumlidot::Diagram::Dot.new(stack, options)
8
+ def initialize(stack, _options)
9
+ @diagram = if ::Xumlidot::Options.diagram_type == :dot
10
+ ::Xumlidot::Diagram::Dot.new(stack)
9
11
  else
10
- ::Xumlidot::Diagram::Xmi.new(stack, options)
12
+ ::Xumlidot::Diagram::Xmi.new(stack)
11
13
  end
12
14
  end
13
15
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'find'
2
4
 
3
5
  module Xumlidot
@@ -9,7 +11,7 @@ module Xumlidot
9
11
  @excluded = Regexp.new(@options.exclude)
10
12
  end
11
13
 
12
- def find_all_rb_files(&block)
14
+ def find_all_rb_files
13
15
  @directories.each do |directory|
14
16
  Find.find(directory) do |path|
15
17
  next if path =~ @exluded
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xumlidot
4
+ # This is code that was living in bin/xumlidot. We need to leverage
5
+ # it for running integration tests though
6
+ class Loader
7
+ def initialize(directories, options)
8
+ @directories = directories
9
+ @options = options
10
+ end
11
+
12
+ def load
13
+ dt = Xumlidot::DirectoryTree.new(directories, options)
14
+
15
+ # This is our tree of klasses/modules etc
16
+ # since we can't assume rails conventions for naming
17
+ # in a Ruby program.
18
+ constants = ::Xumlidot::Parsers::Stack::Constants.new
19
+
20
+ # TODO: move into directory tree
21
+ dt.find_all_rb_files do |path|
22
+ warn path if ::Xumlidot::Options.debug == true
23
+ file_contents = File.read(path)
24
+
25
+ @parser = Xumlidot::Parsers::File.new(file_contents, constants)
26
+ @parser.parse
27
+ end
28
+
29
+ # If a class is inherited from but does not exist in the constants
30
+ # we will create a dummy class.
31
+ #
32
+ # if a class is inherited from, we want to find it using the constant lookup
33
+ # rules defining in the resolver
34
+ #
35
+ # and what ... we want to add a reference too it?
36
+ #
37
+ # This REALLY should be done whenever we add a superklass
38
+ # i.e. yeah, its a hack
39
+ constants.resolve_inheritance
40
+
41
+ diagram = ::Xumlidot::Diagram.new(constants, options)
42
+ diagram.draw
43
+ end
44
+
45
+ private
46
+
47
+ attr_accessor :directories, :options
48
+ end
49
+ end