decode 0.12.0 → 0.13.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: 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