Module: Jade::Frontend::SemanticAnalysis::Implementation
- Extended by:
- Helper, Implementation
- Included in:
- Implementation
- Defined in:
- lib/jade/frontend/semantic_analysis/implementation.rb
Instance Method Summary collapse
Methods included from Helper
analyze_duplicate_fields, analyze_in_parallel, analyze_in_sequence, analyze_node, bind, collect_vars, lookup, validate_type_symbol
Instance Method Details
#analyze(node, registry, scope, entry) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/jade/frontend/semantic_analysis/implementation.rb', line 8 def analyze(node, registry, scope, entry) node => AST::Implementation(interface:, applied_type:, extends:, functions:) interface_ref = entry.lookup_type(interface).to_ref type_sym = lookup_applied_type(applied_type, entry) type_ref = type_sym.to_ref impl_symbol = entry.implementations[[ interface_ref.qualified_name, type_ref.qualified_name, ]] functions_r = analyze_in_parallel(functions, registry, scope, entry) make_error = ->(klass, **kw) { klass.new(entry.name, node.range, **kw) } type_is_local = entry.defined_types.key?(local_type_name(applied_type)) unless entry.defined_types.key?(interface) || type_is_local return make_error .( Error::OrphanImplementation, interface: entry.lookup_type(interface).qname, type: type_sym.qname, ) .then { Result[node, [it], scope] } end iface_sym = registry.lookup(interface_ref) extends_errors = extends .flat_map do |iface_name| ext_sym = entry.lookup_type(iface_name) next [] if entry.implementations.key?([ext_sym.qname, type_sym.qname]) [make_error.( Error::MissingExtendsImplementation, interface: ext_sym.qname, type: type_sym.qname, required_by: iface_sym.qname, )] end cycle_errors = if extends_errors.empty? && cycle_in_extends?(iface_sym.qname, type_sym.qname, entry) [make_error.(Error::CircularExtends, interface: iface_sym.qname, type: type_sym.qname)] else [] end type_param_errors = case [parameterized_interface?(iface_sym), type_sym] in [true, { type_params: [] }] [make_error.(Error::TypeParamRequired, interface: iface_sym.qname, type: type_sym.qname)] else [] end Result .combine(node, scope:, functions: functions_r) .map_node { it.with(symbol: impl_symbol) } .add_errors( fn_name_errors(functions, iface_sym, &make_error) + extends_errors + cycle_errors + type_param_errors, ) end |