starscope 1.4.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,114 @@
1
+ require 'rkelly'
2
+ require 'babel/transpiler'
3
+ require 'sourcemap'
4
+
5
+ module Starscope::Lang
6
+ module Javascript
7
+ VERSION = 0
8
+
9
+ def self.match_file(name)
10
+ name.end_with?('.js')
11
+ end
12
+
13
+ def self.extract(path, contents, &block)
14
+ transform = Babel::Transpiler.transform(contents,
15
+ 'stage' => 0,
16
+ 'blacklist' => ['validation.react'],
17
+ 'externalHelpers' => true,
18
+ 'compact' => false,
19
+ 'sourceMaps' => true)
20
+ map = SourceMap::Map.from_hash(transform['map'])
21
+ ast = RKelly::Parser.new.parse(transform['code'])
22
+ lines = contents.lines.to_a
23
+
24
+ return unless ast
25
+
26
+ found = extract_methods(ast, map, lines, &block)
27
+
28
+ found = extract_var_decls(ast, map, lines, found, &block)
29
+
30
+ extract_var_reads(ast, map, lines, found, &block)
31
+ end
32
+
33
+ def self.extract_methods(ast, map, lines, &block)
34
+ found = {}
35
+
36
+ ast.each do |node|
37
+ case node
38
+ when RKelly::Nodes::FunctionExprNode, RKelly::Nodes::FunctionDeclNode
39
+ line = find_line(node.range.from, map, lines, node.value)
40
+ next unless line
41
+
42
+ type = :func
43
+ type = :class if lines[line - 1].include?("class #{node.value}")
44
+
45
+ yield :defs, node.value, line_no: line, type: type
46
+ found[node.value] ||= Set.new
47
+ found[node.value].add(line)
48
+
49
+ next if type == :class
50
+
51
+ mapping = map.bsearch(SourceMap::Offset.new(node.range.to.line, node.range.to.char))
52
+ yield :end, :'}', line_no: mapping.original.line, type: type
53
+ when RKelly::Nodes::FunctionCallNode
54
+ name = node_name(node.value)
55
+ next unless name
56
+
57
+ line = find_line(node.range.from, map, lines, name)
58
+ next unless line
59
+
60
+ yield :calls, name, line_no: line
61
+ found[name] ||= Set.new
62
+ found[name].add(line)
63
+ end
64
+ end
65
+
66
+ found
67
+ end
68
+
69
+ def self.extract_var_decls(ast, map, lines, found, &block)
70
+ ast.each do |node|
71
+ next unless node.is_a? RKelly::Nodes::VarDeclNode
72
+
73
+ line = find_line(node.range.from, map, lines, node.name)
74
+ next unless line
75
+
76
+ next if found[node.name] && found[node.name].include?(line)
77
+ yield :defs, node.name, line_no: line
78
+ found[node.name] ||= Set.new
79
+ found[node.name].add(line)
80
+ end
81
+
82
+ found
83
+ end
84
+
85
+ def self.extract_var_reads(ast, map, lines, found, &block)
86
+ ast.each do |node|
87
+ name = node_name(node)
88
+ next unless name
89
+
90
+ line = find_line(node.range.from, map, lines, name)
91
+ next unless line
92
+
93
+ next if found[name] && found[name].include?(line)
94
+ yield :reads, name, line_no: line
95
+ end
96
+ end
97
+
98
+ def self.node_name(node)
99
+ case node
100
+ when RKelly::Nodes::DotAccessorNode
101
+ node.accessor
102
+ when RKelly::Nodes::ResolveNode
103
+ node.value
104
+ end
105
+ end
106
+
107
+ def self.find_line(from, map, lines, name)
108
+ mapping = map.bsearch(SourceMap::Offset.new(from.line, from.char))
109
+ return unless mapping
110
+ return unless lines[mapping.original.line - 1].include? name
111
+ mapping.original.line
112
+ end
113
+ end
114
+ end
@@ -18,8 +18,6 @@ module Starscope::Lang
18
18
  extract_tree(ast, [], &block) unless ast.nil?
19
19
  end
20
20
 
21
- private
22
-
23
21
  def self.extract_tree(tree, scope, &block)
24
22
  extract_node(tree, scope, &block)
25
23
 
@@ -40,45 +38,45 @@ module Starscope::Lang
40
38
  case node.type
41
39
  when :send
42
40
  name = scoped_name(node, scope)
43
- yield :calls, name, :line_no => loc.line, :col => loc.column
41
+ yield :calls, name, line_no: loc.line, col: loc.column
44
42
 
45
- if name.last.to_s =~ /\w+=$/
43
+ if name.last =~ /\w+=$/
46
44
  name[-1] = name.last.to_s.chop.to_sym
47
- yield :assigns, name, :line_no => loc.line, :col => loc.column
45
+ yield :assigns, name, line_no: loc.line, col: loc.column
48
46
  elsif node.children[0].nil? && node.children[1] == :require && node.children[2].type == :str
49
47
  yield :requires, node.children[2].children[0].split('/'),
50
- :line_no => loc.line, :col => loc.column
48
+ line_no: loc.line, col: loc.column
51
49
  end
52
50
 
53
51
  when :def
54
52
  yield :defs, scope + [node.children[0]],
55
- :line_no => loc.line, :type => :func, :col => loc.name.column
56
- yield :end, :end, :line_no => loc.end.line, :type => :func, :col => loc.end.column
53
+ line_no: loc.line, type: :func, col: loc.name.column
54
+ yield :end, :end, line_no: loc.end.line, type: :func, col: loc.end.column
57
55
 
58
56
  when :defs
59
57
  yield :defs, scope + [node.children[1]],
60
- :line_no => loc.line, :type => :func, :col => loc.name.column
61
- yield :end, :end, :line_no => loc.end.line, :type => :func, :col => loc.end.column
58
+ line_no: loc.line, type: :func, col: loc.name.column
59
+ yield :end, :end, line_no: loc.end.line, type: :func, col: loc.end.column
62
60
 
63
61
  when :module, :class
64
62
  yield :defs, scope + scoped_name(node.children[0], scope),
65
- :line_no => loc.line, :type => node.type, :col => loc.name.column
66
- yield :end, :end, :line_no => loc.end.line, :type => node.type, :col => loc.end.column
63
+ line_no: loc.line, type: node.type, col: loc.name.column
64
+ yield :end, :end, line_no: loc.end.line, type: node.type, col: loc.end.column
67
65
 
68
66
  when :casgn
69
67
  name = scoped_name(node, scope)
70
- yield :assigns, name, :line_no => loc.line, :col => loc.name.column
71
- yield :defs, name, :line_no => loc.line, :col => loc.name.column
68
+ yield :assigns, name, line_no: loc.line, col: loc.name.column
69
+ yield :defs, name, line_no: loc.line, col: loc.name.column
72
70
 
73
71
  when :lvasgn, :ivasgn, :cvasgn, :gvasgn
74
- yield :assigns, scope + [node.children[0]], :line_no => loc.line, :col => loc.name.column
72
+ yield :assigns, scope + [node.children[0]], line_no: loc.line, col: loc.name.column
75
73
 
76
74
  when :const
77
75
  name = scoped_name(node, scope)
78
- yield :reads, name, :line_no => loc.line, :col => loc.name.column
76
+ yield :reads, name, line_no: loc.line, col: loc.name.column
79
77
 
80
78
  when :lvar, :ivar, :cvar, :gvar
81
- yield :reads, scope + [node.children[0]], :line_no => loc.line, :col => loc.name.column
79
+ yield :reads, scope + [node.children[0]], line_no: loc.line, col: loc.name.column
82
80
 
83
81
  when :sym
84
82
  # handle `:foo` vs `foo: 1`
@@ -87,7 +85,7 @@ module Starscope::Lang
87
85
  else
88
86
  loc.expression.column
89
87
  end
90
- yield :sym, [node.children[0]], :line_no => loc.line, :col => col
88
+ yield :sym, [node.children[0]], line_no: loc.line, col: col
91
89
  end
92
90
  end
93
91
 
@@ -11,9 +11,9 @@ class Starscope::Output
11
11
 
12
12
  def new_pbar(title, num_items)
13
13
  return if @level == :quiet
14
- @pbar = ProgressBar.create(:title => title, :total => num_items,
15
- :format => PBAR_FORMAT, :length => 80,
16
- :out => @out)
14
+ @pbar = ProgressBar.create(title: title, total: num_items,
15
+ format: PBAR_FORMAT, length: 80,
16
+ out: @out)
17
17
  end
18
18
 
19
19
  def inc_pbar
@@ -1,3 +1,3 @@
1
1
  module Starscope
2
- VERSION = '1.4.1'
2
+ VERSION = '1.5.0'
3
3
  end
@@ -5,7 +5,7 @@ Gem::Specification.new do |gem|
5
5
  gem.version = Starscope::VERSION
6
6
  gem.summary = 'Smart code search and indexing'
7
7
  gem.description = <<-EOF
8
- Starscope is a code indexer, search and navigation tool for Ruby and Go.
8
+ Starscope is a code indexer, search and navigation tool for Ruby, Golang, and JavaScript.
9
9
  Inspired by the extremely popular Ctags and Cscope utilities, Starscope can
10
10
  answer a lot of questions about a lot of code.
11
11
  EOF
@@ -17,15 +17,18 @@ Gem::Specification.new do |gem|
17
17
  gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
18
18
  gem.test_files = `git ls-files -- test/*`.split("\n")
19
19
  gem.require_paths = ['lib']
20
- gem.required_ruby_version = '>= 1.8.7'
20
+ gem.required_ruby_version = '>= 1.9.3'
21
21
 
22
22
  gem.add_dependency 'oj', '~> 2.9'
23
23
  gem.add_dependency 'parser', '~> 2.2.2'
24
24
  gem.add_dependency 'ruby-progressbar', '~> 1.5'
25
- gem.add_dependency 'backports', '~> 3.6'
26
- gem.add_development_dependency 'bundler', '~> 1.5'
27
- gem.add_development_dependency 'rake'
28
- gem.add_development_dependency 'pry'
29
- gem.add_development_dependency 'minitest'
30
- gem.add_development_dependency 'mocha'
25
+ gem.add_dependency 'rkelly-remix', '~> 0.0.7'
26
+ gem.add_dependency 'babel-transpiler', '~> 0.7'
27
+ gem.add_dependency 'sourcemap', '~> 0.1'
28
+
29
+ gem.add_development_dependency 'bundler', '~> 1.7'
30
+ gem.add_development_dependency 'rake', '~> 10.4'
31
+ gem.add_development_dependency 'pry', '~> 0.10.1'
32
+ gem.add_development_dependency 'minitest', '~> 5.8'
33
+ gem.add_development_dependency 'mocha', '~> 1.1'
31
34
  end
@@ -0,0 +1,117 @@
1
+ /* @flow */
2
+
3
+ import React from 'react-native';
4
+
5
+ var {
6
+ Component,
7
+ StyleSheet,
8
+ } = React;
9
+
10
+ var {NavigationBar} = Navigator;
11
+
12
+ var styles = StyleSheet.create({
13
+ navigatorBar: {
14
+ height: NavigationBar.Styles.General.NavBarHeight,
15
+ justifyContent: 'center',
16
+ alignItems: 'center',
17
+ },
18
+ });
19
+
20
+ var func1 = () => {
21
+ return 1;
22
+ };
23
+
24
+ function foo() {
25
+ return bar;
26
+ }
27
+
28
+ StatusBarIOS.setStyle(1);
29
+ Router.routes = routes;
30
+
31
+ class MyStat {
32
+ static myStatFunc(
33
+ title
34
+ ): void {
35
+ }
36
+ }
37
+
38
+ var NavigatorRouteMapper = {
39
+ LeftButton({route}, navigator, index) {
40
+ if (!index) { return null; } // Nothing below in stack.
41
+
42
+ return (
43
+ <TouchableOpacity onPress={() => navigator.pop()}>
44
+ <Text style={{color: 'white', fontSize: 12, marginLeft: 1}}>‹</Text>
45
+ </TouchableOpacity>
46
+ );
47
+ },
48
+
49
+ RightButton() {
50
+ return null;
51
+ },
52
+ };
53
+
54
+ class Navigation extends Component {
55
+ constructor(props) {
56
+ super(props);
57
+ this.state = {key: 'foo', selectedTab: 'foo'};
58
+ func1();
59
+
60
+ }
61
+
62
+ _tabItem(routeName: string, params: Object, badgeCount?: number) : PropTypes.element {
63
+ var route = routes[routeName];
64
+
65
+ var onTabPress = () => {
66
+ if (this.state.selectedTab === routeName) {
67
+ if (route === Router.currentRoute) {
68
+ Router.navigator._currentQueryFetcherRoot.fetchData();
69
+ } else {
70
+ Router.popToTop();
71
+ }
72
+ } else {
73
+ this.setState({selectedTab: routeName});
74
+ }
75
+ };
76
+
77
+ return (
78
+ <TabBarIOS.Item
79
+ badge={badgeCount}
80
+ selected={this.state.selectedTab === routeName}
81
+ onPress={onTabPress}
82
+ >
83
+ <Navigator
84
+ ref={::this._setCurrentNavigator}
85
+ navigationBar={
86
+ <NavigationBar routeMapper={NavigatorRouteMapper} style={{backgroundColor: Branding.pink}} />
87
+ }
88
+ />
89
+
90
+ </TabBarIOS.Item>
91
+ );
92
+ }
93
+
94
+ _setCurrentNavigator(nav) {
95
+ Router.navigator = nav;
96
+ }
97
+
98
+ _renderTabScene({route, params}, nav) {
99
+ var setRef = (ref) => {
100
+ nav._currentQueryFetcherRoot = ref;
101
+ };
102
+
103
+ return <QueryFetcherRoot ref={setRef} component={route.component} route={route} params={params} />;
104
+ }
105
+
106
+ render() {
107
+ return (
108
+ <TabBarIOS tintColor={Branding.yellow} barTintColor={Branding.green}>
109
+ {this._tabItem('foo', {})}
110
+ {this._tabItem('bar', {})}
111
+ {this._tabItem('baz', {})}
112
+ </TabBarIOS>
113
+ );
114
+ }
115
+ }
116
+
117
+ export default Navigation;
@@ -26,7 +26,7 @@ class Starscope::DB
26
26
  if format == DB_FORMAT
27
27
  @paths = Oj.load(stream.gets)
28
28
  @files = Oj.load(stream.gets)
29
- @tables = Oj.load(stream.gets, :symbol_keys => true)
29
+ @tables = Oj.load(stream.gets, symbol_keys: true)
30
30
  elsif format <= 2
31
31
  # Old format (pre-json), so read the directories segment then rebuild
32
32
  len = stream.gets.to_i
@@ -59,7 +59,7 @@ class Starscope::DB
59
59
  files = paths.map { |p| self.class.files_from_path(p) }.flatten
60
60
  return if files.empty?
61
61
  if @progress
62
- pbar = ProgressBar.create(:title => 'Building', :total => files.length, :format => PBAR_FORMAT, :length => 80)
62
+ pbar = ProgressBar.create(title: 'Building', total: files.length, format: PBAR_FORMAT, length: 80)
63
63
  end
64
64
  files.each do |f|
65
65
  add_file(f)
@@ -70,7 +70,7 @@ class Starscope::DB
70
70
  def update
71
71
  new_files = (@paths.map { |p| self.class.files_from_path(p) }.flatten) - @files.keys
72
72
  if @progress
73
- pbar = ProgressBar.create(:title => 'Updating', :total => new_files.length + @files.length, :format => PBAR_FORMAT, :length => 80)
73
+ pbar = ProgressBar.create(title: 'Updating', total: new_files.length + @files.length, format: PBAR_FORMAT, length: 80)
74
74
  end
75
75
  changed = @files.keys.map do |f|
76
76
  changed = update_file(f)
@@ -114,7 +114,7 @@ class Starscope::DB
114
114
  if entry[:line_no]
115
115
  tmpdb[entry[:file]] ||= {}
116
116
  tmpdb[entry[:file]][entry[:line_no]] ||= []
117
- tmpdb[entry[:file]][entry[:line_no]] << { :tbl => tbl, :key => key, :entry => entry }
117
+ tmpdb[entry[:file]][entry[:line_no]] << { tbl: tbl, key: key, entry: entry }
118
118
  end
119
119
  end
120
120
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path('../../test_helper', __FILE__)
1
+ require_relative '../test_helper'
2
2
 
3
3
  describe 'starscope executable script' do
4
4
  BASE = 'bundle exec bin/starscope --quiet'
@@ -1,11 +1,12 @@
1
1
  require 'minitest/autorun'
2
2
  require 'minitest/pride'
3
3
  require 'mocha/mini_test'
4
- require File.expand_path('../../lib/starscope.rb', __FILE__)
4
+ require_relative '../lib/starscope'
5
5
 
6
6
  FIXTURES = 'test/fixtures'
7
7
 
8
8
  GOLANG_SAMPLE = "#{FIXTURES}/sample_golang.go"
9
+ JAVASCRIPT_EXAMPLE = "#{FIXTURES}/sample_javascript.js"
9
10
  RUBY_SAMPLE = "#{FIXTURES}/sample_ruby.rb"
10
11
  ERB_SAMPLE = "#{FIXTURES}/sample_erb.erb"
11
12
  EMPTY_FILE = "#{FIXTURES}/empty"
@@ -1,4 +1,4 @@
1
- require File.expand_path('../../test_helper', __FILE__)
1
+ require_relative '../test_helper'
2
2
  require 'tempfile'
3
3
 
4
4
  describe Starscope::DB do
@@ -144,7 +144,7 @@ describe Starscope::DB do
144
144
  it 'must run queries on multiple tables' do
145
145
  @db.add_paths([FIXTURES])
146
146
  ret = @db.query([:calls, :defs], 'foo')
147
- ret.length.must_equal 3
147
+ ret.length.must_equal 4
148
148
  ret.first[:name].last.must_equal :foo
149
149
  end
150
150
 
@@ -161,7 +161,7 @@ describe Starscope::DB do
161
161
  it 'must store extractor metadata returned from the `extract` call' do
162
162
  extractor = mock('extractor')
163
163
  extractor.expects(:match_file).with(GOLANG_SAMPLE).returns(true)
164
- extractor.expects(:extract).with(GOLANG_SAMPLE, File.read(GOLANG_SAMPLE)).returns(:a => 1)
164
+ extractor.expects(:extract).with(GOLANG_SAMPLE, File.read(GOLANG_SAMPLE)).returns(a: 1)
165
165
  extractor.expects(:name).returns('Foo')
166
166
  EXTRACTORS.stubs(:each).yields(extractor)
167
167
 
@@ -1,4 +1,4 @@
1
- require File.expand_path('../../test_helper', __FILE__)
1
+ require_relative '../test_helper'
2
2
 
3
3
  describe Starscope::Exportable do
4
4
  before do
@@ -10,14 +10,14 @@ describe Starscope::Exportable do
10
10
  it 'must export to ctags' do
11
11
  @db.export_to(:ctags, @buf)
12
12
  @buf.rewind
13
- lines = @buf.lines.to_a
13
+ lines = @buf.each_line.to_a
14
14
  lines.must_include "NoTableError\t#{FIXTURES}/sample_ruby.rb\t/^ class NoTableError < StandardError; end$/;\"\tkind:c\tlanguage:Ruby\n"
15
15
  end
16
16
 
17
17
  it 'must export to cscope' do
18
18
  @db.export_to(:cscope, @buf)
19
19
  @buf.rewind
20
- lines = @buf.lines.to_a
20
+ lines = @buf.each_line.to_a
21
21
 
22
22
  lines.must_include "\t@#{FIXTURES}/sample_golang.go\n"
23
23
  lines.must_include "\tgSunday\n"