Class: DAP::Base
- Inherits:
-
Object
- Object
- DAP::Base
- Defined in:
- lib/dap/base.rb
Overview
Base class for DAP types
Direct Known Subclasses
AttachRequestArguments, Breakpoint, BreakpointEventBody, BreakpointLocation, BreakpointLocationsArguments, BreakpointLocationsResponseBody, CancelArguments, Capabilities, CapabilitiesEventBody, Checksum, ColumnDescriptor, CompletionItem, CompletionsArguments, CompletionsResponseBody, ContinueArguments, ContinueResponseBody, ContinuedEventBody, DataBreakpoint, DataBreakpointInfoArguments, DataBreakpointInfoResponseBody, DisassembleArguments, DisassembleResponseBody, DisassembledInstruction, DisconnectArguments, ErrorResponseBody, EvaluateArguments, EvaluateResponseBody, ExceptionBreakpointsFilter, ExceptionDetails, ExceptionInfoArguments, ExceptionInfoResponseBody, ExceptionOptions, ExceptionPathSegment, ExitedEventBody, FunctionBreakpoint, GotoArguments, GotoTarget, GotoTargetsArguments, GotoTargetsResponseBody, InitializeRequestArguments, InstructionBreakpoint, InvalidatedEventBody, LaunchRequestArguments, LoadedSourceEventBody, LoadedSourcesResponseBody, Message, Module, ModuleEventBody, ModulesArguments, ModulesResponseBody, NextArguments, OutputEventBody, PauseArguments, ProcessEventBody, ProgressEndEventBody, ProgressStartEventBody, ProgressUpdateEventBody, ProtocolMessage, ReadMemoryArguments, ReadMemoryResponseBody, RestartFrameArguments, ReverseContinueArguments, RunInTerminalRequestArguments, RunInTerminalResponseBody, Scope, ScopesArguments, ScopesResponseBody, SetBreakpointsArguments, SetBreakpointsResponseBody, SetDataBreakpointsArguments, SetDataBreakpointsResponseBody, SetExceptionBreakpointsArguments, SetExpressionArguments, SetExpressionResponseBody, SetFunctionBreakpointsArguments, SetFunctionBreakpointsResponseBody, SetInstructionBreakpointsArguments, SetInstructionBreakpointsResponseBody, SetVariableArguments, SetVariableResponseBody, Source, SourceArguments, SourceBreakpoint, SourceResponseBody, StackFrame, StackTraceArguments, StackTraceResponseBody, StepBackArguments, StepInArguments, StepInTarget, StepInTargetsArguments, StepInTargetsResponseBody, StepOutArguments, StoppedEventBody, TerminateArguments, TerminateThreadsArguments, TerminatedEventBody, Thread, ThreadEventBody, ThreadsResponseBody, ValueFormat, Variable, VariablePresentationHint, VariablesArguments, VariablesResponseBody
Class Method Summary collapse
-
.build(values) {|values| ... } ⇒ Object
Build an instance of a DAP type.
-
.empty ⇒ Object
Returns a relation that indicates a property is expected to be an empty object.
-
.many(klazz) ⇒ Relation::Many
Returns a relation that indicates a property should be an array of the specified type.
-
.one_of(choices) ⇒ Relation::OneOf
Returns a relation that indicates a property should be one of a set of types.
-
.properties ⇒ Object
Properties of the receiver.
-
.property(*names, as: nil, required: true) ⇒ Object
Defines a property or properties.
-
.property_names ⇒ Object
Names of the receiver’s properties.
-
.transform(name) ⇒ Proc
Retreives the transform for the named property.
Instance Method Summary collapse
- #[](key) ⇒ Object
-
#initialize(values) ⇒ Base
constructor
Create a new instance of the receiver.
-
#to_wire ⇒ Hash
Convert the receiver to a form suitable for encoding.
-
#validate! ⇒ Object
Validate property values against their expectations.
Constructor Details
#initialize(values) ⇒ Base
Create a new instance of the receiver.
120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/dap/base.rb', line 120 def initialize(values) values.transform_keys!(&:to_sym) self.class.property_names.each do |k| v = values[k] transform = self.class.transform(k) v = transform.call(v, values) if transform self[k] = v end end |
Class Method Details
.build(values) {|values| ... } ⇒ Object
Build an instance of a DAP type.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/dap/base.rb', line 7 def self.build(values, &block) values.transform_keys! &:to_sym if values.is_a? Hash if block.arity == 0 klazz = yield else klazz = yield(values) end return values if values.is_a? klazz return klazz.from(values) if klazz < DAP::Enum klazz.new(values) end |
.empty ⇒ Object
Returns a relation that indicates a property is expected to be an empty object.
41 42 43 |
# File 'lib/dap/base.rb', line 41 def self.empty Class.new(DAP::Base) end |
.many(klazz) ⇒ Relation::Many
Returns a relation that indicates a property should be an array of the specified type.
27 28 29 |
# File 'lib/dap/base.rb', line 27 def self.many(klazz) DAP::Relation::Many.new(klazz) end |
.one_of(choices) ⇒ Relation::OneOf
Returns a relation that indicates a property should be one of a set of types.
35 36 37 |
# File 'lib/dap/base.rb', line 35 def self.one_of(choices) DAP::Relation::OneOf.new(choices) end |
.properties ⇒ Object
Properties of the receiver.
97 98 99 100 101 102 |
# File 'lib/dap/base.rb', line 97 def self.properties @properties ||= [] return @properties if self == DAP::Base superclass.properties + @properties end |
.property(*names, as: nil, required: true) ⇒ Object
Defines a property or properties.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/dap/base.rb', line 49 def self.property(*names, as: nil, required: true) @properties ||= [] @transformations ||= {} klazz = name names.each do |name| case as when nil, String # ignore when Class DAP::Relation.supported!(as) transform = ->(value, values, invert: false) { value.nil? ? nil : invert ? value.to_wire : build(value || {}) { as } } when DAP::Relation::Many transform = ->(value, values, invert: false) { value.nil? ? nil : invert ? value.map(&:to_wire) : value.map { |v| build(v) { as.klazz } } } when DAP::Relation::OneOf transform = ->(value, values, invert: false) do return value.to_wire if invert build(value || {}) do key = values[as.key]&.to_sym raise "#{klazz}.#{as.key} missing" if key.nil? raise "Unknown #{klazz}.#{as.key}: '#{key}'" unless as.types.key?(key) as.types[key] end end else raise "Invalid property constraint: #{as.class} #{as.inspect}" end @properties << { name: name, transform: transform, required: required } end attr_reader(*names) end |
.property_names ⇒ Object
Names of the receiver’s properties.
105 106 107 |
# File 'lib/dap/base.rb', line 105 def self.property_names properties.map { |p| p[:name] } end |
.transform(name) ⇒ Proc
Retreives the transform for the named property.
112 113 114 115 116 |
# File 'lib/dap/base.rb', line 112 def self.transform(name) (@properties || []).each { |p| return p[:transform] if p[:name] == name && p[:transform] } return superclass.transform(name) unless self == DAP::Base end |
Instance Method Details
#[](key) ⇒ Object
170 171 172 173 |
# File 'lib/dap/base.rb', line 170 def [](key) key = key.to_sym instance_variable_get("@#{key}".to_sym) if self.class.property_names.include? key end |
#to_wire ⇒ Hash
Convert the receiver to a form suitable for encoding.
155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/dap/base.rb', line 155 def to_wire self.class.property_names.each_with_object({}) do |k, h| v = self[k] next if v.nil? if transform = self.class.transform(k) v = transform.call(v, self, invert: true) if transform else v = convert_complex(v) end h[k] = v end end |
#validate! ⇒ Object
Validate property values against their expectations.
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/dap/base.rb', line 134 def validate! self.class.properties.each do |p| key, required = p[:name], p[:required] value = self[key] if value.nil? raise "Property #{key} of #{self.class} is required" if required next end if value.respond_to?(:validate!) value.validate! elsif value.respond_to?(:each) value.each { |v| v.validate! if v.respond_to?(:validate!) } end end self end |