Class: MilkTea::ModuleBinder
- Inherits:
-
Object
- Object
- MilkTea::ModuleBinder
- Defined in:
- lib/milk_tea/core/module_binder.rb
Instance Method Summary collapse
- #exported_declaration?(analysis, declaration) ⇒ Boolean
- #exported_interface_binding?(interface, analysis, exported_interfaces) ⇒ Boolean
- #exported_interface_implementations(analysis, exported_types, exported_interfaces) ⇒ Object
- #exported_interface_methods?(receiver_type, interface, analysis, exported_types) ⇒ Boolean
- #exported_method_receiver?(receiver_type, analysis, exported_types) ⇒ Boolean
- #exported_method_receiver_argument?(argument, analysis, exported_types) ⇒ Boolean
- #exported_methods(analysis, exported_types) ⇒ Object
- #imported_interface_binding?(interface, imports) ⇒ Boolean
- #imported_receiver_type?(receiver_type, imports) ⇒ Boolean
- #module_binding(analysis) ⇒ Object
Instance Method Details
#exported_declaration?(analysis, declaration) ⇒ Boolean
64 65 66 67 68 69 |
# File 'lib/milk_tea/core/module_binder.rb', line 64 def exported_declaration?(analysis, declaration) return true if analysis.module_kind == :raw_module return false unless declaration.respond_to?(:visibility) declaration.visibility == :public end |
#exported_interface_binding?(interface, analysis, exported_interfaces) ⇒ Boolean
133 134 135 136 137 |
# File 'lib/milk_tea/core/module_binder.rb', line 133 def exported_interface_binding?(interface, analysis, exported_interfaces) return true if exported_interfaces.value?(interface) imported_interface_binding?(interface, analysis.imports) end |
#exported_interface_implementations(analysis, exported_types, exported_interfaces) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/milk_tea/core/module_binder.rb', line 98 def exported_interface_implementations(analysis, exported_types, exported_interfaces) implemented_interfaces = {} private_implemented_interfaces = {} analysis.implemented_interfaces.each do |receiver_type, interfaces| public_interfaces = [] hidden_interfaces = [] interfaces.each do |interface| visible = exported_method_receiver?(receiver_type, analysis, exported_types) && exported_interface_binding?(interface, analysis, exported_interfaces) && exported_interface_methods?(receiver_type, interface, analysis, exported_types) if visible public_interfaces << interface else hidden_interfaces << interface end end implemented_interfaces[receiver_type] = public_interfaces.freeze unless public_interfaces.empty? private_implemented_interfaces[receiver_type] = hidden_interfaces.freeze unless hidden_interfaces.empty? end [implemented_interfaces.freeze, private_implemented_interfaces.freeze] end |
#exported_interface_methods?(receiver_type, interface, analysis, exported_types) ⇒ Boolean
124 125 126 127 128 129 130 131 |
# File 'lib/milk_tea/core/module_binder.rb', line 124 def exported_interface_methods?(receiver_type, interface, analysis, exported_types) return false unless exported_method_receiver?(receiver_type, analysis, exported_types) interface.methods.each_key.all? do |method_name| binding = analysis.methods.fetch(receiver_type, {})[method_name] binding && binding.ast.respond_to?(:visibility) && binding.ast.visibility == :public end end |
#exported_method_receiver?(receiver_type, analysis, exported_types) ⇒ Boolean
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/milk_tea/core/module_binder.rb', line 139 def exported_method_receiver?(receiver_type, analysis, exported_types) return true if receiver_type.is_a?(Types::StringView) return true if receiver_type.is_a?(Types::Primitive) return true if receiver_type.is_a?(Types::Vector) return true if receiver_type.is_a?(Types::Matrix) return true if receiver_type.is_a?(Types::Quaternion) return true if receiver_type.is_a?(Types::SoA) return true if receiver_type.is_a?(Types::Simd) return true if receiver_type.is_a?(Types::Span) return true if receiver_type.is_a?(Types::Task) return true if receiver_type.is_a?(Types::Dyn) return true if exported_types.value?(receiver_type) return true if imported_receiver_type?(receiver_type, analysis.imports) return exported_method_receiver?(receiver_type.base, analysis, exported_types) if receiver_type.is_a?(Types::Nullable) return receiver_type.arguments.all? { |argument| exported_method_receiver_argument?(argument, analysis, exported_types) } if receiver_type.is_a?(Types::GenericInstance) return exported_types.value?(receiver_type.definition) || imported_receiver_type?(receiver_type.definition, analysis.imports) if receiver_type.is_a?(Types::VariantInstance) receiver_type.is_a?(Types::StructInstance) && (exported_types.value?(receiver_type.definition) || imported_receiver_type?(receiver_type.definition, analysis.imports)) end |
#exported_method_receiver_argument?(argument, analysis, exported_types) ⇒ Boolean
160 161 162 163 164 165 |
# File 'lib/milk_tea/core/module_binder.rb', line 160 def exported_method_receiver_argument?(argument, analysis, exported_types) return true if argument.is_a?(Types::LiteralTypeArg) return true if argument.is_a?(Types::TypeVar) exported_method_receiver?(argument, analysis, exported_types) end |
#exported_methods(analysis, exported_types) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/milk_tea/core/module_binder.rb', line 71 def exported_methods(analysis, exported_types) methods = {} private_methods = {} analysis.methods.each do |receiver_type, bindings| public_bindings = {} hidden_bindings = {} bindings.each do |name, binding| visible = binding.ast.respond_to?(:visibility) && binding.ast.visibility == :public && exported_method_receiver?(receiver_type, analysis, exported_types) if visible public_bindings[name] = binding else hidden_bindings[name] = binding end end methods[receiver_type] = public_bindings unless public_bindings.empty? private_methods[receiver_type] = hidden_bindings unless hidden_bindings.empty? end [methods, private_methods] end |
#imported_interface_binding?(interface, imports) ⇒ Boolean
175 176 177 178 179 180 181 |
# File 'lib/milk_tea/core/module_binder.rb', line 175 def imported_interface_binding?(interface, imports) imports.each_value do |module_binding| return true if module_binding.interfaces.value?(interface) end false end |
#imported_receiver_type?(receiver_type, imports) ⇒ Boolean
167 168 169 170 171 172 173 |
# File 'lib/milk_tea/core/module_binder.rb', line 167 def imported_receiver_type?(receiver_type, imports) imports.each_value do |module_binding| return true if module_binding.types.value?(receiver_type) end false end |
#module_binding(analysis) ⇒ Object
5 6 7 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 |
# File 'lib/milk_tea/core/module_binder.rb', line 5 def module_binding(analysis) types = {} type_declarations = {} interfaces = {} attributes = {} private_types = {} private_interfaces = {} private_attributes = {} values = {} private_values = {} functions = {} private_functions = {} analysis.ast.declarations.each do |declaration| case declaration when AST::StructDecl, AST::UnionDecl, AST::VariantDecl, AST::EnumDecl, AST::FlagsDecl, AST::OpaqueDecl, AST::TypeAliasDecl type_declarations[declaration.name] = declaration target = exported_declaration?(analysis, declaration) ? types : private_types target[declaration.name] = analysis.types.fetch(declaration.name) when AST::InterfaceDecl target = exported_declaration?(analysis, declaration) ? interfaces : private_interfaces target[declaration.name] = analysis.interfaces.fetch(declaration.name) when AST::AttributeDecl target = exported_declaration?(analysis, declaration) ? attributes : private_attributes target[declaration.name] = analysis.attributes.fetch(declaration.name) when AST::ConstDecl, AST::VarDecl, AST::EventDecl target = exported_declaration?(analysis, declaration) ? values : private_values target[declaration.name] = analysis.values.fetch(declaration.name) when AST::FunctionDef, AST::ExternFunctionDecl, AST::ForeignFunctionDecl target = exported_declaration?(analysis, declaration) ? functions : private_functions target[declaration.name] = analysis.functions.fetch(declaration.name) end end methods, private_methods = exported_methods(analysis, types) implemented_interfaces, private_implemented_interfaces = exported_interface_implementations(analysis, types, interfaces) ModuleBinding.new( name: analysis.module_name, types:, type_declarations:, interfaces:, attributes:, attribute_applications: analysis.attribute_applications, values:, functions:, methods:, implemented_interfaces:, imports: analysis.imports, private_types:, private_interfaces:, private_attributes:, private_values:, private_functions:, private_methods:, private_implemented_interfaces:, ) end |