From 1026a6408714727835e512e7cf12d2ec882ddd9e Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Sat, 6 Apr 2019 13:50:22 -0500 Subject: [PATCH] Fix rubocop except for parser metrics --- lib/dhall/ast.rb | 28 ++++++++---- lib/dhall/binary.rb | 18 ++------ lib/dhall/normalize.rb | 24 +++++------ lib/dhall/parser.rb | 36 +++++++--------- scripts/generate_citrus_parser.rb | 71 ++++++++++++++++++++----------- 5 files changed, 94 insertions(+), 83 deletions(-) diff --git a/lib/dhall/ast.rb b/lib/dhall/ast.rb index 722b058..eadb0c8 100644 --- a/lib/dhall/ast.rb +++ b/lib/dhall/ast.rb @@ -660,11 +660,8 @@ module Dhall def fetch(k, default=nil) if (type = alternatives.fetch(k)) - Function.new( - var: k, - type: type, - body: Union.from(self, k, Variable[k]) - ).normalize + body = Union.from(self, k, Variable[k]) + Function.new(var: k, type: type, body: body).normalize else Union.from(self, k, nil) end @@ -856,14 +853,13 @@ module Dhall def self.for(*chunks) fixed = - chunks + ([""] + chunks) .flat_map { |c| ["", c, ""] } .map { |c| c.is_a?(Expression) ? c : Text.new(value: c.to_s) } .chunk { |x| x.is_a?(Text) }.flat_map do |(is_text, group)| is_text ? group.reduce(&:<<) : group end - return Text.new(value: "") if fixed.empty? fixed.length == 1 ? fixed.first : new(chunks: fixed) end @@ -884,7 +880,7 @@ module Dhall def initialize(protocol=:nocheck, data=nil) super( protocol: protocol, - data: data + data: data ) end @@ -934,7 +930,7 @@ module Dhall hash.fetch(:headers), authority, *path, - query, + query ) end @@ -1055,6 +1051,12 @@ module Dhall "v" => "\v" }.freeze + def self.decode(var) + var.gsub(/\\[\"\\abfnrtv]/) do |escape| + ESCAPES.fetch(escape[1]) + end + end + def initialize(var) @var = var end @@ -1184,6 +1186,14 @@ module Dhall body Expression end) + def self.for(lets:, body:) + if lets.length == 1 + LetIn.new(let: lets.first, body: body) + else + new(lets: lets, body: body) + end + end + def unflatten lets.reverse.reduce(body) do |inside, let| letin = LetIn.new(let: let, body: inside) diff --git a/lib/dhall/binary.rb b/lib/dhall/binary.rb index a7f5c3d..f5d8e9b 100644 --- a/lib/dhall/binary.rb +++ b/lib/dhall/binary.rb @@ -145,9 +145,9 @@ module Dhall class UnionType def self.decode(record) - new(alternatives: Hash[record.map { |k, v| + new(alternatives: Hash[record.map do |k, v| [k, v.nil? ? v : Dhall.decode(v)] - }]) + end]) end end @@ -187,13 +187,7 @@ module Dhall class Import def self.decode(integrity_check, import_type, path_type, *parts) parts[0] = Dhall.decode(parts[0]) if path_type < 2 && !parts[0].nil? - if PATH_TYPES[path_type] == EnvironmentVariable - parts = parts.map do |part| - part.gsub(/\\[\"\\abfnrtv]/) do |escape| - EnvironmentVariable::ESCAPES.fetch(escape[1]) - end - end - end + parts[0] = EnvironmentVariable.decode(parts[0]) if path_type == 5 new( IntegrityCheck.new(*integrity_check), @@ -214,11 +208,7 @@ module Dhall ) end - if lets.length == 1 - LetIn.new(let: lets.first, body: body) - else - new(lets: lets, body: body) - end + self.for(lets: lets, body: body) end end diff --git a/lib/dhall/normalize.rb b/lib/dhall/normalize.rb index 419d7e7..0eed75b 100644 --- a/lib/dhall/normalize.rb +++ b/lib/dhall/normalize.rb @@ -6,16 +6,18 @@ require "dhall/util" module Dhall module ExpressionVisitor + ExpressionHash = Util::HashOf.new( + ValueSemantics::Anything, + ValueSemantics::Either.new([Expression, nil]) + ) + def self.new(&block) Visitor.new( - Expression => block, - Util::ArrayOf.new(Expression) => lambda do |x| + Expression => block, + Util::ArrayOf.new(Expression) => lambda do |x| x.map(&block) end, - Util::HashOf.new( - ValueSemantics::Anything, - ValueSemantics::Either.new([Expression, nil]) - ) => lambda do |x| + ExpressionHash => lambda do |x| Hash[x.map { |k, v| [k, v.nil? ? v : block[v]] }] end ) @@ -266,13 +268,9 @@ module Dhall def normalize normalized = super if normalized.record.is_a?(Record) && normalized.input.is_a?(Union) - if normalized.input.value.nil? - normalized.record.fetch(normalized.input.tag) - else - normalized.record.fetch(normalized.input.tag).call( - normalized.input.value - ) - end + fetched = normalized.record.fetch(normalized.input.tag) + value = normalized.input.value + value.nil? ? fetched : fetched.call(value) else normalized end diff --git a/lib/dhall/parser.rb b/lib/dhall/parser.rb index 33983a8..f8fb4d3 100644 --- a/lib/dhall/parser.rb +++ b/lib/dhall/parser.rb @@ -113,12 +113,9 @@ module Dhall Float::NAN else float = string.to_f - if float.nan? || float.infinite? - raise Citrus::ParseError, input - end + raise Citrus::ParseError, input if float.nan? || float.infinite? float - end - ) + end) end end @@ -128,9 +125,9 @@ module Dhall *captures(:double_quote_chunk) .map(&:value) .chunk { |s| s.is_a?(String) } - .flat_map { |(is_string, group)| + .flat_map do |(is_string, group)| is_string ? group.join : group - } + end ) end end @@ -152,9 +149,9 @@ module Dhall if first&.string == "\\" && matches[1].string =~ /\Au\h+\Z/i [matches[1].string[1..-1]].pack("H*").force_encoding("UTF-16BE") elsif first&.string == "\\" - ESCAPES.fetch(matches[1].string) do + ESCAPES.fetch(matches[1].string) { raise "Invalid escape: #{string}" - end.encode("UTF-16BE") + }.encode("UTF-16BE") elsif first&.string == "${" matches[1].value else @@ -187,7 +184,7 @@ module Dhall def value if matches.length == 2 [ESCAPES.fetch(first.string, first.string), matches[1].value] - elsif matches.length == 0 + elsif matches.empty? [] else [ @@ -359,14 +356,14 @@ module Dhall if keys.length == 1 capture(keys.first).value elsif captures.key?(:let) - lets = first.matches.map { |let_match| + lets = first.matches.map do |let_match| exprs = let_match.captures(:expression) Let.new( var: let_match.capture(:nonreserved_label).value, assign: exprs.last.value, - type: exprs.length > 1 ? exprs.first.value : nil, + type: exprs.length > 1 ? exprs.first.value : nil ) - } + end if lets.length == 1 LetIn.new(let: lets.first, body: matches.last.value) @@ -394,7 +391,7 @@ module Dhall If.new( predicate: captures(:expression)[0].value, then: captures(:expression)[1].value, - else: captures(:expression)[2].value, + else: captures(:expression)[2].value ) elsif captures.key?(:merge) Merge.new( @@ -438,7 +435,7 @@ module Dhall module Http SCHEME = { "http" => Dhall::Import::Http, - "https" => Dhall::Import::Https, + "https" => Dhall::Import::Https }.freeze def self.escape(s) @@ -452,10 +449,7 @@ module Dhall capture(:import_hashed).value(Dhall::Import::Expression) end, http.capture(:authority).value, - *http.capture(:path).captures(:path_component).map { |c| - # https://github.com/dhall-lang/dhall-lang/issues/456 - c.value # (Http.method(:escape)) - }, + *http.capture(:path).captures(:path_component).map(&:value), http.capture(:query)&.value ) end @@ -484,9 +478,9 @@ module Dhall def value if first&.string == "\\" - ESCAPES.fetch(matches[1].string) do + ESCAPES.fetch(matches[1].string) { raise "Invalid escape: #{string}" - end.encode("UTF-16BE") + }.encode("UTF-16BE") else string end diff --git a/scripts/generate_citrus_parser.rb b/scripts/generate_citrus_parser.rb index 44c83c3..b9a5a36 100644 --- a/scripts/generate_citrus_parser.rb +++ b/scripts/generate_citrus_parser.rb @@ -1,22 +1,33 @@ +# frozen_string_literal: true + require "abnf" require "dhall/parser" require "dhall/util" -class RegexpTree::CharClass - def encode_elt(e) - case e - when 0x09; '\t' - when 0x0a; '\n' - when 0x0d; '\r' - when 0x0c; '\f' - when 0x0b; '\v' - when 0x07; '\a' - when 0x1b; '\e' - when 0x21, 0x22, 0x25, 0x26, 0x27, 0x2c, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x2f, 0x30..0x39, 0x40, 0x41..0x5a, 0x5f, 0x60, 0x61..0x7a, 0x7e - sprintf("%c", e) - else - sprintf("\\u{%02x}", e) +class RegexpTree + class CharClass + MAP = { + 0x09 => '\t', + 0x0a => '\n', + 0x0d => '\r', + 0x0c => '\f', + 0x0b => '\v', + 0x07 => '\a', + 0x1b => '\e' + }.freeze + + def encode_elt(e) + MAP.fetch(e) do + case e + when 0x21, 0x22, 0x25, 0x26, 0x27, 0x2c, 0x3a, 0x3b, 0x3c, + 0x3d, 0x3e, 0x2f, 0x30..0x39, 0x40, 0x41..0x5a, 0x5f, + 0x60, 0x61..0x7a, 0x7e + "%c" % e + else + "\\u{%02x}" % e + end + end end end end @@ -37,7 +48,7 @@ class Sequence end def to_s - @seq.join(' ') + @seq.join(" ") end end @@ -98,37 +109,44 @@ class RuleFormatter formatted.is_a?(Terminal) ? formatted : "(#{formatted})" end + # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity + # rubocop:disable Metrics/MethodLength,Metrics/PerceivedComplexity def format_rule(name, rule) if name == :"simple-label" - return "keyword simple_label_next_char+ | !keyword (simple_label_first_char simple_label_next_char*)" + return "keyword simple_label_next_char+ | " \ + "!keyword (simple_label_first_char simple_label_next_char*)" end if name == :"nonreserved-label" - return "reserved_identifier simple_label_next_char+ | !reserved_identifier label" + return "reserved_identifier simple_label_next_char+ | " \ + "!reserved_identifier label" end case rule when ABNF::Term Terminal.new(@abnf.regexp(name)) when ABNF::Var - rule.name.to_s.gsub(/-/, '_') + rule.name.to_s.tr("-", "_") when ABNF::Seq if rule.elts.empty? '""' else - rule.elts.map(&method(:format_anon_rule)).chunk { |x| x.is_a?(Terminal) }.flat_map { |(terminal, chunk)| - terminal ? chunk.reduce(:+) : Sequence.new(chunk) - }.join(' ') + rule + .elts.map(&method(:format_anon_rule)) + .chunk { |x| x.is_a?(Terminal) } + .flat_map { |(terminal, chunk)| + terminal ? chunk.reduce(:+) : Sequence.new(chunk) + }.join(" ") end when ABNF::Alt - rule.elts.map(&method(:format_anon_rule)).join(' | ') + rule.elts.map(&method(:format_anon_rule)).join(" | ") when ABNF::Rep base = format_anon_rule(rule.elt) - if rule.min == 0 && rule.max.nil? + if rule.min.zero? && rule.max.nil? "#{base}*" elsif rule.min == 1 && rule.max.nil? "#{base}+" - elsif rule.min == 0 && rule.max == 1 + elsif rule.min.zero? && rule.max == 1 "#{base}?" else "#{base} #{rule.min}*#{rule.max}" @@ -136,8 +154,9 @@ class RuleFormatter else raise "Unknown rule type: #{rule.inspect}" end - end + # rubocop:enable Metrics/AbcSize,Metrics/CyclomaticComplexity + # rubocop:enable Metrics/MethodLength,Metrics/PerceivedComplexity end puts "grammar Dhall::Parser::CitrusParser" @@ -147,7 +166,7 @@ abnf = ABNF.parse(STDIN.read) formatter = RuleFormatter.new(abnf) abnf.each do |name, rule| next if name.to_s.start_with?("____") - puts "rule #{name.to_s.gsub(/-/, '_')}" + puts "rule #{name.to_s.tr("-", "_")}" print "\t(#{formatter.format_rule(name, rule)})" extension = name.to_s.split(/-/).map(&:capitalize).join if Dhall::Parser.const_defined?(extension) -- 2.34.5