decode 0.13.0 → 0.15.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/bake/decode/index.rb +1 -1
  3. data/lib/decode/comment/attribute.rb +53 -0
  4. data/lib/decode/comment/node.rb +90 -0
  5. data/lib/decode/comment/parameter.rb +58 -0
  6. data/lib/decode/comment/pragma.rb +50 -0
  7. data/lib/decode/comment/raises.rb +32 -0
  8. data/lib/decode/comment/returns.rb +32 -0
  9. data/lib/decode/comment/tag.rb +50 -0
  10. data/lib/decode/comment/tags.rb +80 -0
  11. data/lib/decode/comment/text.rb +37 -0
  12. data/lib/decode/comment/throws.rb +32 -0
  13. data/lib/decode/comment/yields.rb +52 -0
  14. data/lib/decode/definition.rb +26 -19
  15. data/lib/decode/documentation.rb +21 -66
  16. data/lib/decode/index.rb +7 -7
  17. data/lib/decode/language/generic.rb +2 -2
  18. data/lib/decode/language/reference.rb +39 -9
  19. data/lib/decode/language/ruby.rb +40 -6
  20. data/lib/decode/language/ruby/block.rb +1 -1
  21. data/lib/decode/language/ruby/class.rb +2 -2
  22. data/lib/decode/language/ruby/code.rb +85 -0
  23. data/lib/decode/language/ruby/definition.rb +1 -1
  24. data/lib/decode/language/ruby/method.rb +7 -1
  25. data/lib/decode/language/ruby/module.rb +6 -0
  26. data/lib/decode/language/ruby/parser.rb +11 -3
  27. data/lib/decode/language/ruby/reference.rb +31 -0
  28. data/lib/decode/language/ruby/segment.rb +1 -1
  29. data/lib/decode/scope.rb +3 -0
  30. data/lib/decode/segment.rb +4 -4
  31. data/lib/decode/source.rb +24 -8
  32. data/lib/decode/syntax/link.rb +44 -0
  33. data/lib/decode/syntax/match.rb +53 -0
  34. data/lib/decode/syntax/rewriter.rb +70 -0
  35. data/lib/decode/trie.rb +13 -13
  36. data/lib/decode/version.rb +1 -1
  37. metadata +23 -43
  38. data/.github/workflows/development.yml +0 -50
  39. data/.gitignore +0 -13
  40. data/.rspec +0 -2
  41. data/README.md +0 -47
  42. data/decode.gemspec +0 -33
  43. data/gems.rb +0 -3
  44. data/guides/extract-symbols/extract.rb +0 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d285f0566ed8682b02da2b41c0d1e56d4fd45a47ed26e4d4f4ec5a274dbbca45
4
- data.tar.gz: 41baab474d5c16ea408ded0fded49479dbbe62649044e142f65b536c6a805e52
3
+ metadata.gz: 1e996212bd910f20ac9875edc81588dc35294a4b33069e64b2bda61e754be1a9
4
+ data.tar.gz: f8e78b386f4f2a9cf25267c0d62d90985f50ae8842520f478ed7766044cd6d35
5
5
  SHA512:
6
- metadata.gz: 474044bd964488c5a9003b502c982374d1fca23a00a04a07191b95e86e463ff0c39a54fdb5362ed2dee626538a60e50a07697d3d2cccff3bcc312829f470e535
7
- data.tar.gz: 9ad91167fc2f1c6dddfca9e35d4773237125b9433b49163ee35541899efe01a003f719c8b2bb3eac469efe35c7d505a70d8b3a70a87d1ae804dabef41d1784d3
6
+ metadata.gz: 7dbaf3a9f15060fb40f718271c235a01bec1488954030e3130cd78d56e7f6fc42494c47c757617707bdf0c43714fc365bd69a22493e9e95f6c9265c6b2a91b0a
7
+ data.tar.gz: d0f80917980849a694ade904566a1c89cebd76db7ca5d5267e311f221cf5295ddc9dad8a511b9146bbaeb194050c33a00fa8c03f875904a400a2b9b00f014df4
@@ -1,6 +1,6 @@
1
1
 
2
2
  # Process the given source root and report on comment coverage.
3
- # @param root [String] The root path to index.
3
+ # @parameter root [String] The root path to index.
4
4
  def coverage(root)
5
5
  require 'build/files/glob'
6
6
  require 'decode/index'
@@ -0,0 +1,53 @@
1
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'tag'
22
+
23
+ module Decode
24
+ module Comment
25
+ # Describes an attribute type.
26
+ #
27
+ # - `@attribute [Integer] The person's age.`
28
+ #
29
+ class Attribute < Tag
30
+ PATTERN = /\A\[(?<type>.*?)\](\s+(?<details>.*?))?\Z/
31
+
32
+ def self.build(directive, match)
33
+ node = self.new(directive, match[:type])
34
+
35
+ if details = match[:details]
36
+ node.add(Text.new(details))
37
+ end
38
+
39
+ return node
40
+ end
41
+
42
+ def initialize(directive, type)
43
+ super(directive)
44
+
45
+ @type = type
46
+ end
47
+
48
+ # The type of the attribute.
49
+ # @attribute [String]
50
+ attr :type
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,90 @@
1
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ module Decode
22
+ module Comment
23
+ class Node
24
+ # Initialize the node.
25
+ # @parameter children [Array(Node) | Nil]
26
+ def initialize(children = nil)
27
+ @children = children
28
+ end
29
+
30
+ # Whether this node has any children nodes.
31
+ # Ignores {Text} instances.
32
+ # @returns [Boolean]
33
+ def children?
34
+ @children&.any?{|child| child.is_a?(Node)}
35
+ end
36
+
37
+ # Add a child node to this node.
38
+ # @parameter child [Node] The node to add.
39
+ def add(child)
40
+ @children ||= []
41
+ @children << child
42
+ end
43
+
44
+ # Any children of this node.
45
+ # @attribute [Array(Node | Text) | Nil]
46
+ attr :children
47
+
48
+ # Enumerate all non-text children nodes.
49
+ def each(&block)
50
+ return to_enum unless block_given?
51
+
52
+ @children&.each do |child|
53
+ yield child if child.is_a?(Node)
54
+ end
55
+ end
56
+
57
+ # Any lines of text associated wtih this node.
58
+ # @returns [Array(String) | Nil] The lines of text.
59
+ def text
60
+ if text = self.extract_text
61
+ return text if text.any?
62
+ end
63
+ end
64
+
65
+ # Traverse the tags from this node using {each}.
66
+ # Invoke `descend.call(child)` to recursively traverse the specified child.
67
+ #
68
+ # @yields {|node, descend| descend.call}
69
+ # @parameter node [Node] The current node which is being traversed.
70
+ # @parameter descend [Proc | Nil] The recursive method for traversing children.
71
+ def traverse(&block)
72
+ descend = ->(node){
73
+ node.traverse(&block)
74
+ }
75
+
76
+ yield(self, descend)
77
+ end
78
+
79
+ protected
80
+
81
+ def extract_text
82
+ if children = @children
83
+ @children.select{|child| child.kind_of?(Text)}.map(&:line)
84
+ else
85
+ nil
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,58 @@
1
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'tag'
22
+
23
+ module Decode
24
+ module Comment
25
+ # Describes a named method parameter.
26
+ #
27
+ # - `@parameter age [Float] The users age.`
28
+ #
29
+ class Parameter < Tag
30
+ PATTERN = /\A(?<name>.*?)\s+\[(?<type>.*?)\](\s+(?<details>.*?))?\Z/
31
+
32
+ def self.build(directive, match)
33
+ node = self.new(directive, match[:name], match[:type])
34
+
35
+ if details = match[:details]
36
+ node.add(Text.new(details))
37
+ end
38
+
39
+ return node
40
+ end
41
+
42
+ def initialize(directive, name, type)
43
+ super(directive)
44
+
45
+ @name = name
46
+ @type = type
47
+ end
48
+
49
+ # The name of the parameter.
50
+ # @attribute [String]
51
+ attr :name
52
+
53
+ # The type of the attribute.
54
+ # @attribute [String]
55
+ attr :type
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,50 @@
1
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'tag'
22
+
23
+ module Decode
24
+ module Comment
25
+ # Asserts a specific property about the method signature.
26
+ #
27
+ # - `@reentrant This method is thread-safe.`
28
+ # - `@deprecated Please use {other_method} instead.`
29
+ # - `@blocking This method may block.`
30
+ # - `@asynchronous This method may yield.`
31
+ #
32
+ class Pragma < Tag
33
+ PATTERN = /\A(?<details>.*?)?\Z/
34
+
35
+ def self.build(directive, match)
36
+ node = self.new(directive)
37
+
38
+ if details = match[:details]
39
+ node.add(Text.new(details))
40
+ end
41
+
42
+ return node
43
+ end
44
+
45
+ def initialize(directive)
46
+ super(directive)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,32 @@
1
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'attribute'
22
+
23
+ module Decode
24
+ module Comment
25
+ # Identifies that a method might raise an exception.
26
+ #
27
+ # - `@raises [ArgumentError] If the argument cannot be coerced.`
28
+ #
29
+ class Raises < Attribute
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'attribute'
22
+
23
+ module Decode
24
+ module Comment
25
+ # Describes a return value.
26
+ #
27
+ # - `@returns [Integer] The person's age.`
28
+ #
29
+ class Returns < Attribute
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,50 @@
1
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'node'
22
+
23
+ module Decode
24
+ module Comment
25
+ class Tag < Node
26
+ def self.parse(directive, text, lines, tags, level = 0)
27
+ if match = self::PATTERN.match(text)
28
+ node = self.build(directive, match)
29
+
30
+ tags.parse(lines, level + 1) do |child|
31
+ node.add(child)
32
+ end
33
+
34
+ return node
35
+ else
36
+ # Consume all nested nodes:
37
+ tags.ignore(lines, level + 1)
38
+ end
39
+ end
40
+
41
+ def initialize(directive)
42
+ @directive = directive
43
+ end
44
+
45
+ # The directive that generated the tag.
46
+ # @attribute [String]
47
+ attr :directive
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,80 @@
1
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'text'
22
+
23
+ module Decode
24
+ module Comment
25
+ class Tags
26
+ def self.build
27
+ directives = Hash.new
28
+
29
+ yield directives
30
+
31
+ return self.new(directives)
32
+ end
33
+
34
+ def initialize(directives)
35
+ @directives = directives
36
+ end
37
+
38
+ def valid_indentation?(line, level)
39
+ line.start_with?(' ' * level) || line.start_with?("\t" * level)
40
+ end
41
+
42
+ PATTERN = /\A\s*@(?<directive>.*?)(\s+(?<remainder>.*?))?\Z/
43
+
44
+ def parse(lines, level = 0, &block)
45
+ while line = lines.first
46
+ # Is it at the right indentation level:
47
+ return unless valid_indentation?(line, level)
48
+
49
+ # We are going to consume the line:
50
+ lines.shift
51
+
52
+ # Match it against a tag:
53
+ if match = PATTERN.match(line)
54
+ if klass = @directives[match[:directive]]
55
+ yield klass.parse(
56
+ match[:directive], match[:remainder],
57
+ lines, self, level
58
+ )
59
+ else
60
+ # Ignore unknown directive.
61
+ end
62
+
63
+ # Or it's just text:
64
+ else
65
+ yield Text.new(line.strip)
66
+ end
67
+ end
68
+ end
69
+
70
+ def ignore(lines, level = 0)
71
+ if line = lines.first
72
+ # Is it at the right indentation level:
73
+ return unless valid_indentation?(line, level)
74
+
75
+ lines.shift
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end