decode 0.12.0 → 0.13.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: 353e9f1529672844e406beb0587827a8a5a4e045506511019c1adf91ebf22a42
4
- data.tar.gz: 88ef4f1965c4a95c0ddff8aa3857083e7854eb5c1b2dcbef02c3c1d92749d4b6
3
+ metadata.gz: d285f0566ed8682b02da2b41c0d1e56d4fd45a47ed26e4d4f4ec5a274dbbca45
4
+ data.tar.gz: 41baab474d5c16ea408ded0fded49479dbbe62649044e142f65b536c6a805e52
5
5
  SHA512:
6
- metadata.gz: c386399350a839bd1e53e5398d725a7a14a311fd3af8c946e27bb2b472e1859b30e36bd3286e56c03b5956078705ea2b099ed002dfbaf22b169f8cc729fadc2f
7
- data.tar.gz: e0e20aa3755863f3ad67c1317be7451c141ef783e90cb5f69fde7a5c91ab6992ad522cb11cf9988e91de95ca2d1d1e852b3cb4ba767023356f3c7dd6cb6534de
6
+ metadata.gz: 474044bd964488c5a9003b502c982374d1fca23a00a04a07191b95e86e463ff0c39a54fdb5362ed2dee626538a60e50a07697d3d2cccff3bcc312829f470e535
7
+ data.tar.gz: 9ad91167fc2f1c6dddfca9e35d4773237125b9433b49163ee35541899efe01a003f719c8b2bb3eac469efe35c7d505a70d8b3a70a87d1ae804dabef41d1784d3
data/lib/decode/index.rb CHANGED
@@ -21,11 +21,15 @@
21
21
  require_relative 'source'
22
22
  require_relative 'trie'
23
23
 
24
+ require_relative 'languages'
25
+
24
26
  module Decode
25
27
  # A list of definitions organised for quick lookup and lexical enumeration.
26
28
  class Index
27
29
  # Initialize an empty index.
28
- def initialize
30
+ def initialize(languages = Languages.all)
31
+ @languages = languages
32
+
29
33
  @sources = {}
30
34
  @definitions = {}
31
35
 
@@ -33,6 +37,10 @@ module Decode
33
37
  @trie = Trie.new
34
38
  end
35
39
 
40
+ # All supported languages for this index.
41
+ # @attr [Languages]
42
+ attr :languages
43
+
36
44
  # All source files that have been parsed.
37
45
  # @attr [Array(Source)]
38
46
  attr :sources
@@ -52,7 +60,7 @@ module Decode
52
60
  # @param paths [Array(String)] The source file paths.
53
61
  def update(paths)
54
62
  paths.each do |path|
55
- if source = Source.for?(path)
63
+ if source = @languages.source_for(path)
56
64
  @sources[path] = source
57
65
 
58
66
  source.definitions do |symbol|
@@ -0,0 +1,51 @@
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 'reference'
22
+
23
+ module Decode
24
+ module Language
25
+ # The Ruby language.
26
+ class Generic
27
+ def initialize(name)
28
+ @name = name
29
+ end
30
+
31
+ attr :name
32
+
33
+ # Generate a generic reference.
34
+ def reference_for(identifier)
35
+ Reference.new(identifier, self)
36
+ end
37
+
38
+ # Parse the input yielding definitions.
39
+ # @block `{|definition| ...}`
40
+ # @yield definition [Definition]
41
+ def definitions_for(input, &block)
42
+ end
43
+
44
+ # Parse the input yielding interleaved comments and code segments.
45
+ # @block `{|segment| ...}`
46
+ # @yield segment [Segment]
47
+ def segments_for(input, &block)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,78 @@
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 Language
23
+ # An reference which can be resolved to zero or more definitions.
24
+ class Reference
25
+ # Initialize the reference.
26
+ # @param identifier [String] The identifier part of the reference.
27
+ def initialize(identifier, language)
28
+ @identifier = identifier
29
+ @language = language
30
+
31
+ @lexical_path = nil
32
+ @path = nil
33
+ end
34
+
35
+ # The identifier part of the reference.
36
+ # @attr [String]
37
+ attr :identifier
38
+
39
+ # The language associated with this reference.
40
+ attr :language
41
+
42
+ # Whether the reference starts at the base of the lexical tree.
43
+ def absolute?
44
+ !self.relative?
45
+ end
46
+
47
+ def relative?
48
+ prefix, name = self.lexical_path.first
49
+
50
+ return prefix.nil?
51
+ end
52
+
53
+ def split(identifier)
54
+ identifier.scan(/(\W+)?(\w+)/)
55
+ end
56
+
57
+ def lexical_path
58
+ @lexical_path ||= self.split(@identifier)
59
+ end
60
+
61
+ def best(definitions)
62
+ prefix, name = lexical_path.last
63
+
64
+ definitions.select do |definition|
65
+ definition.language == @language && (
66
+ prefix.nil? || definition.start_with?(prefix)
67
+ )
68
+ end
69
+ end
70
+
71
+ # The lexical path of the reference.
72
+ # @return [Array(String)]
73
+ def path
74
+ @path ||= self.lexical_path.map{|_, name| name.to_sym}
75
+ end
76
+ end
77
+ end
78
+ end
@@ -18,47 +18,15 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
+ require_relative '../reference'
22
+
21
23
  module Decode
22
24
  module Language
23
25
  module Ruby
24
26
  # An Ruby-specific reference which can be resolved to zero or more definitions.
25
- class Reference
26
- # Initialize the reference.
27
- # @param text [String] The text text of the reference.
28
- def initialize(text)
29
- @text = text
30
-
31
- @lexical_path = nil
32
- @path = nil
33
- end
34
-
35
- def language
36
- Ruby
37
- end
38
-
39
- attr :text
40
-
41
- # Whether the reference starts at the base of the lexical tree.
42
- def absolute?
43
- @text.start_with?('::')
44
- end
45
-
46
- def lexical_path
47
- @lexical_path ||= @text.scan(/(::|\.|#|:)?([^:.#]+)/)
48
- end
49
-
50
- def best(definitions)
51
- prefix, name = lexical_path.last
52
-
53
- definitions.select do |definition|
54
- prefix.nil? || definition.start_with?(prefix)
55
- end
56
- end
57
-
58
- # The lexical path of the reference.
59
- # @return [Array(String)]
60
- def path
61
- @path ||= self.lexical_path.map{|_, name| name.to_sym}
27
+ class Reference < Language::Reference
28
+ def split(text)
29
+ text.scan(/(::|\.|#|:)?([^:.#]+)/)
62
30
  end
63
31
  end
64
32
  end
@@ -31,9 +31,17 @@ module Decode
31
31
  "ruby"
32
32
  end
33
33
 
34
+ def self.names
35
+ [self.name]
36
+ end
37
+
38
+ def self.extensions
39
+ ['.rb', '.ru']
40
+ end
41
+
34
42
  # Generate a language-specific reference.
35
- def self.reference(value)
36
- Reference.new(value)
43
+ def self.reference_for(identifier)
44
+ Reference.new(identifier, self)
37
45
  end
38
46
 
39
47
  # Parse the input yielding definitions.
@@ -18,29 +18,11 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
+ require_relative 'language/generic'
21
22
  require_relative 'language/ruby'
22
23
 
23
24
  module Decode
24
25
  # Language specific parsers and definitions.
25
26
  module Language
26
- def self.detect(path)
27
- case path
28
- when /\.(rb|ru)\z/
29
- return Language::Ruby
30
- end
31
- end
32
-
33
- REFERENCE = /\A(?<language>\.[a-z]+)?\s+(?<text>.*?)\z/
34
-
35
- # A language agnostic reference:
36
- # e.g. `.rb MyModule::MyClass`
37
- #
38
- def self.reference(string, language = nil)
39
- if match = REFERENCE.match(string)
40
- language = self.detect(match[:language]) || language
41
-
42
- return language.reference(match[:text])
43
- end
44
- end
45
27
  end
46
28
  end
@@ -0,0 +1,92 @@
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 'language/generic'
22
+ require_relative 'language/ruby'
23
+
24
+ module Decode
25
+ # A context for looking up languages based on file extension or name.
26
+ class Languages
27
+ def self.all
28
+ self.new.tap do |languages|
29
+ languages.add(Language::Ruby)
30
+ end
31
+ end
32
+
33
+ def initialize
34
+ @named = {}
35
+ @extensions = {}
36
+ end
37
+
38
+ def freeze
39
+ return unless frozen?
40
+
41
+ @named.freeze
42
+ @extensions.freeze
43
+
44
+ super
45
+ end
46
+
47
+ def add(language)
48
+ language.names.each do |name|
49
+ @named[name] = language
50
+ end
51
+
52
+ language.extensions.each do |extension|
53
+ @extensions[extension] = language
54
+ end
55
+ end
56
+
57
+ def fetch(name)
58
+ @named.fetch(name) do
59
+ unless @named.frozen?
60
+ @named[name] = Language::Generic.new(name)
61
+ end
62
+ end
63
+ end
64
+
65
+ def source_for(path)
66
+ extension = File.extname(path)
67
+
68
+ if language = @extensions[extension]
69
+ Source.new(path, language)
70
+ end
71
+ end
72
+
73
+ REFERENCE = /\A(?<name>[a-z]+)?\s+(?<identifier>.*?)\z/
74
+
75
+ # Parse a language agnostic reference:
76
+ # e.g. `ruby MyModule::MyClass`
77
+ #
78
+ def parse_reference(text, default_language: nil)
79
+ if match = REFERENCE.match(text)
80
+ language = self.fetch(match[:name]) || default_language
81
+
82
+ return language.reference_for(match[:identifier])
83
+ elsif default_language
84
+ return default_language.reference_for(text)
85
+ end
86
+ end
87
+
88
+ def reference_for(name, identifier)
89
+ self.fetch(name).reference_for(identifier)
90
+ end
91
+ end
92
+ end
data/lib/decode/source.rb CHANGED
@@ -22,15 +22,9 @@ require_relative 'language'
22
22
 
23
23
  module Decode
24
24
  class Source
25
- def self.for?(path)
26
- if language = Language.detect(path)
27
- self.new(path, language)
28
- end
29
- end
30
-
31
- def initialize(path, language = nil)
25
+ def initialize(path, language)
32
26
  @path = path
33
- @language = language || Language.detect(path)
27
+ @language = language
34
28
  end
35
29
 
36
30
  attr :path
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Decode
22
- VERSION = "0.12.0"
22
+ VERSION = "0.13.0"
23
23
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -128,6 +128,8 @@ files:
128
128
  - lib/decode/documentation.rb
129
129
  - lib/decode/index.rb
130
130
  - lib/decode/language.rb
131
+ - lib/decode/language/generic.rb
132
+ - lib/decode/language/reference.rb
131
133
  - lib/decode/language/ruby.rb
132
134
  - lib/decode/language/ruby/attribute.rb
133
135
  - lib/decode/language/ruby/block.rb
@@ -141,6 +143,7 @@ files:
141
143
  - lib/decode/language/ruby/parser.rb
142
144
  - lib/decode/language/ruby/reference.rb
143
145
  - lib/decode/language/ruby/segment.rb
146
+ - lib/decode/languages.rb
144
147
  - lib/decode/scope.rb
145
148
  - lib/decode/segment.rb
146
149
  - lib/decode/source.rb