faml 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9f188aeb028e6438b455033f6f2efe701297ad13
4
- data.tar.gz: cac035f6c7671aef877c83ff47d7e772941b2d1a
3
+ metadata.gz: c643b558a5d6ef910d8545a6be0501d258c730ea
4
+ data.tar.gz: 35de29c371d213c3291c3a3c0f5816b3d9638285
5
5
  SHA512:
6
- metadata.gz: 0e9c2a21ca2ad84c4cb9c219bfbf971c11e85bc07fa02910a177a9f081a82a18ea37a9e4b0ecf900f84150eb41f369f65ed14c1b6b5c3ea8dc5791500c9da58e
7
- data.tar.gz: 2f0873cb28c9d275e2c11ca00d2ff3b0ca3d37d794ab2c76c747eaf82cd8f780a7dc376f615dccbaf736f8a6e32c510516c790002e544fed70d0696bb260d961
6
+ metadata.gz: 5cebe334bdd49fb358a07f2004df19eb9542d4d215be3197b1bd52c45a035e646b5375084e009031669a7e40908d653bb29eb186f263cabee3211a18b419671d
7
+ data.tar.gz: 028cadedad4e8cbbafcb7e62896b2389e40f3c2f18c42bedbc48f1818b5cadfa90d6db8a04af01d8ca9ccdecfeb3d6e873d959008470d0f5d86dad7d91a4c8fb
data/.rubocop.yml CHANGED
@@ -11,31 +11,43 @@ Lint/HandleExceptions:
11
11
  - 'lib/faml/tilt.rb'
12
12
  Lint/Eval:
13
13
  Exclude:
14
- - 'lib/faml/static_hash_parser.rb'
15
14
  - 'spec/spec_helper.rb'
16
15
 
17
16
  Style/BarePercentLiterals:
18
17
  EnforcedStyle: percent_q
18
+
19
19
  Style/CaseEquality:
20
20
  Enabled: false
21
+
22
+ Style/FormatString:
23
+ EnforcedStyle: sprintf
24
+
21
25
  Style/GlobalVars:
22
26
  Exclude:
23
27
  - '**/extconf.rb'
28
+
24
29
  Style/GuardClause:
25
30
  Enabled: false
31
+
26
32
  Style/HashSyntax:
27
33
  Exclude:
28
34
  - 'Rakefile'
35
+
29
36
  Style/IfUnlessModifier:
30
37
  Enabled: false
38
+
31
39
  Style/PercentLiteralDelimiters:
32
40
  Enabled: false
41
+
33
42
  Style/RaiseArgs:
34
43
  EnforcedStyle: compact
44
+
35
45
  Style/SignalException:
36
46
  Enabled: false
47
+
37
48
  Style/TrailingComma:
38
49
  Enabled: false
50
+
39
51
  Style/TrailingWhitespace:
40
52
  Exclude:
41
53
  - 'spec/render/multiline_spec.rb'
data/.rubocop_todo.yml CHANGED
@@ -1,43 +1,23 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2015-10-06 23:31:05 +0900 using RuboCop version 0.34.2.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
8
-
9
- # Offense count: 17
10
1
  Metrics/AbcSize:
11
- Max: 32
2
+ Enabled: false
12
3
 
13
- # Offense count: 1
14
4
  Metrics/BlockNesting:
15
- Max: 4
5
+ Enabled: false
16
6
 
17
- # Offense count: 4
18
- # Configuration parameters: CountComments.
19
7
  Metrics/ClassLength:
20
- Max: 341
8
+ Enabled: false
21
9
 
22
- # Offense count: 7
23
10
  Metrics/CyclomaticComplexity:
24
- Max: 12
11
+ Enabled: false
25
12
 
26
- # Offense count: 214
27
- # Configuration parameters: AllowURI, URISchemes.
28
13
  Metrics/LineLength:
29
- Max: 199
14
+ Enabled: false
30
15
 
31
- # Offense count: 20
32
- # Configuration parameters: CountComments.
33
16
  Metrics/MethodLength:
34
- Max: 29
17
+ Enabled: false
35
18
 
36
- # Offense count: 5
37
19
  Metrics/PerceivedComplexity:
38
- Max: 13
20
+ Enabled: false
39
21
 
40
- # Offense count: 45
41
- # Configuration parameters: Exclude.
42
22
  Style/Documentation:
43
23
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.3.4 (2015-10-19)
2
+ - Support array, rational and complex literal optimization
3
+ - Now `%div{class: %w[foo bar], data: { foo: 1i, bar: 2r }}` is compiled into string literal.
4
+ - Remove `Kernel#eval` from compiler
5
+ - Improve `faml stats` subcommand
6
+ - Show more detailed attribute information
7
+ - Fix several bugs
8
+
1
9
  ## 0.3.3 (2015-10-07)
2
10
  - Improve `Faml::AttributeBuilder.build` performance
3
11
  - Optimize string conversions
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'bundler/gem_tasks'
2
2
 
3
- task :default => [:compile, :spec]
3
+ task :default => [:compile, :spec, :rubocop]
4
4
 
5
5
  require 'rake/extensiontask'
6
6
  Rake::ExtensionTask.new('attribute_builder') do |ext|
@@ -10,6 +10,9 @@ end
10
10
  require 'rspec/core/rake_task'
11
11
  RSpec::Core::RakeTask.new(:spec)
12
12
 
13
+ require 'rubocop/rake_task'
14
+ RuboCop::RakeTask.new(:rubocop)
15
+
13
16
  task :benchmark => ['benchmark:rendering', 'benchmark:compiling']
14
17
 
15
18
  namespace :benchmark do
@@ -10,6 +10,8 @@
10
10
  # define rb_ary_new_capa rb_ary_new2
11
11
  #endif
12
12
 
13
+ #define FOREACH_FUNC(func) ((int (*)(ANYARGS))(func))
14
+
13
15
  VALUE rb_mAttributeBuilder;
14
16
  static ID id_keys, id_sort_bang, id_uniq_bang, id_merge_bang;
15
17
  static ID id_id, id_class, id_underscore, id_hyphen, id_space, id_equal;
@@ -43,7 +45,7 @@ static VALUE
43
45
  stringify_keys(VALUE hash)
44
46
  {
45
47
  VALUE h = rb_hash_new();
46
- rb_hash_foreach(hash, stringify_keys_i, h);
48
+ rb_hash_foreach(hash, FOREACH_FUNC(stringify_keys_i), h);
47
49
  return h;
48
50
  }
49
51
 
@@ -101,7 +103,7 @@ normalize_data_i(VALUE key, VALUE value, VALUE normalized)
101
103
  struct normalize_data_i2_arg arg;
102
104
  arg.key = key;
103
105
  arg.normalized = normalized;
104
- rb_hash_foreach(normalize_data(value), normalize_data_i2, (VALUE)(&arg));
106
+ rb_hash_foreach(normalize_data(value), FOREACH_FUNC(normalize_data_i2), (VALUE)(&arg));
105
107
  } else if (RB_TYPE_P(value, T_TRUE)) {
106
108
  /* Keep Qtrue value */
107
109
  rb_hash_aset(normalized, key, value);
@@ -120,7 +122,7 @@ normalize_data(VALUE data)
120
122
 
121
123
  Check_Type(data, T_HASH);
122
124
  normalized = rb_hash_new();
123
- rb_hash_foreach(data, normalize_data_i, normalized);
125
+ rb_hash_foreach(data, FOREACH_FUNC(normalize_data_i), normalized);
124
126
  return normalized;
125
127
  }
126
128
 
@@ -151,7 +153,7 @@ normalize(VALUE hash)
151
153
 
152
154
  rb_hash_delete(hash, key);
153
155
  data = normalize_data(value);
154
- rb_hash_foreach(data, put_data_attribute, hash);
156
+ rb_hash_foreach(data, FOREACH_FUNC(put_data_attribute), hash);
155
157
  } else if (RB_TYPE_P(value, T_TRUE)) {
156
158
  /* Keep Qtrue value */
157
159
  } else if (RB_TYPE_P(value, T_FALSE) || NIL_P(value)) {
@@ -1,7 +1,7 @@
1
1
  # Incompatibilities
2
2
  ## Versions
3
3
  - Haml 4.0.7
4
- - Faml 0.3.2
4
+ - Faml 0.3.3
5
5
  - Hamlit 1.7.2
6
6
 
7
7
  ## Table of contents
@@ -15,6 +15,7 @@
15
15
  - [spec/render/filters/escaped_spec.md](spec/render/filters/escaped_spec.md) (Hamlit's incompatibility)
16
16
  - [spec/render/filters/javascript_spec.md](spec/render/filters/javascript_spec.md)
17
17
  - [spec/render/filters/markdown_spec.md](spec/render/filters/markdown_spec.md)
18
+ - [spec/render/filters/plain_spec.md](spec/render/filters/plain_spec.md)
18
19
  - [spec/render/filters/preserve_spec.md](spec/render/filters/preserve_spec.md) (Hamlit's incompatibility)
19
20
  - [spec/render/helpers_spec.md](spec/render/helpers_spec.md) (Hamlit's incompatibility)
20
21
  - [spec/render/multiline_spec.md](spec/render/multiline_spec.md) (Hamlit's incompatibility)
@@ -0,0 +1,78 @@
1
+ # [./spec/render/filters/plain_spec.rb:4](../../../../spec/render/filters/plain_spec.rb#L4)
2
+ ## Input
3
+ ```haml
4
+ %span
5
+ :plain
6
+ he#{'llo'}
7
+ %span world
8
+
9
+ ```
10
+
11
+ ## Faml
12
+ ```html
13
+ <span>
14
+ hello
15
+ <span>world</span>
16
+ </span>
17
+
18
+ ```
19
+
20
+ ## Haml, Hamlit
21
+ ```html
22
+ <span>
23
+ hello
24
+
25
+ <span>world</span>
26
+ </span>
27
+
28
+ ```
29
+
30
+ # [./spec/render/filters/plain_spec.rb:13](../../../../spec/render/filters/plain_spec.rb#L13)
31
+ ## Input
32
+ ```haml
33
+ %span
34
+ :plain
35
+ he#{'llo'}
36
+
37
+ abc
38
+
39
+ %span world
40
+
41
+ ```
42
+
43
+ ## Faml
44
+ ```html
45
+ <span>
46
+ hello
47
+
48
+ abc
49
+ <span>world</span>
50
+ </span>
51
+
52
+ ```
53
+
54
+ ## Haml
55
+ ```html
56
+ <span>
57
+ hello
58
+
59
+ abc
60
+
61
+
62
+ <span>world</span>
63
+ </span>
64
+
65
+ ```
66
+
67
+ ## Hamlit
68
+ ```html
69
+ <span>
70
+ hello
71
+
72
+ abc
73
+
74
+ <span>world</span>
75
+ </span>
76
+
77
+ ```
78
+
data/lib/faml/compiler.rb CHANGED
@@ -318,13 +318,23 @@ module Faml
318
318
  parser.static_attributes.each do |k, v|
319
319
  static_attributes[k.to_s] = v
320
320
  end
321
+
322
+ class_list = Array(static_attributes['class']).flat_map { |c| c.to_s.split(/ +/) }
321
323
  unless static_class.empty?
322
- class_list = static_attributes.fetch('class', '').to_s.split(/ +/)
323
- static_attributes['class'] = static_class.split(/ +/).concat(class_list).uniq.sort.join(' ')
324
+ class_list.concat(static_class.split(/ +/))
325
+ end
326
+ unless class_list.empty?
327
+ static_attributes['class'] = class_list.uniq.sort.join(' ')
324
328
  end
329
+
330
+ id_list = Array(static_attributes['id'])
325
331
  unless static_id.empty?
326
- static_attributes['id'] = [static_id, static_attributes['id']].compact.join('_')
332
+ id_list = [static_id].concat(id_list)
327
333
  end
334
+ unless id_list.empty?
335
+ static_attributes['id'] = id_list.join('_')
336
+ end
337
+
328
338
  static_attributes
329
339
  end
330
340
 
@@ -58,35 +58,23 @@ module Faml
58
58
  end
59
59
  end
60
60
 
61
- SYMBOL_FIRST_CHARS = [
62
- ':', # { :'foo' => 'bar' } or { :"foo" => 'bar' }
63
- "'", # { 'foo': 'bar' }
64
- '"', # { "foo": 'bar' }
65
- ].freeze
66
-
67
- def eval_symbol(code)
68
- if SYMBOL_FIRST_CHARS.include?(code[0])
69
- eval(code).to_sym
70
- else
71
- code.to_sym
72
- end
73
- end
74
-
75
61
  def try_static_key(node)
76
62
  case node.type
77
- when :sym
78
- eval_symbol(node.location.expression.source)
79
- when :int, :float, :str
80
- eval(node.location.expression.source)
63
+ when :sym, :int, :float, :str, :rational, :complex
64
+ node.children[0]
81
65
  end
82
66
  end
83
67
 
84
68
  def try_static_value(key_static, node)
85
69
  case node.type
86
- when :sym
87
- @static_attributes[key_static] = eval_symbol(node.location.expression.source)
88
- when :true, :false, :nil, :int, :float, :str
89
- @static_attributes[key_static] = eval(node.location.expression.source)
70
+ when :sym, :int, :float, :str, :rational, :complex
71
+ @static_attributes[key_static] = node.children[0]
72
+ when :true
73
+ @static_attributes[key_static] = true
74
+ when :false
75
+ @static_attributes[key_static] = false
76
+ when :nil
77
+ @static_attributes[key_static] = nil
90
78
  when :dstr
91
79
  @dynamic_attributes[key_static] = node.location.expression.source
92
80
  when :send
@@ -97,7 +85,8 @@ module Faml
97
85
  end
98
86
  when :hash
99
87
  try_static_hash_value(key_static, node)
100
- # TODO: Add array case
88
+ when :array
89
+ try_static_array_value(key_static, node)
101
90
  else
102
91
  throw FAILURE_TAG
103
92
  end
@@ -125,5 +114,12 @@ module Faml
125
114
  @dynamic_attributes[key_static] = "{#{expr}}"
126
115
  end
127
116
  end
117
+
118
+ def try_static_array_value(key_static, node)
119
+ arr = node.children.map do |child|
120
+ try_static_value(key_static, child)
121
+ end
122
+ @static_attributes[key_static] = arr
123
+ end
128
124
  end
129
125
  end
data/lib/faml/stats.rb CHANGED
@@ -8,10 +8,12 @@ module Faml
8
8
  Info = Struct.new(
9
9
  :empty_attribute_count,
10
10
  :static_attribute_count,
11
+ :static_id_or_class_attribute_count,
11
12
  :dynamic_attribute_count,
12
13
  :dynamic_attribute_with_data_count,
13
14
  :dynamic_attribute_with_newline_count,
14
15
  :ruby_attribute_count,
16
+ :multi_attribute_count,
15
17
  :ast_types
16
18
  ) do
17
19
  def initialize(*)
@@ -101,7 +103,7 @@ module Faml
101
103
  if ast.static_class.empty? && ast.static_id.empty?
102
104
  info.empty_attribute_count += 1
103
105
  else
104
- info.static_attribute_count += 1
106
+ info.static_id_or_class_attribute_count += 1
105
107
  end
106
108
  else
107
109
  static_hash_parser = StaticHashParser.new
@@ -109,7 +111,7 @@ module Faml
109
111
  if static_hash_parser.dynamic_attributes.empty?
110
112
  info.static_attribute_count += 1
111
113
  else
112
- if static_hash_parser.dynamic_attributes.key?('data')
114
+ if static_hash_parser.dynamic_attributes.key?('data') || static_hash_parser.dynamic_attributes.key?(:data)
113
115
  info.dynamic_attribute_with_data_count += 1
114
116
  elsif ast.attributes.include?("\n")
115
117
  info.dynamic_attribute_with_newline_count += 1
@@ -118,7 +120,12 @@ module Faml
118
120
  end
119
121
  end
120
122
  else
121
- info.ruby_attribute_count += 1
123
+ call_ast = Parser::CurrentRuby.parse("call(#{ast.attributes})")
124
+ if call_ast.type == :send && call_ast.children[0].nil? && call_ast.children[1] == :call && !call_ast.children[3].nil?
125
+ info.multi_attribute_count += 1
126
+ else
127
+ info.ruby_attribute_count += 1
128
+ end
122
129
  end
123
130
  end
124
131
  end
@@ -126,14 +133,17 @@ module Faml
126
133
  def report_attribute_stats(info)
127
134
  static = info.static_attribute_count
128
135
  dynamic = info.dynamic_attribute_count + info.dynamic_attribute_with_data_count + info.dynamic_attribute_with_newline_count
129
- ruby = info.ruby_attribute_count
136
+ ruby = info.ruby_attribute_count + info.multi_attribute_count
130
137
  total = static + dynamic + ruby
131
138
  puts 'Attribute stats'
139
+ printf(" Empty attributes: %d\n", info.empty_attribute_count)
140
+ printf(" Attributes with id or class only: %d\n", info.static_id_or_class_attribute_count)
132
141
  printf(" Static attributes: %d (%.2f%%)\n", static, static * 100.0 / total)
133
142
  printf(" Dynamic attributes: %d (%.2f%%)\n", dynamic, dynamic * 100.0 / total)
134
143
  printf(" with data: %d\n", info.dynamic_attribute_with_data_count)
135
144
  printf(" with newline: %d\n", info.dynamic_attribute_with_newline_count)
136
145
  printf(" Ruby attributes: %d (%.2f%%)\n", ruby, ruby * 100.0 / total)
146
+ printf(" with multiple arguments: %d\n", info.multi_attribute_count)
137
147
  end
138
148
 
139
149
  def report_ast_stats(info)
data/lib/faml/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Faml
2
- VERSION = '0.3.3'
2
+ VERSION = '0.3.4'
3
3
  end
@@ -30,7 +30,7 @@ RSpec.describe 'Attributes rendering', type: :render do
30
30
 
31
31
  it 'renders array class' do
32
32
  expect(render_string('%span.c2{class: "c1"}')).to eq("<span class='c1 c2'></span>\n")
33
- expect(render_string('%span.c2{class: ["c1", "c3"]}')).to eq("<span class='c1 c2 c3'></span>\n")
33
+ expect(render_string('%span.c2{class: ["c1", "c3", :c2]}')).to eq("<span class='c1 c2 c3'></span>\n")
34
34
  end
35
35
 
36
36
  it 'renders boolean attributes' do
@@ -119,6 +119,7 @@ HAML
119
119
 
120
120
  it 'merges static id' do
121
121
  expect(render_string('#foo{id: "bar"} baz')).to eq("<div id='foo_bar'>baz</div>\n")
122
+ expect(render_string('#foo{id: %w[bar baz]} hoge')).to eq("<div id='foo_bar_baz'>hoge</div>\n")
122
123
  end
123
124
 
124
125
  it 'merges static class' do
@@ -72,7 +72,7 @@ class IncompatibilitiesGenerator
72
72
  obj = Object.new
73
73
  Haml::Engine.new(template, { ugly: true, escape_html: true }.merge(options)).def_method(obj, :haml)
74
74
  obj.haml
75
- rescue => e
75
+ rescue StandardError, SyntaxError => e
76
76
  e
77
77
  end
78
78
 
@@ -80,7 +80,7 @@ class IncompatibilitiesGenerator
80
80
  obj = Object.new
81
81
  obj.instance_eval "def hamlit; #{Hamlit::Engine.new(options).call(template)}; end"
82
82
  obj.hamlit
83
- rescue => e
83
+ rescue StandardError, SyntaxError => e
84
84
  e
85
85
  end
86
86
 
@@ -110,7 +110,7 @@ EOS
110
110
  file.write <<"EOS"
111
111
  ## #{render_section(title, result)}
112
112
  ```html
113
- #{result}
113
+ #{render_body(result)}
114
114
  ```
115
115
 
116
116
  EOS
@@ -125,6 +125,22 @@ EOS
125
125
  end
126
126
  end
127
127
 
128
+ def render_body(result)
129
+ if result.is_a?(Exception)
130
+ result
131
+ else
132
+ result.gsub(/[[:cntrl:]]/) do |m|
133
+ n = m[0].ord
134
+ if n == 0x0a
135
+ # Print NL character as is
136
+ m[0]
137
+ else
138
+ "<0x#{sprintf('%02X', n)}>"
139
+ end
140
+ end
141
+ end
142
+ end
143
+
128
144
  def markdown_path(markdown_root, spec_path)
129
145
  markdown_root.join(spec_path).sub_ext('.md')
130
146
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kohei Suzuki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-06 00:00:00.000000000 Z
11
+ date: 2015-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: escape_utils
@@ -339,6 +339,7 @@ files:
339
339
  - incompatibilities/spec/render/filters/escaped_spec.md
340
340
  - incompatibilities/spec/render/filters/javascript_spec.md
341
341
  - incompatibilities/spec/render/filters/markdown_spec.md
342
+ - incompatibilities/spec/render/filters/plain_spec.md
342
343
  - incompatibilities/spec/render/filters/preserve_spec.md
343
344
  - incompatibilities/spec/render/helpers_spec.md
344
345
  - incompatibilities/spec/render/indent_spec.md
@@ -526,6 +527,7 @@ test_files:
526
527
  - incompatibilities/spec/render/filters/escaped_spec.md
527
528
  - incompatibilities/spec/render/filters/javascript_spec.md
528
529
  - incompatibilities/spec/render/filters/markdown_spec.md
530
+ - incompatibilities/spec/render/filters/plain_spec.md
529
531
  - incompatibilities/spec/render/filters/preserve_spec.md
530
532
  - incompatibilities/spec/render/helpers_spec.md
531
533
  - incompatibilities/spec/render/indent_spec.md