Permalink
Browse files

WIP: untested but theoretically close disjoint_code capability

  • Loading branch information...
1 parent 5a100f9 commit f70ff4ec9c60e5a3c9d15ec04b8847370c9ab62c Brian Glusman committed Oct 17, 2012
Showing with 63 additions and 10 deletions.
  1. +4 −3 examples/.outlawed.example
  2. +3 −1 lib/outlaw.rb
  3. +12 −4 lib/outlaw/law_parser.rb
  4. +36 −2 lib/outlaw/rule.rb
  5. +8 −0 lib/outlaw/rule_methods.rb
View
7 examples/.outlawed.example
@@ -1,6 +1,7 @@
outlaw "@@", "class variables are evil"
outlaw "protected", "use private or public, protected is silly in ruby"
outlaw "module :token end", "nest modules to avoid empty module declarations"
- outlaw "eval", "never eval, rarely class_eval or instance_eval, but never eval"
- outlaw "class :symbol < :core_class", "core classes implemented in c, can cause bad mojo"
- outlaw :trailing_whitespace
+ outlaw "eval", "never eval, rarely class_eval or instance_eval, but never eval"
+ outlaw "class :symbol < :core_class", "core classes implemented in c, can cause bad mojo"
+ outlaw :trailing_whitespace
+ outlaw :touching_methods
View
4 lib/outlaw.rb
@@ -27,7 +27,9 @@ def enforce(dir=".")
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]
+ RULE_CASES = [:whitespace_sensitive, :vertical_whitespace_sensitive]
+ FUNCTION_CASES = [:disjoint_code_seperator]
+ SPECIAL_CASES = RULE_CASES + FUNCTION_CASES
CORE_CLASSES_FILE = File.expand_path("../../data/core_classes.txt", __FILE__)
CORE_CLASS = File.readlines(CORE_CLASSES_FILE).map &:chomp
View
16 lib/outlaw/law_parser.rb
@@ -7,7 +7,7 @@ def parse(restriction, rule)
tokens.each do |token|
case
when special_case?(string_to_sym(token))
- handle_special(token, rule)
+ handle_special(token, rule, parsed_restriction)
when multipart?(token) #this handles multi-token literals, Const.new etc
parsed_restriction += Ripper.lex(token)
.reduce([]){|array, tkn|
@@ -25,9 +25,16 @@ def parse(restriction, rule)
private
- def handle_special(token, rule)
- rule.modifications ||= []
- rule.modifications << string_to_sym(token)
+ def handle_special(token, rule, parsed_restriction)
+ case token
+ when *RULE_CASES
+ rule.modifications ||= []
+ rule.modifications << string_to_sym(token)
+ when *FUNCTION_CASES
+ parsed_restriction << lambda ->(*args) do
+ rule.send(token, *args) #actually required to take 3 arguments
+ end
+ end
end
def special_case?(token)
@@ -60,6 +67,7 @@ def multipart?(token)
end
def build_block(pattern)
+ raise "starting rule with special case not yet supported" if special_case?(pattern.first)
->(file) do
program = Ripper.tokenize(file)
program.each_with_index do |token, index|
View
38 lib/outlaw/rule.rb
@@ -38,6 +38,7 @@ def apply_modifications(restore=nil)
Outlaw.param_types << ws
end
end
+
Outlaw.ignore_types = restore.first if restore
Outlaw.param_types = restore.last if restore
[default_ignores, default_params]
@@ -49,22 +50,55 @@ class << self
def test(program, start_index, pattern)
pattern_index = 0
params = params_count_hash(pattern)
- start_index.upto(program.length) do |index|
+ index = start_index
+ while index < program.length do
code = program[index]
part = pattern[pattern_index]
return false if code.nil?
- next if Outlaw.ignore_types.include?(token_type(code))
+ (index += 1 && next) if Outlaw.ignore_types.include?(token_type(code))
+ if part.kind_of?(Proc)
+ return false unless part.call(pattern[pattern_index+1], program, index)
+ next #^require all function cases must take these 3 arguments
+ end
return false unless match_token?(code, part, params[part])
pattern_index +=1
return true if pattern_index >= pattern.length
+ index +=1
end
return false
# got to end of program without completing pattern
end
+ def disjoint_code_seperator(token, program, index)
+ while program[index] != token && !block_start_tokens.include?(program[index])
+ index += 1
+ return nil if index >= program.length
+ end
+ return true if program[index] == token
+ disjoint_code_seperator(end_token_for(program[index])) if block_start_tokens.include?(program[index])
+ return disjoint_code_seperator(token, program, index)
+ end
+
private
+ def block_start_tokens
+ block_hash.keys
+ end
+
+ def end_token_for(key)
+ block_hash[key]
+ end
+
+ def block_hash
+ {
+ :on_lparen => :on_rparen,
+ :on_lbrace => :on_rbrace,
+ :on_lbracket=> :on_rbracket,
+ :on_kw => :on_kw,
+ }
+ end
+
def match_token?(code, part, parameter)
case part
when Array
View
8 lib/outlaw/rule_methods.rb
@@ -5,4 +5,12 @@ def trailing_whitespace
file.match(/ \n/)
end
end
+
+ def touching_methods
+ Rule.new("Touching methods",
+ "Method definitions should have a blank line between end and next def") do |file|
+ file.match(/\bend\b.*\n.*\bdef\b/)
+ end
+ end
+
end

0 comments on commit f70ff4e

Please sign in to comment.