foobara 0.0.142 → 0.1.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.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CHANGELOG.md +25 -0
  4. data/projects/builtin_types/lib/foobara/builtin_types.rb +1 -0
  5. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/desugarizers/move_defaults_from_element_types_to_root.rb +9 -2
  6. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/desugarizers/symbolize_defaults.rb +1 -1
  7. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/hash_with_symbolic_keys.rb +1 -1
  8. data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/desugarizers/alphabetize_required.rb +5 -5
  9. data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/desugarizers/move_required_from_element_types_to_root.rb +12 -2
  10. data/projects/builtin_types/src/builtin_types.rb +1 -1
  11. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/class_desugarizer.rb +10 -2
  12. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/class_type_desugarizer.rb +7 -2
  13. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/instance_of_class_desugarizer.rb +3 -4
  14. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/instance_of_symbol_desugarizer.rb +3 -4
  15. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/type_declaration_validators/is_valid_class.rb +1 -1
  16. data/projects/builtin_types/src/duck/supported_validators/instance_of.rb +1 -0
  17. data/projects/builtin_types/src/duck/supported_validators/one_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/cast_one_of.rb +4 -3
  18. data/projects/builtin_types/src/duck/supported_validators/one_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/module_desugarizer.rb +3 -3
  19. data/projects/builtin_types/src/tuple/supported_processors/element_type_declarations/type_declaration_extension/extend_tuple_type_declaration/desugarizers/set_size.rb +1 -1
  20. data/projects/builtin_types/src/tuple/supported_processors/element_type_declarations/type_declaration_extension/extend_tuple_type_declaration/type_declaration_validators/size_matches.rb +2 -4
  21. data/projects/command/src/command_pattern_implementation/concerns/inputs_type.rb +12 -12
  22. data/projects/command/src/command_pattern_implementation/concerns/reflection.rb +4 -2
  23. data/projects/command/src/command_pattern_implementation/concerns/result_type.rb +0 -4
  24. data/projects/command_connectors/src/command_connector.rb +41 -16
  25. data/projects/command_connectors/src/command_registry.rb +7 -4
  26. data/projects/command_connectors/src/transformed_command.rb +55 -43
  27. data/projects/command_connectors/src/transformers/auth_errors_transformer.rb +1 -0
  28. data/projects/command_connectors/src/transformers/entity_to_primary_key_inputs_transformer.rb +4 -0
  29. data/projects/common/src/possible_error.rb +27 -21
  30. data/projects/detached_entity/src/concerns/types.rb +7 -1
  31. data/projects/detached_entity/src/detached_entity_type.rb +10 -0
  32. data/projects/detached_entity/src/extensions/builtin_types/detached_entity/validators/model_instance_is_valid.rb +1 -1
  33. data/projects/detached_entity/src/extensions/type_declarations/handlers/extend_detached_entity_type_declaration/hash_desugarizer.rb +6 -9
  34. data/projects/detached_entity/src/extensions/type_declarations/handlers/extend_detached_entity_type_declaration/primary_key_desugarizer.rb +2 -1
  35. data/projects/domain/src/domain_module_extension.rb +12 -4
  36. data/projects/domain/src/is_manifestable.rb +19 -7
  37. data/projects/entity/src/concerns/types.rb +6 -1
  38. data/projects/foobara/lib/foobara/all.rb +4 -4
  39. data/projects/manifest/src/foobara/manifest/type.rb +11 -2
  40. data/projects/manifest/src/foobara/manifest/type_declaration.rb +46 -2
  41. data/projects/model/src/concerns/aliases.rb +8 -0
  42. data/projects/model/src/concerns/reflection.rb +2 -2
  43. data/projects/model/src/concerns/types.rb +35 -20
  44. data/projects/model/src/extensions/builtin_types/model/validators/model_instance_is_valid.rb +12 -8
  45. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/array_with_symbolic_elements.rb +1 -1
  46. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/attributes_handler_desugarizer.rb +15 -1
  47. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/delegates_desugarizer.rb +7 -5
  48. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/hash_desugarizer.rb +4 -7
  49. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/model_class_desugarizer.rb +0 -2
  50. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/move_private_from_element_types_to_root.rb +28 -9
  51. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/symbolize_private.rb +8 -7
  52. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/to_type_transformer.rb +4 -7
  53. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration.rb +14 -2
  54. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/hash_desugarizer.rb +8 -9
  55. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/model_class_type_desugarizer.rb +6 -2
  56. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/mutable_validator.rb +5 -2
  57. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/normalize_mutable_attributes_desugarizer.rb +8 -7
  58. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/to_type_transformer.rb +4 -1
  59. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration.rb +20 -5
  60. data/projects/model/src/extensions/type_declarations/handlers/registered_type_declaration/model_class_desugarizer.rb +23 -5
  61. data/projects/model/src/extensions/type_declarations/lazy_element_types/model.rb +18 -0
  62. data/projects/model_attribute_helpers/src/attribute_helpers.rb +44 -26
  63. data/projects/namespace/src/is_namespace.rb +58 -90
  64. data/projects/namespace/src/namespace/lookup_mode.rb +13 -2
  65. data/projects/namespace/src/namespace_helpers.rb +1 -0
  66. data/projects/namespace/src/prefixless_registry.rb +2 -0
  67. data/projects/persistence/src/entity_base/transaction/concerns/state_transitions.rb +20 -1
  68. data/projects/persistence/src/entity_base/transaction.rb +14 -11
  69. data/projects/persistence/src/entity_base/transaction_table.rb +10 -49
  70. data/projects/persistence/src/entity_base.rb +39 -0
  71. data/projects/persistence/src/persistence.rb +4 -0
  72. data/projects/type_declarations/src/attributes.rb +15 -9
  73. data/projects/type_declarations/src/attributes_transformers/from_yaml.rb +1 -1
  74. data/projects/type_declarations/src/desugarizer_pipeline.rb +9 -0
  75. data/projects/type_declarations/src/dsl/attributes.rb +14 -5
  76. data/projects/type_declarations/src/handlers/extend_array_type_declaration/array_desugarizer.rb +24 -4
  77. data/projects/type_declarations/src/handlers/extend_array_type_declaration/element_type_declaration_desugarizer.rb +23 -9
  78. data/projects/type_declarations/src/handlers/extend_array_type_declaration/to_type_transformer.rb +3 -7
  79. data/projects/type_declarations/src/handlers/extend_array_type_declaration/type_set_to_array_desugarizer.rb +15 -4
  80. data/projects/type_declarations/src/handlers/extend_array_type_declaration.rb +12 -2
  81. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration/key_type_declaration_desugarizer.rb +48 -0
  82. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration/to_type_transformer.rb +3 -11
  83. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration/value_type_declaration_desugarizer.rb +51 -0
  84. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration.rb +12 -2
  85. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/dsl_desugarizer.rb +1 -1
  86. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/element_type_declarations_desugarizer.rb +17 -7
  87. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/hash_desugarizer.rb +16 -19
  88. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/to_type_transformer.rb +3 -6
  89. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration.rb +13 -2
  90. data/projects/type_declarations/src/handlers/extend_registered_type_declaration/to_type_transformer.rb +3 -3
  91. data/projects/type_declarations/src/handlers/extend_registered_type_declaration.rb +16 -4
  92. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration/array_desugarizer.rb +20 -6
  93. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration/to_type_transformer.rb +3 -9
  94. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration.rb +12 -2
  95. data/projects/type_declarations/src/handlers/registered_type_declaration/to_type_transformer.rb +7 -9
  96. data/projects/type_declarations/src/handlers/registered_type_declaration.rb +22 -7
  97. data/projects/type_declarations/src/lazy_element_types/array.rb +19 -0
  98. data/projects/type_declarations/src/lazy_element_types/attributes.rb +27 -0
  99. data/projects/type_declarations/src/lazy_element_types/hash.rb +38 -0
  100. data/projects/type_declarations/src/lazy_element_types/tuple.rb +23 -0
  101. data/projects/type_declarations/src/sensitive_type_remover.rb +6 -1
  102. data/projects/type_declarations/src/sensitive_type_removers/attributes.rb +2 -0
  103. data/projects/type_declarations/src/type_builder.rb +46 -21
  104. data/projects/type_declarations/src/type_declaration.rb +295 -0
  105. data/projects/type_declarations/src/type_declaration_handler.rb +10 -11
  106. data/projects/type_declarations/src/type_declarations.rb +18 -88
  107. data/projects/types/src/type.rb +34 -9
  108. data/projects/value/src/mutator.rb +1 -4
  109. data/projects/value/src/processor/casting.rb +7 -2
  110. data/projects/value/src/processor/pipeline.rb +9 -1
  111. data/projects/value/src/processor.rb +0 -8
  112. data/projects/value/src/transformer.rb +1 -3
  113. data/projects/value/src/validator.rb +0 -2
  114. data/projects/weak_object_set/src/weak_object_set.rb +2 -0
  115. metadata +11 -8
  116. data/projects/type_declarations/src/handlers/registered_type_declaration/desugarizer_metadata_cleanup_desugarizer.rb +0 -29
  117. data/projects/type_declarations/src/handlers/registered_type_declaration/short_type_name_desugarizer.rb +0 -62
  118. data/projects/type_declarations/src/handlers/registered_type_declaration/strict_desugarizer.rb +0 -32
  119. data/projects/type_declarations/src/handlers/registered_type_declaration/strict_stringified_desugarizer.rb +0 -39
  120. data/projects/type_declarations/src/handlers/registered_type_declaration/symbol_desugarizer.rb +0 -30
  121. data/projects/type_declarations/src/handlers/registered_type_declaration/type_desugarizer.rb +0 -24
@@ -8,20 +8,34 @@ module Foobara
8
8
  # TODO: make a quick way to convert a couple simple procs into a transformer
9
9
  class ArrayDesugarizer < TypeDeclarations::Desugarizer
10
10
  def applicable?(sugary_type_declaration)
11
- sugary_type_declaration.is_a?(::Array) && sugary_type_declaration.size > 1
11
+ sugary_type_declaration.array? && sugary_type_declaration.size > 1
12
12
  end
13
13
 
14
14
  def desugarize(sugary_type_declaration)
15
- element_type_declarations = sugary_type_declaration.map do |element_type_declaration|
16
- handler = type_declaration_handler_for(element_type_declaration)
17
-
18
- handler.desugarize(element_type_declaration)
15
+ element_type_declarations = sugary_type_declaration.declaration_data.map do |element_type_declaration|
16
+ if element_type_declaration.is_a?(Types::Type)
17
+ element_type_declaration.reference_or_declaration_data
18
+ else
19
+ declaration = TypeDeclaration.new(element_type_declaration)
20
+ if sugary_type_declaration.deep_duped?
21
+ # TODO: probably not worth directly testing this path
22
+ # :nocov:
23
+ declaration.is_deep_duped = true
24
+ declaration.is_duped = true
25
+ # :nocov:
26
+ end
27
+ handler = type_declaration_handler_for(declaration)
28
+ handler.desugarize(declaration).declaration_data
29
+ end
19
30
  end
20
31
 
21
- {
32
+ sugary_type_declaration.declaration_data = {
22
33
  type: :tuple,
23
34
  element_type_declarations:
24
35
  }
36
+ sugary_type_declaration.is_strict = true
37
+
38
+ sugary_type_declaration
25
39
  end
26
40
  end
27
41
  end
@@ -7,15 +7,9 @@ module Foobara
7
7
  class ExtendTupleTypeDeclaration < ExtendAssociativeArrayTypeDeclaration
8
8
  class ToTypeTransformer < ExtendAssociativeArrayTypeDeclaration::ToTypeTransformer
9
9
  def transform(strict_type_declaration)
10
- super.tap do |type|
11
- element_type_declarations = type.declaration_data[:element_type_declarations]
12
-
13
- if element_type_declarations && !element_type_declarations.empty?
14
- type.element_types = element_type_declarations.map do |element_type_declaration|
15
- type_for_declaration(element_type_declaration)
16
- end
17
- end
18
- end
10
+ type = super
11
+ type.element_types = :Tuple
12
+ type
19
13
  end
20
14
  end
21
15
  end
@@ -3,9 +3,19 @@ module Foobara
3
3
  module Handlers
4
4
  class ExtendTupleTypeDeclaration < ExtendAssociativeArrayTypeDeclaration
5
5
  def applicable?(sugary_type_declaration)
6
- strictish_type_declaration = desugarize(sugary_type_declaration)
6
+ strictish_type_declaration = if sugary_type_declaration.strict?
7
+ sugary_type_declaration
8
+ else
9
+ desugarize(sugary_type_declaration.clone)
10
+ end
7
11
 
8
- strictish_type_declaration.is_a?(::Hash) && strictish_type_declaration[:type] == :tuple
12
+ if strictish_type_declaration.hash? && strictish_type_declaration[:type] == :tuple
13
+ unless strictish_type_declaration.equal?(sugary_type_declaration)
14
+ sugary_type_declaration.assign(strictish_type_declaration)
15
+ end
16
+
17
+ true
18
+ end
9
19
  end
10
20
  end
11
21
  end
@@ -10,16 +10,14 @@ module Foobara
10
10
  registered_type(strict_type_declaration)
11
11
  end
12
12
 
13
- def type_symbol(strict_type_declaration)
14
- strict_type_declaration[:type]
15
- end
16
-
17
13
  def registered_type(strict_type_declaration)
18
- symbol = type_symbol(strict_type_declaration)
19
- if TypeDeclarations.strict? || TypeDeclarations.strict_stringified?
20
- symbol = "::#{symbol}"
21
- end
22
- lookup_type!(symbol)
14
+ type = strict_type_declaration.type || strict_type_declaration.base_type
15
+
16
+ return type if type
17
+
18
+ type = lookup_type!(strict_type_declaration[:type], mode: Namespace::LookupMode::ABSOLUTE)
19
+
20
+ strict_type_declaration.base_type = type
23
21
  end
24
22
 
25
23
  def target_classes(strict_type_declaration)
@@ -6,16 +6,31 @@ module Foobara
6
6
  # TODO: we should just use the symbol instead of {type: symbol} to save space and simplify some stuff...
7
7
  class RegisteredTypeDeclaration < TypeDeclarationHandler
8
8
  def applicable?(sugary_type_declaration)
9
- strict_type_declaration = desugarize(sugary_type_declaration)
9
+ return true if sugary_type_declaration.type
10
10
 
11
- return false unless strict_type_declaration.is_a?(::Hash)
11
+ unless sugary_type_declaration.reference_checked?
12
+ sugary_type_declaration.handle_symbolic_declaration
13
+ return true if sugary_type_declaration.type
14
+ end
15
+
16
+ strict_type_declaration = if sugary_type_declaration.strict?
17
+ sugary_type_declaration
18
+ else
19
+ desugarize(sugary_type_declaration.clone)
20
+ end
12
21
 
13
- # we only handle case where it's a builtin type not an extension of one
14
- if strict_type_declaration.keys == [:type]
15
- type_symbol = strict_type_declaration[:type]
16
- if type_symbol.is_a?(::Symbol) || type_symbol.is_a?(::String)
17
- type_registered?(type_symbol)
22
+ if strict_type_declaration.reference?
23
+ unless strict_type_declaration.type
24
+ # :nocov:
25
+ strict_type_declaration.handle_symbolic_declaration
26
+ # :nocov:
18
27
  end
28
+
29
+ unless sugary_type_declaration.equal?(strict_type_declaration)
30
+ sugary_type_declaration.assign(strict_type_declaration)
31
+ end
32
+
33
+ true
19
34
  end
20
35
  end
21
36
 
@@ -0,0 +1,19 @@
1
+ module Foobara
2
+ module TypeDeclarations
3
+ module LazyElementTypes
4
+ module Array
5
+ module_function
6
+
7
+ def resolve(type)
8
+ element_type_declaration = type.declaration_data[:element_type_declaration]
9
+
10
+ type.element_type = if element_type_declaration
11
+ TypeDeclarations.strict do
12
+ Domain.current.foobara_type_from_declaration(element_type_declaration)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ module Foobara
2
+ module TypeDeclarations
3
+ module LazyElementTypes
4
+ module Attributes
5
+ module_function
6
+
7
+ def resolve(type)
8
+ type_declarations = type.declaration_data[:element_type_declarations]
9
+
10
+ type.element_types = if type_declarations
11
+ if type_declarations.empty?
12
+ {}
13
+ else
14
+ TypeDeclarations.strict do
15
+ domain = Domain.current
16
+
17
+ type_declarations.transform_values do |attribute_declaration|
18
+ domain.foobara_type_from_declaration(attribute_declaration)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ module Foobara
2
+ module TypeDeclarations
3
+ module LazyElementTypes
4
+ # Using Hash instead of AssociativeArray to avoid making a symbol for it
5
+ # (probably doesn't really matter)
6
+ module Hash
7
+ module_function
8
+
9
+ def resolve(type)
10
+ declaration_data = type.declaration_data
11
+
12
+ key_type_declaration = declaration_data[:key_type_declaration]
13
+ value_type_declaration = declaration_data[:value_type_declaration]
14
+
15
+ type.element_types = if key_type_declaration || value_type_declaration
16
+ TypeDeclarations.strict do
17
+ domain = Domain.current
18
+
19
+ key_declaration = if key_type_declaration
20
+ domain.foobara_type_from_declaration(key_type_declaration)
21
+ else
22
+ BuiltinTypes[:duck]
23
+ end
24
+
25
+ value_declaration = if value_type_declaration
26
+ domain.foobara_type_from_declaration(value_type_declaration)
27
+ else
28
+ BuiltinTypes[:duck]
29
+ end
30
+
31
+ [key_declaration, value_declaration]
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,23 @@
1
+ module Foobara
2
+ module TypeDeclarations
3
+ module LazyElementTypes
4
+ module Tuple
5
+ module_function
6
+
7
+ def resolve(type)
8
+ element_type_declarations = type.declaration_data[:element_type_declarations]
9
+
10
+ type.element_types = if element_type_declarations
11
+ TypeDeclarations.strict do
12
+ domain = Domain.current
13
+
14
+ element_type_declarations.map do |element_type_declaration|
15
+ domain.foobara_type_from_declaration(element_type_declaration)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -2,7 +2,12 @@ module Foobara
2
2
  module TypeDeclarations
3
3
  class SensitiveTypeRemover < Value::Transformer
4
4
  def applicable?(strict_type_declaration)
5
- handler.applicable?(strict_type_declaration)
5
+ declaration = TypeDeclaration.new(strict_type_declaration)
6
+
7
+ declaration.is_strict = true
8
+ declaration.is_absolutified = true
9
+
10
+ handler.applicable?(declaration)
6
11
  end
7
12
 
8
13
  def handler
@@ -16,6 +16,8 @@ module Foobara
16
16
  to_remove = []
17
17
 
18
18
  strict_type_declaration[:element_type_declarations].each_pair do |attribute_name, attribute_declaration|
19
+ next if attribute_declaration.is_a?(::Symbol)
20
+
19
21
  if attribute_declaration[:sensitive]
20
22
  to_remove << attribute_name
21
23
  else
@@ -7,9 +7,13 @@ module Foobara
7
7
  def args_to_type_declaration(*args, &block)
8
8
  if block
9
9
  if args.empty? || args == [:attributes]
10
- block
10
+ TypeDeclaration.new(block)
11
11
  elsif args == [:array]
12
- { type: :array, element_type_declaration: block }
12
+ type_declaration = TypeDeclaration.new(type: :array, element_type_declaration: block)
13
+ type_declaration.is_absolutified = true
14
+ type_declaration.is_duped = true
15
+ type_declaration.is_deep_duped = true
16
+ type_declaration
13
17
  else
14
18
  # :nocov:
15
19
  raise ArgumentError, "Cannot provide both block and declaration of #{args}"
@@ -22,23 +26,39 @@ module Foobara
22
26
  raise ArgumentError, "expected 1 argument or a block but got 0 arguments and no block"
23
27
  # :nocov:
24
28
  when 1
25
- args.first
29
+ arg = args.first
30
+
31
+ if arg.is_a?(TypeDeclaration)
32
+ arg
33
+ else
34
+ TypeDeclaration.new(arg)
35
+ end
26
36
  else
27
37
  type, *symbolic_processors, processor_data = args
28
38
 
29
- if !symbolic_processors.empty?
30
- symbolic_processors = symbolic_processors.to_h { |symbol| [symbol, true] }
31
-
32
- if processor_data.is_a?(::Hash) && !processor_data.empty?
33
- processor_data.merge(symbolic_processors)
34
- else
35
- symbolic_processors
36
- end
37
- elsif processor_data.is_a?(::Hash)
38
- processor_data
39
- else
40
- { processor_data.to_sym => true }
41
- end.merge(type:)
39
+ type_declaration = if !symbolic_processors.empty?
40
+ symbolic_processors = symbolic_processors.to_h { |symbol| [symbol, true] }
41
+
42
+ if processor_data.is_a?(::Hash) && !processor_data.empty?
43
+ h = processor_data.merge(symbolic_processors)
44
+ h[:type] = type
45
+ TypeDeclaration.new(h)
46
+ else
47
+ type_declaration = TypeDeclaration.new(symbolic_processors.merge(type:))
48
+ type_declaration.is_deep_duped = true
49
+ type_declaration
50
+ end
51
+ elsif processor_data.is_a?(::Hash)
52
+ TypeDeclaration.new(processor_data.merge(type:))
53
+ else
54
+ h = { type:, processor_data.to_sym => true }
55
+ type_declaration = TypeDeclaration.new(h)
56
+ type_declaration.is_deep_duped = true
57
+ type_declaration
58
+ end
59
+
60
+ type_declaration.is_duped = true
61
+ type_declaration
42
62
  end
43
63
  end
44
64
  end
@@ -81,7 +101,7 @@ module Foobara
81
101
  end
82
102
 
83
103
  raise NoTypeDeclarationHandlerFoundError,
84
- "No type declaration handler found for #{type_declaration}"
104
+ "No type declaration handler found for #{type_declaration.declaration_data}"
85
105
  end
86
106
 
87
107
  def handlers
@@ -94,15 +114,17 @@ module Foobara
94
114
 
95
115
  def type_for_strict_stringified_declaration(type_declaration)
96
116
  TypeDeclarations.strict_stringified do
97
- handler = type_declaration_handler_for(type_declaration)
98
- handler.process_value!(type_declaration)
117
+ declaration = TypeDeclaration.new(type_declaration)
118
+ handler = type_declaration_handler_for(declaration)
119
+ handler.process_value!(declaration)
99
120
  end
100
121
  end
101
122
 
102
123
  def type_for_strict_declaration(type_declaration)
103
124
  TypeDeclarations.strict do
104
- handler = type_declaration_handler_for(type_declaration)
105
- handler.process_value!(type_declaration)
125
+ declaration = TypeDeclaration.new(type_declaration)
126
+ handler = type_declaration_handler_for(declaration)
127
+ handler.process_value!(declaration)
106
128
  end
107
129
  end
108
130
 
@@ -123,6 +145,9 @@ module Foobara
123
145
  def type_for_declaration_without_cache(*type_declaration_bits, &)
124
146
  type_declaration = TypeDeclarations.args_to_type_declaration(*type_declaration_bits, &)
125
147
 
148
+ type = type_declaration.type
149
+ return type if type
150
+
126
151
  handler = type_declaration_handler_for(type_declaration)
127
152
  handler.process_value!(type_declaration)
128
153
  end
@@ -0,0 +1,295 @@
1
+ module Foobara
2
+ # Inheriting from ::Hash for now but we should remove this once all of the handlers are updated
3
+ class TypeDeclaration
4
+ attr_reader :is_strict
5
+
6
+ attr_accessor :is_duped,
7
+ :declaration_data,
8
+ :is_deep_duped,
9
+ :is_absolutified,
10
+ :reference_checked,
11
+ :type,
12
+ :base_type
13
+
14
+ # TODO: we should be able to delete absolutified opt once strict declarations
15
+ # use `:ref` instead of `{type: :ref}` format.
16
+ def initialize(declaration_data, absolutified = false, skip_reference_check = false)
17
+ if TypeDeclarations.strict?
18
+ self.is_strict = true
19
+ elsif absolutified || TypeDeclarations.strict_stringified?
20
+ self.is_absolutified = true
21
+ end
22
+
23
+ self.declaration_data = declaration_data
24
+
25
+ unless strict? || skip_reference_check
26
+ handle_symbolic_declaration
27
+ end
28
+ end
29
+
30
+ def is_strict=(value)
31
+ if value
32
+ self.is_absolutified = true
33
+ end
34
+
35
+ @is_strict = value
36
+ end
37
+
38
+ def handle_symbolic_declaration
39
+ self.reference_checked = true
40
+
41
+ if declaration_data.is_a?(::Symbol)
42
+ symbol = declaration_data
43
+ elsif declaration_data.is_a?(::String) && TypeDeclarations.stringified?
44
+ symbol = declaration_data.to_sym
45
+ end
46
+
47
+ if symbol
48
+ type = if absolutified?
49
+ Domain.current.foobara_lookup_type(symbol, mode: Namespace::LookupMode::ABSOLUTE)
50
+ else
51
+ Domain.current.foobara_lookup_type(symbol)
52
+ end
53
+
54
+ if type
55
+ unless strict?
56
+ self.declaration_data = type.full_type_symbol
57
+ end
58
+
59
+ self.type = type
60
+
61
+ self.is_strict = true
62
+ self.is_deep_duped = true
63
+ self.is_duped = true
64
+
65
+ else
66
+ if declaration_data.is_a?(::Symbol)
67
+ self.is_duped = true
68
+ self.is_deep_duped = true
69
+ end
70
+
71
+ self.declaration_data = declaration_data
72
+ end
73
+ elsif TypeDeclarations.strict_stringified?
74
+ symbolize_keys!
75
+ type_symbol = self[:type].to_sym
76
+ self[:type] = type_symbol
77
+
78
+ type = Domain.current.foobara_lookup_type(type_symbol, mode: Namespace::LookupMode::ABSOLUTE)
79
+
80
+ if type
81
+ if declaration_data.keys.size == 1
82
+ self.type = type
83
+ self.is_strict = true
84
+ self.is_deep_duped = true
85
+ self.is_duped = true
86
+ self.declaration_data = type.full_type_symbol
87
+ else
88
+ self.base_type = type
89
+ end
90
+ end
91
+ elsif declaration_data.is_a?(::Hash)
92
+ type_symbol = self[:type] || self["type"]
93
+
94
+ if type_symbol
95
+ if type_symbol.is_a?(::Symbol) || type_symbol.is_a?(::String)
96
+ type = if absolutified?
97
+ Domain.current.foobara_lookup_type(type_symbol, mode: Namespace::LookupMode::ABSOLUTE)
98
+ else
99
+ Domain.current.foobara_lookup_type(type_symbol)
100
+ end
101
+
102
+ if type
103
+ symbolize_keys!
104
+ self[:type] = type.full_type_symbol
105
+ self.is_absolutified = true
106
+
107
+ if declaration_data.keys.size == 1
108
+ self.declaration_data = type.full_type_symbol
109
+
110
+ self.type = type
111
+ self.is_strict = true
112
+ self.is_deep_duped = true
113
+ else
114
+ self.base_type = type
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+ def hash?
123
+ declaration_data.is_a?(::Hash)
124
+ end
125
+
126
+ def key?(key)
127
+ declaration_data.key?(key)
128
+ end
129
+
130
+ def [](key)
131
+ declaration_data[key]
132
+ end
133
+
134
+ def array?
135
+ declaration_data.is_a?(::Array)
136
+ end
137
+
138
+ def proc?
139
+ declaration_data.is_a?(::Proc)
140
+ end
141
+
142
+ def to_proc
143
+ declaration_data
144
+ end
145
+
146
+ def size
147
+ declaration_data.size
148
+ end
149
+
150
+ def delete(key)
151
+ return unless declaration_data.key?(key)
152
+
153
+ if duped?
154
+ declaration_data.delete(key)
155
+ else
156
+ self.declaration_data = declaration_data.except(key)
157
+ self.is_duped = true
158
+ end
159
+
160
+ if strict?
161
+ self.is_strict = false
162
+ end
163
+
164
+ if absolutified? && key == :type
165
+ self.is_absolutified = false
166
+ end
167
+ end
168
+
169
+ def class?
170
+ declaration_data.is_a?(::Class)
171
+ end
172
+
173
+ def []=(key, value)
174
+ if strict?
175
+ self.is_strict = false
176
+ end
177
+
178
+ unless duped?
179
+ self.declaration_data = declaration_data.dup
180
+ self.is_duped = true
181
+ end
182
+
183
+ declaration_data[key] = value
184
+ end
185
+
186
+ def all_symbolizable_keys?
187
+ Util.all_symbolizable_keys?(declaration_data)
188
+ end
189
+
190
+ def symbolize_keys!
191
+ if duped?
192
+ declaration_data.transform_keys!(&:to_sym)
193
+ else
194
+ self.declaration_data = declaration_data.transform_keys(&:to_sym)
195
+ self.is_duped = true
196
+ end
197
+
198
+ self
199
+ end
200
+
201
+ def except(...)
202
+ parts = declaration_data.except(...)
203
+
204
+ declaration = clone_from_part(parts)
205
+ declaration.is_duped = true
206
+
207
+ if declaration.strict?
208
+ declaration.is_strict = false
209
+ end
210
+
211
+ declaration
212
+ end
213
+
214
+ def slice(...)
215
+ parts = declaration_data.slice(...)
216
+
217
+ declaration = clone_from_part(parts)
218
+ declaration.is_duped = true
219
+
220
+ if declaration.strict?
221
+ declaration.is_strict = false
222
+ end
223
+
224
+ declaration
225
+ end
226
+
227
+ def assign(other)
228
+ self.declaration_data = other.declaration_data
229
+
230
+ if absolutified? != other.absolutified?
231
+ self.is_absolutified = other.absolutified?
232
+ end
233
+
234
+ if strict? != other.strict?
235
+ self.is_strict = other.strict?
236
+ end
237
+
238
+ if duped? != other.duped?
239
+ self.is_duped = other.duped?
240
+ end
241
+
242
+ if deep_duped? != other.deep_duped?
243
+ self.is_deep_duped = other.deep_duped?
244
+ end
245
+
246
+ if other.type
247
+ self.type = other.type
248
+ end
249
+
250
+ if other.base_type
251
+ self.base_type = other.base_type
252
+ end
253
+ end
254
+
255
+ def clone
256
+ declaration = TypeDeclaration.new(declaration_data, false, true)
257
+
258
+ if strict?
259
+ declaration.is_strict = true
260
+ end
261
+
262
+ if absolutified?
263
+ declaration.is_absolutified = true
264
+ end
265
+
266
+ if type
267
+ declaration.type = type
268
+ end
269
+
270
+ if base_type
271
+ declaration.base_type = base_type
272
+ end
273
+
274
+ if reference_checked?
275
+ declaration.reference_checked = true
276
+ end
277
+
278
+ declaration
279
+ end
280
+
281
+ def clone_from_part(part)
282
+ TypeDeclaration.new(part)
283
+ end
284
+
285
+ def reference?
286
+ strict? && declaration_data.is_a?(::Symbol)
287
+ end
288
+
289
+ alias absolutified? is_absolutified
290
+ alias duped? is_duped
291
+ alias deep_duped? is_deep_duped
292
+ alias strict? is_strict
293
+ alias reference_checked? reference_checked
294
+ end
295
+ end