Class: RBS::TypeAliasRegularity
- Inherits:
-
Object
- Object
- RBS::TypeAliasRegularity
- Defined in:
- lib/rbs/type_alias_regularity.rb
Defined Under Namespace
Classes: Diagnostic
Instance Attribute Summary collapse
-
#builder ⇒ Object
readonly
Returns the value of attribute builder.
-
#diagnostics ⇒ Object
readonly
Returns the value of attribute diagnostics.
-
#env ⇒ Object
readonly
Returns the value of attribute env.
Class Method Summary collapse
Instance Method Summary collapse
- #build_alias_type(name) ⇒ Object
- #compatible_args?(args1, args2) ⇒ Boolean
- #each_alias_type(type, &block) ⇒ Object
- #each_mutual_alias_defs(&block) ⇒ Object
-
#initialize(env:) ⇒ TypeAliasRegularity
constructor
A new instance of TypeAliasRegularity.
- #nonregular?(type_name) ⇒ Boolean
- #validate ⇒ Object
- #validate_alias_type(alias_type, names, types) ⇒ Object
Constructor Details
#initialize(env:) ⇒ TypeAliasRegularity
Returns a new instance of TypeAliasRegularity.
16 17 18 19 20 |
# File 'lib/rbs/type_alias_regularity.rb', line 16 def initialize(env:) @env = env @builder = DefinitionBuilder.new(env: env) @diagnostics = {} end |
Instance Attribute Details
#builder ⇒ Object (readonly)
Returns the value of attribute builder.
14 15 16 |
# File 'lib/rbs/type_alias_regularity.rb', line 14 def builder @builder end |
#diagnostics ⇒ Object (readonly)
Returns the value of attribute diagnostics.
14 15 16 |
# File 'lib/rbs/type_alias_regularity.rb', line 14 def diagnostics @diagnostics end |
#env ⇒ Object (readonly)
Returns the value of attribute env.
14 15 16 |
# File 'lib/rbs/type_alias_regularity.rb', line 14 def env @env end |
Class Method Details
.validate(env:) ⇒ Object
120 121 122 123 124 |
# File 'lib/rbs/type_alias_regularity.rb', line 120 def self.validate(env:) self.new(env: env).tap do |validator| validator.validate() end end |
Instance Method Details
#build_alias_type(name) ⇒ Object
61 62 63 64 65 66 67 |
# File 'lib/rbs/type_alias_regularity.rb', line 61 def build_alias_type(name) entry = env.type_alias_decls[name] or return unless entry.decl.type_params.empty? as = entry.decl.type_params.each.map {|param| Types::Variable.new(name: param.name, location: nil) } Types::Alias.new(name: name, args: as, location: nil) end end |
#compatible_args?(args1, args2) ⇒ Boolean
69 70 71 72 73 74 75 76 77 |
# File 'lib/rbs/type_alias_regularity.rb', line 69 def compatible_args?(args1, args2) if args1.size == args2.size args1.zip(args2).all? do |t1, t2| t1.is_a?(Types::Bases::Any) || t2.is_a?(Types::Bases::Any) || t1 == t2 end end end |
#each_alias_type(type, &block) ⇒ Object
110 111 112 113 114 115 116 117 118 |
# File 'lib/rbs/type_alias_regularity.rb', line 110 def each_alias_type(type, &block) if type.is_a?(RBS::Types::Alias) yield type end type.each_type do |ty| each_alias_type(ty, &block) end end |
#each_mutual_alias_defs(&block) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/rbs/type_alias_regularity.rb', line 83 def each_mutual_alias_defs(&block) # @type var each_node: ^() { (TypeName) -> void } -> void each_node = -> (&block) do env.type_alias_decls.each_value do |decl| if normalized = env.normalize_type_name?(decl.name) block[normalized] end end end # @type var each_child: ^(TypeName) { (TypeName) -> void } -> void each_child = -> (name, &block) do if env.type_alias_decls.key?(name) type = builder.(name) each_alias_type(type) do |ty| if normalized = env.normalize_type_name?(ty.name) block[normalized] end end end end TSort.each_strongly_connected_component(each_node, each_child) do |names| yield Set.new(names) end end |
#nonregular?(type_name) ⇒ Boolean
79 80 81 |
# File 'lib/rbs/type_alias_regularity.rb', line 79 def nonregular?(type_name) diagnostics[env.normalize_type_name!(type_name)] end |
#validate ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/rbs/type_alias_regularity.rb', line 22 def validate diagnostics.clear each_mutual_alias_defs do |names| # Find the first generic type alias in strongly connected component. # This is to skip the regularity check when the alias is not generic. names.each do |name| # @type break: nil if type = build_alias_type(name) # Running validation only once from the first generic type is enough, because they are mutual recursive definition. validate_alias_type(type, names, {}) break end end end end |
#validate_alias_type(alias_type, names, types) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/rbs/type_alias_regularity.rb', line 39 def validate_alias_type(alias_type, names, types) alias_name = env.normalize_type_name?(alias_type.name) or return if names.include?(alias_name) if ex_type = types[alias_name] unless compatible_args?(ex_type.args, alias_type.args) diagnostics[alias_name] ||= Diagnostic.new(type_name: alias_type.name, nonregular_type: alias_type) end return else types[alias_type.name] = alias_type end = builder.(alias_name, alias_type.args) each_alias_type() do |at| validate_alias_type(at, names, types) end end end |