kanayago 0.4.0 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c6e26071a97395c4f35c029908d78bba8a927f75129aa361367dc9cf549c3ca
4
- data.tar.gz: be48eae66a3bc69256ff3a9dba5afa842b8b8876f7be66eb72d79774fb94d878
3
+ metadata.gz: f2ec99120dc51fa4605b265aa47d5474d7f9a3540e3d09e10f782eebebcced6f
4
+ data.tar.gz: 0c836dc8b6390755edbbe0a42fe5fc936bb788961c313c75e0c7c559cd61afc2
5
5
  SHA512:
6
- metadata.gz: 5073effb4706b23b912a61f79a3bb40d2565e59f4d9805c6ba6f3006c613d8029340d2e164e67f94eb0341cc7b14d340ca5a9f862ee8c4fb84a2b8a86f1622b9
7
- data.tar.gz: 5731b6e8463b384cbd3dfe7bd3bf67835ea0a4a8f51ac0ee84259f8fd04d414fd5b2e1ea38e79f6f3dfab83787207c86757dfa5bce0180bfbf6fbac1102665ef
6
+ metadata.gz: cd996926d976b0dc9e48f6ee8478d65dd0c02a48dfc81e1754a087a92e10c79f6ec174c34da2eade27c563c04b4c70a638e2ed501c0002c4d5b2e8988d8c1e48
7
+ data.tar.gz: f8bc6647c4daed8b6ed823c7f6e2dcb65646a735f9a9a5c6818e1a514463eb38c1bcf014d106621bbd81bf6de4f71e1b5385639dd4eeb64e727281d0d5ad1a68
data/CHANGELOG.md CHANGED
@@ -7,6 +7,63 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0]
11
+
12
+ ### Added
13
+ - Add LSP (Language Server Protocol) mode
14
+ - `kanayago --lsp` - Start LSP server for editor integration
15
+ - Provides real-time syntax error diagnostics via LSP protocol
16
+ - Supports `textDocument/didOpen`, `didChange`, `didClose` notifications
17
+ - Publishes diagnostics with `textDocument/publishDiagnostics`
18
+ - Compatible with LSP-compliant editors (VSCode, etc.)
19
+ - Add `language_server-protocol` gem dependency (~> 3.17.0)
20
+ - Add CLI mode for syntax checking
21
+ - `kanayago check 'code'` - Check Ruby code syntax directly
22
+ - `kanayago check --file FILE` or `-f FILE` - Check syntax of Ruby file
23
+ - Output "Syntax valid" for valid syntax, "Syntax invalid" for invalid syntax
24
+ - Exit with code 0 for valid syntax, 1 for invalid syntax or errors
25
+ - Add `ParseResult` class to wrap AST and error information
26
+ - `ParseResult#ast` - Returns the parsed AST (ScopeNode)
27
+ - `ParseResult#error` - Returns SyntaxError object if syntax error occurred, false otherwise
28
+ - `ParseResult#valid?` - Returns true if no syntax error occurred
29
+ - `ParseResult#invalid?` - Returns true if syntax error occurred
30
+ - `Kanayago.parse` now returns `ParseResult` instead of raw AST
31
+
32
+ ### Fixed
33
+ - Fix parser crash on syntax errors by implementing `rb_syntax_error_append`
34
+ - Previously, `rb_syntax_error_append` was not available in UniversalParser, causing forced termination when syntax errors occurred during parsing
35
+ - Ported `err_vcatf`, `syntax_error_with_path`, and `rb_syntax_error_append` from Ruby's error.c
36
+ - Added proper copyright notice (Copyright (C) 1993-2007 Yukihiro Matsumoto) as the code is ported from Ruby's error.c
37
+ - Updated patch files for both Ruby 3.4 and head versions
38
+ - Syntax errors now display properly instead of crashing the parser
39
+ - Implement error_tolerant mode to continue parsing despite syntax errors
40
+ - Enable `rb_ruby_parser_error_tolerant` flag for all parsing operations
41
+ - Parser now accumulates syntax errors in `error_buffer` instead of terminating
42
+ - Fixed Qfalse handling in `rb_syntax_error_append` (Qfalse is defined as 0, causing `!exc` to evaluate to true)
43
+ - Added OBJ_FROZEN checks to handle frozen default "compile error" messages in SyntaxError objects
44
+ - Both AST and error information are now available even when syntax errors occur
45
+
46
+ ### Changed
47
+ - Migrate error_buffer accessor implementation from script to patch files
48
+ - Moved `rb_ruby_parser_error_buffer_get` accessor function from `script/setup_parser.rb` to patch files
49
+ - Added parse.c modifications to both `patch/3.4/kanayago.patch` and `patch/head/kanayago.patch`
50
+ - Improved maintainability and version compatibility by using patch-based approach instead of runtime script modifications
51
+ - Removed `add_error_buffer_accessor` function from `script/setup_parser.rb`
52
+ - Update all test files to access AST through `ParseResult#ast`
53
+ - All 93 test files now use `result.ast` instead of direct result access
54
+ - Tests validate both successful parsing and error handling scenarios
55
+
56
+ ## [0.4.1]
57
+
58
+ ### Fixed
59
+ - Fix segmentation fault when parsing dynamic symbols in complex hash structures
60
+ - Fix segmentation fault when parsing nested modules with outer constant references
61
+ - Fix `module_node_new` to use `RNODE_MODULE` instead of incorrect `RNODE_CLASS` macro
62
+ - Add NULL pointer checks in `dynamic_string_node_new`, `dynamic_symbol_node_new`, `dynamic_execute_string_node_new`, and `dynamic_regexp_node_new`
63
+
64
+ ### Changed
65
+ - Remove incorrect `@super` field access from `ModuleNode` (modules do not have superclasses)
66
+
10
67
  ## [0.4.0]
11
68
 
12
69
  ### Added
data/README.md CHANGED
@@ -31,24 +31,105 @@ Finally, build `Kanayago` gem and install it.
31
31
 
32
32
  ```console
33
33
  bundle exec rake build
34
- gem install pkg/kanayago-0.4.0.gem
34
+ gem install pkg/kanayago-0.5.0.gem
35
35
  ```
36
36
 
37
37
  ## Usage
38
38
 
39
+ ### Language Server Protocol (LSP) Mode
40
+
41
+ Kanayago provides LSP server support for real-time syntax checking in your editor:
42
+
43
+ ```bash
44
+ # Start LSP server
45
+ $ kanayago --lsp
46
+ ```
47
+
48
+ This starts an LSP server that communicates via stdin/stdout. You can integrate it with LSP-compliant editors like VSCode, Vim, Emacs, etc.
49
+
50
+ #### VSCode Integration Example
51
+
52
+ Create or modify `.vscode/settings.json`:
53
+
54
+ ```json
55
+ {
56
+ "ruby.lsp.enabled": false,
57
+ "ruby.languageServer": "kanayago-lsp",
58
+ "ruby.languageServerPath": "kanayago",
59
+ "ruby.languageServerArgs": ["--lsp"]
60
+ }
61
+ ```
62
+
63
+ Now VSCode will show syntax errors in real-time as you type Ruby code.
64
+
65
+ #### Vim/Neovim with coc.nvim Integration Example
66
+
67
+ Add the following to your `coc-settings.json` (`:CocConfig` in Vim):
68
+
69
+ ```json
70
+ {
71
+ "languageserver": {
72
+ "kanayago": {
73
+ "command": "kanayago",
74
+ "args": ["--lsp"],
75
+ "filetypes": ["ruby"],
76
+ "rootPatterns": ["Gemfile", ".git"]
77
+ }
78
+ }
79
+ }
80
+ ```
81
+
82
+ Now Vim/Neovim with coc.nvim will show syntax errors in real-time as you edit Ruby files.
83
+
84
+ ### Command Line Interface
85
+
86
+ Kanayago provides a CLI for syntax checking:
87
+
88
+ ```bash
89
+ # Check Ruby code directly
90
+ $ kanayago check 'p 117'
91
+ Syntax valid
92
+
93
+ # Check Ruby code with syntax error
94
+ $ kanayago check 'def foo'
95
+ Syntax invalid
96
+
97
+ # Check a Ruby file
98
+ $ kanayago check --file test.rb
99
+ Syntax valid
100
+
101
+ # Or use the short option
102
+ $ kanayago check -f test.rb
103
+ Syntax valid
104
+ ```
105
+
106
+ The CLI exits with code 0 for valid syntax and code 1 for invalid syntax or errors.
107
+
108
+ ### Ruby API
109
+
39
110
  ```ruby
40
111
  require 'kanayago/kanayago'
41
112
 
42
113
  result = Kanayago.parse('117 + 117')
114
+ # => #<Kanayago::ParseResult:0x00007f522199c5a8>
115
+
116
+ p result.ast
43
117
  # => #<Kanayago::ScopeNode:0x00007f522199c5a8>
44
118
 
45
- p result.body
119
+ p result.ast.body
46
120
  # => #<Kanayago::OperatorCallNode:0x00007f5221b06358>
47
121
 
48
- p result.body.recv
49
- p result.body.recv.val
122
+ p result.ast.body.recv
123
+ p result.ast.body.recv.val
50
124
  # => #<Kanayago::IntegerNode:0x00007f5221b06330>
51
125
  # => 117
126
+
127
+ # Check for syntax errors
128
+ result = Kanayago.parse('def foo')
129
+ p result.valid?
130
+ # => false
131
+ p result.error
132
+ # => #<SyntaxError: syntax error, unexpected end-of-input>
52
133
  ```
53
134
 
54
135
  ## Development
data/exe/kanayago ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'kanayago'
5
+ require 'kanayago/cli'
6
+
7
+ Kanayago::CLI.start(ARGV)
@@ -193,9 +193,8 @@ module_node_new(const NODE *node)
193
193
  {
194
194
  VALUE obj = rb_class_new_instance(0, 0, rb_cModuleNode);
195
195
 
196
- rb_ivar_set(obj, rb_intern("@cpath"), ast_to_node_instance(RNODE_CLASS(node)->nd_cpath));
197
- rb_ivar_set(obj, rb_intern("@super"), ast_to_node_instance(RNODE_CLASS(node)->nd_super));
198
- rb_ivar_set(obj, rb_intern("@body"), ast_to_node_instance(RNODE_CLASS(node)->nd_body));
196
+ rb_ivar_set(obj, rb_intern("@cpath"), ast_to_node_instance(RNODE_MODULE(node)->nd_cpath));
197
+ rb_ivar_set(obj, rb_intern("@body"), ast_to_node_instance(RNODE_MODULE(node)->nd_body));
199
198
 
200
199
  return obj;
201
200
  }
@@ -518,12 +517,22 @@ kanayago_parse(VALUE self, VALUE source)
518
517
  &ruby_parser_data_type, parser);
519
518
  parser->parser_params = parser_params;
520
519
 
520
+ // Enable error tolerant parser
521
+ rb_ruby_parser_error_tolerant(parser_params);
521
522
 
522
523
  VALUE vast = rb_parser_compile_string(vparser, "main", source, 0);
523
524
 
524
525
  rb_ast_t *ast = rb_ruby_ast_data_get(vast);
526
+ VALUE ast_node = ast_to_node_instance(ast->body.root);
527
+
528
+ // Get error_buffer from parser_params using accessor function
529
+ VALUE error_buffer = rb_ruby_parser_error_buffer_get(parser_params);
525
530
 
526
- return ast_to_node_instance(ast->body.root);
531
+ VALUE result = rb_hash_new();
532
+ rb_hash_aset(result, ID2SYM(rb_intern("ast")), ast_node);
533
+ rb_hash_aset(result, ID2SYM(rb_intern("error")), error_buffer);
534
+
535
+ return result;
527
536
  }
528
537
 
529
538
  RUBY_FUNC_EXPORTED void
@@ -12,6 +12,7 @@ VALUE rb_node_rational_literal_val(const NODE *);
12
12
  VALUE rb_node_imaginary_literal_val(const NODE *);
13
13
  VALUE rb_node_str_string_val(const NODE *);
14
14
  VALUE rb_node_sym_string_val(const NODE *);
15
+ VALUE rb_ruby_parser_error_buffer_get(rb_parser_t *);
15
16
 
16
17
  // Add extern for Kanayago
17
18
  extern const rb_data_type_t ruby_parser_data_type;
@@ -19,12 +19,22 @@ dynamic_string_node_new(const NODE *node)
19
19
  {
20
20
  VALUE obj = rb_class_new_instance(0, 0, rb_cDynamicStringNode);
21
21
  rb_parser_string_t *str = RNODE_DSTR(node)->string;
22
- rb_encoding *enc = str->enc;
23
- char *ptr = str->ptr;
24
- long len = str->len;
25
-
26
- rb_ivar_set(obj, rb_intern("@string"), rb_enc_str_new(ptr, len, enc));
27
- rb_ivar_set(obj, rb_intern("@next_nodes"), ast_to_node_instance((const NODE *)RNODE_DSTR(node)->nd_next));
22
+ const NODE *nd_next = (const NODE *)RNODE_DSTR(node)->nd_next;
23
+
24
+ if (str) {
25
+ rb_encoding *enc = str->enc;
26
+ char *ptr = str->ptr;
27
+ long len = str->len;
28
+ rb_ivar_set(obj, rb_intern("@string"), rb_enc_str_new(ptr, len, enc));
29
+ } else {
30
+ rb_ivar_set(obj, rb_intern("@string"), rb_str_new("", 0));
31
+ }
32
+
33
+ if (nd_next && nd_next != (NODE *)-1) {
34
+ rb_ivar_set(obj, rb_intern("@next_nodes"), ast_to_node_instance(nd_next));
35
+ } else {
36
+ rb_ivar_set(obj, rb_intern("@next_nodes"), Qnil);
37
+ }
28
38
 
29
39
  return obj;
30
40
  }
@@ -34,12 +44,22 @@ dynamic_symbol_node_new(const NODE *node)
34
44
  {
35
45
  VALUE obj = rb_class_new_instance(0, 0, rb_cDynamicSymbolNode);
36
46
  rb_parser_string_t *str = RNODE_DSYM(node)->string;
37
- rb_encoding *enc = str->enc;
38
- char *ptr = str->ptr;
39
- long len = str->len;
40
-
41
- rb_ivar_set(obj, rb_intern("@string"), rb_enc_str_new(ptr, len, enc));
42
- rb_ivar_set(obj, rb_intern("@next_nodes"), ast_to_node_instance((const NODE *)RNODE_DSYM(node)->nd_next));
47
+ const NODE *nd_next = (const NODE *)RNODE_DSYM(node)->nd_next;
48
+
49
+ if (str) {
50
+ rb_encoding *enc = str->enc;
51
+ char *ptr = str->ptr;
52
+ long len = str->len;
53
+ rb_ivar_set(obj, rb_intern("@string"), rb_enc_str_new(ptr, len, enc));
54
+ } else {
55
+ rb_ivar_set(obj, rb_intern("@string"), rb_str_new("", 0));
56
+ }
57
+
58
+ if (nd_next && nd_next != (NODE *)-1) {
59
+ rb_ivar_set(obj, rb_intern("@next_nodes"), ast_to_node_instance(nd_next));
60
+ } else {
61
+ rb_ivar_set(obj, rb_intern("@next_nodes"), Qnil);
62
+ }
43
63
 
44
64
  return obj;
45
65
  }
@@ -77,12 +97,22 @@ dynamic_execute_string_node_new(const NODE *node)
77
97
  {
78
98
  VALUE obj = rb_class_new_instance(0, 0, rb_cDynamicExecuteStringNode);
79
99
  rb_parser_string_t *str = RNODE_DXSTR(node)->string;
80
- rb_encoding *enc = str->enc;
81
- char *ptr = str->ptr;
82
- long len = str->len;
83
-
84
- rb_ivar_set(obj, rb_intern("@string"), rb_enc_str_new(ptr, len, enc));
85
- rb_ivar_set(obj, rb_intern("@next_nodes"), ast_to_node_instance((const NODE *)RNODE_DXSTR(node)->nd_next));
100
+ const NODE *nd_next = (const NODE *)RNODE_DXSTR(node)->nd_next;
101
+
102
+ if (str) {
103
+ rb_encoding *enc = str->enc;
104
+ char *ptr = str->ptr;
105
+ long len = str->len;
106
+ rb_ivar_set(obj, rb_intern("@string"), rb_enc_str_new(ptr, len, enc));
107
+ } else {
108
+ rb_ivar_set(obj, rb_intern("@string"), rb_str_new("", 0));
109
+ }
110
+
111
+ if (nd_next && nd_next != (NODE *)-1) {
112
+ rb_ivar_set(obj, rb_intern("@next_nodes"), ast_to_node_instance(nd_next));
113
+ } else {
114
+ rb_ivar_set(obj, rb_intern("@next_nodes"), Qnil);
115
+ }
86
116
 
87
117
  return obj;
88
118
  }
@@ -112,13 +142,24 @@ dynamic_regexp_node_new(const NODE *node)
112
142
  {
113
143
  VALUE obj = rb_class_new_instance(0, 0, rb_cDynamicRegexpNode);
114
144
  rb_parser_string_t *str = RNODE_DREGX(node)->string;
115
- rb_encoding *enc = str->enc;
116
- char *ptr = str->ptr;
117
- long len = str->len;
118
145
  long options = RNODE_DREGX(node)->as.nd_cflag;
146
+ const NODE *nd_next = (const NODE *)RNODE_DREGX(node)->nd_next;
147
+
148
+ if (str) {
149
+ rb_encoding *enc = str->enc;
150
+ char *ptr = str->ptr;
151
+ long len = str->len;
152
+ rb_ivar_set(obj, rb_intern("@string"), rb_enc_str_new(ptr, len, enc));
153
+ } else {
154
+ rb_ivar_set(obj, rb_intern("@string"), rb_str_new("", 0));
155
+ }
156
+
157
+ if (nd_next && nd_next != (NODE *)-1) {
158
+ rb_ivar_set(obj, rb_intern("@next_nodes"), ast_to_node_instance(nd_next));
159
+ } else {
160
+ rb_ivar_set(obj, rb_intern("@next_nodes"), Qnil);
161
+ }
119
162
 
120
- rb_ivar_set(obj, rb_intern("@string"), rb_enc_str_new(ptr, len, enc));
121
- rb_ivar_set(obj, rb_intern("@next_nodes"), ast_to_node_instance((const NODE *)RNODE_DREGX(node)->nd_next));
122
163
  rb_ivar_set(obj, rb_intern("@options"), LONG2FIX(options));
123
164
 
124
165
  return obj;
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'optparse'
4
+
5
+ module Kanayago
6
+ class CLI
7
+ def self.start(argv)
8
+ new(argv).run
9
+ end
10
+
11
+ def initialize(argv)
12
+ @argv = argv
13
+ @file = nil
14
+ @lsp_mode = false
15
+ end
16
+
17
+ def run
18
+ # Check for --lsp flag first
19
+ parse_global_options
20
+
21
+ if @lsp_mode
22
+ start_lsp_server
23
+ return
24
+ end
25
+
26
+ if @argv.empty?
27
+ puts "Usage: kanayago check 'code' or kanayago check --file FILE"
28
+ puts ' kanayago --lsp (start LSP server)'
29
+ exit 1
30
+ end
31
+
32
+ command = @argv.shift
33
+
34
+ case command
35
+ when 'check'
36
+ check_command
37
+ else
38
+ puts "Unknown command: #{command}"
39
+ puts "Usage: kanayago check 'code' or kanayago check --file FILE"
40
+ puts ' kanayago --lsp (start LSP server)'
41
+ exit 1
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def parse_global_options
48
+ # Check for --lsp flag without modifying @argv for other options
49
+ return unless @argv.include?('--lsp')
50
+
51
+ @lsp_mode = true
52
+ @argv.delete('--lsp')
53
+ end
54
+
55
+ def start_lsp_server
56
+ require_relative 'lsp'
57
+ server = Kanayago::LSP::Server.new
58
+ server.start
59
+ end
60
+
61
+ def check_command
62
+ parse_options
63
+
64
+ if @file
65
+ check_file(@file)
66
+ elsif @argv.empty?
67
+ puts 'Error: Please provide Ruby code or use --file option'
68
+ exit 1
69
+ else
70
+ code = @argv.join(' ')
71
+ check_code(code)
72
+ end
73
+ end
74
+
75
+ def parse_options
76
+ OptionParser.new do |opts|
77
+ opts.banner = "Usage: kanayago check [options] 'code'"
78
+
79
+ opts.on('-f FILE', '--file FILE', 'Check syntax of Ruby file') do |file|
80
+ @file = file
81
+ end
82
+
83
+ opts.on('-h', '--help', 'Show this message') do
84
+ puts opts
85
+ exit
86
+ end
87
+ end.parse!(@argv)
88
+ end
89
+
90
+ def check_code(code)
91
+ result = Kanayago.parse(code)
92
+
93
+ if result.valid?
94
+ puts 'Syntax valid'
95
+ exit 0
96
+ else
97
+ puts 'Syntax invalid'
98
+ exit 1
99
+ end
100
+ end
101
+
102
+ def check_file(file_path)
103
+ unless File.exist?(file_path)
104
+ puts "Error: File not found: #{file_path}"
105
+ exit 1
106
+ end
107
+
108
+ code = File.read(file_path)
109
+ check_code(code)
110
+ rescue StandardError => e
111
+ puts "Error: #{e.message}"
112
+ exit 1
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'language_server-protocol'
4
+
5
+ module Kanayago
6
+ module LSP
7
+ # Provides diagnostics for Ruby source code using Kanayago parser
8
+ class DiagnosticsProvider
9
+ def analyze(source)
10
+ diagnostics = []
11
+
12
+ result = Kanayago.parse(source)
13
+
14
+ if result.invalid?
15
+ # Extract error information from SyntaxError
16
+ error = result.error
17
+ diagnostic = create_diagnostic(error)
18
+ diagnostics << diagnostic
19
+ end
20
+
21
+ diagnostics
22
+ end
23
+
24
+ private
25
+
26
+ def create_diagnostic(error)
27
+ # Try to extract line and column from error message
28
+ # SyntaxError message format: "syntax error, unexpected ..."
29
+ # or with location: "(eval):2: syntax error, unexpected ..."
30
+ range = extract_range_from_error(error)
31
+
32
+ {
33
+ range: range,
34
+ severity: LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR,
35
+ source: 'Kanayago',
36
+ message: error.message
37
+ }
38
+ end
39
+
40
+ def extract_range_from_error(error)
41
+ # Try to extract line number from error message
42
+ # Format: "(eval):LINE: message" or just "message"
43
+ message = error.message
44
+
45
+ if message =~ /\(eval\):(\d+):/
46
+ line = ::Regexp.last_match(1).to_i - 1 # Convert to 0-based
47
+ {
48
+ start: { line: line, character: 0 },
49
+ end: { line: line, character: 0 }
50
+ }
51
+ else
52
+ # Default to line 0 if we can't extract line number
53
+ {
54
+ start: { line: 0, character: 0 },
55
+ end: { line: 0, character: 0 }
56
+ }
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'language_server-protocol'
4
+ require_relative 'diagnostics'
5
+
6
+ module Kanayago
7
+ module LSP
8
+ # Language Server Protocol server for Kanayago
9
+ class Server
10
+ def initialize(input: $stdin, output: $stdout)
11
+ @input = input
12
+ @output = output
13
+ @writer = LanguageServer::Protocol::Transport::Io::Writer.new(@output)
14
+ @reader = LanguageServer::Protocol::Transport::Io::Reader.new(@input)
15
+ @diagnostics = DiagnosticsProvider.new
16
+ @documents = {} # URI => content mapping
17
+ end
18
+
19
+ def start
20
+ @reader.read do |request|
21
+ handle_request(request)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def handle_request(request) # rubocop:disable Metrics/CyclomaticComplexity
28
+ case request[:method]
29
+ when 'initialize'
30
+ handle_initialize(request)
31
+ when 'initialized'
32
+ # Client notification, no response needed
33
+ when 'shutdown'
34
+ handle_shutdown(request)
35
+ when 'exit'
36
+ exit(0)
37
+ when 'textDocument/didOpen'
38
+ handle_did_open(request)
39
+ when 'textDocument/didChange'
40
+ handle_did_change(request)
41
+ when 'textDocument/didClose'
42
+ handle_did_close(request)
43
+ else
44
+ # Unsupported method
45
+ send_response(request[:id], nil) if request[:id]
46
+ end
47
+ end
48
+
49
+ def handle_initialize(request)
50
+ result = {
51
+ capabilities: {
52
+ textDocumentSync: {
53
+ openClose: true,
54
+ change: LanguageServer::Protocol::Constant::TextDocumentSyncKind::FULL
55
+ }
56
+ },
57
+ serverInfo: {
58
+ name: 'Kanayago LSP',
59
+ version: Kanayago::VERSION
60
+ }
61
+ }
62
+ send_response(request[:id], result)
63
+ end
64
+
65
+ def handle_shutdown(request)
66
+ send_response(request[:id], nil)
67
+ end
68
+
69
+ def handle_did_open(request)
70
+ params = request[:params]
71
+ uri = params[:textDocument][:uri]
72
+ text = params[:textDocument][:text]
73
+
74
+ @documents[uri] = text
75
+ publish_diagnostics(uri, text)
76
+ end
77
+
78
+ def handle_did_change(request)
79
+ params = request[:params]
80
+ uri = params[:textDocument][:uri]
81
+
82
+ # FULL sync: get entire content
83
+ text = params[:contentChanges][0][:text]
84
+
85
+ @documents[uri] = text
86
+ publish_diagnostics(uri, text)
87
+ end
88
+
89
+ def handle_did_close(request)
90
+ params = request[:params]
91
+ uri = params[:textDocument][:uri]
92
+
93
+ @documents.delete(uri)
94
+ # Clear diagnostics
95
+ publish_diagnostics(uri, nil)
96
+ end
97
+
98
+ def publish_diagnostics(uri, text)
99
+ diagnostics = text ? @diagnostics.analyze(text) : []
100
+
101
+ notification = {
102
+ method: 'textDocument/publishDiagnostics',
103
+ params: {
104
+ uri: uri,
105
+ diagnostics: diagnostics
106
+ }
107
+ }
108
+
109
+ send_notification(notification)
110
+ end
111
+
112
+ def send_response(id, result)
113
+ response = {
114
+ jsonrpc: '2.0',
115
+ id: id,
116
+ result: result
117
+ }
118
+ @writer.write(response)
119
+ end
120
+
121
+ def send_notification(notification)
122
+ message = {
123
+ jsonrpc: '2.0',
124
+ method: notification[:method],
125
+ params: notification[:params]
126
+ }
127
+ @writer.write(message)
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lsp/server'
4
+ require_relative 'lsp/diagnostics'
5
+
6
+ module Kanayago
7
+ # Language Server Protocol support for Kanayago
8
+ module LSP
9
+ end
10
+ end
@@ -74,7 +74,7 @@ module Kanayago
74
74
  end
75
75
 
76
76
  class ModuleNode
77
- attr_reader :cpath, :super, :body
77
+ attr_reader :cpath, :body
78
78
  end
79
79
 
80
80
  class SingletonClassNode
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kanayago
4
- VERSION = '0.4.0'
4
+ VERSION = '0.5.0'
5
5
  end
data/lib/kanayago.rb CHANGED
@@ -14,7 +14,26 @@ require_relative 'kanayago/constant_node'
14
14
 
15
15
  # Parse Ruby code with Ruby's Parser(Universal Parser)
16
16
  module Kanayago
17
+ class ParseResult
18
+ attr_reader :ast, :error
19
+
20
+ def initialize(ast, error)
21
+ @ast = ast
22
+ @error = error
23
+ end
24
+
25
+ def invalid?
26
+ @error.is_a?(SyntaxError)
27
+ end
28
+
29
+ def valid?
30
+ !invalid?
31
+ end
32
+ end
33
+
17
34
  def self.parse(source)
18
- kanayago_parse(source)
35
+ kanayago_parse(source) in { ast:, error: }
36
+
37
+ ParseResult.new(ast, error)
19
38
  end
20
39
  end
@@ -5,7 +5,7 @@ index 8e306d1..d420a02 100644
5
5
  @@ -15,6 +15,29 @@ struct lex_pointer_string {
6
6
  long ptr;
7
7
  };
8
-
8
+
9
9
  +// Add Ruby's Parser struct and enum for Kanayago
10
10
  +enum lex_type {
11
11
  + lex_type_str,
@@ -36,10 +36,111 @@ diff --git a/ext/kanayago/ruby_parser.c b/ext/kanayago/ruby_parser.c
36
36
  index 267f619..841db65 100644
37
37
  --- a/ext/kanayago/ruby_parser.c
38
38
  +++ b/ext/kanayago/ruby_parser.c
39
- @@ -314,6 +314,44 @@ enc_mbc_to_codepoint(const char *p, const char *e, parser_encoding *enc)
40
-
39
+ @@ -34,6 +34,100 @@
40
+
41
+ #define parser_encoding const void
42
+
43
+ +/*
44
+ + * The following functions are ported from Ruby's error.c for Kanayago:
45
+ + * - err_vcatf
46
+ + * - syntax_error_with_path
47
+ + * - rb_syntax_error_append
48
+ + *
49
+ + * Copyright (C) 1993-2007 Yukihiro Matsumoto
50
+ + *
51
+ + * Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
52
+ + * You can redistribute it and/or modify it under either the terms of the
53
+ + * 2-clause BSDL (see the file BSDL), or the conditions below:
54
+ + *
55
+ + * Redistribution and use in source and binary forms, with or without
56
+ + * modification, are permitted provided that the following conditions
57
+ + * are met:
58
+ + * 1. Redistributions of source code must retain the above copyright
59
+ + * notice, this list of conditions and the following disclaimer.
60
+ + * 2. Redistributions in binary form must reproduce the above copyright
61
+ + * notice, this list of conditions and the following disclaimer in the
62
+ + * documentation and/or other materials provided with the distribution.
63
+ + *
64
+ + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
65
+ + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66
+ + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67
+ + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
68
+ + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69
+ + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70
+ + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71
+ + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72
+ + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73
+ + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74
+ + * SUCH DAMAGE.
75
+ + */
76
+ +
77
+ +static VALUE
78
+ +err_vcatf(VALUE str, const char *pre, const char *file, int line,
79
+ + const char *fmt, va_list args)
80
+ +{
81
+ + if (file) {
82
+ + rb_str_cat_cstr(str, file);
83
+ + if (line) rb_str_catf(str, ":%d", line);
84
+ + rb_str_cat_cstr(str, ": ");
85
+ + }
86
+ + if (pre) rb_str_cat_cstr(str, pre);
87
+ + rb_str_vcatf(str, fmt, args);
88
+ + return str;
89
+ +}
90
+ +
91
+ +static VALUE
92
+ +syntax_error_with_path(VALUE exc, VALUE file, VALUE *mesg, rb_encoding *enc)
93
+ +{
94
+ + // Create new SyntaxError if exc is nil or Qfalse (for error_tolerant mode)
95
+ + if (NIL_P(exc) || exc == Qfalse) {
96
+ + exc = rb_class_new_instance(0, 0, rb_eSyntaxError);
97
+ + }
98
+ + *mesg = rb_attr_get(exc, rb_intern("mesg"));
99
+ + // Check if mesg is nil or frozen (default "compile error" may be frozen)
100
+ + if (NIL_P(*mesg) || OBJ_FROZEN(*mesg)) {
101
+ + *mesg = rb_enc_str_new(0, 0, enc);
102
+ + rb_ivar_set(exc, rb_intern("mesg"), *mesg);
103
+ + }
104
+ + return exc;
105
+ +}
106
+ +
107
+ +RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 6, 0)
108
+ +VALUE
109
+ +rb_syntax_error_append(VALUE exc, VALUE file, int line, int column,
110
+ + rb_encoding *enc, const char *fmt, va_list args)
111
+ +{
112
+ + const char *fn = NIL_P(file) ? NULL : RSTRING_PTR(file);
113
+ + if (!exc) {
114
+ + // For error_tolerant mode, create SyntaxError even when writing to stderr
115
+ + exc = rb_class_new_instance(0, 0, rb_eSyntaxError);
116
+ + VALUE mesg = rb_attr_get(exc, rb_intern("mesg"));
117
+ + // Check if mesg is nil or frozen (default "compile error" may be frozen)
118
+ + if (NIL_P(mesg) || OBJ_FROZEN(mesg)) {
119
+ + mesg = rb_enc_str_new(0, 0, enc);
120
+ + rb_ivar_set(exc, rb_intern("mesg"), mesg);
121
+ + }
122
+ + err_vcatf(mesg, NULL, fn, line, fmt, args);
123
+ + // Still write to stderr for compatibility
124
+ + VALUE err_mesg = rb_str_dup(mesg);
125
+ + rb_str_cat_cstr(err_mesg, "\n");
126
+ + rb_write_error_str(err_mesg);
127
+ + }
128
+ + else {
129
+ + VALUE mesg;
130
+ + exc = syntax_error_with_path(exc, file, &mesg, enc);
131
+ + err_vcatf(mesg, NULL, fn, line, fmt, args);
132
+ + }
133
+ +
134
+ + return exc;
135
+ +}
136
+ +
137
+ RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 6, 0)
138
+ static VALUE
139
+ syntax_error_append(VALUE exc, VALUE file, int line, int column,
140
+ @@ -314,6 +408,44 @@ enc_mbc_to_codepoint(const char *p, const char *e, parser_encoding *enc)
141
+
41
142
  extern VALUE rb_eArgError;
42
-
143
+
43
144
  +// Add for Kanayago
44
145
  +static void *
45
146
  +xmalloc_mul_add(size_t x, size_t y, size_t z)
@@ -81,51 +182,51 @@ index 267f619..841db65 100644
81
182
  static const rb_parser_config_t rb_global_parser_config = {
82
183
  .malloc = ruby_xmalloc,
83
184
  .calloc = ruby_xcalloc,
84
- @@ -325,9 +363,9 @@ static const rb_parser_config_t rb_global_parser_config = {
185
+ @@ -325,9 +457,9 @@ static const rb_parser_config_t rb_global_parser_config = {
85
186
  .zalloc = zalloc,
86
187
  .rb_memmove = memmove2,
87
188
  .nonempty_memcpy = nonempty_memcpy,
88
189
  - .xmalloc_mul_add = rb_xmalloc_mul_add,
89
190
  + .xmalloc_mul_add = xmalloc_mul_add, // use xmalloc_mul_add for Kanayago
90
-
191
+
91
192
  - .compile_callback = rb_suppress_tracing,
92
193
  + .compile_callback = suppress_tracing, // use suppress_tracing for Kanayago
93
194
  .reg_named_capture_assign = reg_named_capture_assign,
94
-
195
+
95
196
  .attr_get = rb_attr_get,
96
- @@ -335,7 +373,7 @@ static const rb_parser_config_t rb_global_parser_config = {
197
+ @@ -335,7 +467,7 @@ static const rb_parser_config_t rb_global_parser_config = {
97
198
  .ary_new_from_args = rb_ary_new_from_args,
98
199
  .ary_unshift = rb_ary_unshift,
99
-
200
+
100
201
  - .make_temporary_id = rb_make_temporary_id,
101
202
  + .make_temporary_id = make_temporary_id, // use make_temporary_id for Kanayago
102
203
  .is_local_id = is_local_id2,
103
204
  .is_attrset_id = is_attrset_id2,
104
205
  .is_global_name_punct = is_global_name_punct,
105
- @@ -365,7 +403,7 @@ static const rb_parser_config_t rb_global_parser_config = {
106
-
206
+ @@ -365,7 +497,7 @@ static const rb_parser_config_t rb_global_parser_config = {
207
+
107
208
  .int2num = rb_int2num_inline,
108
-
209
+
109
210
  - .stderr_tty_p = rb_stderr_tty_p,
110
211
  + .stderr_tty_p = stderr_tty_p, //use stderr_tty_p for Kanayago
111
212
  .write_error_str = rb_write_error_str,
112
213
  .io_write = rb_io_write,
113
214
  .io_flush = rb_io_flush,
114
- @@ -412,8 +450,8 @@ static const rb_parser_config_t rb_global_parser_config = {
215
+ @@ -412,8 +544,8 @@ static const rb_parser_config_t rb_global_parser_config = {
115
216
  .gc_guard = gc_guard,
116
217
  .gc_mark = rb_gc_mark,
117
-
218
+
118
219
  - .reg_compile = rb_reg_compile,
119
220
  - .reg_check_preprocess = rb_reg_check_preprocess,
120
221
  + .reg_compile = reg_compile, // use reg_compile for Kanayago
121
222
  + .reg_check_preprocess = reg_check_preprocess, // use reg_check_preprocess for Kanayago
122
223
  .memcicmp = rb_memcicmp,
123
-
224
+
124
225
  .compile_warn = rb_compile_warn,
125
- @@ -443,27 +481,6 @@ static const rb_parser_config_t rb_global_parser_config = {
226
+ @@ -443,27 +575,6 @@ static const rb_parser_config_t rb_global_parser_config = {
126
227
  };
127
228
  #endif
128
-
229
+
129
230
  -enum lex_type {
130
231
  - lex_type_str,
131
232
  - lex_type_io,
@@ -150,13 +251,32 @@ index 267f619..841db65 100644
150
251
  static void
151
252
  parser_mark(void *ptr)
152
253
  {
153
- @@ -501,7 +518,8 @@ parser_memsize(const void *ptr)
254
+ @@ -501,7 +612,8 @@ parser_memsize(const void *ptr)
154
255
  return rb_ruby_parser_memsize(parser->parser_params);
155
256
  }
156
-
257
+
157
258
  -static const rb_data_type_t ruby_parser_data_type = {
158
259
  +// Not static const for Kanayago
159
260
  +const rb_data_type_t ruby_parser_data_type = {
160
261
  "parser",
161
262
  {
162
263
  parser_mark,
264
+ diff --git a/ext/kanayago/parse.c b/ext/kanayago/parse.c
265
+ --- a/ext/kanayago/parse.c
266
+ +++ b/ext/kanayago/parse.c
267
+ @@ -26941,6 +26941,15 @@ ripper_value(struct parser_params *p)
268
+ return p->value;
269
+ }
270
+
271
+ +#else /* !RIPPER */
272
+ +
273
+ +// Accessor function for error_buffer (for Kanayago)
274
+ +VALUE
275
+ +rb_ruby_parser_error_buffer_get(rb_parser_t *p)
276
+ +{
277
+ + return p->error_buffer;
278
+ +}
279
+ +
280
+ #endif /* RIPPER */
281
+ /*
282
+ * Local variables:
@@ -13,6 +13,7 @@ RUBY_PARSER_COPY_TARGETS = %w[
13
13
  internal/basic_operators.h
14
14
  internal/bignum.h
15
15
  internal/bits.h
16
+ internal/box.h
16
17
  internal/compile.h
17
18
  internal/compilers.h
18
19
  internal/complex.h
@@ -5,7 +5,7 @@ index 8e306d1..d420a02 100644
5
5
  @@ -15,6 +15,29 @@ struct lex_pointer_string {
6
6
  long ptr;
7
7
  };
8
-
8
+
9
9
  +// Add Ruby's Parser struct and enum for Kanayago
10
10
  +enum lex_type {
11
11
  + lex_type_str,
@@ -36,10 +36,111 @@ diff --git a/ext/kanayago/ruby_parser.c b/ext/kanayago/ruby_parser.c
36
36
  index 267f619..841db65 100644
37
37
  --- a/ext/kanayago/ruby_parser.c
38
38
  +++ b/ext/kanayago/ruby_parser.c
39
- @@ -314,6 +314,44 @@ enc_mbc_to_codepoint(const char *p, const char *e, parser_encoding *enc)
40
-
39
+ @@ -34,6 +34,100 @@
40
+
41
+ #define parser_encoding const void
42
+
43
+ +/*
44
+ + * The following functions are ported from Ruby's error.c for Kanayago:
45
+ + * - err_vcatf
46
+ + * - syntax_error_with_path
47
+ + * - rb_syntax_error_append
48
+ + *
49
+ + * Copyright (C) 1993-2007 Yukihiro Matsumoto
50
+ + *
51
+ + * Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
52
+ + * You can redistribute it and/or modify it under either the terms of the
53
+ + * 2-clause BSDL (see the file BSDL), or the conditions below:
54
+ + *
55
+ + * Redistribution and use in source and binary forms, with or without
56
+ + * modification, are permitted provided that the following conditions
57
+ + * are met:
58
+ + * 1. Redistributions of source code must retain the above copyright
59
+ + * notice, this list of conditions and the following disclaimer.
60
+ + * 2. Redistributions in binary form must reproduce the above copyright
61
+ + * notice, this list of conditions and the following disclaimer in the
62
+ + * documentation and/or other materials provided with the distribution.
63
+ + *
64
+ + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
65
+ + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66
+ + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67
+ + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
68
+ + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69
+ + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70
+ + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71
+ + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72
+ + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73
+ + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74
+ + * SUCH DAMAGE.
75
+ + */
76
+ +
77
+ +static VALUE
78
+ +err_vcatf(VALUE str, const char *pre, const char *file, int line,
79
+ + const char *fmt, va_list args)
80
+ +{
81
+ + if (file) {
82
+ + rb_str_cat_cstr(str, file);
83
+ + if (line) rb_str_catf(str, ":%d", line);
84
+ + rb_str_cat_cstr(str, ": ");
85
+ + }
86
+ + if (pre) rb_str_cat_cstr(str, pre);
87
+ + rb_str_vcatf(str, fmt, args);
88
+ + return str;
89
+ +}
90
+ +
91
+ +static VALUE
92
+ +syntax_error_with_path(VALUE exc, VALUE file, VALUE *mesg, rb_encoding *enc)
93
+ +{
94
+ + // Create new SyntaxError if exc is nil or Qfalse (for error_tolerant mode)
95
+ + if (NIL_P(exc) || exc == Qfalse) {
96
+ + exc = rb_class_new_instance(0, 0, rb_eSyntaxError);
97
+ + }
98
+ + *mesg = rb_attr_get(exc, rb_intern("mesg"));
99
+ + // Check if mesg is nil or frozen (default "compile error" may be frozen)
100
+ + if (NIL_P(*mesg) || OBJ_FROZEN(*mesg)) {
101
+ + *mesg = rb_enc_str_new(0, 0, enc);
102
+ + rb_ivar_set(exc, rb_intern("mesg"), *mesg);
103
+ + }
104
+ + return exc;
105
+ +}
106
+ +
107
+ +RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 6, 0)
108
+ +VALUE
109
+ +rb_syntax_error_append(VALUE exc, VALUE file, int line, int column,
110
+ + rb_encoding *enc, const char *fmt, va_list args)
111
+ +{
112
+ + const char *fn = NIL_P(file) ? NULL : RSTRING_PTR(file);
113
+ + if (!exc) {
114
+ + // For error_tolerant mode, create SyntaxError even when writing to stderr
115
+ + exc = rb_class_new_instance(0, 0, rb_eSyntaxError);
116
+ + VALUE mesg = rb_attr_get(exc, rb_intern("mesg"));
117
+ + // Check if mesg is nil or frozen (default "compile error" may be frozen)
118
+ + if (NIL_P(mesg) || OBJ_FROZEN(mesg)) {
119
+ + mesg = rb_enc_str_new(0, 0, enc);
120
+ + rb_ivar_set(exc, rb_intern("mesg"), mesg);
121
+ + }
122
+ + err_vcatf(mesg, NULL, fn, line, fmt, args);
123
+ + // Still write to stderr for compatibility
124
+ + VALUE err_mesg = rb_str_dup(mesg);
125
+ + rb_str_cat_cstr(err_mesg, "\n");
126
+ + rb_write_error_str(err_mesg);
127
+ + }
128
+ + else {
129
+ + VALUE mesg;
130
+ + exc = syntax_error_with_path(exc, file, &mesg, enc);
131
+ + err_vcatf(mesg, NULL, fn, line, fmt, args);
132
+ + }
133
+ +
134
+ + return exc;
135
+ +}
136
+ +
137
+ RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 6, 0)
138
+ static VALUE
139
+ syntax_error_append(VALUE exc, VALUE file, int line, int column,
140
+ @@ -314,6 +408,44 @@ enc_mbc_to_codepoint(const char *p, const char *e, parser_encoding *enc)
141
+
41
142
  extern VALUE rb_eArgError;
42
-
143
+
43
144
  +// Add for Kanayago
44
145
  +static void *
45
146
  +xmalloc_mul_add(size_t x, size_t y, size_t z)
@@ -81,51 +182,51 @@ index 267f619..841db65 100644
81
182
  static const rb_parser_config_t rb_global_parser_config = {
82
183
  .malloc = ruby_xmalloc,
83
184
  .calloc = ruby_xcalloc,
84
- @@ -325,9 +363,9 @@ static const rb_parser_config_t rb_global_parser_config = {
185
+ @@ -325,9 +457,9 @@ static const rb_parser_config_t rb_global_parser_config = {
85
186
  .zalloc = zalloc,
86
187
  .rb_memmove = memmove2,
87
188
  .nonempty_memcpy = nonempty_memcpy,
88
189
  - .xmalloc_mul_add = rb_xmalloc_mul_add,
89
190
  + .xmalloc_mul_add = xmalloc_mul_add, // use xmalloc_mul_add for Kanayago
90
-
191
+
91
192
  - .compile_callback = rb_suppress_tracing,
92
193
  + .compile_callback = suppress_tracing, // use suppress_tracing for Kanayago
93
194
  .reg_named_capture_assign = reg_named_capture_assign,
94
-
195
+
95
196
  .attr_get = rb_attr_get,
96
- @@ -335,7 +373,7 @@ static const rb_parser_config_t rb_global_parser_config = {
197
+ @@ -335,7 +467,7 @@ static const rb_parser_config_t rb_global_parser_config = {
97
198
  .ary_new_from_args = rb_ary_new_from_args,
98
199
  .ary_unshift = rb_ary_unshift,
99
-
200
+
100
201
  - .make_temporary_id = rb_make_temporary_id,
101
202
  + .make_temporary_id = make_temporary_id, // use make_temporary_id for Kanayago
102
203
  .is_local_id = is_local_id2,
103
204
  .is_attrset_id = is_attrset_id2,
104
205
  .is_global_name_punct = is_global_name_punct,
105
- @@ -365,7 +403,7 @@ static const rb_parser_config_t rb_global_parser_config = {
106
-
206
+ @@ -365,7 +497,7 @@ static const rb_parser_config_t rb_global_parser_config = {
207
+
107
208
  .int2num = rb_int2num_inline,
108
-
209
+
109
210
  - .stderr_tty_p = rb_stderr_tty_p,
110
211
  + .stderr_tty_p = stderr_tty_p, //use stderr_tty_p for Kanayago
111
212
  .write_error_str = rb_write_error_str,
112
213
  .io_write = rb_io_write,
113
214
  .io_flush = rb_io_flush,
114
- @@ -412,8 +450,8 @@ static const rb_parser_config_t rb_global_parser_config = {
215
+ @@ -412,8 +544,8 @@ static const rb_parser_config_t rb_global_parser_config = {
115
216
  .gc_guard = gc_guard,
116
217
  .gc_mark = rb_gc_mark,
117
-
218
+
118
219
  - .reg_compile = rb_reg_compile,
119
220
  - .reg_check_preprocess = rb_reg_check_preprocess,
120
221
  + .reg_compile = reg_compile, // use reg_compile for Kanayago
121
222
  + .reg_check_preprocess = reg_check_preprocess, // use reg_check_preprocess for Kanayago
122
223
  .memcicmp = rb_memcicmp,
123
-
224
+
124
225
  .compile_warn = rb_compile_warn,
125
- @@ -443,27 +481,6 @@ static const rb_parser_config_t rb_global_parser_config = {
226
+ @@ -443,27 +575,6 @@ static const rb_parser_config_t rb_global_parser_config = {
126
227
  };
127
228
  #endif
128
-
229
+
129
230
  -enum lex_type {
130
231
  - lex_type_str,
131
232
  - lex_type_io,
@@ -150,13 +251,32 @@ index 267f619..841db65 100644
150
251
  static void
151
252
  parser_mark(void *ptr)
152
253
  {
153
- @@ -501,7 +518,8 @@ parser_memsize(const void *ptr)
254
+ @@ -501,7 +612,8 @@ parser_memsize(const void *ptr)
154
255
  return rb_ruby_parser_memsize(parser->parser_params);
155
256
  }
156
-
257
+
157
258
  -static const rb_data_type_t ruby_parser_data_type = {
158
259
  +// Not static const for Kanayago
159
260
  +const rb_data_type_t ruby_parser_data_type = {
160
261
  "parser",
161
262
  {
162
263
  parser_mark,
264
+ diff --git a/ext/kanayago/parse.c b/ext/kanayago/parse.c
265
+ --- a/ext/kanayago/parse.c
266
+ +++ b/ext/kanayago/parse.c
267
+ @@ -27391,6 +27391,15 @@ ripper_value(struct parser_params *p)
268
+ return p->value;
269
+ }
270
+
271
+ +#else /* !RIPPER */
272
+ +
273
+ +// Accessor function for error_buffer (for Kanayago)
274
+ +VALUE
275
+ +rb_ruby_parser_error_buffer_get(rb_parser_t *p)
276
+ +{
277
+ + return p->error_buffer;
278
+ +}
279
+ +
280
+ #endif /* RIPPER */
281
+ /*
282
+ * Local variables:
metadata CHANGED
@@ -1,18 +1,33 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kanayago
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - S-H-GAMELINKS
8
8
  bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
- dependencies: []
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: language_server-protocol
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 3.17.0
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: 3.17.0
12
26
  description: Trying to Make Ruby's Parser Available as a Gem
13
27
  email:
14
28
  - gamelinks007@gmail.com
15
- executables: []
29
+ executables:
30
+ - kanayago
16
31
  extensions:
17
32
  - ext/kanayago/extconf.rb
18
33
  extra_rdoc_files: []
@@ -24,6 +39,7 @@ files:
24
39
  - LICENSE.txt
25
40
  - README.md
26
41
  - Rakefile
42
+ - exe/kanayago
27
43
  - ext/kanayago/extconf.rb
28
44
  - ext/kanayago/kanayago.c
29
45
  - ext/kanayago/kanayago.h
@@ -41,8 +57,12 @@ files:
41
57
  - ext/kanayago/variable_node.h
42
58
  - lib/kanayago.rb
43
59
  - lib/kanayago/call_node.rb
60
+ - lib/kanayago/cli.rb
44
61
  - lib/kanayago/constant_node.rb
45
62
  - lib/kanayago/literal_node.rb
63
+ - lib/kanayago/lsp.rb
64
+ - lib/kanayago/lsp/diagnostics.rb
65
+ - lib/kanayago/lsp/server.rb
46
66
  - lib/kanayago/pattern_node.rb
47
67
  - lib/kanayago/scope_node.rb
48
68
  - lib/kanayago/statement_node.rb
@@ -80,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
100
  - !ruby/object:Gem::Version
81
101
  version: '0'
82
102
  requirements: []
83
- rubygems_version: 3.8.0.dev
103
+ rubygems_version: 4.0.0.dev
84
104
  specification_version: 4
85
105
  summary: Trying to Make Ruby's Parser Available as a Gem
86
106
  test_files: []