Class: Graphlyte::Editors::WithVariables
- Inherits:
-
Object
- Object
- Graphlyte::Editors::WithVariables
- Defined in:
- lib/graphlyte/editors/with_variables.rb
Overview
Use variable values to infer missing variables in the query signature
Direct Known Subclasses
Constant Summary collapse
- CannotInfer =
Class.new(StandardError)
- TypeMismatch =
Class.new(StandardError)
Instance Method Summary collapse
- #annotate_types(doc) ⇒ Object
- #cannot_infer!(ref) ⇒ Object
- #current_operation_variables(operation) ⇒ Object
- #edit(doc) ⇒ Object
- #infer(variables, added, doc, ref) ⇒ Object
- #infer_operation(operation, refs, document) ⇒ Object
- #infer_variable_type(references) ⇒ Object
-
#initialize(schema, operation, variables) ⇒ WithVariables
constructor
A new instance of WithVariables.
- #runtime_type_of(ref) ⇒ Object
- #select_operation(doc) ⇒ Object
Constructor Details
#initialize(schema, operation, variables) ⇒ WithVariables
Returns a new instance of WithVariables.
15 16 17 18 19 |
# File 'lib/graphlyte/editors/with_variables.rb', line 15 def initialize(schema, operation, variables) @schema = schema @operation = operation @variables = variables end |
Instance Method Details
#annotate_types(doc) ⇒ Object
31 32 33 |
# File 'lib/graphlyte/editors/with_variables.rb', line 31 def annotate_types(doc) Editors::AnnotateTypes.new(@schema).edit(doc) if @schema end |
#cannot_infer!(ref) ⇒ Object
82 83 84 |
# File 'lib/graphlyte/editors/with_variables.rb', line 82 def cannot_infer!(ref) raise CannotInfer, ref.variable end |
#current_operation_variables(operation) ⇒ Object
64 65 66 67 |
# File 'lib/graphlyte/editors/with_variables.rb', line 64 def current_operation_variables(operation) operation.variables ||= [] operation.variables.to_h { [_1.variable, _1] } end |
#edit(doc) ⇒ Object
21 22 23 24 25 26 27 28 29 |
# File 'lib/graphlyte/editors/with_variables.rb', line 21 def edit(doc) select_operation(doc) annotate_types(doc) references = Editors::CollectVariableReferences.new.edit(doc) editor = infer_variable_type(references) editor.edit(doc) end |
#infer(variables, added, doc, ref) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/graphlyte/editors/with_variables.rb', line 69 def infer(variables, added, doc, ref) var = doc.variables.fetch(ref.variable, ref.to_definition) type = var.type || ref.inferred_type || runtime_type_of(ref) if type var.type ||= type variables << var added[ref.variable] = var else cannot_infer!(ref) end end |
#infer_operation(operation, refs, document) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/graphlyte/editors/with_variables.rb', line 48 def infer_operation(operation, refs, document) current_vars = current_operation_variables(operation) added = {} refs.to_a.reject { current_vars[_1.variable] }.each do |ref| # Only way this could happen is if `uniq` produces duplicate names # And that can only happen if there are two types inferred # for the same reference. if (prev = added[ref.variable]) raise TypeMismatch, "#{ref.variable}: #{ref.inferred_type} != #{prev.type}" end infer(operation.variables, added, document, ref) end end |
#infer_variable_type(references) ⇒ Object
39 40 41 42 43 44 45 46 |
# File 'lib/graphlyte/editors/with_variables.rb', line 39 def infer_variable_type(references) Editor.new.on_operation do |operation, editor| refs = references[operation.class][operation.name] next unless refs infer_operation(operation, refs, editor.document) end end |
#runtime_type_of(ref) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/graphlyte/editors/with_variables.rb', line 86 def runtime_type_of(ref) value = @variables[ref.variable] case value when Integer Syntax::Type.non_null('Int') when Float Syntax::Type.non_null('Float') when String Syntax::Type.non_null('String') when Date Syntax::Type.non_null('Date') when TrueClass, FalseClass Syntax::Type.non_null('Boolean') when Array Syntax::Type.list_of(runtime_type_of(value.first)) unless value.empty? end end |
#select_operation(doc) ⇒ Object
35 36 37 |
# File 'lib/graphlyte/editors/with_variables.rb', line 35 def select_operation(doc) Editors::SelectOperation.new(@operation).edit(doc) if @operation end |