Module: Laser::Analysis::SexpExtensions::SourceLocation
- Included in:
- Laser::Analysis::Sexp
- Defined in:
- lib/laser/analysis/sexp_extensions/source_location.rb
Instance Method Summary (collapse)
-
- (Object) backtrack_expecting!(location, offset, expectation)
Attempts to backtrack for the given string from the given location.
-
- (Object) backtrack_searching(location, expectation)
Searches for the given text starting at the given location, going backwards.
-
- (Object) forwardtrack_searching(location, expectation)
Searches for the given text starting at the given location, going backwards.
- - (Object) line_number
-
- (Object) source_begin
Calculates, with some lossiness, the start position of the current node in the original text.
-
- (Object) source_end
Calculates, with some lossiness, the end position of the current node in the original text.
-
- (Object) text_at(location, offset, length)
Determines the text at the given location tuple, with some offset, and a given length.
Instance Method Details
- (Object) backtrack_expecting!(location, offset, expectation)
Attempts to backtrack for the given string from the given location. Returns true if successful.
149 150 151 152 153 154 |
# File 'lib/laser/analysis/sexp_extensions/source_location.rb', line 149 def backtrack_expecting!(location, offset, expectation) if text_at(location, offset, expectation.length) == expectation location[1] += offset true end end |
- (Object) backtrack_searching(location, expectation)
Searches for the given text starting at the given location, going backwards. Modifies the location to match the discovered expected text on success.
complexity: O(N) wrt input source location: [Fixnum, Fixnum] expectation: String returns: Boolean
110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/laser/analysis/sexp_extensions/source_location.rb', line 110 def backtrack_searching(location, expectation) result = location.dup line = lines[result[0] - 1] begin if (expectation_location = line.rindex(expectation, result[1])) result[1] = expectation_location return result end result[0] -= 1 line = lines[result[0] - 1] result[1] = line.size end while result[0] >= 0 location end |
- (Object) forwardtrack_searching(location, expectation)
Searches for the given text starting at the given location, going backwards. Modifies the location to match the discovered expected text on success.
complexity: O(N) wrt input source location: [Fixnum, Fixnum] expectation: String returns: Boolean
132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/laser/analysis/sexp_extensions/source_location.rb', line 132 def forwardtrack_searching(location, expectation) result = location.dup line = lines[result[0] - 1] begin if (expectation_location = line.index(expectation, result[1])) result[1] = expectation_location + expectation.size return result end result[0] += 1 result[1] = 0 line = lines[result[0] - 1] end while result[0] <= lines.size location end |
- (Object) line_number
5 6 7 |
# File 'lib/laser/analysis/sexp_extensions/source_location.rb', line 5 def line_number source_begin && source_begin[0] end |
- (Object) source_begin
Calculates, with some lossiness, the start position of the current node in the original text. This will sometimes fail, as the AST does not include sufficient information in many cases to determine where a node lies. We have to figure it out based on nearby identifiers and keywords.
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 |
# File 'lib/laser/analysis/sexp_extensions/source_location.rb', line 13 def source_begin return @source_begin if @source_begin default_result = children.select { |child| Sexp === child }. map(&:source_begin).compact.first @source_begin = case type when :@ident, :@int, :@kw, :@float, :@tstring_content, :@regexp_end, :@ivar, :@cvar, :@gvar, :@const, :@label, :@CHAR, :@op children[1] when :regexp_literal result = default_result.dup if backtrack_expecting!(result, -1, '/') || backtrack_expecting!(result, -3, '%r') result end when :string_literal if default_result result = default_result.dup # make a copy we can mutate if backtrack_expecting!(result, -1, "'") || backtrack_expecting!(result, -1, '"') || backtrack_expecting!(result, -3, '%q') || backtrack_expecting!(result, -3, '%Q') result end end when :string_embexpr if default_result result = default_result.dup result[1] -= 2 result end when :dyna_symbol if default_result result = default_result.dup result[1] -= 2 result end when :symbol_literal result = default_result.dup result[1] -= 1 result when :hash backtrack_searching(default_result, '{') if default_result when :array backtrack_searching(default_result, '[') if default_result when :def, :defs backtrack_searching(default_result, 'def') when :class, :sclass backtrack_searching(default_result, 'class') when :module backtrack_searching(default_result, 'module') else default_result end end |
- (Object) source_end
Calculates, with some lossiness, the end position of the current node in the original text. This will sometimes fail, as the AST does not include sufficient information in many cases to determine where a node ends. We have to figure it out based on nearby identifiers, keywords, and literals.
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 |
# File 'lib/laser/analysis/sexp_extensions/source_location.rb', line 72 def source_end default_result = children.select { |child| Sexp === child }. map(&:source_end).compact.last case type when :@ident, :@int, :@kw, :@float, :@tstring_content, :@regexp_end, :@ivar, :@cvar, :@gvar, :@const, :@label, :@CHAR, :@op text, location = children source_end = location.dup source_end[1] += text.size source_end when :string_literal if source_begin result = default_result.dup result[1] += 1 result end when :string_embexpr, :dyna_symbol if default_result result = default_result.dup result[1] += 1 result end when :hash forwardtrack_searching(default_result, '}') if default_result when :array forwardtrack_searching(default_result, ']') if default_result else default_result end end |
- (Object) text_at(location, offset, length)
Determines the text at the given location tuple, with some offset, and a given length.
158 159 160 161 |
# File 'lib/laser/analysis/sexp_extensions/source_location.rb', line 158 def text_at(location, offset, length) line = lines[location[0] - 1] line[location[1] + offset, length] end |