From f55b1d466f4c7db71a83bdd9dee821641148c3d8 Mon Sep 17 00:00:00 2001 From: Jeremy Woertink Date: Sat, 15 Jun 2024 14:44:20 -0700 Subject: [PATCH] I think I've caught all the options this time. Fixes #92 --- spec/habitat_spec.cr | 15 ++++++++++++--- src/habitat.cr | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/spec/habitat_spec.cr b/spec/habitat_spec.cr index 445633f..6b22bee 100644 --- a/spec/habitat_spec.cr +++ b/spec/habitat_spec.cr @@ -141,14 +141,23 @@ end class ASettingForEverything alias Dot = Int32 Habitat.create do - setting proc_notation : (String -> Nil)? + setting proc_notation : (String -> Nil) + setting nilable_proc_notation : (String -> Nil)? setting alias_setting : Dot = 3 + setting nilable_alias_setting : Dot? setting point : Point = Point.new(x: 3, y: 4) + setting nilable_point : Point? setting mod : SuperMod + setting nilable_mod : SuperMod? setting parent : Parent = Settings::Index.new + setting nilable_parent : Parent? setting things : String | Int32 + setting nilable_things : String | Int32 | Nil setting bomb : Bomb - setting fruit : Fruit(Bomb) + setting nilable_bomb : Bomb? + setting generic : Fruit(Bomb) + setting nilable_generic : Fruit(Bomb)? + setting nilable_generic_of_nilable : Fruit(Bomb?)? end end @@ -169,7 +178,7 @@ describe Habitat do settings.mod = Fruit(String).new settings.things = ["hi", 1].sample settings.bomb = Tacos.new - settings.fruit = Fruit(Bomb).new + settings.generic = Fruit(Bomb).new end end diff --git a/src/habitat.cr b/src/habitat.cr index 1d3b467..9233d9b 100644 --- a/src/habitat.cr +++ b/src/habitat.cr @@ -34,7 +34,7 @@ class Habitat {% for type in TYPES_WITH_HABITAT %} {% for setting in type.constant(:HABITAT_SETTINGS) %} {% if !setting[:decl].type.is_a?(Union) || - (setting[:decl].type.is_a?(Union) && !setting[:decl].type.types.any? { |t| t.is_a?(ProcNotation) ? false : t.names.includes?(Nil.id) }) %} + (setting[:decl].type.is_a?(Union) && !setting[:decl].type.types.any? { |t| (t.is_a?(ProcNotation) || t.is_a?(Generic)) ? false : t.names.includes?(Nil.id) }) %} if {{ type }}.settings.{{ setting[:decl].var }}?.nil? raise MissingSettingError.new {{ type }}, setting_name: {{ setting[:decl].var.stringify }}, example: {{ setting[:example] }} end @@ -231,7 +231,7 @@ class Habitat # NOTE: We can't use the macro level `type.resolve.nilable?` here because # there's a few declaration types that don't respond to it which would make the logic # more complex. Metaclass, and Proc types are the main, but there may be more. - {% if decl.type.is_a?(Union) && decl.type.types.any? { |t| t.is_a?(ProcNotation) ? false : t.names.includes?(Nil.id) } %} + {% if decl.type.is_a?(Union) && decl.type.types.any? { |t| (t.is_a?(ProcNotation) || t.is_a?(Generic)) ? false : t.names.includes?(Nil.id) } %} {% nilable = true %} {% else %} {% nilable = false %}