klenod-build 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a05a70d821a5b94964b4bade32066b9fd1bdade13d2b3899becdeb46d3d33ef
4
- data.tar.gz: 68ac76064521f6ca7678d51256672d5ea9161814215bf4c9e3b5a3f743350bc8
3
+ metadata.gz: 3f6f0bd5e9b747b26e394d5c041f30ce22aa9436f8483689172c48ae2219af1b
4
+ data.tar.gz: 8a11818a46097229cab6c5c2f94515306f9f989c7b2c49eefcb045b46e68a3a8
5
5
  SHA512:
6
- metadata.gz: 440df52a915ecb0b8312622268b94d413c3447d80912ef42a797a959aaadca42ec3c108a08439d79eb7cf9fff0d7baf4a5425e565d087b4f6b18efee84d0f2df
7
- data.tar.gz: 1ddb4e48b0156a21160fa3d93f855ab657bc4ed40d323e5f3d2f6bbd9dc3d27b36c093ec9731b1eeb791a4b601499721ce89665c23c84be4ad57c02c84491d9f
6
+ metadata.gz: f10d5c296da38e42bfd54e37366dd28e834bbb21b2ed455ea0ab1b325eb4e43ca2e8dc41b0e0d30b6709db8563441573ed5132a9d85ef1f81d8287459a9c40a0
7
+ data.tar.gz: ed6f70303f40f60b71147980de86b84482106407d927ac7aa248efccb92c2ee83cff94fdf0baa382e2e18229460e526cad265679383d27b8d80aa2ce8106edde
@@ -28,9 +28,9 @@ module Klenod
28
28
  end
29
29
  end
30
30
 
31
- def initialize(profiler: nil, global_variables: nil)
31
+ def initialize(profiler: nil, variables: nil)
32
32
  @profiler = profiler
33
- @global_variables = global_variables
33
+ @variables = variables || {}
34
34
  @expression_cache = {}
35
35
  @statements_cache = {}
36
36
  @program_cache = {}
@@ -411,6 +411,12 @@ module Klenod
411
411
  source_factory_call(factory: factory, tag: tag, children: children, props: props, mark: mark)
412
412
  end
413
413
 
414
+ def component_factory_call(factory:, tag:, children:, props:, mark: nil)
415
+ call = source_factory_call(factory: factory, tag: tag, children: [], props: props, mark: mark)
416
+ body = Fragment.new("[#{children.map { |child| argument_source(child) }.join(", ")}]", nil)
417
+ script_block("#{call.source} do", body)
418
+ end
419
+
414
420
  def slot_call(name:, fallback:)
415
421
  arguments = ["self", name ? argument_source(name) : "nil"]
416
422
  arguments << argument_source(fallback) if fallback
@@ -505,7 +511,7 @@ module Klenod
505
511
 
506
512
  def rewrite_ruby_source(source, line_no)
507
513
  source = rewrite_line_constant(source, line_no)
508
- rewrite_global_variables(source)
514
+ rewrite_variables(source)
509
515
  end
510
516
 
511
517
  def rewrite_line_constant(source, line_no)
@@ -527,25 +533,33 @@ module Klenod
527
533
  end
528
534
  end
529
535
 
530
- def rewrite_global_variables(source)
531
- return source unless @global_variables
536
+ VARIABLE_TOKEN_KINDS = {
537
+ on_gvar: [:global, "$", /\A\$[a-z]\w*\z/],
538
+ on_cvar: [:class, "@@", /\A@@[a-z]\w*\z/],
539
+ on_ivar: [:instance, "@", /\A@[a-z]\w*\z/]
540
+ }.freeze
541
+
542
+ def rewrite_variables(source)
543
+ return source if @variables.empty?
532
544
 
533
545
  line_offsets = [0]
534
546
  source.each_line(chomp: false) { |line| line_offsets << line_offsets.last + line.length }
535
547
 
536
548
  Ripper
537
549
  .lex(source)
538
- .select { |(_line, _column), type, token, _state| type == :on_gvar && prop_global_variable?(token) }
539
- .reverse_each
540
- .each_with_object(source.dup) do |((line, column), _type, token, _state), rewritten|
541
- name = token.delete_prefix("$")
550
+ .filter_map do |(line, column), type, token, _state|
551
+ kind, prefix, pattern = VARIABLE_TOKEN_KINDS[type]
552
+ receiver = @variables[kind]
553
+ next unless receiver && token.match?(pattern)
554
+
555
+ name = token.delete_prefix(prefix)
542
556
  offset = line_offsets.fetch(line - 1) + column
543
- rewritten[offset, token.length] = "#{@global_variables}[#{symbol_source(name)}]"
557
+ [offset, token.length, "(#{receiver})[#{symbol_source(name)}]"]
558
+ end
559
+ .reverse_each
560
+ .each_with_object(source.dup) do |(offset, length, replacement), rewritten|
561
+ rewritten[offset, length] = replacement
544
562
  end
545
- end
546
-
547
- def prop_global_variable?(token)
548
- token.match?(/\A\$[a-z]\w*\z/)
549
563
  end
550
564
 
551
565
  def source_expressions(expressions)
@@ -36,27 +36,31 @@ module Klenod
36
36
  factory:,
37
37
  styles_source:,
38
38
  translations_source:,
39
+ component_children: :eager,
39
40
  i18n_source: nil,
40
41
  styleable: false,
41
42
  profiler: nil,
42
43
  import_rewriter: nil,
43
44
  markdown_components_source: "{}",
44
- global_variables: nil,
45
+ variables: nil,
45
46
  haml_helper_source: nil,
46
47
  cache_static_subtrees: false
47
48
  )
48
49
  component_base_class = ConstPath.parse(component_base_class, name: "component_base_class")
49
50
  factory = ConstPath.parse(factory, name: "factory")
50
- builder = RubyBuilder.new(profiler: profiler, global_variables: global_variables)
51
+ validate_component_children(component_children)
52
+ builder = RubyBuilder.new(profiler: profiler, variables: variables)
51
53
  haml_helper_source ||= builder.constant_assignment("HamlHelper", "Object") if styleable || cache_static_subtrees
52
54
  previous_profiler = @profiler
53
55
  previous_module_id = @module_id
54
56
  previous_static_constants = @static_constants
55
57
  previous_cache_static_subtrees = @cache_static_subtrees
58
+ previous_component_children = @component_children
56
59
  @profiler = profiler
57
60
  @module_id = module_id
58
61
  @static_constants = []
59
62
  @cache_static_subtrees = cache_static_subtrees
63
+ @component_children = component_children
60
64
  template =
61
65
  if profiler
62
66
  profiler.measure(:haml_compile_template, module_id: module_id.to_s) do
@@ -131,12 +135,19 @@ module Klenod
131
135
  @module_id = previous_module_id
132
136
  @static_constants = previous_static_constants
133
137
  @cache_static_subtrees = previous_cache_static_subtrees
138
+ @component_children = previous_component_children
134
139
  end
135
140
 
136
141
  private
137
142
 
138
143
  Template = Data.define(:ruby, :render, :static_constants)
139
144
 
145
+ def validate_component_children(value)
146
+ return if HamlPlugin::COMPONENT_CHILDREN_MODES.include?(value)
147
+
148
+ raise ArgumentError, "component_children must be one of: #{HamlPlugin::COMPONENT_CHILDREN_MODES.join(", ")}"
149
+ end
150
+
140
151
  def measure_compile(name)
141
152
  return yield unless @profiler
142
153
 
@@ -456,13 +467,17 @@ module Klenod
456
467
  tag = measure_compile_detail(:haml_compile_tag_name) { compile_tag_name(node, builder: builder) }
457
468
  props = measure_compile_detail(:haml_compile_tag_attributes) { attributes(node, styleable: styleable, builder: builder) }
458
469
 
459
- builder.factory_call(
460
- factory: factory,
461
- tag: tag,
462
- children: children,
463
- props: props,
464
- mark: mark
465
- )
470
+ if @component_children == :lazy && constant_tag_name?(node.value.fetch(:name)) && !children.empty?
471
+ builder.component_factory_call(factory: factory, tag: tag, children: children, props: props, mark: mark)
472
+ else
473
+ builder.factory_call(
474
+ factory: factory,
475
+ tag: tag,
476
+ children: children,
477
+ props: props,
478
+ mark: mark
479
+ )
480
+ end
466
481
  end
467
482
 
468
483
  def compile_tag_name(node, builder:)
@@ -28,6 +28,8 @@ module Klenod
28
28
 
29
29
  DEFAULT_COMPONENT_BASE_CLASS = ComponentDefaults::DEFAULT_COMPONENT_BASE_CLASS
30
30
  DEFAULT_FACTORY = ComponentDefaults::DEFAULT_FACTORY
31
+ DEFAULT_COMPONENT_CHILDREN = :eager
32
+ COMPONENT_CHILDREN_MODES = %i[eager lazy].freeze
31
33
  HAML_HELPER_SPECIFIER = "virtual:klenod/haml_helper"
32
34
  HAML_HELPER_MODULE_ID = ModuleId.new("#{HAML_HELPER_SPECIFIER}.rb", nil)
33
35
  STATIC_CLASS_SOURCE_PATTERN = /^[ \t]*(?:%[-:\w]+)?(?:#[\w-]+)?\.[\w-]|[({][^)}\n]*\bclass\s*=/m
@@ -43,6 +45,8 @@ module Klenod
43
45
 
44
46
  DEFAULT_COMPONENT_BASE_CLASS = HamlPlugin::DEFAULT_COMPONENT_BASE_CLASS
45
47
  DEFAULT_FACTORY = HamlPlugin::DEFAULT_FACTORY
48
+ DEFAULT_COMPONENT_CHILDREN = HamlPlugin::DEFAULT_COMPONENT_CHILDREN
49
+ COMPONENT_CHILDREN_MODES = HamlPlugin::COMPONENT_CHILDREN_MODES
46
50
  HAML_HELPER_SPECIFIER = HamlPlugin::HAML_HELPER_SPECIFIER
47
51
  HAML_HELPER_MODULE_ID = HamlPlugin::HAML_HELPER_MODULE_ID
48
52
  STATIC_CLASS_SOURCE_PATTERN = HamlPlugin::STATIC_CLASS_SOURCE_PATTERN
@@ -58,14 +62,16 @@ module Klenod
58
62
  def initialize(
59
63
  component_base_class: DEFAULT_COMPONENT_BASE_CLASS,
60
64
  factory: DEFAULT_FACTORY,
61
- global_variables: nil,
65
+ component_children: DEFAULT_COMPONENT_CHILDREN,
66
+ variables: nil,
62
67
  i18n_class: nil,
63
68
  i18n_constant: nil,
64
69
  cache_static_subtrees: false
65
70
  )
66
71
  @component_base_class = component_base_class
67
72
  @factory = factory
68
- @global_variables = validate_global_variables(global_variables)
73
+ @component_children = validate_component_children(component_children)
74
+ @variables = validate_variables(variables)
69
75
  @i18n_class, @i18n_constant = validate_i18n_options(i18n_class, i18n_constant)
70
76
  @cache_static_subtrees = cache_static_subtrees
71
77
  @transformer = Transformer.new
@@ -191,6 +197,7 @@ module Klenod
191
197
  component_class_name: component_class_name,
192
198
  component_base_class: @component_base_class,
193
199
  factory: @factory,
200
+ component_children: @component_children,
194
201
  styles_source: styles_source,
195
202
  translations_source: translations_source,
196
203
  i18n_source: i18n_source_for(builder),
@@ -199,7 +206,7 @@ module Klenod
199
206
  profiler: context.profiler,
200
207
  import_rewriter: import_rewriter,
201
208
  markdown_components_source: markdown_components_dependency ? "__klenod_import__(#{markdown_components_dependency.id.inspect})::Default" : "{}",
202
- global_variables: @global_variables,
209
+ variables: @variables,
203
210
  cache_static_subtrees: @cache_static_subtrees
204
211
  )
205
212
  import_rewrite =
@@ -257,16 +264,36 @@ module Klenod
257
264
 
258
265
  InlineCssSource = Data.define(:text, :line_offset, :column_offset)
259
266
 
260
- def validate_global_variables(global_variables)
261
- return nil if global_variables.nil?
267
+ VARIABLE_KINDS = %i[global class instance].freeze
268
+
269
+ def validate_component_children(value)
270
+ return value if COMPONENT_CHILDREN_MODES.include?(value)
271
+
272
+ raise ArgumentError, "component_children must be one of: #{COMPONENT_CHILDREN_MODES.join(", ")}"
273
+ end
274
+
275
+ def validate_variables(variables)
276
+ return {}.freeze if variables.nil?
277
+ raise ArgumentError, "variables must be a Hash" unless variables.is_a?(Hash)
278
+
279
+ unknown_kinds = variables.keys - VARIABLE_KINDS
280
+ unless unknown_kinds.empty?
281
+ raise ArgumentError, "variables contains unknown kinds: #{unknown_kinds.map(&:inspect).join(", ")}"
282
+ end
283
+
284
+ variables.to_h { |kind, source| [kind, validate_variable_receiver(kind, source)] }.freeze
285
+ end
286
+
287
+ def validate_variable_receiver(kind, source)
288
+ raise ArgumentError, "variables[#{kind.inspect}] must be a Ruby expression String" unless source.is_a?(String)
262
289
 
263
- source = global_variables.to_s
264
290
  parsed = SyntaxTree.parse(source)&.statements&.body
265
- raise ArgumentError, "global_variables must be a Ruby expression" unless parsed&.length == 1
291
+ raise ArgumentError, "variables[#{kind.inspect}] must be a Ruby expression" unless parsed&.length == 1
292
+ SyntaxTree.parse("(#{source})[:__klenod_variable__]")
266
293
 
267
294
  source
268
295
  rescue SyntaxTree::Parser::ParseError
269
- raise ArgumentError, "global_variables must be a Ruby expression"
296
+ raise ArgumentError, "variables[#{kind.inspect}] must be a Ruby expression"
270
297
  end
271
298
 
272
299
  def validate_i18n_options(i18n_class, i18n_constant)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Klenod
4
4
  module Build
5
- VERSION = "0.0.1"
5
+ VERSION = "0.0.2"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: klenod-build
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrés Alin
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.0.1
18
+ version: 0.0.2
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.0.1
25
+ version: 0.0.2
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: async
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -219,8 +219,7 @@ dependencies:
219
219
  - - "~>"
220
220
  - !ruby/object:Gem::Version
221
221
  version: 0.2.0
222
- description: Klenod build constructs Ruby module graphs, runs plugins, emits assets,
223
- and serializes runtime bundles.
222
+ description: Build system and devtools for Klenod.
224
223
  email:
225
224
  - andreas.alin@gmail.com
226
225
  executables: []
@@ -306,5 +305,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
306
305
  requirements: []
307
306
  rubygems_version: 4.0.16
308
307
  specification_version: 4
309
- summary: Build graph and plugins for Klenod.
308
+ summary: Build system for Klenod.
310
309
  test_files: []