Module: BiDiGenerate Private
- Defined in:
- rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb,
rb/lib/selenium/webdriver/bidi/support/check_generated.rb
Overview
This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.
Generates Ruby WebDriver BiDi protocol modules from the shared, binding-neutral BiDi schema produced by the JavaScript generator (see PR #17700):
//javascript/selenium-webdriver:create-bidi-src_schema -> bidi-schema.json
The schema is already normalized (inline enums hoisted, unions canonicalized, group composition flattened, wire names and nullability preserved verbatim), so this generator is a straight projection into Ruby with no CDDL interpretation.
Invoked via bazel run //rb/lib/selenium/webdriver:bidi-generate. Bazel passes
the schema path (resolved through runfiles) plus the workspace-relative output
directory as ARGV, and supplies the shared generated-note text as a runfile, so
this is not runnable directly from a source checkout.
Defined Under Namespace
Classes: Accessor, Command, Enum, ErrorModule, Event, FieldIR, Module, Param, Schema, TypeClass, UnionClass, VariantIR, VendorCommand, VendorModule
Constant Summary collapse
- BIDI_DOC_URL =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Companion to the generated
@api privatetags: the page explaining why the BiDi implementation layer is internal and what higher-level API to use instead (see #17628). 'https://www.selenium.dev/documentation/warnings/bidi-implementation/'- LINE_LIMIT =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
RuboCop's Layout/LineLength max; emitted Serialization::Record.define calls wrap to stay within it.
120- RUBY_RESERVED =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Ruby keywords that cannot be used as method names unquoted.
%w[begin end rescue ensure raise return yield if unless while until for do case when then class module def].freeze
- RESERVED_FIELD_NAMES =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Object/Data methods a Data member name would shadow (breaking value semantics or reflection), e.g. a "method" field overriding Object#method.
(RUBY_RESERVED + %w[method hash class send dup clone freeze inspect to_h to_s members with deconstruct deconstruct_keys object_id tap itself then display extensible]).freeze
- RBS_VALUE_TYPES =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
The RBS type a schema value primitive maps to; an unrecognized one is untyped.
{'string' => 'String', 'integer' => 'Integer', 'number' => 'Float', 'boolean' => 'bool'}.freeze
- PARAMS_CLASS_KINDS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Param kinds the named args can construct a Parameters object for (record fields, or a union dispatched to one of its variants); anything else forwards a raw hash.
%w[record union].freeze
- INHERITED_INSTANCE_METHODS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Public instance methods every accessor would shadow if it reused their name: Domain's own (
execute/initialize) plus everything Object/Kernel expose. The collision guard fails generation before a schema-driven shadow can ship. (%w[execute initialize].to_set + Object.instance_methods.to_set(&:to_s)).freeze
Class Method Summary collapse
-
.accessor?(type, wrappers, plainly_reached) ⇒ Boolean
private
A type earns a send-side accessor when it is outbound and not a command param/result wrapper (a command method already builds those).
-
.bidi_only_classes(codes) ⇒ Object
private
Class names among
codesthe classic Error module does not already define — the BiDi-only codes bidi/error.rb registers and whose RBS this file must declare. -
.build_accessors(schema, domain, types) ⇒ Object
private
Outbound-scoped domain accessors: for every emitted type a caller constructs to send, a prefix-free constructor on the Domain subclass.
- .build_command(schema, cmd) ⇒ Object private
- .build_event(schema, event) ⇒ Object private
- .build_ir(schema) ⇒ Object private
- .call(schema_path, output_dir) ⇒ Object private
-
.camel_to_snake(str) ⇒ Object
private
A vendor namespace separator (
moz:debugging) reads as a word boundary. -
.check!(schema_rootpath) ⇒ Object
private
Verifies the checked-in protocol .rb match what the generator would produce from the current schema — catching a hand-edit or a forgotten regeneration.
-
.check_accessor_collisions!(mod) ⇒ Object
private
Fail generation if an accessor name would collide with a command method, an inherited method, or another accessor — turning a future shadow into a build error rather than a silently overridden method.
-
.emit(modules, output_dir, template, extension) ⇒ Object
private
Renders every module through one template and writes the result into target, one file per module.
-
.emit_error_module(schema, output_dir) ⇒ Object
private
Writes protocol/error_code.rb (+ its .rbs), the Protocol::ErrorCode map, into the same protocol dir as the generated domain files.
-
.enum_const_path(type_name) ⇒ Object
private
Domain-qualified path to an enum's frozen hash constant ("browsingContext.ReadinessState" → "BrowsingContext::READINESS_STATE"), so a generated command method can reference it for an outbound membership check.
-
.enum_key(value) ⇒ Object
private
snake_case hash key for an enum value (only a label for the wire value it maps to).
-
.error_class_name(code) ⇒ Object
private
WebDriver error-code string -> exception class name, matching Error.for_error's convention ("no such node" -> NoSuchNodeError).
-
.error_code_map(schema) ⇒ Object
private
The ErrorCode wire values mapped to their Ruby exception class names (schema order), e.g.
-
.error_module_current?(schema, protocol_dir) ⇒ Boolean
private
Whether the checked-in protocol/error_code.rb matches what the generator would render now.
-
.nest_synthetic(types) ⇒ Object
private
The projector tags lifted-out types with owner, label.
-
.rbs_nilable(type) ⇒ Object
private
Makes an RBS type admit nil, idempotently (an already-nilable or opaque type is left as-is).
- .render(mod, template_path) ⇒ Object private
-
.ruby_literal(value) ⇒ Object
private
Source literal for a discriminator/const value (string, boolean, or number).
-
.safe_field_name(name, extensible: true) ⇒ Object
private
Append underscore to a field name that would shadow a core method; the wire name is unaffected, only the Ruby reader is renamed.
-
.safe_method_name(name) ⇒ Object
private
Append underscore to avoid clashing with Ruby reserved keywords.
-
.schema_path(rootpath) ⇒ Object
private
$(rootpath) is relative to the runfiles root; dir anchors us there so it resolves the same way locally and on RBE (an execpath would not).
-
.screaming_snake(camel) ⇒ Object
private
SCREAMING_SNAKE constant name for an enum, matching the EVENTS map style (ReadinessState → READINESS_STATE).
-
.sig_dir(output_dir) ⇒ Object
private
The RBS signatures mirror the source tree under sig/ (the repo's convention), e.g.
- .snake_to_class_name(snake) ⇒ Object private
-
.thread_variant_arg_sigs(schema, types) ⇒ Object
private
Give each union its variants' typed
newsignatures, keyed by factory method name, so rbs_variant_factories can emit a checked signature instead of a splat. -
.type_class_name(type_name) ⇒ Object
private
Local constant for a domain-scoped type: "script.LocalValue" -> "LocalValue".
-
.type_ruby_path(type_name) ⇒ Object
private
Protocol-relative class path: "script.LocalValue" -> "Script::LocalValue".
-
.vendor_accessors(vendor_modules) ⇒ Object
private
An accessor per vendor variant, returning a sibling vendor domain over the same connection (
web_extension.moz->Moz.new(connection)). -
.word_array(words) ⇒ Object
private
Source literal for a list of wire keys, in the form RuboCop expects at each size.
-
.wrap_call(prefix, args, indent, open: '(', close: ')') ⇒ Object
private
Renders
prefix(args)on one line, or one argument per line when it would exceed LINE_LIMIT at the given indent.
Class Method Details
.accessor?(type, wrappers, plainly_reached) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
A type earns a send-side accessor when it is outbound and not a command param/result
wrapper (a command method already builds those). A nested-away synthetic reached only
as a union arm is excluded — it is built through its union (a variant factory or the
command's flattened dispatch), never standalone. A top-level union variant record keeps
its accessor (the plan constructs it directly, e.g. extension_path), as does a synthetic
reached by a plain field ref (browsingContext.AccessibilityLocator's value).
1411 1412 1413 1414 1415 1416 1417 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1411 def self.accessor?(type, wrappers, plainly_reached) return false unless type.outbound return false if wrappers.include?(type.schema_name) nested_synthetic = !type.union? && type.synthetic !nested_synthetic || plainly_reached.include?(type.schema_name) end |
.bidi_only_classes(codes) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Class names among codes the classic Error module does not already define — the BiDi-only codes
bidi/error.rb registers and whose RBS this file must declare. Shared codes already have RBS in
common/error.rbs, so re-declaring them would duplicate the classic signatures. Only the RBS needs
this split; the emitted map (error_code.rb) stays the full self-contained set.
1530 1531 1532 1533 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1530 def self.bidi_only_classes(codes) require_relative '../../common/error' codes.filter_map { |_wire, name| name unless ::Selenium::WebDriver::Error.const_defined?(name, false) } end |
.build_accessors(schema, domain, types) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Outbound-scoped domain accessors: for every emitted type a caller constructs to send,
a prefix-free constructor on the Domain subclass. Built from the pre-nesting type list
so a nested synthetic (referenced by a Ruby-relative Owner::Label path) is reachable.
1395 1396 1397 1398 1399 1400 1401 1402 1403 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1395 def self.build_accessors(schema, domain, types) wrappers = schema.command_wrapper_refs(domain) plainly_reached = schema.plainly_reached_types types.select { |t| accessor?(t, wrappers, plainly_reached) }.map do |t| Accessor.new(method_name: safe_method_name(camel_to_snake(type_class_name(t.schema_name))), type_name: schema.domain_relative_path(t.schema_name), union: t.union?, rbs_args: t.union? ? nil : t.rbs_new_args) end end |
.build_command(schema, cmd) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1442 def self.build_command(schema, cmd) params = schema.params_for(cmd['params']) # A param that can't flatten to a typed object (alias or non-record union) would be # silently dropped, so fail generation and handle that shape deliberately if it appears. if cmd['params'] && params.nil? raise "command #{cmd['method']} has params that cannot be expressed as a typed object" end params_ref = cmd['params'] && cmd['params']['ref'] params_kind = schema.type_kind(params_ref) params_class = type_class_name(params_ref) if !params.empty? && PARAMS_CLASS_KINDS.include?(params_kind) Command.new( wire_name: cmd['method'], method_name: safe_method_name(camel_to_snake(cmd['name'])), params: params, result_ref: cmd['result'] && schema.structured_ref(cmd['result']['ref']), params_class: params_class, union_params: params_kind == 'union', spec_href: cmd['specHref'] ) end |
.build_event(schema, event) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
1464 1465 1466 1467 1468 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1464 def self.build_event(schema, event) params = event['params'] payload_ref = params && params['ref'] && schema.structured_ref(params['ref']) Event.new(wire_name: event['method'], event_name: camel_to_snake(event['name']), payload_ref: payload_ref) end |
.build_ir(schema) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1348 def self.build_ir(schema) schema.domains.map do |domain| types = schema.types_for(domain) thread_variant_arg_sigs(schema, types) vendor_modules = schema.vendor_modules_for(domain) mod = Module.new( name: domain, ruby_class: snake_to_class_name(camel_to_snake(domain)), filename: camel_to_snake(domain), commands: schema.commands_for(domain).map { |cmd| build_command(schema, cmd) }, events: schema.events_for(domain).map { |ev| build_event(schema, ev) }, enums: schema.enums_for(domain), accessors: build_accessors(schema, domain, types) + vendor_accessors(vendor_modules), types: nest_synthetic(types), vendor_modules: vendor_modules, spec_href: schema.domain_href(domain) ) check_accessor_collisions!(mod) mod end end |
.call(schema_path, output_dir) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
1492 1493 1494 1495 1496 1497 1498 1499 1500 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1492 def self.call(schema_path, output_dir) raw = load_json(schema_path) schema = Schema.new(raw) modules = build_ir(schema) emit(modules, output_dir, 'module.rb.erb', 'rb') emit(modules, sig_dir(output_dir), 'module.rbs.erb', 'rbs') emit_error_module(schema, output_dir) end |
.camel_to_snake(str) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
A vendor namespace separator (moz:debugging) reads as a word boundary.
52 53 54 55 56 57 58 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 52 def self.camel_to_snake(str) str .tr(':', '_') .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2') .gsub(/([a-z\d])([A-Z])/, '\1_\2') .downcase end |
.check!(schema_rootpath) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Verifies the checked-in protocol .rb match what the generator would produce from the current schema — catching a hand-edit or a forgotten regeneration. Re-renders each module in memory (no file writes) and compares. The .rbs are covered by Steep.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'rb/lib/selenium/webdriver/bidi/support/check_generated.rb', line 27 def self.check!(schema_rootpath) schema = Schema.new(JSON.parse(File.read(schema_path(schema_rootpath)))) protocol_dir = File.('../protocol', __dir__) template = File.join(__dir__, 'templates', 'module.rb.erb') stale = build_ir(schema).filter_map do |mod| path = File.join(protocol_dir, "#{mod.filename}.rb") "#{mod.filename}.rb" unless File.exist?(path) && File.read(path) == render(mod, template) end stale << 'error_code.rb' unless error_module_current?(schema, protocol_dir) return if stale.empty? warn "Generated BiDi protocol code is stale or hand-edited: #{stale.sort.join(', ')}" warn 'Regenerate with: bazel run //rb/lib/selenium/webdriver:bidi-generate' exit 1 end |
.check_accessor_collisions!(mod) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Fail generation if an accessor name would collide with a command method, an inherited method, or another accessor — turning a future shadow into a build error rather than a silently overridden method.
1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1427 def self.check_accessor_collisions!(mod) commands = mod.commands.to_set(&:method_name) seen = {} mod.accessors.each do |accessor| name = accessor.method_name clash = if commands.include?(name) then 'a command method' elsif INHERITED_INSTANCE_METHODS.include?(name) then 'an inherited method' elsif seen[name] then "the accessor for #{seen[name]}" end raise "accessor #{mod.ruby_class}##{name} collides with #{clash}" if clash seen[name] = accessor.type_name end end |
.emit(modules, output_dir, template, extension) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Renders every module through one template and writes the result into target, one file per module. Used for both the Ruby source and its RBS signatures.
1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1537 def self.emit(modules, output_dir, template, extension) target = File.join(workspace_root, output_dir) FileUtils.mkdir_p(target) tmpl = File.join(File.dirname(__FILE__), 'templates', template) modules.each do |mod| path = File.join(target, "#{mod.filename}.#{extension}") File.write(path, render(mod, tmpl)) warn "bidi-generate: wrote #{path}" end end |
.emit_error_module(schema, output_dir) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Writes protocol/error_code.rb (+ its .rbs), the Protocol::ErrorCode map, into the same protocol dir as the generated domain files.
1519 1520 1521 1522 1523 1524 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1519 def self.emit_error_module(schema, output_dir) codes = error_code_map(schema) mod = ErrorModule.new(filename: 'error_code', codes: codes, new_classes: bidi_only_classes(codes)) emit([mod], output_dir, 'error_code.rb.erb', 'rb') emit([mod], sig_dir(output_dir), 'error_code.rbs.erb', 'rbs') end |
.enum_const_path(type_name) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Domain-qualified path to an enum's frozen hash constant ("browsingContext.ReadinessState" → "BrowsingContext::READINESS_STATE"), so a generated command method can reference it for an outbound membership check.
141 142 143 144 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 141 def self.enum_const_path(type_name) domain, local = type_name.split('.', 2) "#{snake_to_class_name(camel_to_snake(domain))}::#{screaming_snake(local)}" end |
.enum_key(value) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
snake_case hash key for an enum value (only a label for the wire value it maps to). Preserves camelCase word boundaries (beforeRequestSent → before_request_sent), maps a leading minus to "neg" (-0 → neg0, -Infinity → neg_infinity; no underscore before a digit, so the key stays normalcase), collapses other punctuation (dedicated-worker → dedicated_worker), and prefixes a numeric value so the key is still a valid symbol (0 → _0).
152 153 154 155 156 157 158 159 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 152 def self.enum_key(value) token = camel_to_snake(value.to_s) .sub(/\A-(?=\d)/, 'neg') .sub(/\A-/, 'neg_') .gsub(/[^a-z0-9]+/, '_') .gsub(/\A_+|_+\z/, '') token.empty? || token.match?(/\A\d/) ? "_#{token}" : token end |
.error_class_name(code) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
WebDriver error-code string -> exception class name, matching Error.for_error's convention ("no such node" -> NoSuchNodeError). The Error suffix is normalized (not doubled) for a code already ending in "error" ("unknown error" -> UnknownError).
1513 1514 1515 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1513 def self.error_class_name(code) "#{code.split.map(&:capitalize).join.sub(/Error$/, '')}Error" end |
.error_code_map(schema) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The ErrorCode wire values mapped to their Ruby exception class names (schema order), e.g. "no such node" => "NoSuchNodeError". This is the schema->Ruby translation: the generated file carries the Ruby names, and a hand-written pass turns them into WebDriverError subclasses under the shared Error namespace. Self-contained — no reference to the classic error module.
1506 1507 1508 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1506 def self.error_code_map(schema) schema.error_codes.map { |code| [code, error_class_name(code)] } end |
.error_module_current?(schema, protocol_dir) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Whether the checked-in protocol/error_code.rb matches what the generator would render now.
45 46 47 48 49 |
# File 'rb/lib/selenium/webdriver/bidi/support/check_generated.rb', line 45 def self.error_module_current?(schema, protocol_dir) mod = ErrorModule.new(filename: 'error_code', codes: error_code_map(schema)) path = File.join(protocol_dir, 'error_code.rb') File.exist?(path) && File.read(path) == render(mod, File.join(__dir__, 'templates', 'error_code.rb.erb')) end |
.nest_synthetic(types) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The projector tags lifted-out types with owner, label. Emit each
synthetic record inside its owner's class body under its bare label, so
Owner_Label becomes the nested Owner::Label (refs resolve there via
ruby_path). Synthetic enums stay domain-level. Raises on a missing owner.
1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1474 def self.nest_synthetic(types) index = types.to_h { |t| [t.schema_name, t] } children = types.select { |t| !t.union? && t.synthetic } children.each do |child| owner = index[child.owner] || raise("synthetic type #{child.schema_name} has no emitted owner #{child.owner}") owner.nested = (owner.nested || []) << child child.ruby_name = child.label end types - children end |
.rbs_nilable(type) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Makes an RBS type admit nil, idempotently (an already-nilable or opaque type is left
as-is). Applied to a field whose schema type is nullable, so its value type allows nil;
keyword-optionality is expressed separately by the ? prefix (see rbs_part / rbs_arg).
132 133 134 135 136 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 132 def self.rbs_nilable(type) return type if type == 'untyped' || type == 'nil' || type.end_with?('?') "#{type}?" end |
.render(mod, template_path) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
1486 1487 1488 1489 1490 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1486 def self.render(mod, template_path) generated_note = GeneratedNote.render('#', 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', 'bazel run //rb/lib/selenium/webdriver:bidi-generate') ERB.new(File.read(template_path), trim_mode: '-').result(binding) end |
.ruby_literal(value) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Source literal for a discriminator/const value (string, boolean, or number).
83 84 85 86 87 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 83 def self.ruby_literal(value) return 'nil' if value.nil? value.is_a?(String) ? "'#{value}'" : value.to_s end |
.safe_field_name(name, extensible: true) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Append underscore to a field name that would shadow a core method; the wire name is unaffected, only the Ruby reader is renamed.
114 115 116 117 118 119 120 121 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 114 def self.safe_field_name(name, extensible: true) # A vendor-prefixed wire name carries a colon (moz:allowPrivateBrowsing); swap it # for an underscore so the Ruby reader is a legal identifier. The wire key is kept. name = name.tr(':', '_') # Only an extensible record holds its undeclared fields in an `extensions` member. reserved = RESERVED_FIELD_NAMES.include?(name) || (extensible && name == 'extensions') reserved ? "#{name}_" : name end |
.safe_method_name(name) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Append underscore to avoid clashing with Ruby reserved keywords.
101 102 103 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 101 def self.safe_method_name(name) RUBY_RESERVED.include?(name) ? "#{name}_" : name end |
.schema_path(rootpath) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
$(rootpath) is relative to the runfiles root; dir anchors us there so it resolves the
same way locally and on RBE (an execpath would not). This file lives at
rb/lib/selenium/webdriver/bidi/support, so expand six levels up to the root — File.expand_path
is separator-agnostic, unlike stripping a "/"-spelled suffix (which would miss on Windows).
The cwd-relative rootpath fallback matches how spec_support's rlocation resolves.
56 57 58 59 60 |
# File 'rb/lib/selenium/webdriver/bidi/support/check_generated.rb', line 56 def self.schema_path(rootpath) runfiles_root = File.('../../../../../..', __dir__) [File.join(runfiles_root, rootpath), rootpath].find { |p| File.exist?(p) } || raise("BiDi schema not found (looked for #{rootpath})") end |
.screaming_snake(camel) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
SCREAMING_SNAKE constant name for an enum, matching the EVENTS map style (ReadinessState → READINESS_STATE).
125 126 127 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 125 def self.screaming_snake(camel) camel_to_snake(camel).upcase end |
.sig_dir(output_dir) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The RBS signatures mirror the source tree under sig/ (the repo's convention), e.g. rb/lib/.../protocol -> rb/sig/lib/.../protocol.
1551 1552 1553 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1551 def self.sig_dir(output_dir) output_dir.sub(%r{(\A|/)lib/}, '\1sig/lib/') end |
.snake_to_class_name(snake) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
60 61 62 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 60 def self.snake_to_class_name(snake) snake.split('_').map(&:capitalize).join end |
.thread_variant_arg_sigs(schema, types) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Give each union its variants' typed new signatures, keyed by factory method name, so
rbs_variant_factories can emit a checked signature instead of a splat. Keyed by ruby
path (the form a variant ref carries); a cross-module variant not in this list falls
back to **untyped.
1383 1384 1385 1386 1387 1388 1389 1390 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1383 def self.thread_variant_arg_sigs(schema, types) record_sigs = types.reject(&:union?).to_h { |t| [schema.ruby_path_for(t.schema_name), t.rbs_new_args] } types.select(&:union?).each do |union| union.variant_arg_sigs = union.value_variants.to_h do |variant| [BiDiGenerate.enum_key(variant.value), record_sigs[variant.ref]] end end end |
.type_class_name(type_name) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Local constant for a domain-scoped type: "script.LocalValue" -> "LocalValue". The first letter is capitalized so a lower-cased spec name (e.g. "permissions.setPermission") still yields a valid Ruby constant.
67 68 69 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 67 def self.type_class_name(type_name) type_name.split('.', 2).last.sub(/\A[a-z]/, &:upcase) end |
.type_ruby_path(type_name) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Protocol-relative class path: "script.LocalValue" -> "Script::LocalValue".
72 73 74 75 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 72 def self.type_ruby_path(type_name) domain = type_name.split('.', 2).first "#{snake_to_class_name(camel_to_snake(domain))}::#{type_class_name(type_name)}" end |
.vendor_accessors(vendor_modules) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
An accessor per vendor variant, returning a sibling vendor domain over the same connection
(web_extension.moz -> Moz.new(connection)). Named after the vendor namespace.
1372 1373 1374 1375 1376 1377 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 1372 def self.vendor_accessors(vendor_modules) vendor_modules.map do |vendor_module| Accessor.new(method_name: safe_method_name(vendor_module.namespace), type_name: vendor_module.name, union: false, vendor: true) end end |
.word_array(words) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Source literal for a list of wire keys, in the form RuboCop expects at each size.
78 79 80 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 78 def self.word_array(words) words.size > 1 ? "%w[#{words.join(' ')}]" : "[#{words.map { |w| "'#{w}'" }.join(', ')}]" end |
.wrap_call(prefix, args, indent, open: '(', close: ')') ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Renders prefix(args) on one line, or one argument per line when it would exceed
LINE_LIMIT at the given indent. open/close default to parentheses (pass {} for a
hash literal) so emitted calls and literals stay within RuboCop's length limit.
92 93 94 95 96 97 98 |
# File 'rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb', line 92 def self.wrap_call(prefix, args, indent, open: '(', close: ')') one_line = "#{prefix}#{open}#{args.join(', ')}#{close}" return one_line if args.empty? || indent + one_line.length <= LINE_LIMIT pad = ' ' * (indent + 2) "#{prefix}#{open}\n#{pad}#{args.join(",\n#{pad}")}\n#{' ' * indent}#{close}" end |