xumlidot 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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