parser 2.7.1.5 → 2.7.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/lib/parser/current.rb +1 -1
  3. data/lib/parser/meta.rb +2 -2
  4. data/lib/parser/ruby28.rb +8047 -0
  5. data/lib/parser/version.rb +1 -1
  6. data/parser.gemspec +1 -20
  7. metadata +7 -96
  8. data/.travis.yml +0 -41
  9. data/.yardopts +0 -21
  10. data/CHANGELOG.md +0 -1137
  11. data/CONTRIBUTING.md +0 -17
  12. data/Gemfile +0 -10
  13. data/LICENSE.txt +0 -25
  14. data/README.md +0 -309
  15. data/Rakefile +0 -167
  16. data/ci/run_rubocop_specs +0 -14
  17. data/doc/AST_FORMAT.md +0 -2284
  18. data/doc/CUSTOMIZATION.md +0 -37
  19. data/doc/INTERNALS.md +0 -21
  20. data/doc/css/.gitkeep +0 -0
  21. data/doc/css/common.css +0 -68
  22. data/lib/parser/lexer.rl +0 -2550
  23. data/lib/parser/macruby.y +0 -2208
  24. data/lib/parser/ruby18.y +0 -1936
  25. data/lib/parser/ruby19.y +0 -2185
  26. data/lib/parser/ruby20.y +0 -2363
  27. data/lib/parser/ruby21.y +0 -2364
  28. data/lib/parser/ruby22.y +0 -2371
  29. data/lib/parser/ruby23.y +0 -2377
  30. data/lib/parser/ruby24.y +0 -2415
  31. data/lib/parser/ruby25.y +0 -2412
  32. data/lib/parser/ruby26.y +0 -2420
  33. data/lib/parser/ruby27.y +0 -2949
  34. data/lib/parser/ruby30.y +0 -3048
  35. data/lib/parser/rubymotion.y +0 -2192
  36. data/test/bug_163/fixtures/input.rb +0 -5
  37. data/test/bug_163/fixtures/output.rb +0 -5
  38. data/test/bug_163/rewriter.rb +0 -20
  39. data/test/helper.rb +0 -103
  40. data/test/parse_helper.rb +0 -328
  41. data/test/racc_coverage_helper.rb +0 -133
  42. data/test/test_ast_processor.rb +0 -32
  43. data/test/test_base.rb +0 -31
  44. data/test/test_current.rb +0 -31
  45. data/test/test_diagnostic.rb +0 -95
  46. data/test/test_diagnostic_engine.rb +0 -59
  47. data/test/test_encoding.rb +0 -99
  48. data/test/test_lexer.rb +0 -3617
  49. data/test/test_lexer_stack_state.rb +0 -78
  50. data/test/test_meta.rb +0 -12
  51. data/test/test_parse_helper.rb +0 -83
  52. data/test/test_parser.rb +0 -9986
  53. data/test/test_runner_parse.rb +0 -56
  54. data/test/test_runner_rewrite.rb +0 -47
  55. data/test/test_source_buffer.rb +0 -165
  56. data/test/test_source_comment.rb +0 -36
  57. data/test/test_source_comment_associator.rb +0 -399
  58. data/test/test_source_map.rb +0 -14
  59. data/test/test_source_range.rb +0 -192
  60. data/test/test_source_rewriter.rb +0 -541
  61. data/test/test_source_rewriter_action.rb +0 -46
  62. data/test/test_source_tree_rewriter.rb +0 -361
  63. data/test/test_static_environment.rb +0 -45
  64. data/test/using_tree_rewriter/fixtures/input.rb +0 -3
  65. data/test/using_tree_rewriter/fixtures/output.rb +0 -3
  66. data/test/using_tree_rewriter/using_tree_rewriter.rb +0 -9
@@ -1,133 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'racc/grammarfileparser'
4
-
5
- # Unfortunately, Ruby's Coverage module ignores module_eval statements,
6
- # which Racc uses to map `parser.y` locations in the generated
7
- # `parser.rb`.
8
- module RaccCoverage
9
- @coverage = {}
10
- @base_path = nil
11
- @trace = nil
12
-
13
- def self.start(parsers, base_path)
14
- @base_path = base_path
15
-
16
- parsers.each do |parser|
17
- @coverage[parser] = extract_interesting_lines(parser, base_path)
18
- end
19
-
20
- @trace = TracePoint.new(:line) do |trace|
21
- lineno = trace.lineno - 1
22
-
23
- if (line_coverage = @coverage[trace.path])
24
- if line_coverage[lineno]
25
- line_coverage[lineno] += 1
26
- end
27
- end
28
- end
29
- @trace.enable
30
- end
31
-
32
- def self.stop
33
- @trace.disable
34
- end
35
-
36
- # Ruby's TracePoint#lineno will point only on "interesting" lines,
37
- # i.e.: only code (no comments or empty lines), no `end` keywords,
38
- # and for multi-line statements, only the first line of the statement.
39
- #
40
- # This method implements a very dumb Ruby parser, which skips empty lines
41
- # or lines with just comments, `end` keywords, and correctly handles
42
- # multi-line statements of the following form:
43
- #
44
- # * All lines of the statement except the last must end with `,`, `.` or `(`.
45
- #
46
- # Coverage can be disabled for code regions with annotations :nocov: and :cov:.
47
- #
48
- # Also, for best results, all actions should be delimited by at least
49
- # one non-action line.
50
- #
51
- def self.extract_interesting_lines(parser, base_path)
52
- grammar_source = File.join(@base_path, parser)
53
- grammar_file = Racc::GrammarFileParser.parse_file(grammar_source)
54
-
55
- ruby_sources = [
56
- # Header and footer aren't passed through module_eval
57
- # in Racc-generated file, so the location info is lost.
58
- *grammar_file.params.inner,
59
- ].compact
60
-
61
- grammar_file.grammar.each_rule do |rule|
62
- source = rule.action.source
63
- next if source.nil?
64
-
65
- ruby_sources << source
66
- end
67
-
68
- lines = []
69
-
70
- ruby_sources.each do |source|
71
- first_line = source.lineno
72
-
73
- state = :first_line
74
-
75
- source.text.each_line.with_index do |line, index|
76
- line = line.strip
77
-
78
- continues = line.end_with?(',') ||
79
- line.end_with?('(') ||
80
- line.end_with?('.')
81
-
82
- case state
83
- when :first_line
84
- if line =~ /:nocov/
85
- state = :nocov
86
- next
87
- elsif line.empty? ||
88
- line == 'end' ||
89
- line.start_with?('#')
90
- next
91
- elsif continues
92
- state = :mid_line
93
- end
94
-
95
- lines[first_line + index - 1] = 0
96
-
97
- when :mid_line
98
- unless continues
99
- state = :first_line
100
- end
101
-
102
- when :nocov
103
- if line =~ /:cov:/
104
- state = :first_line
105
- end
106
- end
107
- end
108
- end
109
-
110
- lines
111
- end
112
-
113
- def self.result
114
- result =
115
- @coverage.map do |parser, coverage|
116
- [File.join(@base_path, parser), coverage]
117
- end
118
-
119
- Hash[result]
120
- end
121
- end
122
-
123
- class << SimpleCov
124
- def result_with_racc_coverage
125
- @result ||= SimpleCov::Result.new(
126
- Coverage.result.merge(RaccCoverage.result))
127
-
128
- result_without_racc_coverage
129
- end
130
-
131
- alias result_without_racc_coverage result
132
- alias result result_with_racc_coverage
133
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'helper'
4
-
5
- class TestASTProcessor < Minitest::Test
6
- LEAF_NODES = %i[
7
- sym str int float complex rational
8
- true false nil self
9
- __FILE__ __LINE__ __ENCODING__
10
- cbase regopt zsuper
11
- match_with_trailing_comma match_nil_pattern
12
- forward_args forwarded_args numargs kwnilarg
13
- objc_varargs objc_restarg objc_kwarg
14
- ident
15
- ].freeze
16
-
17
- def setup
18
- @traversible = Parser::AST::Processor
19
- .instance_methods(false)
20
- .map { |mid| mid.to_s.scan(/\Aon_(.*)/) }
21
- .flatten
22
- .map(&:to_sym)
23
-
24
- @traversible += LEAF_NODES
25
- end
26
-
27
- def test_nodes_are_traversible
28
- for_each_node do |node|
29
- assert_includes @traversible, node.type
30
- end
31
- end
32
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'helper'
4
- require 'parser/current'
5
-
6
- class TestBase < Minitest::Test
7
- include AST::Sexp
8
-
9
- def test_parse
10
- ast = Parser::CurrentRuby.parse('1')
11
- assert_equal s(:int, 1), ast
12
- end
13
-
14
- def test_parse_with_comments
15
- ast, comments = Parser::CurrentRuby.parse_with_comments('1 # foo')
16
- assert_equal s(:int, 1), ast
17
- assert_equal 1, comments.size
18
- assert_equal '# foo', comments.first.text
19
- end
20
-
21
- def test_loc_to_node
22
- ast = Parser::CurrentRuby.parse('1')
23
- assert_equal ast.loc.node, ast
24
- end
25
-
26
- def test_loc_dup
27
- ast = Parser::CurrentRuby.parse('1')
28
- assert_nil ast.loc.dup.node
29
- Parser::AST::Node.new(:zsuper, [], :location => ast.loc)
30
- end
31
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'helper'
4
- require 'parser/current'
5
-
6
- class TestCurrent < Minitest::Test
7
- def test_current
8
- case RUBY_VERSION
9
- when '2.0.0'
10
- assert_equal Parser::Ruby20, Parser::CurrentRuby
11
- when /^2\.1\.\d+/
12
- assert_equal Parser::Ruby21, Parser::CurrentRuby
13
- when /^2\.2\.\d+/
14
- assert_equal Parser::Ruby22, Parser::CurrentRuby
15
- when /^2\.3\.\d+/
16
- assert_equal Parser::Ruby23, Parser::CurrentRuby
17
- when /^2\.4\.\d+/
18
- assert_equal Parser::Ruby24, Parser::CurrentRuby
19
- when /^2\.5\.\d+/
20
- assert_equal Parser::Ruby25, Parser::CurrentRuby
21
- when /^2\.6\.\d+/
22
- assert_equal Parser::Ruby26, Parser::CurrentRuby
23
- when /^2\.7\.\d+/
24
- assert_equal Parser::Ruby27, Parser::CurrentRuby
25
- when /^3\.0\.\d+/
26
- assert_equal Parser::Ruby30, Parser::CurrentRuby
27
- else
28
- flunk "Update test_current for #{RUBY_VERSION}"
29
- end
30
- end
31
- end
@@ -1,95 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'helper'
4
-
5
- class TestDiagnostic < Minitest::Test
6
- def setup
7
- @buffer = Parser::Source::Buffer.new('(string)',
8
- source: 'if (this is some bad code + bugs)')
9
-
10
- @range1 = Parser::Source::Range.new(@buffer, 0, 2) # if
11
- @range2 = Parser::Source::Range.new(@buffer, 4, 8) # this
12
- end
13
-
14
- def test_verifies_levels
15
- error = assert_raises ArgumentError do
16
- Parser::Diagnostic.new(:foobar, :escape_eof, {}, @range1)
17
- end
18
-
19
- assert_match(/level/, error.message)
20
- end
21
-
22
- def test_freezes
23
- string = 'foo'.dup
24
- highlights = [@range2]
25
-
26
- diag = Parser::Diagnostic.new(:error, :escape_eof, @range1, highlights)
27
- assert diag.frozen?
28
- assert diag.arguments.frozen?
29
- assert diag.highlights.frozen?
30
-
31
- refute string.frozen?
32
- refute highlights.frozen?
33
- end
34
-
35
- def test_render
36
- location = Parser::Source::Range.new(@buffer, 26, 27)
37
-
38
- highlights = [
39
- Parser::Source::Range.new(@buffer, 21, 25),
40
- Parser::Source::Range.new(@buffer, 28, 32)
41
- ]
42
-
43
- diag = Parser::Diagnostic.new(:error, :unexpected, { :character => '+' },
44
- location, highlights)
45
- assert_equal([
46
- "(string):1:27: error: unexpected `+'",
47
- '(string):1: if (this is some bad code + bugs)',
48
- '(string):1: ~~~~ ^ ~~~~ '
49
- ], diag.render)
50
- end
51
-
52
- def test_multiline_render
53
- @buffer = Parser::Source::Buffer.new('(string)',
54
- source: "abc abc abc\ndef def def\nghi ghi ghi\n")
55
-
56
- location = Parser::Source::Range.new(@buffer, 4, 27)
57
-
58
- highlights = [
59
- Parser::Source::Range.new(@buffer, 0, 3),
60
- Parser::Source::Range.new(@buffer, 28, 31)
61
- ]
62
-
63
- diag = Parser::Diagnostic.new(:error, :unexpected_token, { :token => 'ghi' },
64
- location, highlights)
65
-
66
- assert_equal([
67
- "(string):1:5-3:3: error: unexpected token ghi",
68
- '(string):1: abc abc abc',
69
- '(string):1: ~~~ ^~~~~~~...',
70
- '(string):3: ghi ghi ghi',
71
- '(string):3: ~~~ ~~~ '
72
- ], diag.render)
73
- end
74
-
75
- def test_bug_error_on_newline
76
- # regression test; see GitHub issue 273
77
- source = <<-CODE
78
- {
79
- foo: ->() # I forgot my brace
80
- }
81
- }
82
- CODE
83
- @buffer = Parser::Source::Buffer.new('(string)', source: source)
84
-
85
- location = Parser::Source::Range.new(@buffer, 33, 34)
86
- diag = Parser::Diagnostic.new(:error, :unexpected_token, { :token => 'tNL' },
87
- location)
88
-
89
- assert_equal([
90
- '(string):2:32: error: unexpected token tNL',
91
- '(string):2: foo: ->() # I forgot my brace',
92
- '(string):2: ^'
93
- ], diag.render)
94
- end
95
- end
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'helper'
4
-
5
- class TestDiagnosticEngine < Minitest::Test
6
- def setup
7
- @engine = Parser::Diagnostic::Engine.new
8
-
9
- @queue = []
10
- @engine.consumer = lambda { |diag| @queue << diag }
11
- end
12
-
13
- def test_process_warnings
14
- warn = Parser::Diagnostic.new(:warning, :invalid_escape, {}, 1..2)
15
- @engine.process(warn)
16
-
17
- assert_equal [warn], @queue
18
- end
19
-
20
- def test_ignore_warnings
21
- @engine.ignore_warnings = true
22
-
23
- warn = Parser::Diagnostic.new(:warning, :invalid_escape, {}, 1..2)
24
- @engine.process(warn)
25
-
26
- assert_equal [], @queue
27
- end
28
-
29
- def test_all_errors_are_fatal
30
- @engine.all_errors_are_fatal = true
31
-
32
- error = Parser::Diagnostic.new(:error, :invalid_escape, {}, 1..2)
33
-
34
- err = assert_raises Parser::SyntaxError do
35
- @engine.process(error)
36
- end
37
-
38
- assert_equal error, err.diagnostic
39
-
40
- assert_equal [error], @queue
41
- end
42
-
43
- def test_all_errors_are_collected
44
- error = Parser::Diagnostic.new(:error, :invalid_escape, {}, 1..2)
45
- @engine.process(error)
46
-
47
- assert_equal [error], @queue
48
- end
49
-
50
- def test_fatal_error
51
- fatal = Parser::Diagnostic.new(:fatal, :invalid_escape, {}, 1..2)
52
-
53
- assert_raises Parser::SyntaxError do
54
- @engine.process(fatal)
55
- end
56
-
57
- assert_equal [fatal], @queue
58
- end
59
- end
@@ -1,99 +0,0 @@
1
- # encoding: binary
2
- # frozen_string_literal: true
3
-
4
- require 'helper'
5
-
6
- class TestEncoding < Minitest::Test
7
- include AST::Sexp
8
-
9
- def recognize(string)
10
- Parser::Source::Buffer.recognize_encoding(string)
11
- end
12
-
13
- require 'parser/all'
14
-
15
- def test_default
16
- assert_nil recognize('foobar')
17
- end
18
-
19
- def test_bom
20
- assert_equal Encoding::UTF_8, recognize("\xef\xbb\xbf\nfoobar")
21
- assert_equal Encoding::UTF_8, recognize("\xef\xbb\xbf# coding:koi8-r\nfoobar")
22
- end
23
-
24
- def test_magic_comment
25
- assert_equal Encoding::KOI8_R, recognize("# coding:koi8-r\nfoobar")
26
- end
27
-
28
- def test_shebang
29
- assert_equal Encoding::KOI8_R, recognize("#!/bin/foo\n# coding:koi8-r\nfoobar")
30
- assert_nil recognize("#!/bin/foo\n")
31
- end
32
-
33
- def test_case
34
- assert_equal Encoding::KOI8_R, recognize("# coding:KoI8-r\nfoobar")
35
- end
36
-
37
- def test_space
38
- assert_equal Encoding::KOI8_R, recognize("# coding : koi8-r\nfoobar")
39
- end
40
-
41
- def test_empty
42
- assert_nil recognize('')
43
- end
44
-
45
- def test_no_comment
46
- assert_nil recognize(%{require 'cane/encoding_aware_iterator'})
47
- end
48
-
49
- def test_adjacent
50
- assert_nil recognize('# codingkoi8-r')
51
- assert_nil recognize('# coding koi8-r')
52
- end
53
-
54
- def test_utf8_mac
55
- assert_equal Encoding::UTF8_MAC, recognize('# coding: utf8-mac')
56
- end
57
-
58
- def test_suffix
59
- assert_equal Encoding::UTF_8, recognize('# coding: utf-8-dos')
60
- assert_equal Encoding::UTF_8, recognize('# coding: utf-8-unix')
61
- assert_equal Encoding::UTF_8, recognize('# coding: utf-8-mac')
62
-
63
- assert_raises(ArgumentError) do
64
- assert_nil recognize('# coding: utf-8-dicks')
65
- end
66
- end
67
-
68
- def test_parse_18_invalid_enc
69
- ast = Parser::Ruby18.parse("# encoding:feynman-diagram\n1")
70
- assert_equal ast, s(:int, 1)
71
- end
72
-
73
- def test_parse_19_invalid_enc
74
- assert_raises(ArgumentError) do
75
- Parser::Ruby19.parse("# encoding:feynman-diagram\n1")
76
- end
77
- end
78
-
79
- def test_ending_comment
80
- assert_nil recognize('foo # coding: koi8-r')
81
- end
82
-
83
- def test_wrong_prefix
84
- assert_nil recognize('# decoding: koi8-r')
85
- end
86
-
87
- def test_no_spaces
88
- assert_equal Encoding::KOI8_R, recognize('#encoding:koi8-r')
89
- assert_equal Encoding::KOI8_R, recognize('#coding:koi8-r')
90
- end
91
-
92
- def test_underscore_and_star_characters
93
- assert_equal Encoding::KOI8_R, recognize('# -*- encoding: koi8-r -*-')
94
- end
95
-
96
- def test_garbage_around_encoding_comment
97
- assert_equal Encoding::KOI8_R, recognize('# 1$# -*- &)* encoding: koi8-r 1$# -*- &)*')
98
- end
99
- end