foobara 0.0.142 → 0.1.1

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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CHANGELOG.md +19 -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 +6 -6
  25. data/projects/command_connectors/src/command_registry.rb +7 -4
  26. data/projects/command_connectors/src/transformed_command.rb +22 -8
  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/detached_entity/src/concerns/types.rb +7 -1
  30. data/projects/detached_entity/src/extensions/builtin_types/detached_entity/validators/model_instance_is_valid.rb +1 -1
  31. data/projects/detached_entity/src/extensions/type_declarations/handlers/extend_detached_entity_type_declaration/hash_desugarizer.rb +6 -9
  32. data/projects/detached_entity/src/extensions/type_declarations/handlers/extend_detached_entity_type_declaration/primary_key_desugarizer.rb +2 -1
  33. data/projects/domain/src/domain_module_extension.rb +12 -4
  34. data/projects/entity/src/concerns/types.rb +6 -1
  35. data/projects/foobara/lib/foobara/all.rb +4 -4
  36. data/projects/manifest/src/foobara/manifest/type.rb +11 -2
  37. data/projects/manifest/src/foobara/manifest/type_declaration.rb +46 -2
  38. data/projects/model/src/concerns/aliases.rb +8 -0
  39. data/projects/model/src/concerns/reflection.rb +2 -2
  40. data/projects/model/src/concerns/types.rb +35 -20
  41. data/projects/model/src/extensions/builtin_types/model/validators/model_instance_is_valid.rb +12 -8
  42. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/array_with_symbolic_elements.rb +1 -1
  43. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/attributes_handler_desugarizer.rb +15 -1
  44. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/delegates_desugarizer.rb +7 -5
  45. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/hash_desugarizer.rb +4 -7
  46. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/model_class_desugarizer.rb +0 -2
  47. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/move_private_from_element_types_to_root.rb +28 -9
  48. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/symbolize_private.rb +8 -7
  49. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/to_type_transformer.rb +4 -7
  50. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration.rb +14 -2
  51. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/hash_desugarizer.rb +8 -9
  52. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/model_class_type_desugarizer.rb +6 -2
  53. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/mutable_validator.rb +5 -2
  54. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/normalize_mutable_attributes_desugarizer.rb +8 -7
  55. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/to_type_transformer.rb +4 -1
  56. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration.rb +20 -5
  57. data/projects/model/src/extensions/type_declarations/handlers/registered_type_declaration/model_class_desugarizer.rb +23 -5
  58. data/projects/model/src/extensions/type_declarations/lazy_element_types/model.rb +18 -0
  59. data/projects/model_attribute_helpers/src/attribute_helpers.rb +44 -26
  60. data/projects/namespace/src/is_namespace.rb +58 -90
  61. data/projects/namespace/src/namespace/lookup_mode.rb +13 -2
  62. data/projects/namespace/src/namespace_helpers.rb +1 -0
  63. data/projects/namespace/src/prefixless_registry.rb +2 -0
  64. data/projects/persistence/src/entity_base/transaction/concerns/state_transitions.rb +20 -1
  65. data/projects/persistence/src/entity_base/transaction.rb +14 -11
  66. data/projects/persistence/src/entity_base/transaction_table.rb +10 -49
  67. data/projects/persistence/src/entity_base.rb +39 -0
  68. data/projects/persistence/src/persistence.rb +4 -0
  69. data/projects/type_declarations/src/attributes.rb +15 -9
  70. data/projects/type_declarations/src/attributes_transformers/from_yaml.rb +1 -1
  71. data/projects/type_declarations/src/desugarizer_pipeline.rb +9 -0
  72. data/projects/type_declarations/src/dsl/attributes.rb +14 -5
  73. data/projects/type_declarations/src/handlers/extend_array_type_declaration/array_desugarizer.rb +24 -4
  74. data/projects/type_declarations/src/handlers/extend_array_type_declaration/element_type_declaration_desugarizer.rb +23 -9
  75. data/projects/type_declarations/src/handlers/extend_array_type_declaration/to_type_transformer.rb +3 -7
  76. data/projects/type_declarations/src/handlers/extend_array_type_declaration/type_set_to_array_desugarizer.rb +15 -4
  77. data/projects/type_declarations/src/handlers/extend_array_type_declaration.rb +12 -2
  78. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration/key_type_declaration_desugarizer.rb +48 -0
  79. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration/to_type_transformer.rb +3 -11
  80. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration/value_type_declaration_desugarizer.rb +51 -0
  81. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration.rb +12 -2
  82. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/dsl_desugarizer.rb +1 -1
  83. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/element_type_declarations_desugarizer.rb +17 -7
  84. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/hash_desugarizer.rb +16 -19
  85. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/to_type_transformer.rb +3 -6
  86. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration.rb +13 -2
  87. data/projects/type_declarations/src/handlers/extend_registered_type_declaration/to_type_transformer.rb +3 -3
  88. data/projects/type_declarations/src/handlers/extend_registered_type_declaration.rb +16 -4
  89. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration/array_desugarizer.rb +20 -6
  90. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration/to_type_transformer.rb +3 -9
  91. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration.rb +12 -2
  92. data/projects/type_declarations/src/handlers/registered_type_declaration/to_type_transformer.rb +7 -9
  93. data/projects/type_declarations/src/handlers/registered_type_declaration.rb +22 -7
  94. data/projects/type_declarations/src/lazy_element_types/array.rb +19 -0
  95. data/projects/type_declarations/src/lazy_element_types/attributes.rb +27 -0
  96. data/projects/type_declarations/src/lazy_element_types/hash.rb +38 -0
  97. data/projects/type_declarations/src/lazy_element_types/tuple.rb +23 -0
  98. data/projects/type_declarations/src/sensitive_type_remover.rb +6 -1
  99. data/projects/type_declarations/src/sensitive_type_removers/attributes.rb +2 -0
  100. data/projects/type_declarations/src/type_builder.rb +46 -21
  101. data/projects/type_declarations/src/type_declaration.rb +295 -0
  102. data/projects/type_declarations/src/type_declaration_handler.rb +10 -11
  103. data/projects/type_declarations/src/type_declarations.rb +12 -5
  104. data/projects/types/src/type.rb +26 -4
  105. data/projects/value/src/mutator.rb +1 -4
  106. data/projects/value/src/processor/casting.rb +7 -2
  107. data/projects/value/src/processor/pipeline.rb +9 -1
  108. data/projects/value/src/processor.rb +0 -2
  109. data/projects/value/src/transformer.rb +1 -3
  110. data/projects/value/src/validator.rb +0 -2
  111. data/projects/weak_object_set/src/weak_object_set.rb +2 -0
  112. metadata +10 -7
  113. data/projects/type_declarations/src/handlers/registered_type_declaration/desugarizer_metadata_cleanup_desugarizer.rb +0 -29
  114. data/projects/type_declarations/src/handlers/registered_type_declaration/short_type_name_desugarizer.rb +0 -62
  115. data/projects/type_declarations/src/handlers/registered_type_declaration/strict_desugarizer.rb +0 -32
  116. data/projects/type_declarations/src/handlers/registered_type_declaration/strict_stringified_desugarizer.rb +0 -39
  117. data/projects/type_declarations/src/handlers/registered_type_declaration/symbol_desugarizer.rb +0 -30
  118. data/projects/type_declarations/src/handlers/registered_type_declaration/type_desugarizer.rb +0 -24
@@ -1,21 +1,20 @@
1
1
  module Foobara
2
2
  module TypeDeclarations
3
3
  module Handlers
4
+ # TODO: Can't we just delete this type entirely?
4
5
  class ExtendRegisteredModelTypeDeclaration < ExtendRegisteredTypeDeclaration
5
6
  class HashDesugarizer < TypeDeclarations::Desugarizer
6
7
  def applicable?(sugary_type_declaration)
7
- return false unless sugary_type_declaration.is_a?(::Hash)
8
+ return false unless sugary_type_declaration.hash?
8
9
 
9
10
  type_symbol = sugary_type_declaration[:type]
10
11
 
11
- if type_symbol
12
- if type_symbol.is_a?(::Symbol) && type_registered?(type_symbol)
13
- type = Foobara.foobara_root_namespace.foobara_lookup_type(
14
- type_symbol, mode: Namespace::LookupMode::ABSOLUTE
15
- )
12
+ if type_symbol.is_a?(::Symbol)
13
+ # TODO: cache this on a #base_type= helper
14
+ type = sugary_type_declaration.type ||
15
+ lookup_type(type_symbol, mode: Namespace::LookupMode::ABSOLUTE)
16
16
 
17
- type&.extends?(BuiltinTypes[expected_type_symbol])
18
- end
17
+ type&.extends?(BuiltinTypes[expected_type_symbol])
19
18
  end
20
19
  end
21
20
 
@@ -24,7 +23,7 @@ module Foobara
24
23
  end
25
24
 
26
25
  def desugarize(sugary_type_declaration)
27
- Util.symbolize_keys(sugary_type_declaration)
26
+ sugary_type_declaration.symbolize_keys!
28
27
  end
29
28
 
30
29
  def priority
@@ -4,7 +4,7 @@ module Foobara
4
4
  class ExtendRegisteredModelTypeDeclaration < ExtendRegisteredTypeDeclaration
5
5
  class ModelClassTypeDesugarizer < TypeDeclarations::Desugarizer
6
6
  def applicable?(sugary_type_declaration)
7
- if sugary_type_declaration.is_a?(::Hash) && sugary_type_declaration.key?(:type)
7
+ if sugary_type_declaration.hash? && sugary_type_declaration.key?(:type)
8
8
  type = sugary_type_declaration[:type]
9
9
  type.is_a?(::Class) && type < Model
10
10
  end
@@ -12,7 +12,11 @@ module Foobara
12
12
 
13
13
  def desugarize(hash)
14
14
  model_class = hash[:type]
15
- hash.merge(type: model_class.model_type.foobara_manifest_reference.to_sym)
15
+ hash[:type] = model_class.model_type.foobara_manifest_reference.to_sym
16
+
17
+ hash.handle_symbolic_declaration
18
+
19
+ hash
16
20
  end
17
21
 
18
22
  def priority
@@ -21,9 +21,12 @@ module Foobara
21
21
 
22
22
  def validation_errors(strict_type_declaration)
23
23
  mutable = strict_type_declaration[:mutable]
24
- return if [true, false].include?(mutable)
24
+ return if mutable == true || mutable == false
25
+
26
+ model_type = strict_type_declaration.type
27
+
28
+ model_type ||= type_for_declaration(strict_type_declaration[:type])
25
29
 
26
- model_type = type_for_declaration(strict_type_declaration[:type])
27
30
  valid_attribute_names = model_type.element_types.element_types.keys
28
31
 
29
32
  mutable.map do |key|
@@ -4,22 +4,23 @@ module Foobara
4
4
  class ExtendRegisteredModelTypeDeclaration < ExtendRegisteredTypeDeclaration
5
5
  class NormalizeMutableAttributesDesugarizer < TypeDeclarations::Desugarizer
6
6
  def applicable?(value)
7
- if value.is_a?(::Hash) && value.key?(:mutable) && value.key?(:type)
7
+ if value.hash? && value.key?(:mutable) && value.key?(:type)
8
8
  mutable = value[:mutable]
9
9
 
10
- return false if [true, false].include?(mutable)
10
+ return false if mutable == true || mutable == false
11
11
 
12
12
  if !mutable.is_a?(::Array) || (mutable.is_a?(::Array) && mutable.any? { |k| !k.is_a?(::Symbol) })
13
- type = type_for_declaration(value[:type])
14
- type.extends?(BuiltinTypes[:model])
13
+ type = value.type ||
14
+ lookup_type(value[:type], mode: Namespace::LookupMode::ABSOLUTE_SINGLE_NAMESPACE)
15
+
16
+ type&.extends?(BuiltinTypes[:model])
15
17
  end
16
18
  end
17
19
  end
18
20
 
19
21
  def desugarize(rawish_type_declaration)
20
- rawish_type_declaration.merge(
21
- mutable: Util.array(rawish_type_declaration[:mutable]).map!(&:to_sym)
22
- )
22
+ rawish_type_declaration[:mutable] = Util.array(rawish_type_declaration[:mutable]).map!(&:to_sym)
23
+ rawish_type_declaration
23
24
  end
24
25
  end
25
26
  end
@@ -2,6 +2,7 @@ module Foobara
2
2
  module TypeDeclarations
3
3
  module Handlers
4
4
  class ExtendRegisteredModelTypeDeclaration < ExtendRegisteredTypeDeclaration
5
+ # TODO: seems like we can delete this handler entirely?
5
6
  class ToTypeTransformer < ExtendRegisteredTypeDeclaration::ToTypeTransformer
6
7
  # TODO: make declaration validator for model_class and model_base_class
7
8
  def target_classes(strict_type_declaration)
@@ -14,7 +15,9 @@ module Foobara
14
15
  end
15
16
 
16
17
  def declaration_to_type(strict_type_declaration)
17
- type_for_declaration(strict_type_declaration[:type])
18
+ # TODO: cache this on a #base_type= helper
19
+ strict_type_declaration.type ||
20
+ lookup_type(strict_type_declaration[:type], mode: Namespace::LookupMode::ABSOLUTE_SINGLE_NAMESPACE)
18
21
  end
19
22
  end
20
23
  end
@@ -4,17 +4,32 @@ module Foobara
4
4
  # Why doesn't this inherit from ExtendModelTypeDeclaration
5
5
  class ExtendRegisteredModelTypeDeclaration < ExtendRegisteredTypeDeclaration
6
6
  def applicable?(sugary_type_declaration)
7
- strict_type_declaration = desugarize(sugary_type_declaration)
7
+ strict_type_declaration = if sugary_type_declaration.strict?
8
+ # :nocov:
9
+ sugary_type_declaration
10
+ # :nocov:
11
+ else
12
+ desugarize(sugary_type_declaration.clone)
13
+ end
8
14
 
9
- if strict_type_declaration.is_a?(::Hash) && strict_type_declaration.key?(:type)
15
+ if strict_type_declaration.hash? && strict_type_declaration.key?(:type)
10
16
  type_symbol = strict_type_declaration[:type]
11
17
 
12
18
  return false if type_symbol == expected_type_symbol
13
19
  return false unless type_symbol.is_a?(::Symbol) || type_symbol.is_a?(::String)
14
20
 
15
- if type_registered?(type_symbol)
16
- type = lookup_type!(type_symbol)
17
- type.extends?(BuiltinTypes[expected_type_symbol])
21
+ # TODO: cache this on a #base_type= helper
22
+ type = strict_type_declaration.type ||
23
+ lookup_type(type_symbol, mode: Namespace::LookupMode::ABSOLUTE)
24
+
25
+ if type
26
+ if type.extends?(BuiltinTypes[expected_type_symbol])
27
+ unless sugary_type_declaration.equal?(strict_type_declaration)
28
+ sugary_type_declaration.assign(strict_type_declaration)
29
+ end
30
+
31
+ true
32
+ end
18
33
  end
19
34
  end
20
35
  end
@@ -4,13 +4,31 @@ module Foobara
4
4
  class RegisteredTypeDeclaration < TypeDeclarationHandler
5
5
  class ModelClassDesugarizer < TypeDeclarations::Desugarizer
6
6
  def applicable?(sugary_type_declaration)
7
- sugary_type_declaration.is_a?(Class) && sugary_type_declaration < Model
7
+ sugary_type_declaration.class? && sugary_type_declaration.declaration_data < Model
8
8
  end
9
9
 
10
- def desugarize(model_class)
11
- {
12
- type: model_class.model_type.foobara_manifest_reference.to_sym
13
- }
10
+ def desugarize(declaration)
11
+ model_class = declaration.declaration_data
12
+
13
+ declaration.declaration_data = model_class.model_type.foobara_manifest_reference.to_sym
14
+
15
+ type = model_class.model_type
16
+
17
+ if type
18
+ declaration.type = type
19
+ declaration.reference_checked = true
20
+ else
21
+ # :nocov:
22
+ declaration.reference_checked = false
23
+ # :nocov:
24
+ end
25
+
26
+ declaration.is_absolutified = true
27
+ declaration.is_strict = true
28
+ declaration.is_duped = true
29
+ declaration.is_deep_duped = true
30
+
31
+ declaration
14
32
  end
15
33
 
16
34
  def priority
@@ -0,0 +1,18 @@
1
+ module Foobara
2
+ module TypeDeclarations
3
+ module LazyElementTypes
4
+ module Model
5
+ module_function
6
+
7
+ def resolve(type)
8
+ attributes_type_declaration = type.declaration_data[:attributes_declaration]
9
+
10
+ type.element_types = TypeDeclarations.strict do
11
+ handler = Domain.current.foobara_type_builder.handler_for_class(Handlers::ExtendAttributesTypeDeclaration)
12
+ handler.process_value!(TypeDeclaration.new(attributes_type_declaration))
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -54,7 +54,7 @@ module Foobara
54
54
  end
55
55
 
56
56
  unless include_delegates
57
- declaration = Foobara::TypeDeclarations::Attributes.reject(declaration, *delegates.keys)
57
+ declaration = Foobara::TypeDeclarations::Attributes.reject(declaration, *foobara_delegates.keys)
58
58
  end
59
59
 
60
60
  Domain.current.foobara_type_from_declaration(declaration)
@@ -80,9 +80,11 @@ module Foobara
80
80
  if type.extends?(BuiltinTypes[:entity])
81
81
  target_class = type.target_class
82
82
 
83
- entry = foobara_type_declaration_value_at(declaration, DataPath.new(data_path).path)
84
- entry.clear
85
- entry.merge!(target_class.foobara_attributes_for_aggregate_update(initial: false))
83
+ set_foobara_type_declaration_value_at(
84
+ declaration,
85
+ DataPath.new(data_path).path,
86
+ target_class.foobara_attributes_for_aggregate_update(initial: false)
87
+ )
86
88
  end
87
89
  end
88
90
 
@@ -111,9 +113,12 @@ module Foobara
111
113
  # TODO: do we really need declaration_data? Why cant we use the type directly?
112
114
  # TODO: make this work with the type directly for performance reasons.
113
115
  primary_key_type_declaration = target_class.foobara_primary_key_type.declaration_data
114
- entry = foobara_type_declaration_value_at(declaration, DataPath.new(data_path).path)
115
- entry.clear
116
- entry.merge!(primary_key_type_declaration)
116
+
117
+ set_foobara_type_declaration_value_at(
118
+ declaration,
119
+ DataPath.new(data_path).path,
120
+ primary_key_type_declaration
121
+ )
117
122
  end
118
123
  end
119
124
 
@@ -131,31 +136,44 @@ module Foobara
131
136
  TypeDeclarations::Handlers::ExtendAttributesTypeDeclaration
132
137
  )
133
138
 
134
- handler.desugarize(
135
- type: "::attributes",
136
- element_type_declarations:
137
- )
139
+ declaration = TypeDeclaration.new(type: :attributes, element_type_declarations:)
140
+ declaration.is_absolutified = true
141
+ declaration.is_duped = true
142
+
143
+ handler.desugarize(declaration).declaration_data
138
144
  end
139
145
 
140
146
  private
141
147
 
142
- def foobara_type_declaration_value_at(declaration, path_parts)
143
- return declaration if path_parts.empty?
144
-
148
+ def set_foobara_type_declaration_value_at(declaration, path_parts, value)
145
149
  path_part, *path_parts = path_parts
146
150
 
147
- declaration = case path_part
148
- when :"#"
149
- declaration[:element_type_declaration]
150
- when Symbol, Integer
151
- declaration[:element_type_declarations][path_part]
152
- else
153
- # :nocov:
154
- raise "Bad path part #{path_part}"
155
- # :nocov:
156
- end
157
-
158
- foobara_type_declaration_value_at(declaration, path_parts)
151
+ case path_part
152
+ when :"#"
153
+ if path_parts.empty?
154
+ declaration[:element_type_declaration] = value
155
+ else
156
+ set_foobara_type_declaration_value_at(
157
+ declaration[:element_type_declaration],
158
+ path_parts,
159
+ value
160
+ )
161
+ end
162
+ when Symbol, Integer
163
+ if path_parts.empty?
164
+ declaration[:element_type_declarations][path_part] = value
165
+ else
166
+ set_foobara_type_declaration_value_at(
167
+ declaration[:element_type_declarations][path_part],
168
+ path_parts,
169
+ value
170
+ )
171
+ end
172
+ else
173
+ # :nocov:
174
+ raise "Bad path part #{path_part}"
175
+ # :nocov:
176
+ end
159
177
  end
160
178
  end
161
179
  end
@@ -98,9 +98,12 @@ module Foobara
98
98
  scopedish
99
99
  end
100
100
 
101
+ # TODO: make this thread-safe
101
102
  def foobara_register(scoped)
102
103
  foobara_registry.register(scoped)
103
104
 
105
+ # TODO: do we really need to clear the whole cache? Why not just the possible
106
+ # impacted keys based on scoped.scoped_path ?
104
107
  IsNamespace.clear_lru_cache!
105
108
  # awkward??
106
109
  scoped.scoped_namespace = self
@@ -134,48 +137,29 @@ module Foobara
134
137
  IsNamespace.lru_cache
135
138
  end
136
139
 
137
- def foobara_lookup(
138
- path,
139
- filter: nil,
140
- mode: LookupMode::GENERAL,
141
- visited: nil,
142
- initial: true
143
- )
144
- # TODO: make it so this is only necessary when initial
140
+ def foobara_lookup(path, filter: nil, mode: LookupMode::GENERAL)
141
+ LookupMode.validate!(mode)
145
142
  path = Namespace.to_registry_path(path)
146
- visited_key = [path, mode, initial, self]
147
143
 
148
- if initial
149
- lru_key = [path, mode, self, filter]
150
- found, value = lru_cache.get(lru_key)
151
- return value if found
144
+ lru_cache.cached([path, mode, self, filter]) do
145
+ visited = Set.new
146
+ foobara_lookup_without_cache(path, filter:, mode:, visited:)
152
147
  end
148
+ end
153
149
 
154
- return nil if visited&.include?(visited_key)
150
+ def foobara_lookup_without_cache(path, filter:, mode:, visited:)
151
+ visited_key = [path, mode, self]
152
+ return nil if visited.include?(visited_key)
155
153
 
156
- visited ||= Set.new
157
154
  visited << visited_key
158
155
 
159
- LookupMode.validate!(mode)
160
-
161
156
  if mode == LookupMode::RELAXED
162
- scoped = foobara_lookup(
163
- path,
164
- filter:,
165
- mode: LookupMode::GENERAL,
166
- visited:,
167
- initial: false
168
- )
169
- if scoped
170
- if initial
171
- lru_cache.set_if_missing(lru_key, scoped)
172
- end
157
+ scoped = foobara_lookup_without_cache(path, filter:, mode: LookupMode::GENERAL, visited:)
173
158
 
174
- return scoped
175
- end
159
+ return scoped if scoped
176
160
 
177
161
  candidates = foobara_children.map do |namespace|
178
- namespace.foobara_lookup(path, filter:, mode:, visited:, initial: false)
162
+ namespace.foobara_lookup_without_cache(path, filter:, mode:, visited:)
179
163
  end.compact
180
164
 
181
165
  if candidates.size > 1
@@ -186,11 +170,7 @@ module Foobara
186
170
  end
187
171
 
188
172
  scoped = candidates.first ||
189
- foobara_parent_namespace&.foobara_lookup(path, filter:, mode:, visited:, initial: false)
190
-
191
- if initial
192
- lru_cache.set_if_missing(lru_key, scoped)
193
- end
173
+ foobara_parent_namespace&.foobara_lookup_without_cache(path, filter:, mode:, visited:)
194
174
 
195
175
  return scoped
196
176
  end
@@ -204,25 +184,41 @@ module Foobara
204
184
  path = path[(foobara_root_namespace.scoped_path.size + 1)..]
205
185
  end
206
186
 
207
- return foobara_root_namespace.foobara_lookup(path, filter:, mode: LookupMode::ABSOLUTE, initial: true)
187
+ return foobara_lookup_without_cache(path, filter:, mode: LookupMode::ABSOLUTE, visited:)
188
+ end
189
+
190
+ root = foobara_root_namespace
191
+
192
+ if mode == LookupMode::ABSOLUTE
193
+ [
194
+ root,
195
+ *root.foobara_depends_on_namespaces.map(&:foobara_root_namespace)
196
+ ].uniq.each do |namespace|
197
+ scoped = namespace.foobara_lookup_without_cache(path,
198
+ filter:,
199
+ mode: LookupMode::CHILDREN_ONLY,
200
+ visited:)
201
+ return scoped if scoped
202
+ end
203
+
204
+ return nil
205
+ end
206
+
207
+ if mode == LookupMode::ABSOLUTE_SINGLE_NAMESPACE
208
+ return foobara_root_namespace.foobara_lookup_without_cache(path,
209
+ filter:,
210
+ mode: LookupMode::CHILDREN_ONLY,
211
+ visited:)
208
212
  end
209
213
 
210
214
  partial = foobara_registry.lookup(path, filter)
211
215
 
212
216
  if mode == LookupMode::DIRECT
213
- if initial
214
- lru_cache.set_if_missing(lru_key, partial)
215
- end
216
-
217
217
  return partial
218
218
  end
219
219
 
220
220
  if partial
221
221
  if partial.scoped_path == path
222
- if initial
223
- lru_cache.set_if_missing(lru_key, partial)
224
- end
225
-
226
222
  return partial
227
223
  end
228
224
  end
@@ -236,23 +232,15 @@ module Foobara
236
232
  scoped = _lookup_in(path, to_consider, filter:, visited:)
237
233
 
238
234
  if scoped
239
- if initial
240
- lru_cache.set_if_missing(lru_key, scoped)
241
- end
242
-
243
235
  return scoped
244
236
  end
245
237
 
246
- if [LookupMode::GENERAL, LookupMode::STRICT].include?(mode) && foobara_parent_namespace
247
- scoped = foobara_parent_namespace.foobara_lookup(
248
- path, filter:, mode: LookupMode::STRICT, visited:, initial: false
238
+ if (mode == LookupMode::GENERAL || mode == LookupMode::STRICT) && foobara_parent_namespace
239
+ scoped = foobara_parent_namespace.foobara_lookup_without_cache(
240
+ path, filter:, mode: LookupMode::STRICT, visited:
249
241
  )
250
242
 
251
243
  if scoped
252
- if initial
253
- lru_cache.set_if_missing(lru_key, scoped)
254
- end
255
-
256
244
  return scoped
257
245
  end
258
246
  end
@@ -261,10 +249,6 @@ module Foobara
261
249
  scoped = _lookup_in(path, foobara_depends_on_namespaces, filter:, visited:)
262
250
 
263
251
  if scoped
264
- if initial
265
- lru_cache.set_if_missing(lru_key, scoped)
266
- end
267
-
268
252
  return scoped
269
253
  end
270
254
  end
@@ -277,7 +261,7 @@ module Foobara
277
261
  end
278
262
 
279
263
  candidates = to_consider.map do |namespace|
280
- namespace.foobara_lookup(path, filter:, mode:, visited:, initial: false)
264
+ namespace.foobara_lookup_without_cache(path, filter:, mode:, visited:)
281
265
  end.compact
282
266
 
283
267
  if candidates.size > 1
@@ -286,27 +270,7 @@ module Foobara
286
270
  # :nocov:
287
271
  end
288
272
 
289
- scoped = candidates.first || partial
290
-
291
- if scoped
292
- if initial
293
- lru_cache.set_if_missing(lru_key, scoped)
294
- end
295
-
296
- return scoped
297
- end
298
-
299
- # As a last resort we'll see if we're trying to fetch a builtin type from a different namespace
300
- # TODO: these lookup modes are really confusing and were designed prior to having multiple root
301
- # namespaces playing a role in command connectors.
302
- if initial
303
- scoped = Namespace.global.foobara_lookup(path, filter:, mode: LookupMode::ABSOLUTE, visited:, initial: false)
304
-
305
- if scoped.is_a?(Types::Type) && scoped.builtin?
306
- lru_cache.set_if_missing(lru_key, scoped)
307
- scoped
308
- end
309
- end
273
+ candidates.first || partial
310
274
  end
311
275
 
312
276
  def foobara_parent_namespace
@@ -328,9 +292,10 @@ module Foobara
328
292
  def foobara_each(filter: nil, mode: Namespace::LookupMode::GENERAL, &)
329
293
  foobara_registry.each_scoped(filter:, &)
330
294
 
331
- return if mode == Namespace::LookupMode::DIRECT
332
-
333
- if [Namespace::LookupMode::GENERAL, Namespace::LookupMode::ABSOLUTE].include?(mode)
295
+ if mode == LookupMode::GENERAL ||
296
+ mode == LookupMode::CHILDREN_ONLY ||
297
+ mode == LookupMode::ABSOLUTE ||
298
+ mode == LookupMode::ABSOLUTE_SINGLE_NAMESPACE
334
299
  foobara_children.each do |child|
335
300
  child.foobara_each(filter:, mode:, &)
336
301
  end
@@ -414,6 +379,10 @@ module Foobara
414
379
  Foobara::Namespace::UnambiguousRegistry
415
380
  when Foobara::Namespace::BaseRegistry::WouldMakeRegistryAmbiguousError
416
381
  Foobara::Namespace::AmbiguousRegistry
382
+ else
383
+ # :nocov:
384
+ raise ArgumentError, "Not sure how to upgrade a #{error.class}"
385
+ # :nocov:
417
386
  end
418
387
 
419
388
  old_registry = foobara_registry
@@ -442,19 +411,18 @@ module Foobara
442
411
  end
443
412
 
444
413
  matching_children.sort_by(&:first).reverse.each do |(matching_child_score, matching_child)|
445
- scoped = matching_child.foobara_lookup(
414
+ scoped = matching_child.foobara_lookup_without_cache(
446
415
  path[matching_child_score..],
447
- mode: LookupMode::ABSOLUTE,
416
+ mode: LookupMode::CHILDREN_ONLY,
448
417
  filter:,
449
- visited:,
450
- initial: false
418
+ visited:
451
419
  )
452
420
 
453
421
  return scoped if scoped
454
422
  end
455
423
 
456
424
  last_resort.uniq.each do |namespace|
457
- scoped = namespace.foobara_lookup(path, filter:, mode: LookupMode::ABSOLUTE, visited:, initial: false)
425
+ scoped = namespace.foobara_lookup_without_cache(path, filter:, mode: LookupMode::CHILDREN_ONLY, visited:)
458
426
  return scoped if scoped
459
427
  end
460
428
 
@@ -1,6 +1,6 @@
1
1
  module Foobara
2
2
  class Namespace
3
- # TODO: need to define these better...
3
+ # TODO: need to define these better/more intuitively
4
4
  # use-cases
5
5
  # 1. general: just general lookup. find it wherever the heck it might be
6
6
  # children: y
@@ -17,6 +17,14 @@ module Foobara
17
17
  # 4. absolute
18
18
  # children: y
19
19
  # parent: n
20
+ # dependent: y
21
+ # 5. absolute_single_namespace
22
+ # children: y
23
+ # parent: n
24
+ # dependent: n
25
+ # 6. children_only (internal use... absolute and absolute_single_namespace jump to top, children only does not)
26
+ # children: y
27
+ # parent: n
20
28
  # dependent: n
21
29
  # TODO: don't we have an enumerated class/project for this?
22
30
  module LookupMode
@@ -25,7 +33,10 @@ module Foobara
25
33
  DIRECT = :direct
26
34
  STRICT = :strict
27
35
  ABSOLUTE = :absolute
28
- ALL = [GENERAL, RELAXED, DIRECT, STRICT, ABSOLUTE].freeze
36
+ ABSOLUTE_SINGLE_NAMESPACE = :absolute_single_namespace
37
+ CHILDREN_ONLY = :children_only
38
+
39
+ ALL = [GENERAL, RELAXED, DIRECT, STRICT, ABSOLUTE, ABSOLUTE_SINGLE_NAMESPACE, CHILDREN_ONLY].freeze
29
40
 
30
41
  class << self
31
42
  def validate!(mode)
@@ -243,6 +243,7 @@ module Foobara
243
243
  # I guess we could just iterate over all objects and patch up any with matching prefixes?
244
244
  # is this expensive to have to look at all of them or no? I guess at least it's a one-time thing.
245
245
  # TODO: somehow look things up by prefixes since we know mod's path
246
+ # TODO: can't there be multiple namespace roots??
246
247
  Foobara.foobara_root_namespace.foobara_each do |scoped|
247
248
  parent = scoped.scoped_namespace
248
249
  next if parent == mod
@@ -41,6 +41,8 @@ module Foobara
41
41
  registry.each_value(&)
42
42
  end
43
43
 
44
+ private
45
+
44
46
  def to_key(scoped)
45
47
  if scoped.scoped_prefix
46
48
  raise RegisteringScopedWithPrefixError,
@@ -80,7 +80,26 @@ module Foobara
80
80
 
81
81
  # TODO: this belongs elsewhere
82
82
  def each_table(&)
83
- tables.values.each(&)
83
+ @ordered_tables ||= if tables.size <= 1
84
+ tables.values
85
+ else
86
+ entity_class_to_table = {}
87
+ entity_classes = []
88
+
89
+ tables.each_value do |table|
90
+ entity_class = table.entity_class
91
+ entity_classes << entity_class
92
+ entity_class_to_table[entity_class] = table
93
+ end
94
+
95
+ ordered_entity_classes = EntityBase.order_entity_classes(entity_classes)
96
+
97
+ ordered_entity_classes.map do |entity_class|
98
+ entity_class_to_table[entity_class]
99
+ end
100
+ end
101
+
102
+ @ordered_tables.each(&)
84
103
  end
85
104
 
86
105
  def rollback!(because_of = nil)