CoffeeTags 0.0.2.2 → 0.0.2.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  A simple tool for generating CoffeeScript tags (Ctags compatible).
4
4
 
5
+ [![Build Status](https://secure.travis-ci.org/lukaszkorecki/CoffeeTags.png?branch=master)](http://travis-ci.org/lukaszkorecki/CoffeeTags)
6
+
5
7
 
6
8
  ### Example + Screenshot
7
9
  Showing only functions (right) or with variables included (left)
@@ -1,5 +1,7 @@
1
1
  module Coffeetags
2
2
  class Formatter
3
+ # Generates CTAGS header
4
+ # @returns [String] ctags header
3
5
  def self.header
4
6
  return [
5
7
  "!_TAG_FILE_FORMAT 2 /extended format/",
@@ -11,6 +13,10 @@ module Coffeetags
11
13
  ].map { |h| "#{h}\n"}.join ''
12
14
  end
13
15
 
16
+ # New Formatter class
17
+ #
18
+ # @param [String] file file name
19
+ # @param [Array] tree parse tree for given file generated by Coffeetags::Parser
14
20
  def initialize file, tree =[]
15
21
  @file = file
16
22
  @tree = tree
@@ -26,6 +32,7 @@ module Coffeetags
26
32
  end
27
33
 
28
34
 
35
+ # Helper function for formatting a source line into regex
29
36
  def regex_line line
30
37
  "/#{line}/;\""
31
38
  end
@@ -47,8 +54,9 @@ module Coffeetags
47
54
 
48
55
  def parse_tree
49
56
  @lines = @tree.map do | content|
50
- line_to_string content unless content[:line].nil? or content[:name].blank?
51
- end.reject{|l| l.nil? }
57
+ line_to_string content unless content[:line].nil? or content[:name].blank?
58
+ end
59
+ @lines.reject{|l| l.nil? }
52
60
  end
53
61
 
54
62
 
@@ -1,6 +1,11 @@
1
1
  module Coffeetags
2
2
  class Parser
3
3
  attr_reader :tree
4
+ # Creates a new parser
5
+ #
6
+ # @param [String] source source of the CoffeeScript file
7
+ # @param [Bool] include_vars include objects in generated tree (default false)
8
+ # @return [Coffeetags::Parser]
4
9
  def initialize source, include_vars = false
5
10
  @include_vars = include_vars
6
11
  @source = source
@@ -17,12 +22,46 @@ module Coffeetags
17
22
  @var_regex = /([@a-zA-Z0-9_]*)\s*[=:]{1}\s*$/
18
23
  @token_regex = /([@a-zA-Z0-9_]*)\s*[:=]{1}/
19
24
  @iterator_regex = /^\s*for\s*([a-zA-Z0-9_]*)\s*/
25
+ @comment_regex = /^\s*#/
26
+ @block_comment_regex = /^\s*###/
27
+ @comment_lines = mark_commented_lines
20
28
  end
21
29
 
30
+
31
+ # Mark line numbers as commented out
32
+ # either by single line comment (#)
33
+ # or block comments (###~###)
34
+ def mark_commented_lines
35
+ [].tap do |reg|
36
+ in_block_comment = false
37
+ @source.each_with_index do |line, index|
38
+ line_no = index+1
39
+
40
+ in_block_comment = !(in_block_comment) if line =~ @block_comment_regex
41
+ reg << line_no if in_block_comment
42
+ reg << line_no if line =~ @comment_regex and not in_block_comment
43
+ end
44
+ end
45
+ end
46
+
47
+ # Detect current line level based on indentation
48
+ # very useful in parsing, since CoffeeScript's syntax
49
+ # depends on whitespace
50
+ # @param [String] line currently parsed line
51
+ # @return [Integer]
22
52
  def line_level line
23
53
  line.match(/^[ \t]*/)[0].gsub("\t", " ").split('').length
24
54
  end
25
55
 
56
+ # Generate current scope path, for example:
57
+ # e ->
58
+ # f ->
59
+ # z ->
60
+ # Scope path for function z would be:
61
+ # window.e.f
62
+ # @param [Hash, nil] _el element of a prase tree (last one for given tree is used by default)
63
+ # @param [Array, nil] _tree parse tree (or currently built)
64
+ # @returns [String] string representation of scope for given element
26
65
  def scope_path _el = nil, _tree = nil
27
66
  bf = []
28
67
  tree = (_tree || @tree)
@@ -38,40 +77,63 @@ module Coffeetags
38
77
  end
39
78
  end
40
79
  bf.uniq.reverse.join('.')
80
+ end
41
81
 
82
+ # Helper function for generating parse tree elements for given
83
+ # line and regular expression
84
+ #
85
+ # @param [String] line source line currently being parsed
86
+ # @param [RegExp] regex regular expression for matching a syntax element
87
+ # @param [Integer] level current indentation/line level
88
+ # @param [Hash, {}] additional_fields additional fields which need to be added to generated element
89
+ # @returns [Hash,nil] returns a parse tree element consiting of:
90
+ # :name of the element
91
+ # indentation :level of the element
92
+ def item_for_regex line, regex, level, additional_fields={}
93
+ if item = line.match(regex)
94
+ entry_for_item = {
95
+ :name => item[1],
96
+ :level => level
97
+ }
98
+ entry_for_item.merge(additional_fields)
99
+ end
42
100
  end
43
101
 
102
+ # Parse the source and create a tags tree
103
+ # @note this method mutates @tree instance variable of Coffeetags::Parser instance
104
+ # @returns self it can be chained
44
105
  def execute!
45
106
  line_n = 0
46
107
  level = 0
47
- # indentify scopes
48
108
  @source.each_line do |line|
49
109
  line_n += 1
110
+ # indentify scopes
50
111
  level = line_level line
51
112
 
52
113
  # ignore comments!
53
- next if line =~ /^\s*#/
54
-
55
- # FIXME this could be DRYied
56
- if (_class = line.match @class_regex)
57
- @tree << { :name => _class[1], :level => level }
114
+ next if @comment_lines.include? line_n
115
+
116
+ # extract elements for given line
117
+ [
118
+ @class_regex,
119
+ @proto_meths,
120
+ @var_regex
121
+ ].each do |regex|
122
+ mt = item_for_regex line, regex, level
123
+ @tree << mt unless mt.nil?
58
124
  end
59
125
 
60
- if(_proto = line.match @proto_meths)
61
- @tree << { :name => _proto[1], :level => level }
62
- end
63
126
 
64
- if(var = line.match @var_regex)
65
- @tree << { :name => var[1], :level => level }
66
- end
127
+ # does this line contain a block?
128
+ mt = item_for_regex line, @block, level, :kind => 'b'
129
+ @tree << mt unless mt.nil?
67
130
 
68
- if(_block = line.match @block)
69
- @tree << { :name => _block[1], :level => level , :kind => 'b'}
70
- end
71
131
 
132
+ # instance variable or iterator (for/in)?
72
133
  token = line.match(@token_regex )
73
134
  token ||= line.match(@iterator_regex)
74
135
 
136
+ # we have found something!
75
137
  if not token.nil?
76
138
  o = {
77
139
  :name => token[1],
@@ -85,8 +147,8 @@ module Coffeetags
85
147
  # - if a line containes a line like: element.getElement('type=[checkbox]').lol()
86
148
  is_in_string = line =~ /.*['"].*#{token[1]}.*=.*["'].*/
87
149
 
88
- # - scope access and comparison in if x == 'lol'
89
- is_in_comparison = line =~ /::|==/
150
+ # - scope access and comparison in if x == 'lol'
151
+ is_in_comparison = line =~ /::|==/
90
152
 
91
153
  # - objects with blank parent (parser bug?)
92
154
  has_blank_parent = o[:parent] =~ /\.$/
@@ -95,7 +157,7 @@ module Coffeetags
95
157
  is_previous_not_the_same = !(@tree.last and @tree.last[:name] == o[:name] and @tree.last[:level] == o[:level])
96
158
 
97
159
  if is_in_string.nil? and is_in_comparison.nil? and has_blank_parent.nil? and is_previous_not_the_same
98
- o[:kind] = line =~ /[:=]{1}.*[-=]\>/ ? 'f' : 'o'
160
+ o[:kind] = line =~ /[:=]{1}.*[-=]\>/ ? 'f' : 'o'
99
161
  o[:parent] = scope_path o
100
162
  o[:parent] = @fake_parent if o[:parent].empty?
101
163
 
@@ -103,7 +165,9 @@ module Coffeetags
103
165
  @tree << o if o[:kind] == 'o' and @include_vars
104
166
  end
105
167
  end
168
+ # get rid of duplicate entries
106
169
  @tree.uniq!
170
+ self # chain!
107
171
  end
108
172
  end
109
173
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Coffeetags
3
- VERSION = "0.0.2.2"
3
+ VERSION = "0.0.2.4"
4
4
  end
@@ -0,0 +1,7 @@
1
+ ###
2
+ Lol wut
3
+ echo : ->
4
+ echoes
5
+ ###
6
+
7
+ echo2 :-> console.log 'echo'
@@ -0,0 +1,7 @@
1
+ !_TAG_FILE_FORMAT 2 /extended format/
2
+ !_TAG_FILE_SORTED 0 /0=unsorted, 1=sorted, 2=foldcase/
3
+ !_TAG_PROGRAM_AUTHOR Łukasz Korecki /lukasz@coffeesounds.com/
4
+ !_TAG_PROGRAM_NAME CoffeeTags //
5
+ !_TAG_PROGRAM_URL https://github.com/lukaszkorecki/CoffeeTags /GitHub repository/
6
+ !_TAG_PROGRAM_VERSION 0.0.2.4 //
7
+ echo2 spec/fixtures/blockcomment.coffee /echo2/;" f lineno:7 object:window type:function
@@ -3,20 +3,29 @@
3
3
  !_TAG_PROGRAM_AUTHOR Łukasz Korecki /lukasz@coffeesounds.com/
4
4
  !_TAG_PROGRAM_NAME CoffeeTags //
5
5
  !_TAG_PROGRAM_URL https://github.com/lukaszkorecki/CoffeeTags /GitHub repository/
6
- !_TAG_PROGRAM_VERSION 0.0.2.2 //
6
+ !_TAG_PROGRAM_VERSION 0.0.2.4 //
7
7
  bump spec/fixtures/test.coffee /bump/;" f lineno:1 object:window type:function
8
+
8
9
  ho spec/fixtures/test.coffee /ho/;" f lineno:5 object:Wat type:function
10
+
9
11
  bump spec/fixtures/test.coffee /bump/;" f lineno:10 object:Wat.ho.@lolWat type:function
10
12
  bump_up spec/fixtures/test.coffee /bump_up/;" f lineno:12 object:Wat.ho.@lolWat type:function
11
13
  @filter spec/fixtures/test.coffee /@filter/;" f lineno:14 object:Wat.ho type:function
12
14
  _loop spec/fixtures/test.coffee /_loop/;" f lineno:19 object:window type:function
15
+
16
+
17
+
18
+
13
19
  bound_func spec/fixtures/test.coffee /bound_func/;" f lineno:41 object:window type:function
14
20
  beam_magnum spec/fixtures/test.coffee /beam_magnum/;" f lineno:44 object:window type:function
21
+
15
22
  constructor spec/fixtures/campfire.coffee /constructor/;" f lineno:8 object:Campfire type:function
16
23
  handlers spec/fixtures/campfire.coffee /handlers/;" f lineno:14 object:Campfire type:function
24
+
17
25
  onSuccess spec/fixtures/campfire.coffee /onSuccess/;" f lineno:16 object:Campfire.handlers.resp type:function
18
26
  onFailure spec/fixtures/campfire.coffee /onFailure/;" f lineno:24 object:Campfire.handlers.resp type:function
19
27
  rooms spec/fixtures/campfire.coffee /rooms/;" f lineno:29 object:Campfire type:function
20
28
  roomInfo spec/fixtures/campfire.coffee /roomInfo/;" f lineno:34 object:Campfire type:function
21
29
  recent spec/fixtures/campfire.coffee /recent/;" f lineno:40 object:Campfire type:function
30
+
22
31
  bump spec/fixtures/campfire.coffee /bump/;" f lineno:46 object:Test type:function
@@ -3,12 +3,18 @@
3
3
  !_TAG_PROGRAM_AUTHOR Łukasz Korecki /lukasz@coffeesounds.com/
4
4
  !_TAG_PROGRAM_NAME CoffeeTags //
5
5
  !_TAG_PROGRAM_URL https://github.com/lukaszkorecki/CoffeeTags /GitHub repository/
6
- !_TAG_PROGRAM_VERSION 0.0.2.2 //
6
+ !_TAG_PROGRAM_VERSION 0.0.2.4 //
7
7
  bump spec/fixtures/test.coffee /bump/;" f lineno:1 object:window type:function
8
+
8
9
  ho spec/fixtures/test.coffee /ho/;" f lineno:5 object:Wat type:function
10
+
9
11
  bump spec/fixtures/test.coffee /bump/;" f lineno:10 object:Wat.ho.@lolWat type:function
10
12
  bump_up spec/fixtures/test.coffee /bump_up/;" f lineno:12 object:Wat.ho.@lolWat type:function
11
13
  @filter spec/fixtures/test.coffee /@filter/;" f lineno:14 object:Wat.ho type:function
12
14
  _loop spec/fixtures/test.coffee /_loop/;" f lineno:19 object:window type:function
15
+
16
+
17
+
18
+
13
19
  bound_func spec/fixtures/test.coffee /bound_func/;" f lineno:41 object:window type:function
14
20
  beam_magnum spec/fixtures/test.coffee /beam_magnum/;" f lineno:44 object:window type:function
data/spec/parser_spec.rb CHANGED
@@ -167,5 +167,43 @@ describe 'CoffeeTags::Parser' do
167
167
  subject[:parent].should == '_loop'
168
168
  end
169
169
  end
170
+ context 'Block comments' do
171
+ let(:bc_file) { 'spec/fixtures/blockcomment.coffee'}
172
+ let(:bc_ctags_file) { 'spec/fixtures/blockcomment.ctags'}
173
+ let(:blockcomment_file) { File.read(bc_file)}
174
+ let(:blockcomment_tree) {
175
+ [{:level=>0,
176
+ :parent=>"window",
177
+ :source=>"echo2 :-> console.log 'echo'",
178
+ :line=>7,
179
+ :kind=>"f",
180
+ :name=>"echo2"}]
181
+ }
182
+
183
+ subject {
184
+ parser = Coffeetags::Parser.new(blockcomment_file, true)
185
+ parser.execute!
186
+ parser
187
+ }
188
+
189
+ it 'ignores block comments when parsing the contents' do
190
+ subject.tree.first.should == blockcomment_tree.first
191
+ end
192
+
193
+
194
+ context 'top-down test' do
195
+ let(:blockcomment_ctags){ File.read(bc_ctags_file) }
196
+ subject {
197
+ Coffeetags::Utils.run 'test_bc.out', nil, bc_file
198
+ File.read 'test_bc.out'
199
+ }
200
+
201
+ after(:all) { `rm test_bc.out` }
202
+
203
+ it 'ignores block comments in output' do
204
+ subject.should == blockcomment_ctags
205
+ end
206
+ end
207
+ end
170
208
  end
171
209
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: CoffeeTags
3
3
  version: !ruby/object:Gem::Version
4
- hash: 67
4
+ hash: 79
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
9
  - 2
10
- - 2
11
- version: 0.0.2.2
10
+ - 4
11
+ version: 0.0.2.4
12
12
  platform: ruby
13
13
  authors:
14
14
  - "\xC5\x81ukasz Korecki"
@@ -16,8 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2012-03-06 00:00:00 +00:00
20
- default_executable:
19
+ date: 2012-03-12 00:00:00 Z
21
20
  dependencies: []
22
21
 
23
22
  description: CoffeeTags generates ctags compatibile tags for CoffeeScript.
@@ -45,6 +44,8 @@ files:
45
44
  - lib/CoffeeTags/parser.rb
46
45
  - lib/CoffeeTags/version.rb
47
46
  - spec/coffeetags_spec.rb
47
+ - spec/fixtures/blockcomment.coffee
48
+ - spec/fixtures/blockcomment.ctags
48
49
  - spec/fixtures/campfire.coffee
49
50
  - spec/fixtures/campfire.js
50
51
  - spec/fixtures/campfire.js.tags
@@ -60,7 +61,6 @@ files:
60
61
  - tagbar-info.markdown
61
62
  - test.rb
62
63
  - vim/tagbar-coffee.vim.erb
63
- has_rdoc: true
64
64
  homepage: http://github.com/lukaszkorecki/CoffeeTags
65
65
  licenses: []
66
66
 
@@ -90,12 +90,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
90
  requirements: []
91
91
 
92
92
  rubyforge_project: CoffeeTags
93
- rubygems_version: 1.5.0
93
+ rubygems_version: 1.8.16
94
94
  signing_key:
95
95
  specification_version: 3
96
96
  summary: tags generator for CoffeeScript
97
97
  test_files:
98
98
  - spec/coffeetags_spec.rb
99
+ - spec/fixtures/blockcomment.coffee
100
+ - spec/fixtures/blockcomment.ctags
99
101
  - spec/fixtures/campfire.coffee
100
102
  - spec/fixtures/campfire.js
101
103
  - spec/fixtures/campfire.js.tags