Skip to content

Commit 3433e7a

Browse files
committed
[GR-45043] Adopt latest changes in Prism
PullRequest: truffleruby/4202
2 parents db4908a + da307a0 commit 3433e7a

39 files changed

+3245
-812
lines changed

spec/ruby/language/case_spec.rb

+13
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,19 @@ def test(v)
415415
self.test("bar").should == false
416416
self.test(true).should == true
417417
end
418+
419+
it "warns if there are identical when clauses" do
420+
-> {
421+
eval <<~RUBY
422+
case 1
423+
when 2
424+
:foo
425+
when 2
426+
:bar
427+
end
428+
RUBY
429+
}.should complain(/warning: duplicated .when' clause with line \d+ is ignored/, verbose: true)
430+
end
418431
end
419432

420433
describe "The 'case'-construct with no target expression" do

spec/ruby/language/if_spec.rb

+9
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,15 @@
305305
6.times(&b)
306306
ScratchPad.recorded.should == [4, 5, 4, 5]
307307
end
308+
309+
it "warns when Integer literals are used instead of predicates" do
310+
-> {
311+
eval <<~RUBY
312+
10.times { |i| ScratchPad << i if 4..5 }
313+
RUBY
314+
}.should complain(/warning: integer literal in flip-flop/, verbose: true)
315+
ScratchPad.recorded.should == []
316+
end
308317
end
309318

310319
describe "when a branch syntactically does not return a value" do

spec/tags/core/warning/warn_tags.txt

-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,3 @@ slow:Warning.warn has Warning as the method owner
22
slow:Warning.warn can be overridden
33
slow:Warning.warn does not add a newline
44
slow:Warning.warn returns nil
5-
fails(https://github.com/ruby/prism/issues/2005):Warning.warn is called by parser warnings

spec/tags/language/if_tags.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fails:The if expression with a boolean range ('flip-flop' operator) warns when Integer literals are used instead of predicates

spec/truffle/parsing/fixtures/case/with_expression_and_when/with_splat_operator_and_preceding_and_following_elements.yaml

+6-6
Original file line numberDiff line numberDiff line change
@@ -103,20 +103,20 @@ ast: |
103103
sourceLength = 0
104104
children:
105105
values = [
106-
StringLiteralNode
106+
FrozenStringLiteralNode
107107
attributes:
108-
encoding = UTF-8
108+
definition = expression
109109
flags = 0
110+
frozenString = bar
110111
sourceCharIndex = 31
111112
sourceLength = 5
112-
tstring = bar
113-
StringLiteralNode
113+
FrozenStringLiteralNode
114114
attributes:
115-
encoding = UTF-8
115+
definition = expression
116116
flags = 0
117+
frozenString = baz
117118
sourceCharIndex = 38
118119
sourceLength = 5
119-
tstring = baz
120120
]
121121
]
122122
ReadLocalVariableNode
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
subject: "case expression"
2+
description: "with expression to match / and String literal in when clause (case exp when 'string' ... end)"
3+
notes: >
4+
String becomes frozen and is represented as FrozenStringLiteralNode
5+
focused_on_node: "org.truffleruby.language.control.IfElseNode"
6+
ruby: |
7+
case 42
8+
when "foo"
9+
true
10+
end
11+
ast: |
12+
IfElseNodeGen
13+
attributes:
14+
flags = 0
15+
sourceCharIndex = -1
16+
sourceLength = 0
17+
children:
18+
condition =
19+
InlinedCaseEqualNodeGen
20+
attributes:
21+
assumptions = [Assumption(valid, name=set_trace_func is not used)]
22+
flags = 0
23+
integerCaseEqualAssumption = Assumption(valid, name=inlined Integer#===)
24+
parameters = RubyCallNodeParameters{methodName='===', descriptor=NoKeywordArgumentsDescriptor, isSplatted=false, ignoreVisibility=true, isVCall=false, isSafeNavigation=false, isAttrAssign=false}
25+
sourceCharIndex = -1
26+
sourceLength = 0
27+
children:
28+
leftNode_ =
29+
FrozenStringLiteralNode
30+
attributes:
31+
definition = expression
32+
flags = 0
33+
frozenString = foo
34+
sourceCharIndex = 13
35+
sourceLength = 5
36+
rightNode_ =
37+
ReadLocalVariableNode
38+
attributes:
39+
flags = 0
40+
frameSlot = 2 # %case_0
41+
sourceCharIndex = -1
42+
sourceLength = 0
43+
type = FRAME_LOCAL
44+
elseBody =
45+
NilLiteralNode
46+
attributes:
47+
flags = 0
48+
sourceCharIndex = -1
49+
sourceLength = 0
50+
thenBody =
51+
BooleanLiteralNode
52+
attributes:
53+
flags = 1
54+
sourceCharIndex = 21
55+
sourceLength = 4
56+
value = true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
subject: "case expression"
2+
description: "without expression to match / and String literal in when clause (case exp when 'string' ... end)"
3+
notes: >
4+
String becomes frozen and is represented as FrozenStringLiteralNode
5+
focused_on_node: "org.truffleruby.language.control.IfElseNode"
6+
ruby: |
7+
case
8+
when "foo"
9+
true
10+
end
11+
ast: |
12+
IfElseNodeGen
13+
attributes:
14+
flags = 1
15+
sourceCharIndex = 0
16+
sourceLength = 26
17+
children:
18+
condition =
19+
FrozenStringLiteralNode
20+
attributes:
21+
definition = expression
22+
flags = 0
23+
frozenString = foo
24+
sourceCharIndex = 10
25+
sourceLength = 5
26+
elseBody =
27+
NilLiteralNode
28+
attributes:
29+
flags = 0
30+
sourceCharIndex = -1
31+
sourceLength = 0
32+
thenBody =
33+
BooleanLiteralNode
34+
attributes:
35+
flags = 1
36+
sourceCharIndex = 18
37+
sourceLength = 4
38+
value = true

src/main/c/yarp/include/prism.h

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "prism/parser.h"
2222
#include "prism/prettyprint.h"
2323
#include "prism/regexp.h"
24+
#include "prism/static_literals.h"
2425
#include "prism/version.h"
2526

2627
#include <assert.h>

src/main/c/yarp/include/prism/ast.h

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
/* if you are looking to modify the */
66
/* template */
77
/******************************************************************************/
8+
89
/**
910
* @file ast.h
1011
*

src/main/c/yarp/include/prism/diagnostic.h

+3
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,10 @@ typedef enum {
306306
PM_WARN_AMBIGUOUS_SLASH,
307307
PM_WARN_EQUAL_IN_CONDITIONAL,
308308
PM_WARN_END_IN_METHOD,
309+
PM_WARN_DUPLICATED_HASH_KEY,
310+
PM_WARN_DUPLICATED_WHEN_CLAUSE,
309311
PM_WARN_FLOAT_OUT_OF_RANGE,
312+
PM_WARN_INTEGER_IN_FLIP_FLOP,
310313

311314
// This is the number of diagnostic codes.
312315
PM_DIAGNOSTIC_ID_LEN,

src/main/c/yarp/include/prism/node.h

+27
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@
1010
#include "prism/parser.h"
1111
#include "prism/util/pm_buffer.h"
1212

13+
/**
14+
* Attempts to grow the node list to the next size. If there is already
15+
* capacity in the list, this function does nothing. Otherwise it reallocates
16+
* the list to be twice as large as it was before. If the reallocation fails,
17+
* this function returns false, otherwise it returns true.
18+
*
19+
* @param list The list to grow.
20+
* @return True if the list was successfully grown, false otherwise.
21+
*/
22+
bool pm_node_list_grow(pm_node_list_t *list);
23+
1324
/**
1425
* Append a new node onto the end of the node list.
1526
*
@@ -18,6 +29,22 @@
1829
*/
1930
void pm_node_list_append(pm_node_list_t *list, pm_node_t *node);
2031

32+
/**
33+
* Prepend a new node onto the beginning of the node list.
34+
*
35+
* @param list The list to prepend to.
36+
* @param node The node to prepend.
37+
*/
38+
void
39+
pm_node_list_prepend(pm_node_list_t *list, pm_node_t *node);
40+
41+
/**
42+
* Free the internal memory associated with the given node list.
43+
*
44+
* @param list The list to free.
45+
*/
46+
void pm_node_list_free(pm_node_list_t *list);
47+
2148
/**
2249
* Deallocate a node and all of its children.
2350
*

src/main/c/yarp/include/prism/options.h

+52-1
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,50 @@ typedef struct {
7676
*/
7777
pm_options_version_t version;
7878

79+
/** A bitset of the various options that were set on the command line. */
80+
uint8_t command_line;
81+
7982
/** Whether or not the frozen string literal option has been set. */
8083
bool frozen_string_literal;
8184
} pm_options_t;
8285

86+
/**
87+
* A bit representing whether or not the command line -a option was set. -a
88+
* splits the input line $_ into $F.
89+
*/
90+
static const uint8_t PM_OPTIONS_COMMAND_LINE_A = 0x1;
91+
92+
/**
93+
* A bit representing whether or not the command line -e option was set. -e
94+
* allow the user to specify a script to be executed. This is necessary for
95+
* prism to know because certain warnings are not generated when -e is used.
96+
*/
97+
static const uint8_t PM_OPTIONS_COMMAND_LINE_E = 0x2;
98+
99+
/**
100+
* A bit representing whether or not the command line -l option was set. -l
101+
* chomps the input line by default.
102+
*/
103+
static const uint8_t PM_OPTIONS_COMMAND_LINE_L = 0x4;
104+
105+
/**
106+
* A bit representing whether or not the command line -n option was set. -n
107+
* wraps the script in a while gets loop.
108+
*/
109+
static const uint8_t PM_OPTIONS_COMMAND_LINE_N = 0x8;
110+
111+
/**
112+
* A bit representing whether or not the command line -p option was set. -p
113+
* prints the value of $_ at the end of each loop.
114+
*/
115+
static const uint8_t PM_OPTIONS_COMMAND_LINE_P = 0x10;
116+
117+
/**
118+
* A bit representing whether or not the command line -x option was set. -x
119+
* searches the input file for a shebang that matches the current Ruby engine.
120+
*/
121+
static const uint8_t PM_OPTIONS_COMMAND_LINE_X = 0x20;
122+
83123
/**
84124
* Set the filepath option on the given options struct.
85125
*
@@ -112,6 +152,14 @@ PRISM_EXPORTED_FUNCTION void pm_options_encoding_set(pm_options_t *options, cons
112152
*/
113153
PRISM_EXPORTED_FUNCTION void pm_options_frozen_string_literal_set(pm_options_t *options, bool frozen_string_literal);
114154

155+
/**
156+
* Sets the command line option on the given options struct.
157+
*
158+
* @param options The options struct to set the command line option on.
159+
* @param command_line The command_line value to set.
160+
*/
161+
PRISM_EXPORTED_FUNCTION void pm_options_command_line_set(pm_options_t *options, uint8_t command_line);
162+
115163
/**
116164
* Set the version option on the given options struct by parsing the given
117165
* string. If the string contains an invalid option, this returns false.
@@ -186,7 +234,10 @@ PRISM_EXPORTED_FUNCTION void pm_options_free(pm_options_t *options);
186234
* | `4` | the length the encoding |
187235
* | ... | the encoding bytes |
188236
* | `1` | frozen string literal |
189-
* | `1` | suppress warnings |
237+
* | `1` | -p command line option |
238+
* | `1` | -n command line option |
239+
* | `1` | -l command line option |
240+
* | `1` | -a command line option |
190241
* | `1` | the version |
191242
* | `4` | the number of scopes |
192243
* | ... | the scopes |

src/main/c/yarp/include/prism/parser.h

+3
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,9 @@ struct pm_parser {
703703
/** The version of prism that we should use to parse. */
704704
pm_options_version_t version;
705705

706+
/** The command line flags given from the options. */
707+
uint8_t command_line;
708+
706709
/** Whether or not we're at the beginning of a command. */
707710
bool command_start;
708711

0 commit comments

Comments
 (0)