forked from whitequark/parser
/
comment.rb
134 lines (120 loc) · 3.22 KB
/
comment.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# frozen_string_literal: true
module Parser
module Source
##
# A comment in the source code.
#
# @!attribute [r] text
# @return [String]
#
# @!attribute [r] location
# @return [Parser::Source::Range]
#
# @api public
#
class Comment
attr_reader :text
attr_reader :location
alias_method :loc, :location
##
# Associate `comments` with `ast` nodes by their corresponding node.
#
# @param [Parser::AST::Node] ast
# @param [Array<Comment>] comments
# @return [Hash<Parser::AST::Node, Array<Comment>>]
# @see Parser::Source::Comment::Associator#associate
# @deprecated Use {associate_locations}.
#
def self.associate(ast, comments)
associator = Associator.new(ast, comments)
associator.associate
end
##
# Associate `comments` with `ast` nodes by their location in the
# source.
#
# @param [Parser::AST::Node] ast
# @param [Array<Comment>] comments
# @return [Hash<Parser::Source::Map, Array<Comment>>]
# @see Parser::Source::Comment::Associator#associate_locations
#
def self.associate_locations(ast, comments)
associator = Associator.new(ast, comments)
associator.associate_locations
end
##
# Associate `comments` with `ast` nodes using identity.
#
# @param [Parser::AST::Node] ast
# @param [Array<Comment>] comments
# @return [Hash<Parser::Source::Node, Array<Comment>>]
# @see Parser::Source::Comment::Associator#associate_by_identity
#
def self.associate_by_identity(ast, comments)
associator = Associator.new(ast, comments)
associator.associate_by_identity
end
##
# @param [Parser::Source::Range] range
#
def initialize(range)
@location = Parser::Source::Map.new(range)
@text = range.source.freeze
freeze
end
##
# Type of this comment.
#
# * Inline comments correspond to `:inline`:
#
# # whatever
#
# * Block comments correspond to `:document`:
#
# =begin
# hi i am a document
# =end
#
# @return [Symbol]
#
def type
if text.start_with?("#".freeze)
:inline
elsif text.start_with?("=begin".freeze)
:document
end
end
##
# @see #type
# @return [Boolean] true if this is an inline comment.
#
def inline?
type == :inline
end
##
# @see #type
# @return [Boolean] true if this is a block comment.
#
def document?
type == :document
end
##
# Compares comments. Two comments are equal if they
# correspond to the same source range.
#
# @param [Object] other
# @return [Boolean]
#
def ==(other)
other.is_a?(Source::Comment) &&
@location == other.location
end
##
# @return [String] a human-readable representation of this comment
#
def inspect
"#<Parser::Source::Comment #{@location.expression.to_s} #{text.inspect}>"
end
end
end
end