prism 0.17.1 → 0.18.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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -1
  3. data/Makefile +5 -5
  4. data/README.md +2 -2
  5. data/config.yml +26 -13
  6. data/docs/build_system.md +6 -6
  7. data/docs/building.md +1 -1
  8. data/docs/configuration.md +1 -0
  9. data/docs/encoding.md +68 -32
  10. data/docs/heredocs.md +1 -1
  11. data/docs/javascript.md +29 -1
  12. data/docs/ruby_api.md +14 -0
  13. data/ext/prism/api_node.c +74 -45
  14. data/ext/prism/extconf.rb +91 -127
  15. data/ext/prism/extension.c +1 -1
  16. data/ext/prism/extension.h +1 -1
  17. data/include/prism/ast.h +148 -133
  18. data/include/prism/diagnostic.h +27 -1
  19. data/include/prism/enc/pm_encoding.h +42 -1
  20. data/include/prism/parser.h +6 -0
  21. data/include/prism/version.h +3 -3
  22. data/lib/prism/compiler.rb +3 -3
  23. data/lib/prism/debug.rb +4 -0
  24. data/lib/prism/desugar_compiler.rb +1 -0
  25. data/lib/prism/dispatcher.rb +14 -14
  26. data/lib/prism/dot_visitor.rb +4334 -0
  27. data/lib/prism/dsl.rb +11 -11
  28. data/lib/prism/ffi.rb +3 -3
  29. data/lib/prism/mutation_compiler.rb +6 -6
  30. data/lib/prism/node.rb +182 -113
  31. data/lib/prism/node_ext.rb +61 -3
  32. data/lib/prism/parse_result.rb +46 -12
  33. data/lib/prism/serialize.rb +125 -131
  34. data/lib/prism/visitor.rb +3 -3
  35. data/lib/prism.rb +1 -0
  36. data/prism.gemspec +5 -1
  37. data/rbi/prism.rbi +83 -54
  38. data/sig/prism.rbs +47 -32
  39. data/src/diagnostic.c +61 -3
  40. data/src/enc/pm_big5.c +63 -0
  41. data/src/enc/pm_cp51932.c +57 -0
  42. data/src/enc/pm_euc_jp.c +10 -0
  43. data/src/enc/pm_gbk.c +5 -2
  44. data/src/enc/pm_tables.c +1478 -148
  45. data/src/node.c +33 -21
  46. data/src/prettyprint.c +1027 -925
  47. data/src/prism.c +925 -374
  48. data/src/regexp.c +12 -12
  49. data/src/serialize.c +36 -9
  50. metadata +6 -2
data/ext/prism/extconf.rb CHANGED
@@ -1,136 +1,100 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rbconfig"
3
+ if ARGV.delete("--help")
4
+ print(<<~TEXT)
5
+ USAGE: ruby #{$PROGRAM_NAME} [options]
6
+
7
+ Flags that are always valid:
8
+
9
+ --enable-debug-mode-build
10
+ Enable debug mode build.
11
+ You may also use set PRISM_DEBUG_MODE_BUILD environment variable.
12
+
13
+ --help
14
+ Display this message.
15
+
16
+ Environment variables used:
4
17
 
5
- module Prism
6
- module ExtConf
7
- class << self
8
- def configure
9
- unless RUBY_ENGINE == "ruby"
10
- # On non-CRuby we only need the shared library, so build only that and not the C extension.
11
- # We also avoid `require "mkmf"` as that prepends the LLVM toolchain to PATH on TruffleRuby,
12
- # but we want to use the native toolchain here since librubyparser is run natively.
13
- build_shared_rubyparser
14
- File.write("Makefile", "all install clean:\n\t@#{RbConfig::CONFIG["NULLCMD"]}\n")
15
- return
16
- end
17
-
18
- require "mkmf"
19
- configure_c_extension
20
- configure_rubyparser
21
-
22
- create_makefile("prism/prism")
23
-
24
- if static_link?
25
- File.open('Makefile', 'a') do |mf|
26
- mf.puts
27
- mf.puts '# Automatically rebuild the extension if librubyparser.a changed'
28
- mf.puts '$(TARGET_SO): $(LOCAL_LIBS)'
29
- end
30
- end
31
- end
32
-
33
- def configure_c_extension
34
- append_cflags("-DPRISM_DEBUG_MODE_BUILD") if debug_mode_build?
35
- append_cflags("-fvisibility=hidden")
36
- end
37
-
38
- def configure_rubyparser
39
- if static_link?
40
- static_archive_path = File.join(build_dir, "librubyparser.a")
41
- unless File.exist?(static_archive_path)
42
- build_static_rubyparser
43
- end
44
- $LOCAL_LIBS << " #{static_archive_path}"
45
- else
46
- shared_library_path = File.join(build_dir, "librubyparser.#{RbConfig::CONFIG["SOEXT"]}")
47
- unless File.exist?(shared_library_path)
48
- build_shared_rubyparser
49
- end
50
- unless find_library("rubyparser", "pm_parser_init", build_dir)
51
- raise "could not link against #{File.basename(shared_library_path)}"
52
- end
53
- end
54
-
55
- find_header("prism.h", include_dir) or raise "prism.h is required"
56
-
57
- # Explicitly look for the extension header in the parent directory
58
- # because we want to consistently look for prism/extension.h in our
59
- # source files to line up with our mirroring in CRuby.
60
- find_header("prism/extension.h", File.join(__dir__, "..")) or raise "prism/extension.h is required"
61
- end
62
-
63
- def build_shared_rubyparser
64
- build_target_rubyparser "build/librubyparser.#{RbConfig::CONFIG["SOEXT"]}"
65
- end
66
-
67
- def build_static_rubyparser
68
- build_target_rubyparser "build/librubyparser.a"
69
- end
70
-
71
- def build_target_rubyparser(target)
72
- Dir.chdir(root_dir) do
73
- if !File.exist?("include/prism/ast.h") && Dir.exist?(".git")
74
- # this block only exists to support building the gem from a "git" source,
75
- # normally we package up the configure and other files in the gem itself
76
- system("templates/template.rb", exception: true)
77
- end
78
- system("make", target, exception: true)
79
- end
80
- end
81
-
82
- def root_dir
83
- File.expand_path("../..", __dir__)
84
- end
85
-
86
- def include_dir
87
- File.join(root_dir, "include")
88
- end
89
-
90
- def build_dir
91
- File.join(root_dir, "build")
92
- end
93
-
94
- def print_help
95
- print(<<~TEXT)
96
- USAGE: ruby #{$PROGRAM_NAME} [options]
97
-
98
- Flags that are always valid:
99
-
100
- --enable-static
101
- --disable-static
102
- Enable or disable static linking against librubyparser.
103
- The default is to statically link.
104
-
105
- --enable-debug-mode-build
106
- Enable debug mode build.
107
- You may also use set PRISM_DEBUG_MODE_BUILD environment variable.
108
-
109
- --help
110
- Display this message.
111
-
112
- Environment variables used:
113
-
114
- PRISM_DEBUG_MODE_BUILD
115
- Equivalent to `--enable-debug-mode-build` when set, even if nil or blank.
116
-
117
- TEXT
118
- end
119
-
120
- def static_link?
121
- enable_config("static", true)
122
- end
123
-
124
- def debug_mode_build?
125
- enable_config("debug-mode-build", ENV["PRISM_DEBUG_MODE_BUILD"] || false)
126
- end
18
+ PRISM_DEBUG_MODE_BUILD
19
+ Equivalent to `--enable-debug-mode-build` when set, even if nil or blank.
20
+
21
+ TEXT
22
+ exit!(0)
23
+ end
24
+
25
+ # Runs `make` in the root directory of the project. Note that this is the
26
+ # `Makefile` for the overall project, not the `Makefile` that is being generated
27
+ # by this script.`
28
+ def make(target)
29
+ Dir.chdir(File.expand_path("../..", __dir__)) do
30
+ # If this gem is being build from a git source, then we need to run
31
+ # templating if it hasn't been run yet. In normal packaging, we would have
32
+ # shipped the templated files with the gem, so this wouldn't be necessary.
33
+ if !File.exist?("include/prism/ast.h") && Dir.exist?(".git")
34
+ system("templates/template.rb", exception: true)
127
35
  end
36
+
37
+ system("make", target, exception: true)
128
38
  end
129
39
  end
130
40
 
131
- if ARGV.delete("--help")
132
- Prism::ExtConf.print_help
133
- exit!(0)
41
+ require "rbconfig"
42
+
43
+ # On non-CRuby we only need the shared library since we'll interface with it
44
+ # through FFI, so we'll build only that and not the C extension. We also avoid
45
+ # `require "mkmf"` as that prepends the LLVM toolchain to PATH on TruffleRuby,
46
+ # but we want to use the native toolchain here since libprism is run natively.
47
+ if RUBY_ENGINE != "ruby"
48
+ make("build/libprism.#{RbConfig::CONFIG["SOEXT"]}")
49
+ File.write("Makefile", "all install clean:\n\t@#{RbConfig::CONFIG["NULLCMD"]}\n")
50
+ return
51
+ end
52
+
53
+ require "mkmf"
54
+
55
+ # First, ensure that we can find the header for the prism library.
56
+ unless find_header("prism.h", File.expand_path("../../include", __dir__))
57
+ raise "prism.h is required"
134
58
  end
135
59
 
136
- Prism::ExtConf.configure
60
+ # Next, ensure we can find the header for the C extension. Explicitly look for
61
+ # the extension header in the parent directory because we want to consistently
62
+ # look for `prism/extension.h` in our source files to line up with our mirroring
63
+ # in CRuby.
64
+ unless find_header("prism/extension.h", File.expand_path("..", __dir__))
65
+ raise "prism/extension.h is required"
66
+ end
67
+
68
+ # If `--enable-debug-mode-build` is passed to this script or the
69
+ # `PRISM_DEBUG_MODE_BUILD` environment variable is defined, we'll build with the
70
+ # `PRISM_DEBUG_MODE_BUILD` macro defined. This causes parse functions to
71
+ # duplicate their input so that they have clearly set bounds, which is useful
72
+ # for finding bugs that cause the parser to read off the end of the input.
73
+ if enable_config("debug-mode-build", ENV["PRISM_DEBUG_MODE_BUILD"] || false)
74
+ append_cflags("-DPRISM_DEBUG_MODE_BUILD")
75
+ end
76
+
77
+ # By default, all symbols are hidden in the shared library.
78
+ append_cflags("-fvisibility=hidden")
79
+
80
+ # We need to link against the libprism.a archive, which is built by the
81
+ # project's `Makefile`. We'll build it if it doesn't exist yet, and then add it
82
+ # to `mkmf`'s list of local libraries.
83
+ archive_target = "build/libprism.a"
84
+ archive_path = File.expand_path("../../#{archive_target}", __dir__)
85
+
86
+ make(archive_target) unless File.exist?(archive_path)
87
+ $LOCAL_LIBS << " #{archive_path}"
88
+
89
+ # Finally, we'll create the `Makefile` that is going to be used to configure and
90
+ # build the C extension.
91
+ create_makefile("prism/prism")
92
+
93
+ # Now that the `Makefile` for the C extension is built, we'll append on an extra
94
+ # rule that dictates that the extension should be rebuilt if the archive is
95
+ # updated.
96
+ File.open("Makefile", "a") do |mf|
97
+ mf.puts
98
+ mf.puts("# Automatically rebuild the extension if libprism.a changed")
99
+ mf.puts("$(TARGET_SO): $(LOCAL_LIBS)")
100
+ end
@@ -1,7 +1,7 @@
1
1
  #include "prism/extension.h"
2
2
 
3
3
  // NOTE: this file should contain only bindings. All non-trivial logic should be
4
- // in librubyparser so it can be shared its the various callers.
4
+ // in libprism so it can be shared its the various callers.
5
5
 
6
6
  VALUE rb_cPrism;
7
7
  VALUE rb_cPrismNode;
@@ -1,7 +1,7 @@
1
1
  #ifndef PRISM_EXT_NODE_H
2
2
  #define PRISM_EXT_NODE_H
3
3
 
4
- #define EXPECTED_PRISM_VERSION "0.17.1"
4
+ #define EXPECTED_PRISM_VERSION "0.18.0"
5
5
 
6
6
  #include <ruby.h>
7
7
  #include <ruby/encoding.h>