class Watir::Generator::Base::Visitor

Public Class Methods

new() click to toggle source
Calls superclass method
# File lib/watir-webdriver/generator/base/visitor.rb, line 5
def initialize
  super

  # When an interface has multiple IDL definitions in the spec, the inheritance is sometimes
  # not repeated. So we'll keep track ourselves.
  @inheritance_map = {}

  @already_defined = []
end

Public Instance Methods

visit_implements_statement(stmt) click to toggle source
# File lib/watir-webdriver/generator/base/visitor.rb, line 47
def visit_implements_statement(stmt)
  # ignored
end
visit_interface(interface) click to toggle source

WebIDL visitor interface

# File lib/watir-webdriver/generator/base/visitor.rb, line 19
def visit_interface(interface)
  name   = interface.name
  parent = interface.inherits.first

  $stderr.puts name
  return if name !~ interface_regexp || name =~ /(Collection|Document)$/

  if force_inheritance.keys.include?(name)
    parent = force_inheritance[name]
  elsif parent
    @inheritance_map[name] ||= parent.name
    parent = parent.name
  else
    parent = @inheritance_map[name] || return
  end

  [ :scope,
    [:block,
      element_class(interface.name, extract_attributes(interface), parent),
      collection_class(interface.name)
    ]
  ]
end
visit_module(mod) click to toggle source
# File lib/watir-webdriver/generator/base/visitor.rb, line 43
def visit_module(mod)
  # ignored
end

Private Instance Methods

attribute_calls(attributes) click to toggle source
# File lib/watir-webdriver/generator/base/visitor.rb, line 103
def attribute_calls(attributes)
  attributes.map do |attribute|
    call(:attribute, [
      [:lit, ruby_type_for(attribute.type)],
      [:lit, ruby_method_name_for(attribute)],
      [:lit, attribute.name.to_sym]
    ])
  end
end
call(name, args) click to toggle source
# File lib/watir-webdriver/generator/base/visitor.rb, line 113
def call(name, args)
  [:call, nil, name.to_sym, [:arglist] + args]
end
collection_class(name) click to toggle source
# File lib/watir-webdriver/generator/base/visitor.rb, line 95
def collection_class(name)
  return if @already_defined.include?(name)
  @already_defined << name
  name = Util.classify(classify_regexp, name)

  [:class, "#{name}Collection", [:const, :ElementCollection]]
end
element_class(name, attributes, parent) click to toggle source

TODO: do everything in the visitor somehow? problem is we lack the tag name info while walking the interface AST # # Watir generator visitor interface #

def visit_tag(tag_name, interface_name)

tag_string       = tag.inspect
singular         = Util.paramify(classify_regexp, tag)
plural           = singular.pluralize
element_class    = Util.classify(classify_regexp, interfaces.first.name)
collection_class = "#{element_class}Collection"

[:defn,
 :a,
 [:args, :"*args"],
 [:scope,
  [:block,
   [:call,
    [:const, :Anchor],
    :new,
    [:arglist,
     [:self],
     [:call,
      [:call, nil, :extract_selector, [:arglist, [:lvar, :args]]],
      :merge,
      [:arglist, [:hash, [:lit, :tag_name], [:str, "a"]]]]]]]]]

end

# File lib/watir-webdriver/generator/base/visitor.rb, line 82
def element_class(name, attributes, parent)
  [:class, Util.classify(classify_regexp, name), [:const, Util.classify(classify_regexp, parent)],
    *attribute_calls(attributes)
  ]
end
extract_attributes(interface) click to toggle source
# File lib/watir-webdriver/generator/base/visitor.rb, line 88
def extract_attributes(interface)
  members = interface.members
  members += interface.implements.flat_map(&:members)

  members.select { |e| e.kind_of?(WebIDL::Ast::Attribute) }
end
ruby_method_name_for(attribute) click to toggle source
# File lib/watir-webdriver/generator/base/visitor.rb, line 117
def ruby_method_name_for(attribute)
  str = attribute.name.snake_case

  if attribute.type.name == :Boolean
    str = $1 if str =~ /^is_(.+)/
    str << '?'
  end

  str = 'for' if str == 'html_for'

  str.to_sym
end
ruby_type_for(type) click to toggle source
# File lib/watir-webdriver/generator/base/visitor.rb, line 130
def ruby_type_for(type)
  case type.name.to_s
  when 'DOMString', 'any'
    String
  when 'UnsignedLong', 'Long', 'Integer', 'Short', 'UnsignedShort',
       'SVGAnimatedLength'
    Fixnum
  when 'Float', /.*Double$/
    Float
  when 'Boolean'
    'Boolean'
  when 'WindowProxy', 'ValidityState', 'TimeRanges', 'Location',
       'Any', 'TimedTrackArray', 'TimedTrack', 'TextTrackArray', 'TextTrack',
       /Media.+/, 'TextTrackKind', 'Function', /.*EventHandler$/,
       'Document', 'DocumentFragment', 'DOMTokenList', 'DOMSettableTokenList',
       'DOMStringMap', 'HTMLPropertiesCollection', /HTML.*Element/, /HTML.*Collection/,
       'CSSStyleDeclaration',  /.+List$/, 'Date', 'Element', /DOM.+ReadOnly/,
       /SVGAnimated.+/, /SVG.*Element/, /SVG.*Collection/, 'SVGViewSpec'
    # probably completely wrong.
    String
  else
    raise "unknown type: #{type.name}"
  end
end