Class: RBS::Validator
Relationships & Source Files | |
Inherits: | Object |
Defined in: | lib/rbs/validator.rb |
Class Method Summary
- .new(env:, resolver:) ⇒ Validator constructor
Instance Attribute Summary
- #definition_builder readonly
- #env readonly
- #resolver readonly
Instance Method Summary
- #absolute_type(type, context:)
- #type_alias_dependency
- #type_alias_regularity
- #validate_method_definition(method_def, type_name:)
-
#validate_type(type, context:)
Validates presence of the relative type, and application arity match.
- #validate_type_alias(entry:)
- #validate_type_params(params, type_name:, method_name: nil, location:)
Constructor Details
.new(env:, resolver:) ⇒ Validator
# File 'lib/rbs/validator.rb', line 9
def initialize(env:, resolver:) @env = env @resolver = resolver @definition_builder = DefinitionBuilder.new(env: env) end
Instance Attribute Details
#definition_builder (readonly)
[ GitHub ]# File 'lib/rbs/validator.rb', line 7
attr_reader :definition_builder
#env (readonly)
[ GitHub ]# File 'lib/rbs/validator.rb', line 5
attr_reader :env
#resolver (readonly)
[ GitHub ]# File 'lib/rbs/validator.rb', line 6
attr_reader :resolver
Instance Method Details
#absolute_type(type, context:)
[ GitHub ]# File 'lib/rbs/validator.rb', line 15
def absolute_type(type, context:) type.map_type_name do |type_name, _, type| resolver.resolve(type_name, context: context) || yield(type) end end
#type_alias_dependency
[ GitHub ]# File 'lib/rbs/validator.rb', line 149
def type_alias_dependency @type_alias_dependency ||= TypeAliasDependency.new(env: env) end
#type_alias_regularity
[ GitHub ]# File 'lib/rbs/validator.rb', line 153
def type_alias_regularity @type_alias_regularity ||= TypeAliasRegularity.validate(env: env) end
#validate_method_definition(method_def, type_name:)
[ GitHub ]# File 'lib/rbs/validator.rb', line 100
def validate_method_definition(method_def, type_name:) method_def.types.each do |method_type| unless method_type.type_params.empty? loc = method_type.location&.aref(:type_params) validate_type_params( method_type.type_params, type_name: type_name, method_name: method_def.name, location: loc ) end end end
#validate_type(type, context:)
Validates presence of the relative type, and application arity match.
# File 'lib/rbs/validator.rb', line 22
def validate_type(type, context:) case type when Types::ClassInstance, Types::Interface, Types::Alias # @type var type: Types::ClassInstance | Types::Interface | Types::Alias if type.name.namespace.relative? type = _ = absolute_type(type, context: context) do |_| NoTypeFoundError.check!(type.name.absolute!, env: env, location: type.location) end end definition_builder.validate_type_name(type.name, type.location) type_params = case type when Types::ClassInstance env.class_decls[type.name].type_params when Types::Interface env.interface_decls[type.name].decl.type_params when Types::Alias env.alias_decls[type.name].decl.type_params end InvalidTypeApplicationError.check!( type_name: type.name, args: type.args, params: type_params.each.map(&:name), location: type.location ) when Types::ClassSingleton definition_builder.validate_type_presence(type) end type.each_type do |type| validate_type(type, context: context) end end
#validate_type_alias(entry:)
[ GitHub ]# File 'lib/rbs/validator.rb', line 59
def validate_type_alias(entry:) type_name = entry.decl.name if type_alias_dependency.circular_definition?(type_name) location = entry.decl.location or raise raise RecursiveTypeAliasError.new(alias_names: [type_name], location: location) end if diagnostic = type_alias_regularity.nonregular?(type_name) location = entry.decl.location or raise raise NonregularTypeAliasError.new(diagnostic: diagnostic, location: location) end unless entry.decl.type_params.empty? calculator = VarianceCalculator.new(builder: definition_builder) result = calculator.in_type_alias(name: type_name) if set = result.incompatible?(entry.decl.type_params) set.each do |param_name| param = entry.decl.type_params.find {|param| param.name == param_name } or raise next if param.unchecked? raise InvalidVarianceAnnotationError.new( type_name: type_name, param: param, location: entry.decl.type.location ) end end validate_type_params( entry.decl.type_params, type_name: type_name, location: entry.decl.location&.aref(:type_params) ) end if block_given? yield entry.decl.type end end
#validate_type_params(params, type_name:, method_name: nil, location:)
[ GitHub ]# File 'lib/rbs/validator.rb', line 115
def validate_type_params(params, type_name: , method_name: nil, location:) # @type var each_node: TSort::_EachNode[Symbol] each_node = __skip__ = -> (&block) do params.each do |param| block[param.name] end end # @type var each_child: TSort::_EachChild[Symbol] each_child = __skip__ = -> (name, &block) do if param = params.find {|p| p.name == name } if b = param.upper_bound b.free_variables.each do |tv| block[tv] end end end end TSort.each_strongly_connected_component(each_node, each_child) do |names| if names.size > 1 params = names.map do |name| params.find {|param| param.name == name} or raise end raise CyclicTypeParameterBound.new( type_name: type_name, method_name: method_name, params: params, location: location ) end end end