tailor 1.0.0.alpha2 → 1.0.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.
- data/.gitignore +1 -0
- data/.tailor +10 -2
- data/Gemfile.lock +2 -2
- data/History.rdoc +20 -0
- data/README.rdoc +176 -26
- data/features/configurable.feature +19 -39
- data/features/horizontal_spacing.feature +3 -2
- data/features/indentation.feature +2 -2
- data/features/indentation/bad_files_with_no_trailing_newline.feature +9 -8
- data/features/indentation/good_files_with_no_trailing_newline.feature +19 -6
- data/features/name_detection.feature +2 -2
- data/features/support/env.rb +0 -2
- data/features/support/file_cases/horizontal_spacing_cases.rb +5 -4
- data/features/support/file_cases/indentation_cases.rb +105 -54
- data/features/support/file_cases/naming_cases.rb +0 -1
- data/features/support/file_cases/vertical_spacing_cases.rb +0 -1
- data/features/support/legacy/bad_ternary_colon_spacing.rb +1 -1
- data/features/valid_ruby.feature +17 -0
- data/features/vertical_spacing.feature +40 -19
- data/lib/ext/string_ext.rb +12 -0
- data/lib/tailor/cli.rb +7 -5
- data/lib/tailor/cli/options.rb +13 -3
- data/lib/tailor/composite_observable.rb +17 -2
- data/lib/tailor/configuration.rb +83 -72
- data/lib/tailor/configuration/style.rb +85 -0
- data/lib/tailor/critic.rb +67 -117
- data/lib/tailor/formatter.rb +38 -0
- data/lib/tailor/formatters/text.rb +35 -10
- data/lib/tailor/lexed_line.rb +38 -5
- data/lib/tailor/lexer.rb +150 -14
- data/lib/tailor/{lexer_constants.rb → lexer/lexer_constants.rb} +9 -7
- data/lib/tailor/lexer/token.rb +6 -2
- data/lib/tailor/logger.rb +4 -0
- data/lib/tailor/problem.rb +8 -73
- data/lib/tailor/reporter.rb +1 -1
- data/lib/tailor/ruler.rb +67 -6
- data/lib/tailor/rulers/allow_camel_case_methods_ruler.rb +9 -1
- data/lib/tailor/rulers/allow_hard_tabs_ruler.rb +9 -1
- data/lib/tailor/rulers/allow_invalid_ruby_ruler.rb +38 -0
- data/lib/tailor/rulers/allow_screaming_snake_case_classes_ruler.rb +9 -2
- data/lib/tailor/rulers/allow_trailing_line_spaces_ruler.rb +10 -5
- data/lib/tailor/rulers/indentation_spaces_ruler.rb +93 -26
- data/lib/tailor/rulers/indentation_spaces_ruler/indentation_manager.rb +128 -84
- data/lib/tailor/rulers/max_code_lines_in_class_ruler.rb +9 -5
- data/lib/tailor/rulers/max_code_lines_in_method_ruler.rb +9 -5
- data/lib/tailor/rulers/max_line_length_ruler.rb +10 -5
- data/lib/tailor/rulers/spaces_after_comma_ruler.rb +13 -4
- data/lib/tailor/rulers/spaces_after_lbrace_ruler.rb +8 -4
- data/lib/tailor/rulers/spaces_after_lbracket_ruler.rb +8 -4
- data/lib/tailor/rulers/spaces_after_lparen_ruler.rb +8 -4
- data/lib/tailor/rulers/spaces_before_comma_ruler.rb +8 -4
- data/lib/tailor/rulers/spaces_before_lbrace_ruler.rb +13 -6
- data/lib/tailor/rulers/spaces_before_rbrace_ruler.rb +12 -8
- data/lib/tailor/rulers/spaces_before_rbracket_ruler.rb +12 -5
- data/lib/tailor/rulers/spaces_before_rparen_ruler.rb +13 -6
- data/lib/tailor/rulers/spaces_in_empty_braces_ruler.rb +13 -9
- data/lib/tailor/rulers/trailing_newlines_ruler.rb +10 -5
- data/lib/tailor/tailorrc.erb +3 -3
- data/lib/tailor/version.rb +1 -1
- data/m.rb +15 -0
- data/spec/spec_helper.rb +0 -1
- data/spec/tailor/cli_spec.rb +8 -9
- data/spec/tailor/composite_observable_spec.rb +41 -0
- data/spec/tailor/configuration/style_spec.rb +197 -0
- data/spec/tailor/configuration_spec.rb +52 -33
- data/spec/tailor/critic_spec.rb +7 -8
- data/spec/tailor/formatter_spec.rb +52 -0
- data/spec/tailor/lexed_line_spec.rb +236 -88
- data/spec/tailor/lexer_spec.rb +8 -63
- data/spec/tailor/problem_spec.rb +14 -46
- data/spec/tailor/reporter_spec.rb +8 -8
- data/spec/tailor/ruler_spec.rb +1 -1
- data/spec/tailor/rulers/indentation_spaces_ruler/indentation_manager_spec.rb +132 -176
- data/spec/tailor/rulers/indentation_spaces_ruler_spec.rb +41 -33
- data/spec/tailor/rulers/{spaces_after_comma_spec.rb → spaces_after_comma_ruler_spec.rb} +5 -5
- data/spec/tailor/rulers/spaces_after_lbrace_ruler_spec.rb +14 -14
- data/spec/tailor/rulers/spaces_before_lbrace_ruler_spec.rb +1 -1
- data/spec/tailor/rulers/spaces_before_rbrace_ruler_spec.rb +1 -1
- data/spec/tailor/version_spec.rb +1 -1
- data/spec/tailor_spec.rb +3 -1
- data/tailor.gemspec +11 -3
- data/uest.rb +9 -0
- metadata +66 -41
- data/features/step_definitions/spacing/commas_steps.rb +0 -14
    
        data/lib/tailor/lexed_line.rb
    CHANGED
    
    | @@ -1,9 +1,12 @@ | |
| 1 1 | 
             
            require_relative 'logger'
         | 
| 2 | 
            -
            require_relative 'lexer_constants'
         | 
| 2 | 
            +
            require_relative 'lexer/lexer_constants'
         | 
| 3 3 | 
             
            require_relative 'lexer/token'
         | 
| 4 4 | 
             
            require 'ripper'
         | 
| 5 5 |  | 
| 6 6 | 
             
            class Tailor
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              # This class provides methods for finding info about the current line.  It
         | 
| 9 | 
            +
              # works off the format that results from {Tailor::Lexer}.
         | 
| 7 10 | 
             
              class LexedLine < Array
         | 
| 8 11 | 
             
                include LexerConstants
         | 
| 9 12 |  | 
| @@ -97,6 +100,9 @@ class Tailor | |
| 97 100 | 
             
                  previous_event.first.last.zero? || previous_event.first.last.nil?
         | 
| 98 101 | 
             
                end
         | 
| 99 102 |  | 
| 103 | 
            +
                # Allows for calling a couple styles of methods:
         | 
| 104 | 
            +
                # * #ends_with_(.+)?  - Allows for checking if the line ends with (.+)
         | 
| 105 | 
            +
                # * #only_(.+)?  - Allows for checking if the line is only spaces and (.+)
         | 
| 100 106 | 
             
                def method_missing(meth, *args, &blk)
         | 
| 101 107 | 
             
                  if meth.to_s =~ /^ends_with_(.+)\?$/
         | 
| 102 108 | 
             
                    event = "on_#{$1}".to_sym
         | 
| @@ -145,10 +151,17 @@ class Tailor | |
| 145 151 | 
             
                end
         | 
| 146 152 |  | 
| 147 153 | 
             
                # @return [Array] The lexed event that represents the last event in the
         | 
| 148 | 
            -
                #   line that's not a  | 
| 154 | 
            +
                #   line that's not a line-feed.  Line-feed events are signified by
         | 
| 155 | 
            +
                #   +:on_nl+ and +on_ignored_nl+ events, and by +:on_sp+ events when they
         | 
| 156 | 
            +
                #   equal +"\\\n" (which occurs when a line is broken by a backslash).
         | 
| 149 157 | 
             
                def last_non_line_feed_event
         | 
| 150 | 
            -
                  self.find_all  | 
| 151 | 
            -
                    [ | 
| 158 | 
            +
                  events = self.find_all do |e|
         | 
| 159 | 
            +
                    e[1] != :on_nl &&
         | 
| 160 | 
            +
                      e[1] != :on_ignored_nl &&
         | 
| 161 | 
            +
                      e.last != "\\\n"
         | 
| 162 | 
            +
                  end
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                  events.last || [[]]
         | 
| 152 165 | 
             
                end
         | 
| 153 166 |  | 
| 154 167 | 
             
                # @return [Fixnum] The length of the line minus the +\n+.
         | 
| @@ -184,7 +197,7 @@ class Tailor | |
| 184 197 | 
             
                end
         | 
| 185 198 |  | 
| 186 199 | 
             
                # If a trailing comment exists in the line, remove it and the spaces that
         | 
| 187 | 
            -
                # come before it.  This is necessary, as  | 
| 200 | 
            +
                # come before it.  This is necessary, as +Ripper+ doesn't trigger an event
         | 
| 188 201 | 
             
                # for the end of the line when the line ends with a comment.  Without this
         | 
| 189 202 | 
             
                # observers that key off ending the line will never get triggered, and thus
         | 
| 190 203 | 
             
                # style won't get checked for that line.
         | 
| @@ -230,6 +243,26 @@ class Tailor | |
| 230 243 | 
             
                    self.none? { |e| e[1] == :on_tstring_beg }
         | 
| 231 244 | 
             
                end
         | 
| 232 245 |  | 
| 246 | 
            +
                # When Ripper lexes a Symbol, it generates one event for :on_symbeg, which
         | 
| 247 | 
            +
                # is the ':' token, and one for the name of the Symbol.  Since your Symbol
         | 
| 248 | 
            +
                # name can be anything, the second event could be something like "class", in
         | 
| 249 | 
            +
                # which case :on_kw will get called and probably result in unexpected
         | 
| 250 | 
            +
                # behavior.
         | 
| 251 | 
            +
                #
         | 
| 252 | 
            +
                # This assumes the keyword in question is the last event in the line.
         | 
| 253 | 
            +
                #
         | 
| 254 | 
            +
                # @return [Boolean]
         | 
| 255 | 
            +
                def keyword_is_symbol?
         | 
| 256 | 
            +
                  current_index = self.index(self.last)
         | 
| 257 | 
            +
                  previous_event = self.at(current_index - 1)
         | 
| 258 | 
            +
             | 
| 259 | 
            +
                  return false if previous_event.nil?
         | 
| 260 | 
            +
                  return false unless self.last[1] == :on_kw
         | 
| 261 | 
            +
                  return false unless previous_event[1] == :on_symbeg
         | 
| 262 | 
            +
             | 
| 263 | 
            +
                  true
         | 
| 264 | 
            +
                end
         | 
| 265 | 
            +
             | 
| 233 266 | 
             
                #---------------------------------------------------------------------------
         | 
| 234 267 | 
             
                # Privates!
         | 
| 235 268 | 
             
                #---------------------------------------------------------------------------
         | 
    
        data/lib/tailor/lexer.rb
    CHANGED
    
    | @@ -1,15 +1,16 @@ | |
| 1 1 | 
             
            require 'ripper'
         | 
| 2 2 | 
             
            require_relative 'composite_observable'
         | 
| 3 3 | 
             
            require_relative 'lexed_line'
         | 
| 4 | 
            -
            require_relative 'lexer_constants'
         | 
| 4 | 
            +
            require_relative 'lexer/lexer_constants'
         | 
| 5 5 | 
             
            require_relative 'logger'
         | 
| 6 6 | 
             
            require_relative 'lexer/token'
         | 
| 7 7 |  | 
| 8 8 |  | 
| 9 9 | 
             
            class Tailor
         | 
| 10 10 |  | 
| 11 | 
            -
              #  | 
| 12 | 
            -
              #  | 
| 11 | 
            +
              # This is what provides the main file parsing for tailor.  For every event
         | 
| 12 | 
            +
              # that's encountered, it calls the appropriate notifier method.  Notifier
         | 
| 13 | 
            +
              # methods are provided by {Tailor::CompositeObservable}.
         | 
| 13 14 | 
             
              class Lexer < Ripper::Lexer
         | 
| 14 15 | 
             
                include CompositeObservable
         | 
| 15 16 | 
             
                include LexerConstants
         | 
| @@ -31,9 +32,16 @@ class Tailor | |
| 31 32 | 
             
                  @added_newline = @file_text != @original_file_text
         | 
| 32 33 | 
             
                end
         | 
| 33 34 |  | 
| 34 | 
            -
                 | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 35 | 
            +
                # This kicks off the process of parsing the file and publishing events
         | 
| 36 | 
            +
                # as the events are discovered.
         | 
| 37 | 
            +
                def lex
         | 
| 38 | 
            +
                  file_beg_changed
         | 
| 39 | 
            +
                  notify_file_beg_observers(@file_name)
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  super
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  file_end_changed
         | 
| 44 | 
            +
                  notify_file_end_observers(count_trailing_newlines(@original_file_text))
         | 
| 37 45 | 
             
                end
         | 
| 38 46 |  | 
| 39 47 | 
             
                def on_backref(token)
         | 
| @@ -41,11 +49,18 @@ class Tailor | |
| 41 49 | 
             
                  super(token)
         | 
| 42 50 | 
             
                end
         | 
| 43 51 |  | 
| 52 | 
            +
                # Called when the lexer matches the first ` in a `` statement (the second
         | 
| 53 | 
            +
                # matches :on_tstring_end; this may or may not be a Ruby bug).
         | 
| 54 | 
            +
                #
         | 
| 55 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 44 56 | 
             
                def on_backtick(token)
         | 
| 45 57 | 
             
                  log "BACKTICK: '#{token}'"
         | 
| 46 58 | 
             
                  super(token)
         | 
| 47 59 | 
             
                end
         | 
| 48 60 |  | 
| 61 | 
            +
                # Called when the lexer matches a comma.
         | 
| 62 | 
            +
                #
         | 
| 63 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 49 64 | 
             
                def on_comma(token)
         | 
| 50 65 | 
             
                  log "COMMA: #{token}"
         | 
| 51 66 | 
             
                  log "Line length: #{current_line_of_text.length}"
         | 
| @@ -56,6 +71,10 @@ class Tailor | |
| 56 71 | 
             
                  super(token)
         | 
| 57 72 | 
             
                end
         | 
| 58 73 |  | 
| 74 | 
            +
                # Called when the lexer matches a #.  The token includes the # as well as
         | 
| 75 | 
            +
                # the content after it.
         | 
| 76 | 
            +
                #
         | 
| 77 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 59 78 | 
             
                def on_comment(token)
         | 
| 60 79 | 
             
                  log "COMMENT: '#{token}'"
         | 
| 61 80 |  | 
| @@ -67,6 +86,10 @@ class Tailor | |
| 67 86 | 
             
                  super(token)
         | 
| 68 87 | 
             
                end
         | 
| 69 88 |  | 
| 89 | 
            +
                # Called when the lexer matches a constant (including class names, of
         | 
| 90 | 
            +
                # course).
         | 
| 91 | 
            +
                #
         | 
| 92 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 70 93 | 
             
                def on_const(token)
         | 
| 71 94 | 
             
                  log "CONST: '#{token}'"
         | 
| 72 95 |  | 
| @@ -78,27 +101,41 @@ class Tailor | |
| 78 101 | 
             
                  super(token)
         | 
| 79 102 | 
             
                end
         | 
| 80 103 |  | 
| 104 | 
            +
                # Called when the lexer matches a class variable.
         | 
| 105 | 
            +
                #
         | 
| 106 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 81 107 | 
             
                def on_cvar(token)
         | 
| 82 108 | 
             
                  log "CVAR: '#{token}'"
         | 
| 83 109 | 
             
                  super(token)
         | 
| 84 110 | 
             
                end
         | 
| 85 111 |  | 
| 112 | 
            +
                # Called when the lexer matches the content inside a =begin/=end.
         | 
| 113 | 
            +
                #
         | 
| 114 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 86 115 | 
             
                def on_embdoc(token)
         | 
| 87 116 | 
             
                  log "EMBDOC: '#{token}'"
         | 
| 88 117 | 
             
                  super(token)
         | 
| 89 118 | 
             
                end
         | 
| 90 119 |  | 
| 120 | 
            +
                # Called when the lexer matches =begin.
         | 
| 121 | 
            +
                #
         | 
| 122 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 91 123 | 
             
                def on_embdoc_beg(token)
         | 
| 92 124 | 
             
                  log "EMBDOC_BEG: '#{token}'"
         | 
| 93 125 | 
             
                  super(token)
         | 
| 94 126 | 
             
                end
         | 
| 95 127 |  | 
| 128 | 
            +
                # Called when the lexer matches =end.
         | 
| 129 | 
            +
                #
         | 
| 130 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 96 131 | 
             
                def on_embdoc_end(token)
         | 
| 97 132 | 
             
                  log "EMBDOC_BEG: '#{token}'"
         | 
| 98 133 | 
             
                  super(token)
         | 
| 99 134 | 
             
                end
         | 
| 100 135 |  | 
| 101 | 
            -
                #  | 
| 136 | 
            +
                # Called when the lexer matches a #{.
         | 
| 137 | 
            +
                #
         | 
| 138 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 102 139 | 
             
                def on_embexpr_beg(token)
         | 
| 103 140 | 
             
                  log "EMBEXPR_BEG: '#{token}'"
         | 
| 104 141 | 
             
                  embexpr_beg_changed
         | 
| @@ -106,6 +143,11 @@ class Tailor | |
| 106 143 | 
             
                  super(token)
         | 
| 107 144 | 
             
                end
         | 
| 108 145 |  | 
| 146 | 
            +
                # Called when the lexer matches the } that closes a #{.  Note that as of
         | 
| 147 | 
            +
                # MRI 1.9.3-p125, this never gets called.  Logged as a bug and fixed, but
         | 
| 148 | 
            +
                # not yet released: https://bugs.ruby-lang.org/issues/6211.
         | 
| 149 | 
            +
                #
         | 
| 150 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 109 151 | 
             
                def on_embexpr_end(token)
         | 
| 110 152 | 
             
                  log "EMBEXPR_END: '#{token}'"
         | 
| 111 153 | 
             
                  embexpr_end_changed
         | 
| @@ -118,27 +160,42 @@ class Tailor | |
| 118 160 | 
             
                  super(token)
         | 
| 119 161 | 
             
                end
         | 
| 120 162 |  | 
| 163 | 
            +
                # Called when the lexer matches a Float.
         | 
| 164 | 
            +
                #
         | 
| 165 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 121 166 | 
             
                def on_float(token)
         | 
| 122 167 | 
             
                  log "FLOAT: '#{token}'"
         | 
| 123 168 | 
             
                  super(token)
         | 
| 124 169 | 
             
                end
         | 
| 125 170 |  | 
| 126 | 
            -
                #  | 
| 171 | 
            +
                # Called when the lexer matches a global variable.
         | 
| 172 | 
            +
                #
         | 
| 173 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 127 174 | 
             
                def on_gvar(token)
         | 
| 128 175 | 
             
                  log "GVAR: '#{token}'"
         | 
| 129 176 | 
             
                  super(token)
         | 
| 130 177 | 
             
                end
         | 
| 131 178 |  | 
| 179 | 
            +
                # Called when the lexer matches the beginning of a heredoc.
         | 
| 180 | 
            +
                #
         | 
| 181 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 132 182 | 
             
                def on_heredoc_beg(token)
         | 
| 133 183 | 
             
                  log "HEREDOC_BEG: '#{token}'"
         | 
| 134 184 | 
             
                  super(token)
         | 
| 135 185 | 
             
                end
         | 
| 136 186 |  | 
| 187 | 
            +
                # Called when the lexer matches the end of a heredoc.
         | 
| 188 | 
            +
                #
         | 
| 189 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 137 190 | 
             
                def on_heredoc_end(token)
         | 
| 138 191 | 
             
                  log "HEREDOC_END: '#{token}'"
         | 
| 139 192 | 
             
                  super(token)
         | 
| 140 193 | 
             
                end
         | 
| 141 194 |  | 
| 195 | 
            +
                # Called when the lexer matches an identifier (method name, variable, the
         | 
| 196 | 
            +
                # text part of a Symbol, etc.).
         | 
| 197 | 
            +
                #
         | 
| 198 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 142 199 | 
             
                def on_ident(token)
         | 
| 143 200 | 
             
                  log "IDENT: '#{token}'"
         | 
| 144 201 | 
             
                  l_token = Tailor::Lexer::Token.new(token)
         | 
| @@ -163,18 +220,23 @@ class Tailor | |
| 163 220 | 
             
                  super(token)
         | 
| 164 221 | 
             
                end
         | 
| 165 222 |  | 
| 223 | 
            +
                # Called when the lexer matches an Integer.
         | 
| 224 | 
            +
                #
         | 
| 225 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 166 226 | 
             
                def on_int(token)
         | 
| 167 227 | 
             
                  log "INT: '#{token}'"
         | 
| 168 228 | 
             
                  super(token)
         | 
| 169 229 | 
             
                end
         | 
| 170 230 |  | 
| 171 | 
            -
                #  | 
| 231 | 
            +
                # Called when the lexer matches an instance variable.
         | 
| 232 | 
            +
                #
         | 
| 233 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 172 234 | 
             
                def on_ivar(token)
         | 
| 173 235 | 
             
                  log "IVAR: '#{token}'"
         | 
| 174 236 | 
             
                  super(token)
         | 
| 175 237 | 
             
                end
         | 
| 176 238 |  | 
| 177 | 
            -
                # Called when the lexer matches a Ruby keyword
         | 
| 239 | 
            +
                # Called when the lexer matches a Ruby keyword.
         | 
| 178 240 | 
             
                #
         | 
| 179 241 | 
             
                # @param [String] token The token that the lexer matched.
         | 
| 180 242 | 
             
                def on_kw(token)
         | 
| @@ -194,13 +256,20 @@ class Tailor | |
| 194 256 | 
             
                  super(token)
         | 
| 195 257 | 
             
                end
         | 
| 196 258 |  | 
| 259 | 
            +
                # Called when the lexer matches a label (the first part in a non-rocket
         | 
| 260 | 
            +
                # style Hash).
         | 
| 261 | 
            +
                #
         | 
| 262 | 
            +
                # Example:
         | 
| 263 | 
            +
                #   one: 1     # Matches one:
         | 
| 264 | 
            +
                #
         | 
| 265 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 197 266 | 
             
                def on_label(token)
         | 
| 198 267 | 
             
                  log "LABEL: '#{token}'"
         | 
| 199 268 | 
             
                  super(token)
         | 
| 200 269 | 
             
                end
         | 
| 201 270 |  | 
| 202 271 | 
             
                # Called when the lexer matches a {.  Note a #{ match calls
         | 
| 203 | 
            -
                #  | 
| 272 | 
            +
                # +#on_embexpr_beg+.
         | 
| 204 273 | 
             
                #
         | 
| 205 274 | 
             
                # @param [String] token The token that the lexer matched.
         | 
| 206 275 | 
             
                def on_lbrace(token)
         | 
| @@ -222,6 +291,9 @@ class Tailor | |
| 222 291 | 
             
                  super(token)
         | 
| 223 292 | 
             
                end
         | 
| 224 293 |  | 
| 294 | 
            +
                # Called when the lexer matches a (.
         | 
| 295 | 
            +
                #
         | 
| 296 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 225 297 | 
             
                def on_lparen(token)
         | 
| 226 298 | 
             
                  log "LPAREN: '#{token}'"
         | 
| 227 299 | 
             
                  lparen_changed
         | 
| @@ -240,12 +312,17 @@ class Tailor | |
| 240 312 | 
             
                  super(token)
         | 
| 241 313 | 
             
                end
         | 
| 242 314 |  | 
| 243 | 
            -
                #  | 
| 315 | 
            +
                # Called when the lexer matches an operator.
         | 
| 316 | 
            +
                #
         | 
| 317 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 244 318 | 
             
                def on_op(token)
         | 
| 245 319 | 
             
                  log "OP: '#{token}'"
         | 
| 246 320 | 
             
                  super(token)
         | 
| 247 321 | 
             
                end
         | 
| 248 322 |  | 
| 323 | 
            +
                # Called when the lexer matches a period.
         | 
| 324 | 
            +
                #
         | 
| 325 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 249 326 | 
             
                def on_period(token)
         | 
| 250 327 | 
             
                  log "PERIOD: '#{token}'"
         | 
| 251 328 |  | 
| @@ -255,6 +332,10 @@ class Tailor | |
| 255 332 | 
             
                  super(token)
         | 
| 256 333 | 
             
                end
         | 
| 257 334 |  | 
| 335 | 
            +
                # Called when the lexer matches '%w'.  Statement is ended by a
         | 
| 336 | 
            +
                # +:on_words_end+.
         | 
| 337 | 
            +
                #
         | 
| 338 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 258 339 | 
             
                def on_qwords_beg(token)
         | 
| 259 340 | 
             
                  log "QWORDS_BEG: '#{token}'"
         | 
| 260 341 | 
             
                  super(token)
         | 
| @@ -286,16 +367,25 @@ class Tailor | |
| 286 367 | 
             
                  super(token)
         | 
| 287 368 | 
             
                end
         | 
| 288 369 |  | 
| 370 | 
            +
                # Called when the lexer matches the beginning of a Regexp.
         | 
| 371 | 
            +
                #
         | 
| 372 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 289 373 | 
             
                def on_regexp_beg(token)
         | 
| 290 374 | 
             
                  log "REGEXP_BEG: '#{token}'"
         | 
| 291 375 | 
             
                  super(token)
         | 
| 292 376 | 
             
                end
         | 
| 293 377 |  | 
| 378 | 
            +
                # Called when the lexer matches the end of a Regexp.
         | 
| 379 | 
            +
                #
         | 
| 380 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 294 381 | 
             
                def on_regexp_end(token)
         | 
| 295 382 | 
             
                  log "REGEXP_END: '#{token}'"
         | 
| 296 383 | 
             
                  super(token)
         | 
| 297 384 | 
             
                end
         | 
| 298 385 |  | 
| 386 | 
            +
                # Called when the lexer matches a ).
         | 
| 387 | 
            +
                #
         | 
| 388 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 299 389 | 
             
                def on_rparen(token)
         | 
| 300 390 | 
             
                  log "RPAREN: '#{token}'"
         | 
| 301 391 |  | 
| @@ -306,68 +396,114 @@ class Tailor | |
| 306 396 | 
             
                  super(token)
         | 
| 307 397 | 
             
                end
         | 
| 308 398 |  | 
| 399 | 
            +
                # Called when the lexer matches a ;.
         | 
| 400 | 
            +
                #
         | 
| 401 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 309 402 | 
             
                def on_semicolon(token)
         | 
| 310 403 | 
             
                  log "SEMICOLON: '#{token}'"
         | 
| 311 404 | 
             
                  super(token)
         | 
| 312 405 | 
             
                end
         | 
| 313 406 |  | 
| 407 | 
            +
                # Called when the lexer matches any type of space character.
         | 
| 408 | 
            +
                #
         | 
| 409 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 314 410 | 
             
                def on_sp(token)
         | 
| 315 411 | 
             
                  log "SP: '#{token}'; size: #{token.size}"
         | 
| 316 412 | 
             
                  l_token = Tailor::Lexer::Token.new(token)
         | 
| 317 413 | 
             
                  sp_changed
         | 
| 318 414 | 
             
                  notify_sp_observers(l_token, lineno, column)
         | 
| 415 | 
            +
             | 
| 416 | 
            +
                  # Deal with lines that end with \
         | 
| 417 | 
            +
                  if token == "\\\n"
         | 
| 418 | 
            +
                    current_line = LexedLine.new(super, lineno)
         | 
| 419 | 
            +
                    ignored_nl_changed
         | 
| 420 | 
            +
                    notify_ignored_nl_observers(current_line, lineno, column)
         | 
| 421 | 
            +
                  end
         | 
| 319 422 | 
             
                  super(token)
         | 
| 320 423 | 
             
                end
         | 
| 321 424 |  | 
| 425 | 
            +
                # Called when the lexer matches the : at the beginning of a Symbol.
         | 
| 426 | 
            +
                #
         | 
| 427 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 322 428 | 
             
                def on_symbeg(token)
         | 
| 323 429 | 
             
                  log "SYMBEG: '#{token}'"
         | 
| 324 430 | 
             
                  super(token)
         | 
| 325 431 | 
             
                end
         | 
| 326 432 |  | 
| 433 | 
            +
                # Called when the lexer matches the -> as a lambda.
         | 
| 434 | 
            +
                #
         | 
| 435 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 327 436 | 
             
                def on_tlambda(token)
         | 
| 328 437 | 
             
                  log "TLAMBDA: '#{token}'"
         | 
| 329 438 | 
             
                  super(token)
         | 
| 330 439 | 
             
                end
         | 
| 331 440 |  | 
| 441 | 
            +
                # Called when the lexer matches the { that represents the beginning of a
         | 
| 442 | 
            +
                # -> lambda.
         | 
| 443 | 
            +
                #
         | 
| 444 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 332 445 | 
             
                def on_tlambeg(token)
         | 
| 333 446 | 
             
                  log "TLAMBEG: '#{token}'"
         | 
| 334 447 | 
             
                  super(token)
         | 
| 335 448 | 
             
                end
         | 
| 336 449 |  | 
| 450 | 
            +
                # Called when the lexer matches the beginning of a String.
         | 
| 451 | 
            +
                #
         | 
| 452 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 337 453 | 
             
                def on_tstring_beg(token)
         | 
| 338 454 | 
             
                  log "TSTRING_BEG: '#{token}'"
         | 
| 455 | 
            +
                  current_line = LexedLine.new(super, lineno)
         | 
| 339 456 | 
             
                  tstring_beg_changed
         | 
| 340 | 
            -
                  notify_tstring_beg_observers(lineno)
         | 
| 457 | 
            +
                  notify_tstring_beg_observers(current_line, lineno)
         | 
| 341 458 | 
             
                  super(token)
         | 
| 342 459 | 
             
                end
         | 
| 343 460 |  | 
| 461 | 
            +
                # Called when the lexer matches the content of any String.
         | 
| 462 | 
            +
                #
         | 
| 463 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 344 464 | 
             
                def on_tstring_content(token)
         | 
| 345 465 | 
             
                  log "TSTRING_CONTENT: '#{token}'"
         | 
| 346 466 | 
             
                  super(token)
         | 
| 347 467 | 
             
                end
         | 
| 348 468 |  | 
| 469 | 
            +
                # Called when the lexer matches the end of a String.
         | 
| 470 | 
            +
                #
         | 
| 471 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 349 472 | 
             
                def on_tstring_end(token)
         | 
| 350 473 | 
             
                  log "TSTRING_END: '#{token}'"
         | 
| 351 474 | 
             
                  tstring_end_changed
         | 
| 352 | 
            -
                  notify_tstring_end_observers
         | 
| 475 | 
            +
                  notify_tstring_end_observers(lineno)
         | 
| 353 476 | 
             
                  super(token)
         | 
| 354 477 | 
             
                end
         | 
| 355 478 |  | 
| 479 | 
            +
                # Called when the lexer matches '%W'.
         | 
| 480 | 
            +
                #
         | 
| 481 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 356 482 | 
             
                def on_words_beg(token)
         | 
| 357 483 | 
             
                  log "WORDS_BEG: '#{token}'"
         | 
| 358 484 | 
             
                  super(token)
         | 
| 359 485 | 
             
                end
         | 
| 360 486 |  | 
| 487 | 
            +
                # Called when the lexer matches the separators in a %w or %W (by default,
         | 
| 488 | 
            +
                # this is a single space).
         | 
| 489 | 
            +
                #
         | 
| 490 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 361 491 | 
             
                def on_words_sep(token)
         | 
| 362 492 | 
             
                  log "WORDS_SEP: '#{token}'"
         | 
| 363 493 | 
             
                  super(token)
         | 
| 364 494 | 
             
                end
         | 
| 365 495 |  | 
| 496 | 
            +
                # Called when the lexer matches __END__.
         | 
| 497 | 
            +
                #
         | 
| 498 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 366 499 | 
             
                def on___end__(token)
         | 
| 367 500 | 
             
                  log "__END__: '#{token}'"
         | 
| 368 501 | 
             
                  super(token)
         | 
| 369 502 | 
             
                end
         | 
| 370 503 |  | 
| 504 | 
            +
                # Called when the lexer matches CHAR.
         | 
| 505 | 
            +
                #
         | 
| 506 | 
            +
                # @param [String] token The token that the lexer matched.
         | 
| 371 507 | 
             
                def on_CHAR(token)
         | 
| 372 508 | 
             
                  log "CHAR: '#{token}'"
         | 
| 373 509 | 
             
                  super(token)
         |