prism 0.17.1 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -1
- data/Makefile +5 -5
- data/README.md +2 -2
- data/config.yml +26 -13
- data/docs/build_system.md +6 -6
- data/docs/building.md +1 -1
- data/docs/configuration.md +1 -0
- data/docs/encoding.md +68 -32
- data/docs/heredocs.md +1 -1
- data/docs/javascript.md +29 -1
- data/docs/ruby_api.md +14 -0
- data/ext/prism/api_node.c +74 -45
- data/ext/prism/extconf.rb +91 -127
- data/ext/prism/extension.c +1 -1
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +148 -133
- data/include/prism/diagnostic.h +27 -1
- data/include/prism/enc/pm_encoding.h +42 -1
- data/include/prism/parser.h +6 -0
- data/include/prism/version.h +3 -3
- data/lib/prism/compiler.rb +3 -3
- data/lib/prism/debug.rb +4 -0
- data/lib/prism/desugar_compiler.rb +1 -0
- data/lib/prism/dispatcher.rb +14 -14
- data/lib/prism/dot_visitor.rb +4334 -0
- data/lib/prism/dsl.rb +11 -11
- data/lib/prism/ffi.rb +3 -3
- data/lib/prism/mutation_compiler.rb +6 -6
- data/lib/prism/node.rb +182 -113
- data/lib/prism/node_ext.rb +61 -3
- data/lib/prism/parse_result.rb +46 -12
- data/lib/prism/serialize.rb +125 -131
- data/lib/prism/visitor.rb +3 -3
- data/lib/prism.rb +1 -0
- data/prism.gemspec +5 -1
- data/rbi/prism.rbi +83 -54
- data/sig/prism.rbs +47 -32
- data/src/diagnostic.c +61 -3
- data/src/enc/pm_big5.c +63 -0
- data/src/enc/pm_cp51932.c +57 -0
- data/src/enc/pm_euc_jp.c +10 -0
- data/src/enc/pm_gbk.c +5 -2
- data/src/enc/pm_tables.c +1478 -148
- data/src/node.c +33 -21
- data/src/prettyprint.c +1027 -925
- data/src/prism.c +925 -374
- data/src/regexp.c +12 -12
- data/src/serialize.c +36 -9
- metadata +6 -2
data/ext/prism/extconf.rb
CHANGED
@@ -1,136 +1,100 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
132
|
-
|
133
|
-
|
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
|
-
|
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
|
data/ext/prism/extension.c
CHANGED
@@ -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
|
4
|
+
// in libprism so it can be shared its the various callers.
|
5
5
|
|
6
6
|
VALUE rb_cPrism;
|
7
7
|
VALUE rb_cPrismNode;
|