yard-js 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +138 -0
  4. data/lib/yard-js.rb +30 -0
  5. data/lib/yard-js/code_objects.rb +8 -0
  6. data/lib/yard-js/code_objects/event_object.rb +11 -0
  7. data/lib/yard-js/code_objects/property_object.rb +83 -0
  8. data/lib/yard-js/core_ext/parsejs.rb +13 -0
  9. data/lib/yard-js/core_ext/yard.rb +17 -0
  10. data/lib/yard-js/core_ext/yard/code_objects.rb +45 -0
  11. data/lib/yard-js/core_ext/yard/registry.rb +29 -0
  12. data/lib/yard-js/core_ext/yard/tags.rb +48 -0
  13. data/lib/yard-js/core_ext/yard/templates.rb +116 -0
  14. data/lib/yard-js/core_ext/yard/yardoc.rb +23 -0
  15. data/lib/yard-js/handlers.rb +7 -0
  16. data/lib/yard-js/handlers/base.rb +53 -0
  17. data/lib/yard-js/handlers/class_handler.rb +43 -0
  18. data/lib/yard-js/handlers/comment_handler.rb +33 -0
  19. data/lib/yard-js/handlers/constant_handler.rb +50 -0
  20. data/lib/yard-js/handlers/instance_method_handler.rb +26 -0
  21. data/lib/yard-js/handlers/mixin_handler.rb +18 -0
  22. data/lib/yard-js/handlers/module_handler.rb +33 -0
  23. data/lib/yard-js/parser.rb +23 -0
  24. data/lib/yard-js/plugin.rb +23 -0
  25. data/lib/yard-js/tags.rb +37 -0
  26. data/lib/yard-js/version.rb +3 -0
  27. data/templates/default/class/setup.rb +11 -0
  28. data/templates/default/fulldoc/html/css/highlight.github.css +127 -0
  29. data/templates/default/fulldoc/html/css/style.css +10 -0
  30. data/templates/default/fulldoc/html/full_list_property.erb +12 -0
  31. data/templates/default/fulldoc/html/js/highlight.pack.js +1 -0
  32. data/templates/default/fulldoc/html/setup.rb +18 -0
  33. data/templates/default/layout/html/headers.erb +17 -0
  34. data/templates/default/layout/html/setup.rb +14 -0
  35. data/templates/default/method_details/setup.rb +13 -0
  36. data/templates/default/module/html/constructor_summary.erb +9 -0
  37. data/templates/default/module/html/events_details.erb +8 -0
  38. data/templates/default/module/html/events_summary.erb +20 -0
  39. data/templates/default/module/html/inherited_methods.erb +8 -0
  40. data/templates/default/module/html/inherited_properties.erb +8 -0
  41. data/templates/default/module/html/item_summary.erb +38 -0
  42. data/templates/default/module/html/method_summary.erb +11 -0
  43. data/templates/default/module/html/methods_details.erb +8 -0
  44. data/templates/default/module/html/properties_details.erb +8 -0
  45. data/templates/default/module/html/properties_summary.erb +11 -0
  46. data/templates/default/module/setup.rb +75 -0
  47. data/templates/default/tags/callback.erb +21 -0
  48. data/templates/default/tags/setup.rb +24 -0
  49. data/templates/default/tags/value.erb +6 -0
  50. data/yard-js.gemspec +15 -0
  51. metadata +92 -0
@@ -0,0 +1,116 @@
1
+ module YARD
2
+ module Templates
3
+ module Helpers
4
+ module HtmlHelper
5
+ def link_object(obj, otitle = nil, anchor = nil, relative = true)
6
+ return otitle if obj.nil?
7
+ obj = Registry.resolve(object, obj, true, true) if obj.is_a?(String)
8
+ if !otitle && obj.root?
9
+ title = "Top Level Namespace"
10
+ elsif otitle
11
+ title = otitle.to_s
12
+ elsif object.is_a?(CodeObjects::Base)
13
+ # Check if we're linking to a class method in the current
14
+ # object. If we are, create a title in the format of
15
+ # "CurrentClass.method_name"
16
+ title = h(object.relative_path(obj))
17
+ if obj.is_a?(YARDJS::CodeObjects::PropertyObject) && obj.property_type == :function
18
+ title += '()'
19
+ elsif obj.title != obj.path
20
+ title = h(obj.title)
21
+ end
22
+ else
23
+ title = h(obj.to_s)
24
+ end
25
+ return title unless serializer
26
+ return title if obj.is_a?(CodeObjects::Proxy)
27
+
28
+ link = url_for(obj, anchor, relative)
29
+ link = link ? link_url(link, title, :title => h("#{obj.title} (#{obj.type})")) : title
30
+ "<span class='object_link'>" + link + "</span>"
31
+ end
32
+
33
+ def signature_types(meth, link = true)
34
+ meth = convert_method_to_overload(meth)
35
+ if meth.respond_to?(:object) && !meth.has_tag?(:return)
36
+ meth = meth.object
37
+ end
38
+ return unless meth
39
+
40
+ type = options.default_return || ""
41
+ if meth.tag(:return) && meth.tag(:return).types
42
+ types = meth.tags(:return).map {|t| t.types ? t.types : [] }.flatten.uniq
43
+ first = link ? h(types.first) : format_types([types.first], false)
44
+ if types.size == 2 && types.last == 'null'
45
+ type = first + '<sup>?</sup>'
46
+ elsif types.size == 2 && types.last =~ /^(Array)?<#{Regexp.quote types.first}>$/
47
+ type = first + '<sup>+</sup>'
48
+ elsif types.size > 2
49
+ type = [first, '...'].join(', ')
50
+ elsif types == ['void'] && options.hide_void_return
51
+ type = ""
52
+ else
53
+ type = link ? h(types.join(", ")) : format_types(types, false)
54
+ end
55
+ elsif !type.empty?
56
+ type = link ? h(type) : format_types([type], false)
57
+ end
58
+ type = "(#{type}) " unless type.empty?
59
+ type
60
+ end
61
+
62
+ def signature(meth, link = true, show_extras = true, full_attr_name = true)
63
+ meth = convert_method_to_overload(meth)
64
+
65
+ small_type = true
66
+ type = signature_types(meth, link)
67
+ args = ''
68
+ name = meth.name.to_s
69
+
70
+ if meth.constructor?
71
+ type, name = 'new ', meth.namespace.path.gsub(/_\d+/, '')
72
+ end
73
+
74
+ if meth.property_type == :function
75
+ if meth.parameters
76
+ args = meth.parameters.map {|n, v| v ? "#{n} = #{v}" : n.to_s }.join(", ")
77
+ end
78
+ args = "(#{args})"
79
+ end
80
+
81
+ if YARDJS::Tags::CallbackTag === meth
82
+ small_type = false
83
+ type = ''
84
+ args += ' { ... }'
85
+ end
86
+
87
+ extras = []
88
+ extras_text = ''
89
+ if show_extras
90
+ extras << 'static' if meth.tag(:static)
91
+ extras << 'readonly' if meth.tag(:readonly)
92
+ extras << 'writeonly' if meth.tag(:writeonly)
93
+ extras << 'readwrite' if !meth.tag(:readonly) && !meth.tag(:writeonly) && meth.property_type != :function
94
+ extras << meth.visibility if meth.visibility != :public
95
+ extras_text = ' <span class="extras">(' + extras.join(", ") + ')</span>' unless extras.empty?
96
+ end
97
+
98
+ if small_type
99
+ title = "<small>%s</small><strong>%s</strong>%s" % [type, h(name), args]
100
+ else
101
+ title = "%s<strong>%s</strong>%s" % [type, h(name), args]
102
+ end
103
+
104
+ if link
105
+ link_title = h(name)
106
+ obj = meth.respond_to?(:object) ? meth.object : meth
107
+ url = url_for(object, obj)
108
+ link_url(url, title, :title => link_title) + extras_text
109
+ else
110
+ title + extras_text
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,23 @@
1
+ module YARD
2
+ module CLI
3
+ class Yardoc
4
+ def general_options_yardjs(opts)
5
+ general_options_orig(opts)
6
+
7
+ opts.on('--define-class-expr EXPR') do |expr|
8
+ YARDJS.options.define_class_expression = expr
9
+ end
10
+
11
+ opts.on('--update-class-expr EXPR') do |expr|
12
+ YARDJS.options.update_class_expression = expr
13
+ end
14
+
15
+ opts.on('--mixin-module-expr EXPR') do |expr|
16
+ YARDJS.options.mixin_module_expression = expr
17
+ end
18
+ end
19
+ alias general_options_orig general_options
20
+ alias general_options general_options_yardjs
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'handlers/base'
2
+ require_relative 'handlers/class_handler'
3
+ require_relative 'handlers/comment_handler'
4
+ require_relative 'handlers/constant_handler'
5
+ require_relative 'handlers/instance_method_handler'
6
+ require_relative 'handlers/mixin_handler'
7
+ require_relative 'handlers/module_handler'
@@ -0,0 +1,53 @@
1
+ require_relative '../core_ext/yard'
2
+ require_relative '../core_ext/parsejs'
3
+
4
+ module YARDJS
5
+ module Handlers
6
+ class Base < YARD::Handlers::Base
7
+ include ParseJS::AST
8
+
9
+ def self.handles?(node)
10
+ handlers.any? {|h| node.is_a?(h) }
11
+ end
12
+
13
+ def call_params; [] end
14
+ def caller_method; nil end
15
+
16
+ def parse_block(inner_node, opts = {})
17
+ push_state(opts) { parser.process([inner_node].flatten) }
18
+ end
19
+
20
+ def handle_default_comments(comments = statement.comments)
21
+ return if comments.size == 1
22
+ comments[0...-1].each do |comment|
23
+ register_docstring(nil, clean_comment(comment.body))
24
+ end
25
+
26
+ if parser.extra_state.ignore_next_statement
27
+ parser.extra_state.ignore_next_statement = nil
28
+ abort!
29
+ end
30
+ end
31
+
32
+ def clean_comment(comment)
33
+ comment = comment.body if comment.respond_to?(:body)
34
+ return "" if comment.nil?
35
+ comment.gsub(/^[ \t]*\*[ \t]{0,1}/, '')
36
+ end
37
+
38
+ def register_docstring(object, docstring = statement.comments, stmt = statement)
39
+ docstring = docstring.last if Array === docstring
40
+ docstring = clean_comment(docstring) if docstring
41
+ docstring.force_encoding('utf-8') if docstring
42
+
43
+ super(object, docstring, stmt)
44
+ end
45
+
46
+ def register_source(object, source = statement.source, type = parser.parser_type)
47
+ return unless object.is_a?(CodeObjects::PropertyObject)
48
+ object.source ||= source
49
+ object.source_type = type
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,43 @@
1
+ require_relative 'base'
2
+
3
+ module YARDJS
4
+ module Handlers
5
+ class ClassHandler < Base
6
+ handles AssignmentExpression
7
+ handles Property
8
+
9
+ process do
10
+ statement.comments ||= parser.extra_state.comments
11
+ handle_default_comments
12
+
13
+ if statement.is_a?(AssignmentExpression)
14
+ left, right = statement.left, statement.right
15
+ else
16
+ left, right = statement.key, statement.value
17
+ end
18
+
19
+ return unless right.is_a?(CallExpression) &&
20
+ right.callee.source =~ YARDJS.options.define_class_expression
21
+
22
+ obj = register YARD::CodeObjects::ClassObject.new(namespace, left.source)
23
+ obj.superclass = right.args.first.source if right.args.size > 1
24
+
25
+ defs = right.args.last.properties
26
+ parse_block(defs, :namespace => obj)
27
+ end
28
+ end
29
+
30
+ class UpdateClassHandler < Base
31
+ handles CallExpression
32
+
33
+ process do
34
+ return unless statement.callee.source =~
35
+ YARDJS.options.update_class_expression
36
+
37
+ ns = P(statement.args.first.source.gsub(/\.prototype/, ''))
38
+ ensure_loaded!(ns)
39
+ parse_block(statement.args.last.properties, :namespace => ns)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'base'
2
+
3
+ module YARDJS
4
+ module Handlers
5
+ class CommentedStatementHandler < Base
6
+ handles CommentedStatement
7
+
8
+ process do
9
+ parser.extra_state.comments = statement.comments
10
+ parse_block(statement.statement)
11
+ parser.extra_state.comments = nil
12
+ end
13
+ end
14
+
15
+ class ExpressionStatementHandler < Base
16
+ handles ExpressionStatement
17
+ process { parse_block statement.expression }
18
+ end
19
+
20
+ class SequenceExpressionStatementHandler < Base
21
+ handles SequenceExpression
22
+ process { parse_block statement.expressions }
23
+ end
24
+
25
+ class CommentHandler < Base
26
+ handles Comment
27
+
28
+ process do
29
+ register_docstring(nil)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,50 @@
1
+ require_relative 'base'
2
+
3
+ module YARDJS
4
+ module Handlers
5
+ class ConstantHandler < Base
6
+ handles AssignmentExpression
7
+ handles Property
8
+
9
+ process do
10
+ if statement.is_a?(AssignmentExpression)
11
+ name, value = statement.left.source, statement.right
12
+ else
13
+ name, value = statement.key.val, statement.value
14
+ end
15
+
16
+ return if value.is_a?(FunctionExpression)
17
+ return if value.is_a?(ObjectExpression)
18
+ return if value.is_a?(CallExpression)
19
+
20
+ handle_default_comments
21
+
22
+ obj = register CodeObjects::PropertyObject.new(namespace, name)
23
+ if value.is_a?(Literal)
24
+ obj.property_type = :literal
25
+ if type = parse_type(value.val)
26
+ obj.docstring.add_tag(YARD::Tags::Tag.new(:return, '', [type]))
27
+ end
28
+ else
29
+ obj.property_type = :object
30
+ end
31
+
32
+ unless obj.has_tag?(:value)
33
+ obj.docstring.add_tag(YARD::Tags::Tag.new(:value, value.source))
34
+ end
35
+
36
+ unless obj.has_tag?(:static)
37
+ obj.docstring.add_tag(YARD::Tags::Tag.new(:static, ''))
38
+ end
39
+ end
40
+
41
+ def parse_type(type)
42
+ case type
43
+ when Node; type.class.to_s[/::([^:]+)$/, 1]
44
+ when FalseClass, TrueClass; 'Boolean'
45
+ when NilClass; 'null'
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'base'
2
+
3
+ module YARDJS
4
+ module Handlers
5
+ class InstanceMethodHandler < Base
6
+ handles Property
7
+
8
+ process do
9
+ return unless statement.value.is_a?(FunctionExpression)
10
+
11
+ handle_default_comments
12
+
13
+ name = statement.key.val
14
+ params = statement.value.params.list.map {|t| [t.val, nil]}
15
+
16
+ obj = register CodeObjects::PropertyObject.new(namespace, name)
17
+ obj.property_type = :function
18
+ obj.parameters = params
19
+ obj.signature = "#{name}(#{params.join(', ')})"
20
+ unless obj.has_tag?(:return)
21
+ obj.docstring.add_tag(YARD::Tags::Tag.new(:return, '', ['void']))
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'base'
2
+
3
+ module YARDJS
4
+ module Handlers
5
+ class MixinHandler < Base
6
+ handles CallExpression
7
+
8
+ process do
9
+ return unless statement.callee.source =~ YARDJS.options.mixin_module_expression
10
+
11
+ obj = YARD::CodeObjects::ClassObject.new(:root, statement.args.first.source)
12
+ obj.instance_mixins.push(*statement.args[1..-1].map do |arg|
13
+ YARD::CodeObjects::ClassObject.new(:root, arg.source)
14
+ end)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'base'
2
+
3
+ module YARDJS
4
+ module Handlers
5
+ class ModuleHandler < Base
6
+ handles AssignmentExpression
7
+ handles VariableDeclaration
8
+ handles Property
9
+
10
+ process do
11
+ case statement
12
+ when VariableDeclaration
13
+ left = statement.declarations.first.id
14
+ right = statement.declarations.first.init
15
+ when AssignmentExpression
16
+ left = statement.left
17
+ right = statement.right
18
+ when Property
19
+ left = statement.key
20
+ right = statement.value
21
+ end
22
+
23
+ return unless ObjectExpression === right
24
+
25
+ statement.comments ||= parser.extra_state.comments
26
+ handle_default_comments
27
+
28
+ obj = register YARD::CodeObjects::ModuleObject.new(namespace, left.source)
29
+ parse_block(right.properties, :namespace => obj)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'core_ext/yard'
2
+
3
+ module YARDJS
4
+ module Parser
5
+ class JavaScriptParser < YARD::Parser::Base
6
+ attr_accessor :file, :source, :ast
7
+
8
+ def initialize(source, filename)
9
+ self.source = source
10
+ self.file = filename
11
+ end
12
+
13
+ def parse
14
+ self.ast = ParseJS.parse(source)
15
+ self
16
+ end
17
+
18
+ def enumerator
19
+ ast.elements
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'core_ext/yard'
2
+ require_relative 'code_objects'
3
+ require_relative 'handlers'
4
+ require_relative 'tags'
5
+ require_relative 'parser'
6
+
7
+ YARD::Parser::SourceParser.register_parser_type(:js, YARDJS::Parser::JavaScriptParser, ['js'])
8
+ YARD::Handlers::Processor.register_handler_namespace(:js, YARDJS::Handlers)
9
+
10
+ YARD::Templates::Engine.register_template_path(File.dirname(__FILE__) + '/../../templates')
11
+
12
+ [:readonly, :writeonly, :static].each do |tag|
13
+ YARD::Tags::Library.define_tag(tag.to_s.capitalize, tag)
14
+ end
15
+ YARD::Tags::Library.define_tag 'Default Value', :default, :with_name
16
+ YARD::Tags::Library.define_tag 'Default Value', :value
17
+ YARD::Tags::Library.define_tag 'Constant', :constant
18
+ YARD::Tags::Library.define_tag 'Context (<tt>this</tt>)', :context, :with_types
19
+ YARD::Tags::Library.define_tag 'Callback', :callback, YARDJS::Tags::CallbackTag
20
+ YARD::Tags::Library.visible_tags.unshift(:value, :context)
21
+
22
+ YARD::Tags::Library.define_directive(:ignore, YARDJS::Tags::IgnoreDirective)
23
+ YARD::Tags::Library.define_directive(:event, :with_title_and_text, YARDJS::Tags::EventDirective)