rucoa 0.3.0 → 0.5.1

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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +12 -2
  5. data/README.md +37 -6
  6. data/data/definitions_ruby_3_1 +0 -0
  7. data/images/diagnostics.gif +0 -0
  8. data/images/document-formatting.gif +0 -0
  9. data/images/document-symbol.gif +0 -0
  10. data/images/selection-ranges.gif +0 -0
  11. data/lib/rucoa/configuration.rb +62 -28
  12. data/lib/rucoa/definition_archiver.rb +29 -0
  13. data/lib/rucoa/definition_builders/rbs_constant_definition_builder.rb +44 -0
  14. data/lib/rucoa/definition_builders/rbs_method_definition_builder.rb +106 -0
  15. data/lib/rucoa/definition_builders/yard_method_definition_builder.rb +218 -0
  16. data/lib/rucoa/definition_builders.rb +9 -0
  17. data/lib/rucoa/definition_store.rb +63 -0
  18. data/lib/rucoa/definitions/base.rb +12 -0
  19. data/lib/rucoa/definitions/constant_definition.rb +51 -0
  20. data/lib/rucoa/definitions/method_definition.rb +126 -0
  21. data/lib/rucoa/definitions/method_parameter_definition.rb +30 -0
  22. data/lib/rucoa/definitions.rb +9 -0
  23. data/lib/rucoa/handler_concerns/diagnostics_publishable.rb +140 -0
  24. data/lib/rucoa/handlers/base.rb +8 -0
  25. data/lib/rucoa/handlers/exit_handler.rb +11 -0
  26. data/lib/rucoa/handlers/initialize_handler.rb +7 -0
  27. data/lib/rucoa/handlers/initialized_handler.rb +10 -0
  28. data/lib/rucoa/handlers/shutdown_handler.rb +12 -0
  29. data/lib/rucoa/handlers/text_document_code_action_handler.rb +78 -3
  30. data/lib/rucoa/handlers/text_document_did_change_handler.rb +1 -20
  31. data/lib/rucoa/handlers/text_document_did_open_handler.rb +11 -4
  32. data/lib/rucoa/handlers/text_document_document_symbol_handler.rb +242 -0
  33. data/lib/rucoa/handlers/text_document_formatting_handler.rb +36 -5
  34. data/lib/rucoa/handlers/text_document_range_formatting_handler.rb +65 -13
  35. data/lib/rucoa/handlers/text_document_selection_range_handler.rb +124 -8
  36. data/lib/rucoa/handlers/text_document_signature_help_handler.rb +68 -0
  37. data/lib/rucoa/handlers.rb +4 -0
  38. data/lib/rucoa/node_concerns/name_full_qualifiable.rb +20 -0
  39. data/lib/rucoa/node_concerns.rb +7 -0
  40. data/lib/rucoa/node_inspector.rb +111 -0
  41. data/lib/rucoa/nodes/base.rb +43 -0
  42. data/lib/rucoa/nodes/casgn_node.rb +14 -0
  43. data/lib/rucoa/nodes/class_node.rb +8 -0
  44. data/lib/rucoa/nodes/const_node.rb +12 -0
  45. data/lib/rucoa/nodes/def_node.rb +71 -0
  46. data/lib/rucoa/nodes/defs_node.rb +12 -0
  47. data/lib/rucoa/nodes/lvar_node.rb +25 -0
  48. data/lib/rucoa/nodes/module_node.rb +21 -0
  49. data/lib/rucoa/nodes/sclass_node.rb +8 -0
  50. data/lib/rucoa/nodes/send_node.rb +60 -0
  51. data/lib/rucoa/nodes/str_node.rb +4 -0
  52. data/lib/rucoa/nodes/sym_node.rb +12 -0
  53. data/lib/rucoa/nodes.rb +10 -0
  54. data/lib/rucoa/parser_builder.rb +20 -10
  55. data/lib/rucoa/position.rb +2 -2
  56. data/lib/rucoa/range.rb +64 -14
  57. data/lib/rucoa/rbs_document_loader.rb +43 -0
  58. data/lib/rucoa/rubocop_autocorrector.rb +1 -1
  59. data/lib/rucoa/rubocop_investigator.rb +1 -1
  60. data/lib/rucoa/server.rb +20 -1
  61. data/lib/rucoa/source.rb +56 -6
  62. data/lib/rucoa/source_store.rb +6 -10
  63. data/lib/rucoa/types/method_type.rb +23 -0
  64. data/lib/rucoa/types.rb +7 -0
  65. data/lib/rucoa/version.rb +1 -1
  66. data/lib/rucoa/yard_glob_document_loader.rb +47 -0
  67. data/lib/rucoa/yard_string_document_loader.rb +70 -0
  68. data/lib/rucoa.rb +10 -5
  69. data/rucoa.gemspec +2 -0
  70. metadata +68 -7
  71. data/lib/rucoa/code_action_provider.rb +0 -102
  72. data/lib/rucoa/diagnostic_provider.rb +0 -143
  73. data/lib/rucoa/formatting_provider.rb +0 -54
  74. data/lib/rucoa/range_formatting_provider.rb +0 -67
  75. data/lib/rucoa/selection_range_provider.rb +0 -99
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'set'
4
+
5
+ module Rucoa
6
+ class NodeInspector
7
+ # @param definition_store [Rucoa::DefinitionStore]
8
+ # @param node [Rucoa::Node]
9
+ def initialize(definition_store:, node:)
10
+ @definition_store = definition_store
11
+ @node = node
12
+ end
13
+
14
+ # @return [Array<String>]
15
+ def method_definitions
16
+ method_full_qualified_names.flat_map do |full_qualified_name|
17
+ @definition_store.select_by_full_qualified_name(full_qualified_name)
18
+ end
19
+ end
20
+
21
+ # @return [Array<String>]
22
+ def method_receiver_types
23
+ return [] unless @node.is_a?(Nodes::SendNode)
24
+
25
+ if @node.receiver
26
+ self.class.new(
27
+ definition_store: @definition_store,
28
+ node: @node.receiver
29
+ ).return_types
30
+ else
31
+ [@node.namespace]
32
+ end
33
+ end
34
+
35
+ # @return [Array<String>]
36
+ def return_types
37
+ case @node.type
38
+ when :const
39
+ [@node.name]
40
+ when :lvar
41
+ return_types_for_lvar
42
+ when :send
43
+ return_types_for_send
44
+ when :array
45
+ %w[Array]
46
+ when :class, :module, :nil
47
+ %w[NilClass]
48
+ when :complex
49
+ %w[Complex]
50
+ when :def, :sym
51
+ %w[Symbol]
52
+ when :dstr, :str, :xstr
53
+ %w[String]
54
+ when :erange, :irange
55
+ %w[Range]
56
+ when false
57
+ %w[FalseClass]
58
+ when :float
59
+ %w[Float]
60
+ when :hash, :pair
61
+ %w[Hash]
62
+ when :int
63
+ %w[Integer]
64
+ when :rational
65
+ %w[Rational]
66
+ when :regexp, :regopt
67
+ %w[Regexp]
68
+ when true
69
+ %w[TrueClass]
70
+ else
71
+ []
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ # @return [Array<String>]
78
+ def method_full_qualified_names
79
+ method_receiver_types.map do |type|
80
+ [
81
+ type,
82
+ @node.name
83
+ ].join('#')
84
+ end
85
+ end
86
+
87
+ # @return [String, nil]
88
+ def nearest_def_full_qualified_name
89
+ @node.each_ancestor(:def).first&.full_qualified_name
90
+ end
91
+
92
+ # @return [Array<String>]
93
+ def return_types_for_lvar
94
+ full_qualified_name = nearest_def_full_qualified_name
95
+ return [] unless full_qualified_name
96
+
97
+ @definition_store.select_by_full_qualified_name(full_qualified_name).flat_map do |definition|
98
+ definition.parameters.select do |parameter|
99
+ parameter.name == @node.name
100
+ end.flat_map(&:types)
101
+ end
102
+ end
103
+
104
+ # @return [Array<String>]
105
+ def return_types_for_send
106
+ method_full_qualified_names.flat_map do |full_qualified_name|
107
+ @definition_store.select_by_full_qualified_name(full_qualified_name).flat_map(&:return_types)
108
+ end.uniq
109
+ end
110
+ end
111
+ end
@@ -64,6 +64,19 @@ module Rucoa
64
64
  self
65
65
  end
66
66
 
67
+ # @note Override.
68
+ # Some nodes change their type depending on the context.
69
+ # For example, `const` node can be `casgn` node.
70
+ # @return [Rucoa::Nodes::Base]
71
+ def updated(type = nil, children = nil, properties = {})
72
+ properties[:location] ||= @location
73
+ ParserBuilder.node_class_for(type || @type).new(
74
+ type || @type,
75
+ children || @children,
76
+ properties
77
+ )
78
+ end
79
+
67
80
  # @param position [Rucoa::Position]
68
81
  # @return [Boolean]
69
82
  def include_position?(position)
@@ -72,6 +85,36 @@ module Rucoa
72
85
  Range.from_parser_range(location.expression).include?(position)
73
86
  end
74
87
 
88
+ # @note namespace is a String representation of `Module.nesting`.
89
+ # @return [String]
90
+ # @example returns namespace
91
+ # node = Rucoa::Source.new(
92
+ # content: <<~RUBY
93
+ # module Foo
94
+ # class Bar
95
+ # def baz
96
+ # end
97
+ # end
98
+ # end
99
+ # RUBY
100
+ # ).node_at(
101
+ # Rucoa::Position.new(
102
+ # column: 4,
103
+ # line: 3
104
+ # )
105
+ # )
106
+ # expect(node.namespace).to eq('Foo::Bar')
107
+ # @example returns "Object" when the node is not in a namespace
108
+ # node = Rucoa::Parser.call(
109
+ # <<~RUBY
110
+ # foo
111
+ # RUBY
112
+ # )
113
+ # expect(node.namespace).to eq('Object')
114
+ def namespace
115
+ each_ancestor(:module, :class).first&.full_qualified_name || 'Object'
116
+ end
117
+
75
118
  protected
76
119
 
77
120
  # Visit all descendants.
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Nodes
5
+ class CasgnNode < Base
6
+ include NodeConcerns::NameFullQualifiable
7
+
8
+ # @return [String]
9
+ def name
10
+ children[1].to_s
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Nodes
5
+ class ClassNode < ModuleNode
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Nodes
5
+ class ConstNode < Base
6
+ # @return [String]
7
+ def name
8
+ children[1].to_s
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Nodes
5
+ class DefNode < Base
6
+ # @return [String]
7
+ # @example returns method name
8
+ # node = Rucoa::Source.new(
9
+ # content: <<~RUBY
10
+ # module Foo
11
+ # class Bar
12
+ # def baz
13
+ # end
14
+ # end
15
+ # end
16
+ # RUBY
17
+ # ).node_at(
18
+ # Rucoa::Position.new(
19
+ # column: 4,
20
+ # line: 3
21
+ # )
22
+ # )
23
+ # expect(node.name).to eq('baz')
24
+ def name
25
+ children[0].to_s
26
+ end
27
+
28
+ # @return [String]
29
+ # @example returns full qualified name
30
+ # node = Rucoa::Source.new(
31
+ # content: <<~RUBY
32
+ # module Foo
33
+ # class Bar
34
+ # def baz
35
+ # end
36
+ # end
37
+ # end
38
+ # RUBY
39
+ # ).node_at(
40
+ # Rucoa::Position.new(
41
+ # column: 4,
42
+ # line: 3
43
+ # )
44
+ # )
45
+ # expect(node.full_qualified_name).to eq('Foo::Bar#baz')
46
+ def full_qualified_name
47
+ [
48
+ namespace,
49
+ method_marker,
50
+ name
51
+ ].join
52
+ end
53
+
54
+ private
55
+
56
+ # @return [String]
57
+ def method_marker
58
+ if singleton?
59
+ '.'
60
+ else
61
+ '#'
62
+ end
63
+ end
64
+
65
+ # @return [Boolean]
66
+ def singleton?
67
+ each_ancestor(:sclass).any?
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Nodes
5
+ class DefsNode < Base
6
+ # @return [String]
7
+ def name
8
+ children[1].to_s
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Nodes
5
+ class LvarNode < Base
6
+ # @return [String]
7
+ # @example returns local variable name
8
+ # node = Rucoa::Source.new(
9
+ # content: <<~RUBY
10
+ # foo = 1
11
+ # foo
12
+ # RUBY
13
+ # ).node_at(
14
+ # Rucoa::Position.new(
15
+ # column: 2,
16
+ # line: 2
17
+ # )
18
+ # )
19
+ # expect(node.name).to eq('foo')
20
+ def name
21
+ children[0].to_s
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Nodes
5
+ class ModuleNode < Base
6
+ include NodeConcerns::NameFullQualifiable
7
+
8
+ # @return [String]
9
+ def name
10
+ const_node.name
11
+ end
12
+
13
+ private
14
+
15
+ # @return [Rucoa::Nodes::ConstNode]
16
+ def const_node
17
+ children[0]
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Nodes
5
+ class SclassNode < Base
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Nodes
5
+ class SendNode < Base
6
+ # @return [Array<Rucoa::Nodes::Base>]
7
+ # @example returns arguments
8
+ # node = Rucoa::Parser.call(
9
+ # <<~RUBY
10
+ # foo(bar, baz)
11
+ # RUBY
12
+ # )
13
+ # expect(node.arguments.map(&:name)).to eq(
14
+ # %w[
15
+ # bar
16
+ # baz
17
+ # ]
18
+ # )
19
+ def arguments
20
+ children[2..]
21
+ end
22
+
23
+ # @return [String]
24
+ # @example returns method name
25
+ # node = Rucoa::Parser.call(
26
+ # <<~RUBY
27
+ # foo(bar, baz)
28
+ # RUBY
29
+ # )
30
+ # expect(node.name).to eq('foo')
31
+ def name
32
+ children[1].to_s
33
+ end
34
+
35
+ # @return [Rucoa::Nodes::Base, nil]
36
+ # @example returns nil for receiver-less method call
37
+ # node = Rucoa::Parser.call(
38
+ # <<~RUBY
39
+ # foo(bar, baz)
40
+ # RUBY
41
+ # )
42
+ # expect(node.receiver).to be_nil
43
+ # @example returns receiver
44
+ # node = Rucoa::Source.new(
45
+ # content: <<~RUBY
46
+ # foo.bar
47
+ # RUBY
48
+ # ).node_at(
49
+ # Rucoa::Position.new(
50
+ # column: 4,
51
+ # line: 1
52
+ # )
53
+ # )
54
+ # expect(node.receiver).to be_a(Rucoa::Nodes::SendNode)
55
+ def receiver
56
+ children[0]
57
+ end
58
+ end
59
+ end
60
+ end
@@ -3,6 +3,10 @@
3
3
  module Rucoa
4
4
  module Nodes
5
5
  class StrNode < Base
6
+ # @return [String]
7
+ def value
8
+ children[0]
9
+ end
6
10
  end
7
11
  end
8
12
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Nodes
5
+ class SymNode < Base
6
+ # @return [String]
7
+ def value
8
+ children[0]
9
+ end
10
+ end
11
+ end
12
+ end
data/lib/rucoa/nodes.rb CHANGED
@@ -3,6 +3,16 @@
3
3
  module Rucoa
4
4
  module Nodes
5
5
  autoload :Base, 'rucoa/nodes/base'
6
+ autoload :ClassNode, 'rucoa/nodes/class_node'
7
+ autoload :CasgnNode, 'rucoa/nodes/casgn_node'
8
+ autoload :ConstNode, 'rucoa/nodes/const_node'
9
+ autoload :DefNode, 'rucoa/nodes/def_node'
10
+ autoload :DefsNode, 'rucoa/nodes/defs_node'
11
+ autoload :LvarNode, 'rucoa/nodes/lvar_node'
12
+ autoload :ModuleNode, 'rucoa/nodes/module_node'
13
+ autoload :SclassNode, 'rucoa/nodes/sclass_node'
14
+ autoload :SendNode, 'rucoa/nodes/send_node'
6
15
  autoload :StrNode, 'rucoa/nodes/str_node'
16
+ autoload :SymNode, 'rucoa/nodes/sym_node'
7
17
  end
8
18
  end
@@ -5,24 +5,34 @@ require 'parser/current'
5
5
  module Rucoa
6
6
  class ParserBuilder < ::Parser::Builders::Default
7
7
  NODE_CLASS_BY_TYPE = {
8
- str: Nodes::StrNode
8
+ casgn: Nodes::CasgnNode,
9
+ class: Nodes::ClassNode,
10
+ const: Nodes::ConstNode,
11
+ def: Nodes::DefNode,
12
+ defs: Nodes::DefsNode,
13
+ lvar: Nodes::LvarNode,
14
+ module: Nodes::ModuleNode,
15
+ sclass: Nodes::SclassNode,
16
+ send: Nodes::SendNode,
17
+ str: Nodes::StrNode,
18
+ sym: Nodes::SymNode
9
19
  }.freeze
10
20
 
21
+ class << self
22
+ # @param type [Symbol]
23
+ # @return [Class]
24
+ def node_class_for(type)
25
+ NODE_CLASS_BY_TYPE.fetch(type, Nodes::Base)
26
+ end
27
+ end
28
+
11
29
  # @note Override.
12
30
  def n(type, children, source_map)
13
- node_class_for(type).new(
31
+ self.class.node_class_for(type).new(
14
32
  type,
15
33
  children,
16
34
  location: source_map
17
35
  )
18
36
  end
19
-
20
- private
21
-
22
- # @param type [Symbol]
23
- # @return [Class]
24
- def node_class_for(type)
25
- NODE_CLASS_BY_TYPE.fetch(type, Nodes::Base)
26
- end
27
37
  end
28
38
  end
@@ -47,8 +47,8 @@ module Rucoa
47
47
  # @return [Hash]
48
48
  def to_vscode_position
49
49
  {
50
- character: @column,
51
- line: @line - 1
50
+ 'character' => @column,
51
+ 'line' => @line - 1
52
52
  }
53
53
  end
54
54
  end
data/lib/rucoa/range.rb CHANGED
@@ -30,28 +30,85 @@ module Rucoa
30
30
 
31
31
  # @param beginning [Rucoa::Position]
32
32
  # @param ending [Ruoca::Position]
33
- # @param exclude_end [Boolean]
34
- def initialize(beginning, ending, exclude_end: true)
33
+ # @param including_ending [Boolean]
34
+ def initialize(beginning, ending, including_ending: true)
35
35
  @beginning = beginning
36
36
  @ending = ending
37
- @exclude_end = exclude_end
37
+ @including_ending = including_ending
38
38
  end
39
39
 
40
40
  # @param range [Rucoa::Range]
41
41
  # @return [Boolean]
42
- def contains?(range)
43
- copy = with_including_end
44
- copy.include?(range.beginning) && copy.include?(range.ending)
42
+ # @example returns true when the range is contained in self
43
+ # range = Rucoa::Range.new(
44
+ # Rucoa::Position.new(
45
+ # column: 0,
46
+ # line: 0
47
+ # ),
48
+ # Rucoa::Position.new(
49
+ # column: 0,
50
+ # line: 2
51
+ # )
52
+ # )
53
+ # expect(range).to contain(
54
+ # Rucoa::Range.new(
55
+ # Rucoa::Position.new(
56
+ # column: 0,
57
+ # line: 0
58
+ # ),
59
+ # Rucoa::Position.new(
60
+ # column: 0,
61
+ # line: 0
62
+ # )
63
+ # )
64
+ # )
65
+ def contain?(range)
66
+ include?(range.beginning) && include?(range.ending)
45
67
  end
46
68
 
47
69
  # @param position [Rucoa::Position]
48
70
  # @return [Boolean]
71
+ # @example returns true when the position is included in self
72
+ # range = Rucoa::Range.new(
73
+ # Rucoa::Position.new(
74
+ # column: 0,
75
+ # line: 0
76
+ # ),
77
+ # Rucoa::Position.new(
78
+ # column: 0,
79
+ # line: 2
80
+ # )
81
+ # )
82
+ # expect(range).to include(
83
+ # Rucoa::Position.new(
84
+ # column: 0,
85
+ # line: 0
86
+ # )
87
+ # )
88
+ # expect(range).to include(
89
+ # Rucoa::Position.new(
90
+ # column: 0,
91
+ # line: 1
92
+ # )
93
+ # )
94
+ # expect(range).to include(
95
+ # Rucoa::Position.new(
96
+ # column: 0,
97
+ # line: 2
98
+ # )
99
+ # )
100
+ # expect(range).not_to include(
101
+ # Rucoa::Position.new(
102
+ # column: 0,
103
+ # line: 3
104
+ # )
105
+ # )
49
106
  def include?(position)
50
107
  return false if position.line > @ending.line
51
108
  return false if position.line < @beginning.line
52
109
  return false if position.column < @beginning.column
53
110
  return false if position.column > @ending.column
54
- return false if position.column == @ending.column && @exclude_end
111
+ return false if position.column == @ending.column && !@including_ending
55
112
 
56
113
  true
57
114
  end
@@ -63,12 +120,5 @@ module Rucoa
63
120
  start: @beginning.to_vscode_position
64
121
  }
65
122
  end
66
-
67
- private
68
-
69
- # @return [Rucoa::Range]
70
- def with_including_end
71
- self.class.new(@beginning, @ending, exclude_end: false)
72
- end
73
123
  end
74
124
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rbs'
4
+
5
+ module Rucoa
6
+ class RbsDocumentLoader
7
+ class << self
8
+ def call
9
+ new.call
10
+ end
11
+ end
12
+
13
+ # @return [Array<Rucoa::Definitions::Base>]
14
+ def call
15
+ declarations.flat_map do |declaration|
16
+ case declaration
17
+ when ::RBS::AST::Declarations::Constant
18
+ [
19
+ DefinitionBuilders::RbsConstantDefinitionBuilder.call(declaration: declaration)
20
+ ]
21
+ when ::RBS::AST::Declarations::Class, ::RBS::AST::Declarations::Module
22
+ declaration.members.grep(::RBS::AST::Members::MethodDefinition).map do |method_definition|
23
+ DefinitionBuilders::RbsMethodDefinitionBuilder.call(
24
+ declaration: declaration,
25
+ method_definition: method_definition
26
+ )
27
+ end
28
+ else
29
+ []
30
+ end
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ # @return [Array<RBS::AST::Declarations::Base>]
37
+ def declarations
38
+ ::RBS::Environment.from_loader(
39
+ ::RBS::EnvironmentLoader.new
40
+ ).resolve_type_names.declarations
41
+ end
42
+ end
43
+ end
@@ -31,7 +31,7 @@ module Rucoa
31
31
  # @return [String]
32
32
  def call
33
33
  @options[:stdin] = @source.content
34
- run([@source.path])
34
+ run([@source.path || 'untitled'])
35
35
  @options[:stdin]
36
36
  end
37
37
  end
@@ -31,7 +31,7 @@ module Rucoa
31
31
  # @return [Array<RuboCop::Cop::Offense>]
32
32
  def call
33
33
  @options[:stdin] = @source.content
34
- run([@source.path])
34
+ run([@source.path || 'untitled'])
35
35
  @offenses
36
36
  end
37
37