diff --git a/lib/outlaw.rb b/lib/outlaw.rb index e1406e5..d99c840 100644 --- a/lib/outlaw.rb +++ b/lib/outlaw.rb @@ -7,7 +7,7 @@ module Outlaw extend self - attr_accessor :ignore_types + attr_accessor :ignore_types, :param_types def outlaw(pattern, message) rule = Rule.new(pattern, message) @@ -17,11 +17,13 @@ def outlaw(pattern, message) def enforce(dir=".") Outlaw::Enforcement.process_directory(dir) end - PARAM_TYPES = [:on_const, :on_ident, :on_ivar, :on_cvar] - self.ignore_types = [:on_sp, :on_nl, :on_ignored_nl, :on_rparen, :on_lparen] - WHITESPACE = [:on_sp, :on_nl, :on_ignored_nl] - SPECIAL_CASES = [:whitespace_sensitive] #these come from ripper's Lexer - CORE_CLASSES_FILE = File.expand_path("../../data/core_classes.txt", __FILE__) - CORE_CLASS = File.readlines(CORE_CLASSES_FILE).map &:chomp + self.param_types = [:on_const, :on_ident, :on_ivar, :on_cvar] + self.ignore_types = [:on_sp, :on_nl, :on_ignored_nl, :on_rparen, :on_lparen] + WHITESPACE = [:on_sp, :on_nl, :on_ignored_nl] + VERTICAL_WHITESPACE = [:on_nl, :on_ignored_nl] + SPECIAL_CASES = [:whitespace_sensitive, :vertical_whitespace_sensitive] + + CORE_CLASSES_FILE = File.expand_path("../../data/core_classes.txt", __FILE__) + CORE_CLASS = File.readlines(CORE_CLASSES_FILE).map &:chomp end diff --git a/lib/outlaw/law_parser.rb b/lib/outlaw/law_parser.rb index 419157e..c651ffa 100644 --- a/lib/outlaw/law_parser.rb +++ b/lib/outlaw/law_parser.rb @@ -6,7 +6,7 @@ def parse(restriction, rule) parsed_restriction = [] tokens.each do |token| case - when special_case?(token) + when special_case?(string_to_sym(token)) handle_special(token, rule) when multipart?(token) #this handles multi-token literals, Const.new etc parsed_restriction += Ripper.lex(token) @@ -27,7 +27,7 @@ def parse(restriction, rule) def handle_special(token, rule) rule.modifications ||= [] - rule.modifications << token + rule.modifications << string_to_sym(token) end def special_case?(token) diff --git a/lib/outlaw/rule.rb b/lib/outlaw/rule.rb index 14cdee3..54fc0c8 100644 --- a/lib/outlaw/rule.rb +++ b/lib/outlaw/rule.rb @@ -23,16 +23,27 @@ def detect_violation(code) end def apply_modifications(restore=nil) - return nil if restore.nil? - defaults = Outlaw.ignore_types - Outlaw.ignore_types.delete(WHITESPACE) if modifications - .include?(:whitespace_sensitive) - Outlaw.ignore_types = restore if restore - defaults + return nil if modifications.nil? && restore.nil? + default_ignores = Outlaw.ignore_types.clone + default_params = Outlaw.param_types.clone + if modifications.include?(:whitespace_sensitive) + WHITESPACE.each do |ws| + Outlaw.ignore_types.delete(ws) + Outlaw.param_types << ws + end + end + if modifications.include?(:vertical_whitespace_sensitive) + VERTICAL_WHITESPACE.each do |ws| + Outlaw.ignore_types.delete(ws) + Outlaw.param_types << ws + end + end + Outlaw.ignore_types = restore.first if restore + Outlaw.param_types = restore.last if restore + [default_ignores, default_params] end - - + public class << self def test(program, start_index, pattern) @@ -41,8 +52,8 @@ def test(program, start_index, pattern) start_index.upto(program.length) do |index| code = program[index] part = pattern[pattern_index] - - next if Outlaw.ignore_types.include? token_type(code) + return false if code.nil? + next if Outlaw.ignore_types.include?(token_type(code)) return false unless match_token?(code, part, params[part]) pattern_index +=1 return true if pattern_index >= pattern.length @@ -85,7 +96,7 @@ def match_token?(code, part, parameter) def param_type_equal(lex, param) #for now just check if it's a variable type, not kw, ws or other token - PARAM_TYPES.include? lex + Outlaw.param_types.include? lex end def token_type(code) diff --git a/test/outlaw_test.rb b/test/outlaw_test.rb index 9f5250c..f121f1a 100644 --- a/test/outlaw_test.rb +++ b/test/outlaw_test.rb @@ -2,7 +2,7 @@ module Outlaw describe LawParser do - it "returns a Rule which is violation?ed on code and returns true or false" do + it "returns a Rule which is called on code and returns true or false" do end before do @@ -17,6 +17,9 @@ module WithContent def sumthin class_eval('1 + 1') end + + def okishthing + end end } end @@ -142,6 +145,28 @@ class MyClass < Struct.new("Customer", :name, :address) result8a.must_equal false end + it "correctly builds whitespace sensitive rule" do + code9 = ":vertical_whitespace_sensitive end\ndef" + rule9 = Rule.new(code9) + + def_file = %{ + class Mine + def method + true + end + def method2 + false + end + end + } + + def_result = rule9.violation?(def_file) + result9a = rule9.violation?(@okay_file) + + def_result.must_equal true + result9a.must_equal false + end + it "returns a hash with key counts and nil placeholders" do params = Rule.send(:params_count_hash, [/module/, :token1, :token2, :token1, /class/, :token3, /end/]) params.keys.size.must_equal 3