Top Level Namespace

Includes:
Helpers::ModuleHelper

Defined Under Namespace

Modules: SketchUpYARD, YARD Classes: StubFile

Constant Summary collapse

CAMELCASE_CONSTANT =
/^([A-Z]+[a-z]+)/
MANUAL_CONSTANT_GROUPS =
{
  constants: %w{IDABORT IDCANCEL IDIGNORE IDNO IDOK IDRETRY IDYES},
  group: 'ID_MESSAGEBOX'
},
# Axes
{
  constants: %w{X_AXIS Y_AXIS Z_AXIS},
  group: 'AXES'
},
# Axes 2D
{
  constants: %w{X_AXIS_2D Y_AXIS_2D},
  group: 'AXES2D'
},
# Transformation
{
  constants: %w{IDENTITY IDENTITY_2D},
  group: 'IDENTITY'
},
# Geom::PolygonMesh
{
  constants: %w{
    AUTO_SOFTEN HIDE_BASED_ON_INDEX NO_SMOOTH_OR_HIDE SMOOTH_SOFT_EDGES
    SOFTEN_BASED_ON_INDEX},
  group: 'SOFTEN'
},
# Sketchup::Importer
# The other constants start with Import, this was odd one out.
{
  constants: %w{ImporterNotFound},
  group: 'Import'
},
# Sketchup::Http
{
  constants: %w{DELETE GET HEAD OPTIONS PATCH POST PUT},
  group: 'HTTP'
},
# Sketchup::Licensing
{
  constants: %w{EXPIRED LICENSED NOT_LICENSED TRIAL TRIAL_EXPIRED},
  group: 'EX_LICENSE'
},
# Sketchup::Model
{
  constants: %w{Make MakeTrial ProLicensed ProTrial},
  group: 'SU_LICENSE'
},
# Sketchup::RenderingOptions
# Most ROP constants start with ROPSet, with a handful of exceptions.
{
  regex: /^ROP/,
  group: 'ROP'
}
MANIFEST_FILENAME =
'coverage.manifest'.freeze
VERSION_MATCH =
/^\D+([0-9.]+)(?:\s+M(\d+))?$/

Instance Method Summary collapse

Instance Method Details

#all_objectsObject



10
11
12
# File 'lib/yard-sketchup/templates/apis/fulldoc/text/setup.rb', line 10

def all_objects
  run_verifier(Registry.all)
end

#apiObject



10
11
12
13
14
# File 'lib/yard-sketchup/templates/default/docstring/setup.rb', line 10

def api
  return unless object.has_tag?(:api)
  # Displays a a message warning the user that the API is not stable.
  erb(:api)
end

#changelog_filenameObject



26
27
28
# File 'lib/yard-sketchup/templates/changelog/fulldoc/text/setup.rb', line 26

def changelog_filename
  'Changelog SU201x.log'
end

#class_objectsObject



16
17
18
# File 'lib/yard-sketchup/templates/inheritance/fulldoc/text/setup.rb', line 16

def class_objects
  run_verifier(Registry.all(:class))
end

#copy(source, target = nil) ⇒ Object

Copy verbatim an asset file to the target output. By default it uses the same relative path as the source for the target path.

Raises:

  • (ArgumentError)


5
6
7
8
9
10
11
12
# File 'lib/yard-sketchup/templates/default/fulldoc/html/setup.rb', line 5

def copy(source, target = nil)
  path = self.class.find_file(source)
  # puts "copy(#{source}, #{target})"
  # puts "> path: #{path}"
  raise ArgumentError, "no file for '#{source}' in #{self.class.path}" unless path
  target ||= source
  asset(target, File.binread(path))
end

#ensure_exist(path) ⇒ Object



286
287
288
289
290
291
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 286

def ensure_exist(path)
  unless File.directory?(path)
    FileUtils.mkdir_p(path)
  end
  path
end


71
72
73
74
75
76
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 71

def file_footer(object)
  return if object.root?
  footer = StringIO.new
  footer.puts 'end'
  footer.string
end

#file_header(object) ⇒ Object



63
64
65
66
67
68
69
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 63

def file_header(object)
  header = StringIO.new
  header.puts "# Copyright:: Copyright #{Time.now.year} Trimble Inc."
  header.puts "# License:: The MIT License (MIT)"
  #header.puts "# Generated:: #{Time.now.strftime('%F %R')}"
  header.string
end

#find_all_apisObject



15
16
17
18
19
20
21
22
23
# File 'lib/yard-sketchup/templates/apis/fulldoc/text/setup.rb', line 15

def find_all_apis
  apis = Set.new
  all_objects.each { |object|
    version_tag = object.tag(:api)
    apis << version_tag.text if version_tag
  }
  puts apis.sort.join("\n")
  exit # Avoid the YARD summary
end

#find_all_versionsObject



17
18
19
20
21
22
23
24
25
# File 'lib/yard-sketchup/templates/versions/fulldoc/text/setup.rb', line 17

def find_all_versions
  versions = Set.new
  all_objects.each { |object|
    version_tag = object.tag(:version)
    versions << version_tag.text if version_tag
  }
  puts versions.sort.join("\n")
  exit # Avoid the YARD summary
end

#generate_assetsObject



22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/yard-sketchup/templates/default/fulldoc/html/setup.rb', line 22

def generate_assets
  super

  # TODO: Can this be part of html_helper.rb ?
  # IgorPro
  # Pastie
  asset('css/rouge.css', Rouge::Themes::IgorPro.render(scope: 'pre.code.cpp'))

  copy('favicon.ico')
  copy('images/sketchup-logo.svg')
  copy('images/trimble-logo-white.svg')
  copy('images/Ruby.svg')
end

#generate_autoloader(namespace_objects) ⇒ Object



29
30
31
32
33
34
35
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 29

def generate_autoloader(namespace_objects)
  generator = SketchUpYARD::Stubs::AutoLoadGenerator.new
  autoload_file = File.join(stubs_gem_path, 'sketchup.rb')
  File.open(autoload_file, 'w') do |file|
    generator.generate(namespace_objects, file)
  end
end

#generate_changelogObject



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/yard-sketchup/templates/changelog/fulldoc/text/setup.rb', line 30

def generate_changelog
  #p (methods - Object.instance_methods).sort
  #p ARGV
  puts "Generating #{changelog_filename}..."
  output = StringIO.new
  new_objects = all_objects.sort { |a, b| a.path <=> b.path }
  new_objects.each do |object|
    #object.meths.each { |method|
      #methods << "#{method.namespace}##{method.name}"
    #}
    output.puts "Added #{object.type} #{object.path}"
  end
  changelog_path = File.join(output_path, changelog_filename)
  File.write(changelog_path, output.string)
end

#generate_class_methods(object) ⇒ Object



188
189
190
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 188

def generate_class_methods(object)
  generate_methods(object, :class, 'self.')
end

#generate_constants(object) ⇒ Object

Sort constants without grouping.



167
168
169
170
171
172
173
174
175
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 167

def generate_constants(object)
  output = StringIO.new
  constants = run_verifier(object.constants(object_options))
  constants = stable_sort_by(constants, &:name)
  constants.each { |constant|
    output.puts "  #{constant.name} = nil # Stub value."
  }
  output.string
end

#generate_constants_grouped(object) ⇒ Object

Sorts and groups constants for easier reading.



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 143

def generate_constants_grouped(object)
  constants = run_verifier(object.constants(object_options))
  # The constants are not sorted before chunking. This is because `chunk` groups
  # consecutive items - and we want to chunk them based their relationship
  # with each other. This ensure that constants that doesn't follow the normal
  # pattern of PREFIX_SOME_NAME will still be grouped next to each other.
  groups = constants.chunk { |constant|
    group_constant(constant)
  }
  grouped_output = groups.map { |group, group_constants|
    output = StringIO.new
    # Each group itself is sorted in order to more easily scan the list.
    sorted = stable_sort_by(group_constants, &:name)
    sorted.each { |constant|
      output.puts "  #{constant.name} = nil # Stub value."
    }
    output.string
  }
  # Finally each group is also sorted, again to ease scanning for a particular
  # name. We simply use the first character of each group.
  stable_sort_by(grouped_output) { |item| item.lstrip[0] }.join("\n")
end

#generate_docstring(object, indent_step = 0) ⇒ Object



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 254

def generate_docstring(object, indent_step = 0)
  output = StringIO.new
  indent = '  ' * indent_step
  docstring = object.docstring
  docstring.delete_tags(:par) # Remove obsolete @par tags.
  docstring.to_raw.lines.each { |line|
    # Naive check for tags with no indent - if it is we insert an extra line
    # in order to get some space for easier reader. Doing it this way in order
    # to avoid hacking YARD too much.
    output.puts "#{indent}#" if line.start_with?('@')
    # This is the original docstring line.
    output.puts "#{indent}# #{line}"
  }
  output.string
end

#generate_instance_methods(object) ⇒ Object



192
193
194
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 192

def generate_instance_methods(object)
  generate_methods(object, :instance)
end

#generate_manifestObject



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/yard-sketchup/templates/coverage/fulldoc/text/setup.rb', line 23

def generate_manifest
  puts "Generating #{MANIFEST_FILENAME}..."
  methods = Set.new
  namespace_objects.each do |object|
    run_verifier(object.meths).each { |method|
      # TODO(thomthom): Currently the manifest doesn't distinguish between
      # class and instance methods. This should be addressed, but we need to
      # update TestUp to handle this first.
      # TODO(thomthom): Make this a configurable filter.
      # Layout has its own tests - and should be isolated so its own suite.
      next if method.namespace.to_s.start_with?('Layout')
      methods << "#{method.namespace}.#{method.name}"
    }
  end
  manifest = methods.sort.join("\n")
  manifest_path = File.join(output_path, MANIFEST_FILENAME)
  puts manifest_path
  File.write(manifest_path, manifest)
end

#generate_method_signature(object) ⇒ Object

NOTE: This may modify the docstring of the object.



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 219

def generate_method_signature(object)
  signature = "#{object.name}"
  # If there is a single overload then use that as the parameter list. Many of
  # the SketchUp Ruby API methods will have this as it was safer to add an
  # @overload tag instead of renaming the function argument names.
  overloads = object.docstring.tags(:overload)
  if overloads.size == 1
    overload = overloads.first
    parameters = overload.parameters
    # Move the tags from the @overload tag to the root of the docstring. No need
    # for a single overload tag - it's unexpected when reading the source.
    object.docstring.add_tag(*overload.tags)
    object.docstring.delete_tags(:overload)
  else
    parameters = object.parameters
  end
  # Compile the signature for the arguments and default values.
  params = parameters.map { |param|
    param.last.nil? ? param.first : param.join(' = ')
    if param.last.nil?
      param.first
    else
      if param.first.end_with?(':')
        # Named param.
        param.join(' ')
      else
        # Positional param.
        param.join(' = ')
      end
    end
  }.join(', ')
  signature << "(#{params})" unless params.empty?
  signature
end

#generate_methods(object, scope, prefix = '') ⇒ Object



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 196

def generate_methods(object, scope, prefix = '')
  methods = sort_methods(object, scope)
  signatures = methods.map { |method|
    output = StringIO.new
    # Cannot use `methods.signature` here as it would return the C/C++ function
    # signature. Must generate one from the YARD data.
    signature = generate_method_signature(method)
    # NOTE: We must call `generate_docstring` after `generate_method_signature`
    # because `generate_method_signature` will also clean up docstrings with
    # a single @overload tag.
    output.puts generate_docstring(method, 1)
    output.puts "  def #{prefix}#{signature}"
    output.puts "  end"
    # Include aliases.
    method.aliases.each { |method_alias|
      output.puts "  alias_method :#{method_alias.name}, :#{method.name}"
    }
    output.string
  }
  signatures.join("\n")
end

#generate_mixins(object, scope) ⇒ Object



177
178
179
180
181
182
183
184
185
186
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 177

def generate_mixins(object, scope)
  output = StringIO.new
  mixin_type = (scope == :class) ? 'extend' : 'include'
  mixins = run_verifier(object.mixins(scope))
  mixins = stable_sort_by(mixins, &:path)
  mixins.each { |mixin|
    output.puts "  #{mixin_type} #{mixin.path}"
  }
  output.string
end

#generate_module_stubs(object) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 45

def generate_module_stubs(object)
  filename = stub_filename(object)
  ensure_exist(File.dirname(filename))
  StubFile.open(filename, 'w') { |file|
    file.puts file_header(object)
    file.puts
    file.puts namespace_definition(object)
    print_section(file, 'Extends', generate_mixins(object, :class))
    print_section(file, 'Includes', generate_mixins(object, :instance))
    print_section(file, 'Constants', generate_constants_grouped(object))
    print_section(file, 'Class Methods', generate_class_methods(object))
    print_section(file, 'Instance Methods', generate_instance_methods(object))
    file.puts
    file.puts file_footer(object)
  }
  #trim_trailing_white_space(filename)
end

#generate_object_types_listObject

Custom search list grouping the classes in the API into similar groups. TODO(thomthom): This file is just a stub.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/yard-sketchup/templates/default/fulldoc/html/setup.rb', line 39

def generate_object_types_list
   #@items = options.objects if options.objects
   @items = [
      "App Level Classes",
      "Entity Classes",
      "Collection Classes",
      "Geom Classes",
      "UI Classes",
      "Observer Classes",
      "Core Ruby Classes"
   ]
   @list_title = "Object Index"
   @list_type = "object_types"

   # optional: the specified stylesheet class
   # when not specified it will default to the value of @list_type
   @list_class = "class"

   # Generate the full list html file with named feature_list.html
   # @note this file must be match the name of the type
   asset(url_for_list(@list_type), erb(:full_list))
end

#generate_stubsObject



20
21
22
23
24
25
26
27
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 20

def generate_stubs
  puts "Generating stubs..."
  generate_module_stubs(Registry.root)
  namespace_objects.each do |object|
    generate_module_stubs(object)
  end
  generate_autoloader(namespace_objects)
end

#group_constant(constant) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 126

def group_constant(constant)
  constant_name = constant.name.to_s
  MANUAL_CONSTANT_GROUPS.each { |rule|
    if rule[:constants]
      return rule[:group] if rule[:constants].include?(constant_name)
    else
      return rule[:group] if rule[:regex].match(constant_name)
    end
  }
  if constant_name.include?('_')
    constant_name.split('_').first
  else
    constant_name[CAMELCASE_CONSTANT] || constant_name
  end
end

#initObject



5
6
7
# File 'lib/yard-sketchup/templates/apis/fulldoc/text/setup.rb', line 5

def init
  find_all_apis
end

#javascriptsObject

TODO(thomthom): Temporarily disabled until we have time to fully implement this. def menu_lists

# Load the existing menus
super + [ { :type => 'object_types', :title => 'Object Reference', :search_title => 'Object Reference List' } ]

end



11
12
13
14
15
16
17
18
19
20
21
# File 'lib/yard-sketchup/templates/default/layout/html/setup.rb', line 11

def javascripts
  # Using the latest 1.x jQuery from CDN broke the YARD js. For now we must
  # continue to use the version shipping with the YARD template we use as base.
  #
  # UPDATE: jQuery 1.9 removed a number of functions.
  #   GitHub report security warnings for jQuery older than 1.9. In order to
  #   upgrade we vendor jQuery of a newer version (1.x branch) along with their
  #   migration plugin to allow YARD to continue to work.
  #   https://github.com/lsegal/yard/pull/1351
  %w(js/jquery.js js/jquery-migrate.js js/app.js)
end

#javascripts_full_listObject

Template overrides:



16
17
18
# File 'lib/yard-sketchup/templates/default/fulldoc/html/setup.rb', line 16

def javascripts_full_list
  %w(js/jquery.js js/jquery-migrate.js js/full_list.js js/sketchup.js)
end

#list_all_classesObject



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/yard-sketchup/templates/inheritance/fulldoc/text/setup.rb', line 43

def list_all_classes
  # versions = Set.new
  klasses = []
  class_objects.each { |object|
    # version_tag = object.tag(:version)
    # versions << version_tag.text if version_tag
    klasses << namespace_definition(object)
  }
  # puts klasses.sort.join("\n")
  puts klasses.sort.join
  exit # Avoid the YARD summary
end

#namespace_definition(object) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 78

def namespace_definition(object)
  return if object.root?
  definition = "#{object.type} #{object.path}"
  if object.type == :class && object.superclass.name != :Object
    definition << " < #{object.superclass.path}"
  end
  output = StringIO.new
  output.puts generate_docstring(object)
  output.puts definition
  output.string
end

#namespace_objectsObject

NOTE: Remember to run objects outputted through ‘run_verifier` first in order to filter out items that should be excluded by command line arguments.



16
17
18
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 16

def namespace_objects
  run_verifier(Registry.all(:class, :module))
end

#object_optionsObject



278
279
280
281
282
283
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 278

def object_options
  {
    :inherited => false,
    :included => false
  }
end

#output_pathObject



90
91
92
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 90

def output_path
  options.serializer.options[:basepath] || File.join(Dir.pwd, 'stubs')
end


37
38
39
40
41
42
43
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 37

def print_section(io, title, content)
  return if content.strip.empty?
  io.puts
  io.puts "  # #{title}"
  io.puts
  io.puts content
end

#reference_listObject

See ‘class_list` in fulldoc/html.



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/yard-sketchup/templates/default/fulldoc/html/setup.rb', line 64

def reference_list
   even_odd = "odd"
   out = ""
   @items.each { |item|
      out << "<li class='#{even_odd}'>"
      out << "<a class='toggle'></a>"
      out << item
      out << "</li>"
      even_odd = (even_odd == 'even' ? 'odd' : 'even')
   }
   out
end

#sort_methods(object, scope) ⇒ Object



270
271
272
273
274
275
276
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 270

def sort_methods(object, scope)
  methods = run_verifier(object.meths(object_options))
  objects = methods.select { |method|
    !method.is_alias? && method.scope == scope
  }
  stable_sort_by(objects, &:name)
end

#sourceObject



4
5
6
# File 'lib/yard-sketchup/templates/default/method_details/setup.rb', line 4

def source 
  return 
end

#stable_sort_by(list) ⇒ Array

A stable sort_by method.

Parameters:

  • (Enumerable)

Returns:

  • (Array)


120
121
122
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 120

def stable_sort_by(list)
  list.each_with_index.sort_by { |item, i| [yield(item), i] }.map(&:first)
end

#stub_filename(object) ⇒ Object



110
111
112
113
114
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 110

def stub_filename(object)
  basename = object.path.gsub('::', '/')
  basename = '_top_level' if basename.empty?
  File.join(stubs_path, "#{basename}.rb")
end

#stubs_gem_pathObject



102
103
104
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 102

def stubs_gem_path
  ensure_exist(File.join(stubs_lib_path, 'sketchup-api-stubs'))
end

#stubs_lib_pathObject



98
99
100
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 98

def stubs_lib_path
  ensure_exist(File.join(stubs_root_path, 'lib'))
end

#stubs_pathObject



106
107
108
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 106

def stubs_path
  ensure_exist(File.join(stubs_gem_path, 'stubs'))
end

#stubs_root_pathObject



94
95
96
# File 'lib/yard-sketchup/templates/stubs/fulldoc/text/setup.rb', line 94

def stubs_root_path
  ensure_exist(output_path)
end

#stylesheetsObject



23
24
25
# File 'lib/yard-sketchup/templates/default/layout/html/setup.rb', line 23

def stylesheets
  %w(css/style.css css/sketchup.css css/rubyapi.css)
end