diff --git a/snapshots/3.3-3.3/block_args_in_array_assignment.txt b/snapshots/3.3-3.3/block_args_in_array_assignment.txt new file mode 100644 index 0000000000..03327a51f6 --- /dev/null +++ b/snapshots/3.3-3.3/block_args_in_array_assignment.txt @@ -0,0 +1,50 @@ +@ ProgramNode (location: (1,0)-(1,21)) +├── flags: ∅ +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,21)) + ├── flags: ∅ + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,21)) + ├── flags: newline, attribute_write + ├── receiver: + │ @ CallNode (location: (1,0)-(1,6)) + │ ├── flags: variable_call, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :matrix + │ ├── message_loc: (1,0)-(1,6) = "matrix" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: ∅ + ├── call_operator_loc: ∅ + ├── name: :[]= + ├── message_loc: (1,6)-(1,17) = "[5, &block]" + ├── opening_loc: (1,6)-(1,7) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,7)-(1,21)) + │ ├── flags: ∅ + │ └── arguments: (length: 2) + │ ├── @ IntegerNode (location: (1,7)-(1,8)) + │ │ ├── flags: static_literal, decimal + │ │ └── value: 5 + │ └── @ IntegerNode (location: (1,20)-(1,21)) + │ ├── flags: static_literal, decimal + │ └── value: 8 + ├── closing_loc: (1,16)-(1,17) = "]" + └── block: + @ BlockArgumentNode (location: (1,10)-(1,16)) + ├── flags: ∅ + ├── expression: + │ @ CallNode (location: (1,11)-(1,16)) + │ ├── flags: variable_call, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :block + │ ├── message_loc: (1,11)-(1,16) = "block" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: ∅ + └── operator_loc: (1,10)-(1,11) = "&" diff --git a/snapshots/3.3-3.3/it.txt b/snapshots/3.3-3.3/it.txt new file mode 100644 index 0000000000..a8a8d521c0 --- /dev/null +++ b/snapshots/3.3-3.3/it.txt @@ -0,0 +1,58 @@ +@ ProgramNode (location: (1,0)-(5,9)) +├── flags: ∅ +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,9)) + ├── flags: ∅ + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(3,3)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :x + │ ├── message_loc: (1,0)-(1,1) = "x" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: + │ @ BlockNode (location: (1,2)-(3,3)) + │ ├── flags: ∅ + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (2,2)-(2,4)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (2,2)-(2,4)) + │ │ ├── flags: newline, variable_call, ignore_visibility + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── name: :it + │ │ ├── message_loc: (2,2)-(2,4) = "it" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ └── block: ∅ + │ ├── opening_loc: (1,2)-(1,4) = "do" + │ └── closing_loc: (3,0)-(3,3) = "end" + └── @ LambdaNode (location: (5,0)-(5,9)) + ├── flags: newline + ├── locals: [] + ├── operator_loc: (5,0)-(5,2) = "->" + ├── opening_loc: (5,3)-(5,4) = "{" + ├── closing_loc: (5,8)-(5,9) = "}" + ├── parameters: ∅ + └── body: + @ StatementsNode (location: (5,5)-(5,7)) + ├── flags: ∅ + └── body: (length: 1) + └── @ CallNode (location: (5,5)-(5,7)) + ├── flags: newline, variable_call, ignore_visibility + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── name: :it + ├── message_loc: (5,5)-(5,7) = "it" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + └── block: ∅ diff --git a/snapshots/3.3-3.3/it_indirect_writes.txt b/snapshots/3.3-3.3/it_indirect_writes.txt new file mode 100644 index 0000000000..918eca9a37 --- /dev/null +++ b/snapshots/3.3-3.3/it_indirect_writes.txt @@ -0,0 +1,455 @@ +@ ProgramNode (location: (1,0)-(23,24)) +├── flags: ∅ +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(23,24)) + ├── flags: ∅ + └── body: (length: 12) + ├── @ CallNode (location: (1,0)-(1,15)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :tap + │ ├── message_loc: (1,0)-(1,3) = "tap" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: + │ @ BlockNode (location: (1,4)-(1,15)) + │ ├── flags: ∅ + │ ├── locals: [:it] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (1,6)-(1,13)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 1) + │ │ └── @ LocalVariableOperatorWriteNode (location: (1,6)-(1,13)) + │ │ ├── flags: newline + │ │ ├── name_loc: (1,6)-(1,8) = "it" + │ │ ├── binary_operator_loc: (1,9)-(1,11) = "+=" + │ │ ├── value: + │ │ │ @ IntegerNode (location: (1,12)-(1,13)) + │ │ │ ├── flags: static_literal, decimal + │ │ │ └── value: 1 + │ │ ├── name: :it + │ │ ├── binary_operator: :+ + │ │ └── depth: 0 + │ ├── opening_loc: (1,4)-(1,5) = "{" + │ └── closing_loc: (1,14)-(1,15) = "}" + ├── @ CallNode (location: (3,0)-(3,16)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :tap + │ ├── message_loc: (3,0)-(3,3) = "tap" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: + │ @ BlockNode (location: (3,4)-(3,16)) + │ ├── flags: ∅ + │ ├── locals: [:it] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (3,6)-(3,14)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 1) + │ │ └── @ LocalVariableOrWriteNode (location: (3,6)-(3,14)) + │ │ ├── flags: newline + │ │ ├── name_loc: (3,6)-(3,8) = "it" + │ │ ├── operator_loc: (3,9)-(3,12) = "||=" + │ │ ├── value: + │ │ │ @ IntegerNode (location: (3,13)-(3,14)) + │ │ │ ├── flags: static_literal, decimal + │ │ │ └── value: 1 + │ │ ├── name: :it + │ │ └── depth: 0 + │ ├── opening_loc: (3,4)-(3,5) = "{" + │ └── closing_loc: (3,15)-(3,16) = "}" + ├── @ CallNode (location: (5,0)-(5,16)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :tap + │ ├── message_loc: (5,0)-(5,3) = "tap" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: + │ @ BlockNode (location: (5,4)-(5,16)) + │ ├── flags: ∅ + │ ├── locals: [:it] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (5,6)-(5,14)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 1) + │ │ └── @ LocalVariableAndWriteNode (location: (5,6)-(5,14)) + │ │ ├── flags: newline + │ │ ├── name_loc: (5,6)-(5,8) = "it" + │ │ ├── operator_loc: (5,9)-(5,12) = "&&=" + │ │ ├── value: + │ │ │ @ IntegerNode (location: (5,13)-(5,14)) + │ │ │ ├── flags: static_literal, decimal + │ │ │ └── value: 1 + │ │ ├── name: :it + │ │ └── depth: 0 + │ ├── opening_loc: (5,4)-(5,5) = "{" + │ └── closing_loc: (5,15)-(5,16) = "}" + ├── @ CallNode (location: (7,0)-(7,19)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :tap + │ ├── message_loc: (7,0)-(7,3) = "tap" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: + │ @ BlockNode (location: (7,4)-(7,19)) + │ ├── flags: ∅ + │ ├── locals: [:it] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (7,6)-(7,17)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 2) + │ │ ├── @ CallNode (location: (7,6)-(7,8)) + │ │ │ ├── flags: newline, variable_call, ignore_visibility + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── name: :it + │ │ │ ├── message_loc: (7,6)-(7,8) = "it" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ └── block: ∅ + │ │ └── @ LocalVariableOperatorWriteNode (location: (7,10)-(7,17)) + │ │ ├── flags: newline + │ │ ├── name_loc: (7,10)-(7,12) = "it" + │ │ ├── binary_operator_loc: (7,13)-(7,15) = "+=" + │ │ ├── value: + │ │ │ @ IntegerNode (location: (7,16)-(7,17)) + │ │ │ ├── flags: static_literal, decimal + │ │ │ └── value: 1 + │ │ ├── name: :it + │ │ ├── binary_operator: :+ + │ │ └── depth: 0 + │ ├── opening_loc: (7,4)-(7,5) = "{" + │ └── closing_loc: (7,18)-(7,19) = "}" + ├── @ CallNode (location: (9,0)-(9,20)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :tap + │ ├── message_loc: (9,0)-(9,3) = "tap" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: + │ @ BlockNode (location: (9,4)-(9,20)) + │ ├── flags: ∅ + │ ├── locals: [:it] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (9,6)-(9,18)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 2) + │ │ ├── @ CallNode (location: (9,6)-(9,8)) + │ │ │ ├── flags: newline, variable_call, ignore_visibility + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── name: :it + │ │ │ ├── message_loc: (9,6)-(9,8) = "it" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ └── block: ∅ + │ │ └── @ LocalVariableOrWriteNode (location: (9,10)-(9,18)) + │ │ ├── flags: newline + │ │ ├── name_loc: (9,10)-(9,12) = "it" + │ │ ├── operator_loc: (9,13)-(9,16) = "||=" + │ │ ├── value: + │ │ │ @ IntegerNode (location: (9,17)-(9,18)) + │ │ │ ├── flags: static_literal, decimal + │ │ │ └── value: 1 + │ │ ├── name: :it + │ │ └── depth: 0 + │ ├── opening_loc: (9,4)-(9,5) = "{" + │ └── closing_loc: (9,19)-(9,20) = "}" + ├── @ CallNode (location: (11,0)-(11,20)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :tap + │ ├── message_loc: (11,0)-(11,3) = "tap" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: + │ @ BlockNode (location: (11,4)-(11,20)) + │ ├── flags: ∅ + │ ├── locals: [:it] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (11,6)-(11,18)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 2) + │ │ ├── @ CallNode (location: (11,6)-(11,8)) + │ │ │ ├── flags: newline, variable_call, ignore_visibility + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── name: :it + │ │ │ ├── message_loc: (11,6)-(11,8) = "it" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ └── block: ∅ + │ │ └── @ LocalVariableAndWriteNode (location: (11,10)-(11,18)) + │ │ ├── flags: newline + │ │ ├── name_loc: (11,10)-(11,12) = "it" + │ │ ├── operator_loc: (11,13)-(11,16) = "&&=" + │ │ ├── value: + │ │ │ @ IntegerNode (location: (11,17)-(11,18)) + │ │ │ ├── flags: static_literal, decimal + │ │ │ └── value: 1 + │ │ ├── name: :it + │ │ └── depth: 0 + │ ├── opening_loc: (11,4)-(11,5) = "{" + │ └── closing_loc: (11,19)-(11,20) = "}" + ├── @ CallNode (location: (13,0)-(13,19)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :tap + │ ├── message_loc: (13,0)-(13,3) = "tap" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: + │ @ BlockNode (location: (13,4)-(13,19)) + │ ├── flags: ∅ + │ ├── locals: [:it] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (13,6)-(13,17)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 2) + │ │ ├── @ LocalVariableOperatorWriteNode (location: (13,6)-(13,13)) + │ │ │ ├── flags: newline + │ │ │ ├── name_loc: (13,6)-(13,8) = "it" + │ │ │ ├── binary_operator_loc: (13,9)-(13,11) = "+=" + │ │ │ ├── value: + │ │ │ │ @ IntegerNode (location: (13,12)-(13,13)) + │ │ │ │ ├── flags: static_literal, decimal + │ │ │ │ └── value: 1 + │ │ │ ├── name: :it + │ │ │ ├── binary_operator: :+ + │ │ │ └── depth: 0 + │ │ └── @ LocalVariableReadNode (location: (13,15)-(13,17)) + │ │ ├── flags: newline + │ │ ├── name: :it + │ │ └── depth: 0 + │ ├── opening_loc: (13,4)-(13,5) = "{" + │ └── closing_loc: (13,18)-(13,19) = "}" + ├── @ CallNode (location: (15,0)-(15,20)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :tap + │ ├── message_loc: (15,0)-(15,3) = "tap" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: + │ @ BlockNode (location: (15,4)-(15,20)) + │ ├── flags: ∅ + │ ├── locals: [:it] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (15,6)-(15,18)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 2) + │ │ ├── @ LocalVariableOrWriteNode (location: (15,6)-(15,14)) + │ │ │ ├── flags: newline + │ │ │ ├── name_loc: (15,6)-(15,8) = "it" + │ │ │ ├── operator_loc: (15,9)-(15,12) = "||=" + │ │ │ ├── value: + │ │ │ │ @ IntegerNode (location: (15,13)-(15,14)) + │ │ │ │ ├── flags: static_literal, decimal + │ │ │ │ └── value: 1 + │ │ │ ├── name: :it + │ │ │ └── depth: 0 + │ │ └── @ LocalVariableReadNode (location: (15,16)-(15,18)) + │ │ ├── flags: newline + │ │ ├── name: :it + │ │ └── depth: 0 + │ ├── opening_loc: (15,4)-(15,5) = "{" + │ └── closing_loc: (15,19)-(15,20) = "}" + ├── @ CallNode (location: (17,0)-(17,20)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :tap + │ ├── message_loc: (17,0)-(17,3) = "tap" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: + │ @ BlockNode (location: (17,4)-(17,20)) + │ ├── flags: ∅ + │ ├── locals: [:it] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (17,6)-(17,18)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 2) + │ │ ├── @ LocalVariableAndWriteNode (location: (17,6)-(17,14)) + │ │ │ ├── flags: newline + │ │ │ ├── name_loc: (17,6)-(17,8) = "it" + │ │ │ ├── operator_loc: (17,9)-(17,12) = "&&=" + │ │ │ ├── value: + │ │ │ │ @ IntegerNode (location: (17,13)-(17,14)) + │ │ │ │ ├── flags: static_literal, decimal + │ │ │ │ └── value: 1 + │ │ │ ├── name: :it + │ │ │ └── depth: 0 + │ │ └── @ LocalVariableReadNode (location: (17,16)-(17,18)) + │ │ ├── flags: newline + │ │ ├── name: :it + │ │ └── depth: 0 + │ ├── opening_loc: (17,4)-(17,5) = "{" + │ └── closing_loc: (17,19)-(17,20) = "}" + ├── @ CallNode (location: (19,0)-(19,23)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :tap + │ ├── message_loc: (19,0)-(19,3) = "tap" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: + │ @ BlockNode (location: (19,4)-(19,23)) + │ ├── flags: ∅ + │ ├── locals: [:it] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (19,6)-(19,21)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 3) + │ │ ├── @ CallNode (location: (19,6)-(19,8)) + │ │ │ ├── flags: newline, variable_call, ignore_visibility + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── name: :it + │ │ │ ├── message_loc: (19,6)-(19,8) = "it" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ └── block: ∅ + │ │ ├── @ LocalVariableOperatorWriteNode (location: (19,10)-(19,17)) + │ │ │ ├── flags: newline + │ │ │ ├── name_loc: (19,10)-(19,12) = "it" + │ │ │ ├── binary_operator_loc: (19,13)-(19,15) = "+=" + │ │ │ ├── value: + │ │ │ │ @ IntegerNode (location: (19,16)-(19,17)) + │ │ │ │ ├── flags: static_literal, decimal + │ │ │ │ └── value: 1 + │ │ │ ├── name: :it + │ │ │ ├── binary_operator: :+ + │ │ │ └── depth: 0 + │ │ └── @ LocalVariableReadNode (location: (19,19)-(19,21)) + │ │ ├── flags: newline + │ │ ├── name: :it + │ │ └── depth: 0 + │ ├── opening_loc: (19,4)-(19,5) = "{" + │ └── closing_loc: (19,22)-(19,23) = "}" + ├── @ CallNode (location: (21,0)-(21,24)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :tap + │ ├── message_loc: (21,0)-(21,3) = "tap" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: + │ @ BlockNode (location: (21,4)-(21,24)) + │ ├── flags: ∅ + │ ├── locals: [:it] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (21,6)-(21,22)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 3) + │ │ ├── @ CallNode (location: (21,6)-(21,8)) + │ │ │ ├── flags: newline, variable_call, ignore_visibility + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── name: :it + │ │ │ ├── message_loc: (21,6)-(21,8) = "it" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ └── block: ∅ + │ │ ├── @ LocalVariableOrWriteNode (location: (21,10)-(21,18)) + │ │ │ ├── flags: newline + │ │ │ ├── name_loc: (21,10)-(21,12) = "it" + │ │ │ ├── operator_loc: (21,13)-(21,16) = "||=" + │ │ │ ├── value: + │ │ │ │ @ IntegerNode (location: (21,17)-(21,18)) + │ │ │ │ ├── flags: static_literal, decimal + │ │ │ │ └── value: 1 + │ │ │ ├── name: :it + │ │ │ └── depth: 0 + │ │ └── @ LocalVariableReadNode (location: (21,20)-(21,22)) + │ │ ├── flags: newline + │ │ ├── name: :it + │ │ └── depth: 0 + │ ├── opening_loc: (21,4)-(21,5) = "{" + │ └── closing_loc: (21,23)-(21,24) = "}" + └── @ CallNode (location: (23,0)-(23,24)) + ├── flags: newline, ignore_visibility + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── name: :tap + ├── message_loc: (23,0)-(23,3) = "tap" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + └── block: + @ BlockNode (location: (23,4)-(23,24)) + ├── flags: ∅ + ├── locals: [:it] + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (23,6)-(23,22)) + │ ├── flags: ∅ + │ └── body: (length: 3) + │ ├── @ CallNode (location: (23,6)-(23,8)) + │ │ ├── flags: newline, variable_call, ignore_visibility + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── name: :it + │ │ ├── message_loc: (23,6)-(23,8) = "it" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ └── block: ∅ + │ ├── @ LocalVariableAndWriteNode (location: (23,10)-(23,18)) + │ │ ├── flags: newline + │ │ ├── name_loc: (23,10)-(23,12) = "it" + │ │ ├── operator_loc: (23,13)-(23,16) = "&&=" + │ │ ├── value: + │ │ │ @ IntegerNode (location: (23,17)-(23,18)) + │ │ │ ├── flags: static_literal, decimal + │ │ │ └── value: 1 + │ │ ├── name: :it + │ │ └── depth: 0 + │ └── @ LocalVariableReadNode (location: (23,20)-(23,22)) + │ ├── flags: newline + │ ├── name: :it + │ └── depth: 0 + ├── opening_loc: (23,4)-(23,5) = "{" + └── closing_loc: (23,23)-(23,24) = "}" diff --git a/snapshots/3.3-3.3/it_read_and_assignment.txt b/snapshots/3.3-3.3/it_read_and_assignment.txt new file mode 100644 index 0000000000..d30b9c2902 --- /dev/null +++ b/snapshots/3.3-3.3/it_read_and_assignment.txt @@ -0,0 +1,81 @@ +@ ProgramNode (location: (1,0)-(1,30)) +├── flags: ∅ +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,30)) + ├── flags: ∅ + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,30)) + ├── flags: newline + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,2)) + │ ├── flags: static_literal, decimal + │ └── value: 42 + ├── call_operator_loc: (1,2)-(1,3) = "." + ├── name: :tap + ├── message_loc: (1,3)-(1,6) = "tap" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + └── block: + @ BlockNode (location: (1,7)-(1,30)) + ├── flags: ∅ + ├── locals: [:it] + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (1,9)-(1,28)) + │ ├── flags: ∅ + │ └── body: (length: 3) + │ ├── @ CallNode (location: (1,9)-(1,13)) + │ │ ├── flags: newline, ignore_visibility + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── name: :p + │ │ ├── message_loc: (1,9)-(1,10) = "p" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (1,11)-(1,13)) + │ │ │ ├── flags: ∅ + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (1,11)-(1,13)) + │ │ │ ├── flags: variable_call, ignore_visibility + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── name: :it + │ │ │ ├── message_loc: (1,11)-(1,13) = "it" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ └── block: ∅ + │ │ ├── closing_loc: ∅ + │ │ └── block: ∅ + │ ├── @ LocalVariableWriteNode (location: (1,15)-(1,22)) + │ │ ├── flags: newline + │ │ ├── name: :it + │ │ ├── depth: 0 + │ │ ├── name_loc: (1,15)-(1,17) = "it" + │ │ ├── value: + │ │ │ @ LocalVariableReadNode (location: (1,20)-(1,22)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :it + │ │ │ └── depth: 0 + │ │ └── operator_loc: (1,18)-(1,19) = "=" + │ └── @ CallNode (location: (1,24)-(1,28)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :p + │ ├── message_loc: (1,24)-(1,25) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,26)-(1,28)) + │ │ ├── flags: ∅ + │ │ └── arguments: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (1,26)-(1,28)) + │ │ ├── flags: ∅ + │ │ ├── name: :it + │ │ └── depth: 0 + │ ├── closing_loc: ∅ + │ └── block: ∅ + ├── opening_loc: (1,7)-(1,8) = "{" + └── closing_loc: (1,29)-(1,30) = "}" diff --git a/snapshots/3.3-3.3/it_with_ordinary_parameter.txt b/snapshots/3.3-3.3/it_with_ordinary_parameter.txt new file mode 100644 index 0000000000..ab3178de33 --- /dev/null +++ b/snapshots/3.3-3.3/it_with_ordinary_parameter.txt @@ -0,0 +1,43 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── flags: ∅ +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + ├── flags: ∅ + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,14)) + ├── flags: newline, ignore_visibility + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── name: :proc + ├── message_loc: (1,0)-(1,4) = "proc" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + └── block: + @ BlockNode (location: (1,5)-(1,14)) + ├── flags: ∅ + ├── locals: [] + ├── parameters: + │ @ BlockParametersNode (location: (1,7)-(1,9)) + │ ├── flags: ∅ + │ ├── parameters: ∅ + │ ├── locals: (length: 0) + │ ├── opening_loc: (1,7)-(1,8) = "|" + │ └── closing_loc: (1,8)-(1,9) = "|" + ├── body: + │ @ StatementsNode (location: (1,10)-(1,12)) + │ ├── flags: ∅ + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,10)-(1,12)) + │ ├── flags: newline, variable_call, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :it + │ ├── message_loc: (1,10)-(1,12) = "it" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: ∅ + ├── opening_loc: (1,5)-(1,6) = "{" + └── closing_loc: (1,13)-(1,14) = "}" diff --git a/snapshots/3.3-3.3/keyword_args_in_array_assignment.txt b/snapshots/3.3-3.3/keyword_args_in_array_assignment.txt new file mode 100644 index 0000000000..785542a3e5 --- /dev/null +++ b/snapshots/3.3-3.3/keyword_args_in_array_assignment.txt @@ -0,0 +1,56 @@ +@ ProgramNode (location: (1,0)-(1,23)) +├── flags: ∅ +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,23)) + ├── flags: ∅ + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,23)) + ├── flags: newline, attribute_write + ├── receiver: + │ @ CallNode (location: (1,0)-(1,6)) + │ ├── flags: variable_call, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :matrix + │ ├── message_loc: (1,0)-(1,6) = "matrix" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: ∅ + ├── call_operator_loc: ∅ + ├── name: :[]= + ├── message_loc: (1,6)-(1,19) = "[5, axis: :y]" + ├── opening_loc: (1,6)-(1,7) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,7)-(1,23)) + │ ├── flags: contains_keywords + │ └── arguments: (length: 3) + │ ├── @ IntegerNode (location: (1,7)-(1,8)) + │ │ ├── flags: static_literal, decimal + │ │ └── value: 5 + │ ├── @ KeywordHashNode (location: (1,10)-(1,18)) + │ │ ├── flags: symbol_keys + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (1,10)-(1,18)) + │ │ ├── flags: static_literal + │ │ ├── key: + │ │ │ @ SymbolNode (location: (1,10)-(1,15)) + │ │ │ ├── flags: static_literal, forced_us_ascii_encoding + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (1,10)-(1,14) = "axis" + │ │ │ ├── closing_loc: (1,14)-(1,15) = ":" + │ │ │ └── unescaped: "axis" + │ │ ├── value: + │ │ │ @ SymbolNode (location: (1,16)-(1,18)) + │ │ │ ├── flags: static_literal, forced_us_ascii_encoding + │ │ │ ├── opening_loc: (1,16)-(1,17) = ":" + │ │ │ ├── value_loc: (1,17)-(1,18) = "y" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "y" + │ │ └── operator_loc: ∅ + │ └── @ IntegerNode (location: (1,22)-(1,23)) + │ ├── flags: static_literal, decimal + │ └── value: 8 + ├── closing_loc: (1,18)-(1,19) = "]" + └── block: ∅ diff --git a/snapshots/3.3-3.3/return_in_sclass.txt b/snapshots/3.3-3.3/return_in_sclass.txt new file mode 100644 index 0000000000..d8f298b23a --- /dev/null +++ b/snapshots/3.3-3.3/return_in_sclass.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(1,23)) +├── flags: ∅ +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,23)) + ├── flags: ∅ + └── body: (length: 1) + └── @ SingletonClassNode (location: (1,0)-(1,23)) + ├── flags: newline + ├── locals: [] + ├── class_keyword_loc: (1,0)-(1,5) = "class" + ├── operator_loc: (1,6)-(1,8) = "<<" + ├── expression: + │ @ ConstantReadNode (location: (1,9)-(1,10)) + │ ├── flags: ∅ + │ └── name: :A + ├── body: + │ @ StatementsNode (location: (1,12)-(1,18)) + │ ├── flags: ∅ + │ └── body: (length: 1) + │ └── @ ReturnNode (location: (1,12)-(1,18)) + │ ├── flags: newline + │ ├── keyword_loc: (1,12)-(1,18) = "return" + │ └── arguments: ∅ + └── end_keyword_loc: (1,20)-(1,23) = "end" diff --git a/snapshots/3.4/circular_parameters.txt b/snapshots/3.4/circular_parameters.txt new file mode 100644 index 0000000000..3e74882f6c --- /dev/null +++ b/snapshots/3.4/circular_parameters.txt @@ -0,0 +1,167 @@ +@ ProgramNode (location: (1,0)-(4,19)) +├── flags: ∅ +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,19)) + ├── flags: ∅ + └── body: (length: 4) + ├── @ DefNode (location: (1,0)-(1,23)) + │ ├── flags: newline + │ ├── name: :foo + │ ├── name_loc: (1,4)-(1,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (1,8)-(1,17)) + │ │ ├── flags: ∅ + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 1) + │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,17)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :bar + │ │ │ ├── name_loc: (1,8)-(1,11) = "bar" + │ │ │ ├── operator_loc: (1,12)-(1,13) = "=" + │ │ │ └── value: + │ │ │ @ LocalVariableReadNode (location: (1,14)-(1,17)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :bar + │ │ │ └── depth: 0 + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (1,21)-(1,23)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 1) + │ │ └── @ IntegerNode (location: (1,21)-(1,23)) + │ │ ├── flags: static_literal, decimal + │ │ └── value: 42 + │ ├── locals: [:bar] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (1,7)-(1,8) = "(" + │ ├── rparen_loc: (1,17)-(1,18) = ")" + │ ├── equal_loc: (1,19)-(1,20) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (2,0)-(2,22)) + │ ├── flags: newline + │ ├── name: :foo + │ ├── name_loc: (2,4)-(2,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (2,8)-(2,16)) + │ │ ├── flags: ∅ + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 1) + │ │ │ └── @ OptionalKeywordParameterNode (location: (2,8)-(2,16)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :bar + │ │ │ ├── name_loc: (2,8)-(2,12) = "bar:" + │ │ │ └── value: + │ │ │ @ LocalVariableReadNode (location: (2,13)-(2,16)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :bar + │ │ │ └── depth: 0 + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (2,20)-(2,22)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 1) + │ │ └── @ IntegerNode (location: (2,20)-(2,22)) + │ │ ├── flags: static_literal, decimal + │ │ └── value: 42 + │ ├── locals: [:bar] + │ ├── def_keyword_loc: (2,0)-(2,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (2,7)-(2,8) = "(" + │ ├── rparen_loc: (2,16)-(2,17) = ")" + │ ├── equal_loc: (2,18)-(2,19) = "=" + │ └── end_keyword_loc: ∅ + ├── @ CallNode (location: (3,0)-(3,20)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :proc + │ ├── message_loc: (3,0)-(3,4) = "proc" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: + │ @ BlockNode (location: (3,5)-(3,20)) + │ ├── flags: ∅ + │ ├── locals: [:foo] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (3,7)-(3,18)) + │ │ ├── flags: ∅ + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (3,8)-(3,17)) + │ │ │ ├── flags: ∅ + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 1) + │ │ │ │ └── @ OptionalParameterNode (location: (3,8)-(3,17)) + │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── name: :foo + │ │ │ │ ├── name_loc: (3,8)-(3,11) = "foo" + │ │ │ │ ├── operator_loc: (3,12)-(3,13) = "=" + │ │ │ │ └── value: + │ │ │ │ @ LocalVariableReadNode (location: (3,14)-(3,17)) + │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── name: :foo + │ │ │ │ └── depth: 0 + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 0) + │ │ │ ├── keyword_rest: ∅ + │ │ │ └── block: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: (3,7)-(3,8) = "|" + │ │ └── closing_loc: (3,17)-(3,18) = "|" + │ ├── body: ∅ + │ ├── opening_loc: (3,5)-(3,6) = "{" + │ └── closing_loc: (3,19)-(3,20) = "}" + └── @ CallNode (location: (4,0)-(4,19)) + ├── flags: newline, ignore_visibility + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── name: :proc + ├── message_loc: (4,0)-(4,4) = "proc" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + └── block: + @ BlockNode (location: (4,5)-(4,19)) + ├── flags: ∅ + ├── locals: [:foo] + ├── parameters: + │ @ BlockParametersNode (location: (4,7)-(4,17)) + │ ├── flags: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (4,8)-(4,16)) + │ │ ├── flags: ∅ + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 1) + │ │ │ └── @ OptionalKeywordParameterNode (location: (4,8)-(4,16)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :foo + │ │ │ ├── name_loc: (4,8)-(4,12) = "foo:" + │ │ │ └── value: + │ │ │ @ LocalVariableReadNode (location: (4,13)-(4,16)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :foo + │ │ │ └── depth: 0 + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── locals: (length: 0) + │ ├── opening_loc: (4,7)-(4,8) = "|" + │ └── closing_loc: (4,16)-(4,17) = "|" + ├── body: ∅ + ├── opening_loc: (4,5)-(4,6) = "{" + └── closing_loc: (4,18)-(4,19) = "}" diff --git a/snapshots/it.txt b/snapshots/3.4/it.txt similarity index 100% rename from snapshots/it.txt rename to snapshots/3.4/it.txt diff --git a/snapshots/3.4/it_assignment.txt b/snapshots/3.4/it_assignment.txt new file mode 100644 index 0000000000..83469791c0 --- /dev/null +++ b/snapshots/3.4/it_assignment.txt @@ -0,0 +1,58 @@ +@ ProgramNode (location: (1,0)-(1,24)) +├── flags: ∅ +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,24)) + ├── flags: ∅ + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,24)) + ├── flags: newline + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,2)) + │ ├── flags: static_literal, decimal + │ └── value: 42 + ├── call_operator_loc: (1,2)-(1,3) = "." + ├── name: :tap + ├── message_loc: (1,3)-(1,6) = "tap" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + └── block: + @ BlockNode (location: (1,7)-(1,24)) + ├── flags: ∅ + ├── locals: [:it] + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (1,9)-(1,22)) + │ ├── flags: ∅ + │ └── body: (length: 2) + │ ├── @ LocalVariableWriteNode (location: (1,9)-(1,16)) + │ │ ├── flags: newline + │ │ ├── name: :it + │ │ ├── depth: 0 + │ │ ├── name_loc: (1,9)-(1,11) = "it" + │ │ ├── value: + │ │ │ @ LocalVariableReadNode (location: (1,14)-(1,16)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :it + │ │ │ └── depth: 0 + │ │ └── operator_loc: (1,12)-(1,13) = "=" + │ └── @ CallNode (location: (1,18)-(1,22)) + │ ├── flags: newline, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :p + │ ├── message_loc: (1,18)-(1,19) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,20)-(1,22)) + │ │ ├── flags: ∅ + │ │ └── arguments: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (1,20)-(1,22)) + │ │ ├── flags: ∅ + │ │ ├── name: :it + │ │ └── depth: 0 + │ ├── closing_loc: ∅ + │ └── block: ∅ + ├── opening_loc: (1,7)-(1,8) = "{" + └── closing_loc: (1,23)-(1,24) = "}" diff --git a/snapshots/it_indirect_writes.txt b/snapshots/3.4/it_indirect_writes.txt similarity index 100% rename from snapshots/it_indirect_writes.txt rename to snapshots/3.4/it_indirect_writes.txt diff --git a/snapshots/it_read_and_assignment.txt b/snapshots/3.4/it_read_and_assignment.txt similarity index 100% rename from snapshots/it_read_and_assignment.txt rename to snapshots/3.4/it_read_and_assignment.txt diff --git a/snapshots/endless_methods_command_call.txt b/snapshots/3.5/endless_methods_command_call.txt similarity index 100% rename from snapshots/endless_methods_command_call.txt rename to snapshots/3.5/endless_methods_command_call.txt diff --git a/snapshots/leading_logical.txt b/snapshots/3.5/leading_logical.txt similarity index 100% rename from snapshots/leading_logical.txt rename to snapshots/3.5/leading_logical.txt diff --git a/src/prism.c b/src/prism.c index 0ebcae62f9..95e7d09050 100644 --- a/src/prism.c +++ b/src/prism.c @@ -15764,7 +15764,7 @@ parse_return(pm_parser_t *parser, pm_node_t *node) { break; } } - if (in_sclass) { + if (in_sclass && parser->version >= PM_OPTIONS_VERSION_CRUBY_3_4) { pm_parser_err_node(parser, node, PM_ERR_RETURN_INVALID); } } diff --git a/test/prism/errors/3.3-3.3/circular_parameters.txt b/test/prism/errors/3.3-3.3/circular_parameters.txt new file mode 100644 index 0000000000..ef9642b075 --- /dev/null +++ b/test/prism/errors/3.3-3.3/circular_parameters.txt @@ -0,0 +1,12 @@ +def foo(bar = bar) = 42 + ^~~ circular argument reference - bar + +def foo(bar: bar) = 42 + ^~~ circular argument reference - bar + +proc { |foo = foo| } + ^~~ circular argument reference - foo + +proc { |foo: foo| } + ^~~ circular argument reference - foo + diff --git a/test/prism/errors/3.3-3.4/leading_logical.txt b/test/prism/errors/3.3-3.4/leading_logical.txt new file mode 100644 index 0000000000..2a702e281d --- /dev/null +++ b/test/prism/errors/3.3-3.4/leading_logical.txt @@ -0,0 +1,34 @@ +1 +&& 2 +^~ unexpected '&&', ignoring it +&& 3 +^~ unexpected '&&', ignoring it + +1 +|| 2 +^ unexpected '|', ignoring it + ^ unexpected '|', ignoring it +|| 3 +^ unexpected '|', ignoring it + ^ unexpected '|', ignoring it + +1 +and 2 +^~~ unexpected 'and', ignoring it +and 3 +^~~ unexpected 'and', ignoring it + +1 +or 2 +^~ unexpected 'or', ignoring it +or 3 +^~ unexpected 'or', ignoring it + +1 +and foo +^~~ unexpected 'and', ignoring it + +2 +or foo +^~ unexpected 'or', ignoring it + diff --git a/test/prism/errors/3.3-3.4/private_endless_method.txt b/test/prism/errors/3.3-3.4/private_endless_method.txt new file mode 100644 index 0000000000..8aae5e0cd3 --- /dev/null +++ b/test/prism/errors/3.3-3.4/private_endless_method.txt @@ -0,0 +1,3 @@ +private def foo = puts "Hello" + ^ unexpected string literal, expecting end-of-input + diff --git a/test/prism/errors/block_args_in_array_assignment.txt b/test/prism/errors/3.4/block_args_in_array_assignment.txt similarity index 100% rename from test/prism/errors/block_args_in_array_assignment.txt rename to test/prism/errors/3.4/block_args_in_array_assignment.txt diff --git a/test/prism/errors/dont_allow_return_inside_sclass_body.txt b/test/prism/errors/3.4/dont_allow_return_inside_sclass_body.txt similarity index 100% rename from test/prism/errors/dont_allow_return_inside_sclass_body.txt rename to test/prism/errors/3.4/dont_allow_return_inside_sclass_body.txt diff --git a/test/prism/errors/it_with_ordinary_parameter.txt b/test/prism/errors/3.4/it_with_ordinary_parameter.txt similarity index 100% rename from test/prism/errors/it_with_ordinary_parameter.txt rename to test/prism/errors/3.4/it_with_ordinary_parameter.txt diff --git a/test/prism/errors/keyword_args_in_array_assignment.txt b/test/prism/errors/3.4/keyword_args_in_array_assignment.txt similarity index 100% rename from test/prism/errors/keyword_args_in_array_assignment.txt rename to test/prism/errors/3.4/keyword_args_in_array_assignment.txt diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb index 9dd4aea728..9abed92652 100644 --- a/test/prism/errors_test.rb +++ b/test/prism/errors_test.rb @@ -1,41 +1,19 @@ # frozen_string_literal: true +return if RUBY_VERSION < "3.3.0" + require_relative "test_helper" module Prism class ErrorsTest < TestCase base = File.expand_path("errors", __dir__) - filepaths = Dir["*.txt", base: base] - - if RUBY_VERSION < "3.0" - filepaths -= [ - "cannot_assign_to_a_reserved_numbered_parameter.txt", - "writing_numbered_parameter.txt", - "targeting_numbered_parameter.txt", - "defining_numbered_parameter.txt", - "defining_numbered_parameter_2.txt", - "numbered_parameters_in_block_arguments.txt", - "numbered_and_write.txt", - "numbered_or_write.txt", - "numbered_operator_write.txt" - ] - end - - if RUBY_VERSION < "3.4" - filepaths -= [ - "it_with_ordinary_parameter.txt", - "block_args_in_array_assignment.txt", - "keyword_args_in_array_assignment.txt" - ] - end - - if RUBY_VERSION < "3.4" || RUBY_RELEASE_DATE < "2024-07-24" - filepaths -= ["dont_allow_return_inside_sclass_body.txt"] - end + filepaths = Dir["**/*.txt", base: base] filepaths.each do |filepath| - define_method(:"test_#{File.basename(filepath, ".txt")}") do - assert_errors(File.join(base, filepath)) + ruby_versions_for(filepath).each do |version| + define_method(:"test_#{version}_#{File.basename(filepath, ".txt")}") do + assert_errors(File.join(base, filepath), version) + end end end @@ -86,38 +64,15 @@ def test_invalid_message_name assert_equal :"", Prism.parse_statement("+.@foo,+=foo").write_name end - def test_circular_parameters - source = <<~RUBY - def foo(bar = bar) = 42 - def foo(bar: bar) = 42 - proc { |foo = foo| } - proc { |foo: foo| } - RUBY - - source.each_line do |line| - assert_predicate Prism.parse(line, version: "3.3.0"), :failure? - assert_predicate Prism.parse(line), :success? - end - end - - def test_private_endless_method - source = <<~RUBY - private def foo = puts "Hello" - RUBY - - assert_predicate Prism.parse(source, version: "3.4"), :failure? - assert_predicate Prism.parse(source), :success? - end - private - def assert_errors(filepath) + def assert_errors(filepath, version) expected = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8) source = expected.lines.grep_v(/^\s*\^/).join.gsub(/\n*\z/, "") - refute_valid_syntax(source) + refute_valid_syntax(source) if current_major_minor == version - result = Prism.parse(source) + result = Prism.parse(source, version: version) errors = result.errors refute_empty errors, "Expected errors in #{filepath}" diff --git a/test/prism/fixtures/3.3-3.3/block_args_in_array_assignment.txt b/test/prism/fixtures/3.3-3.3/block_args_in_array_assignment.txt new file mode 100644 index 0000000000..6d6b052681 --- /dev/null +++ b/test/prism/fixtures/3.3-3.3/block_args_in_array_assignment.txt @@ -0,0 +1 @@ +matrix[5, &block] = 8 diff --git a/test/prism/fixtures/it.txt b/test/prism/fixtures/3.3-3.3/it.txt similarity index 100% rename from test/prism/fixtures/it.txt rename to test/prism/fixtures/3.3-3.3/it.txt diff --git a/test/prism/fixtures/it_indirect_writes.txt b/test/prism/fixtures/3.3-3.3/it_indirect_writes.txt similarity index 100% rename from test/prism/fixtures/it_indirect_writes.txt rename to test/prism/fixtures/3.3-3.3/it_indirect_writes.txt diff --git a/test/prism/fixtures/it_read_and_assignment.txt b/test/prism/fixtures/3.3-3.3/it_read_and_assignment.txt similarity index 100% rename from test/prism/fixtures/it_read_and_assignment.txt rename to test/prism/fixtures/3.3-3.3/it_read_and_assignment.txt diff --git a/test/prism/fixtures/3.3-3.3/it_with_ordinary_parameter.txt b/test/prism/fixtures/3.3-3.3/it_with_ordinary_parameter.txt new file mode 100644 index 0000000000..178b641e6b --- /dev/null +++ b/test/prism/fixtures/3.3-3.3/it_with_ordinary_parameter.txt @@ -0,0 +1 @@ +proc { || it } diff --git a/test/prism/fixtures/3.3-3.3/keyword_args_in_array_assignment.txt b/test/prism/fixtures/3.3-3.3/keyword_args_in_array_assignment.txt new file mode 100644 index 0000000000..88016c2afe --- /dev/null +++ b/test/prism/fixtures/3.3-3.3/keyword_args_in_array_assignment.txt @@ -0,0 +1 @@ +matrix[5, axis: :y] = 8 diff --git a/test/prism/fixtures/3.3-3.3/return_in_sclass.txt b/test/prism/fixtures/3.3-3.3/return_in_sclass.txt new file mode 100644 index 0000000000..f1fde5771a --- /dev/null +++ b/test/prism/fixtures/3.3-3.3/return_in_sclass.txt @@ -0,0 +1 @@ +class << A; return; end diff --git a/test/prism/fixtures/3.4/circular_parameters.txt b/test/prism/fixtures/3.4/circular_parameters.txt new file mode 100644 index 0000000000..11537023ad --- /dev/null +++ b/test/prism/fixtures/3.4/circular_parameters.txt @@ -0,0 +1,4 @@ +def foo(bar = bar) = 42 +def foo(bar: bar) = 42 +proc { |foo = foo| } +proc { |foo: foo| } diff --git a/test/prism/fixtures/3.4/it.txt b/test/prism/fixtures/3.4/it.txt new file mode 100644 index 0000000000..5410b01e71 --- /dev/null +++ b/test/prism/fixtures/3.4/it.txt @@ -0,0 +1,5 @@ +x do + it +end + +-> { it } diff --git a/test/prism/fixtures/3.4/it_indirect_writes.txt b/test/prism/fixtures/3.4/it_indirect_writes.txt new file mode 100644 index 0000000000..bb87e9483e --- /dev/null +++ b/test/prism/fixtures/3.4/it_indirect_writes.txt @@ -0,0 +1,23 @@ +tap { it += 1 } + +tap { it ||= 1 } + +tap { it &&= 1 } + +tap { it; it += 1 } + +tap { it; it ||= 1 } + +tap { it; it &&= 1 } + +tap { it += 1; it } + +tap { it ||= 1; it } + +tap { it &&= 1; it } + +tap { it; it += 1; it } + +tap { it; it ||= 1; it } + +tap { it; it &&= 1; it } diff --git a/test/prism/fixtures/3.4/it_read_and_assignment.txt b/test/prism/fixtures/3.4/it_read_and_assignment.txt new file mode 100644 index 0000000000..2cceeb2a54 --- /dev/null +++ b/test/prism/fixtures/3.4/it_read_and_assignment.txt @@ -0,0 +1 @@ +42.tap { p it; it = it; p it } diff --git a/test/prism/fixtures/endless_methods_command_call.txt b/test/prism/fixtures/3.5/endless_methods_command_call.txt similarity index 100% rename from test/prism/fixtures/endless_methods_command_call.txt rename to test/prism/fixtures/3.5/endless_methods_command_call.txt diff --git a/test/prism/fixtures/leading_logical.txt b/test/prism/fixtures/3.5/leading_logical.txt similarity index 100% rename from test/prism/fixtures/leading_logical.txt rename to test/prism/fixtures/3.5/leading_logical.txt diff --git a/test/prism/fixtures_test.rb b/test/prism/fixtures_test.rb index ddb6ffb40c..9d2acfdc1b 100644 --- a/test/prism/fixtures_test.rb +++ b/test/prism/fixtures_test.rb @@ -24,9 +24,13 @@ class FixturesTest < TestCase except << "whitequark/ruby_bug_19281.txt" end + if RUBY_VERSION < "3.4.0" + except << "3.4/circular_parameters.txt" + end + # Leaving these out until they are supported by parse.y. - except << "leading_logical.txt" - except << "endless_methods_command_call.txt" + except << "3.5/leading_logical.txt" + except << "3.5/endless_methods_command_call.txt" # https://bugs.ruby-lang.org/issues/21168#note-5 except << "command_method_call_2.txt" diff --git a/test/prism/lex_test.rb b/test/prism/lex_test.rb index 3a0da1a2d8..9682bf8a32 100644 --- a/test/prism/lex_test.rb +++ b/test/prism/lex_test.rb @@ -43,16 +43,16 @@ class LexTest < TestCase end # https://bugs.ruby-lang.org/issues/20925 - except << "leading_logical.txt" + except << "3.5/leading_logical.txt" # https://bugs.ruby-lang.org/issues/17398#note-12 - except << "endless_methods_command_call.txt" + except << "3.5/endless_methods_command_call.txt" # https://bugs.ruby-lang.org/issues/21168#note-5 except << "command_method_call_2.txt" - Fixture.each(except: except) do |fixture| - define_method(fixture.test_name) { assert_lex(fixture) } + Fixture.each_with_version(except: except) do |fixture, version| + define_method(fixture.test_name(version)) { assert_lex(fixture, version) } end def test_lex_file @@ -97,10 +97,12 @@ def test_parse_lex_file private - def assert_lex(fixture) + def assert_lex(fixture, version) + return unless current_major_minor == version + source = fixture.read - result = Prism.lex_compat(source) + result = Prism.lex_compat(source, version: version) assert_equal [], result.errors Prism.lex_ripper(source).zip(result.value).each do |(ripper, prism)| diff --git a/test/prism/locals_test.rb b/test/prism/locals_test.rb index 9a3224e8ef..d5def0d18f 100644 --- a/test/prism/locals_test.rb +++ b/test/prism/locals_test.rb @@ -32,8 +32,8 @@ class LocalsTest < TestCase "whitequark/ruby_bug_10653.txt", # Leaving these out until they are supported by parse.y. - "leading_logical.txt", - "endless_methods_command_call.txt", + "3.5/leading_logical.txt", + "3.5/endless_methods_command_call.txt", "command_method_call_2.txt" ] diff --git a/test/prism/ruby/parser_test.rb b/test/prism/ruby/parser_test.rb index 10b5fca5ea..016fda91f0 100644 --- a/test/prism/ruby/parser_test.rb +++ b/test/prism/ruby/parser_test.rb @@ -65,11 +65,14 @@ class ParserTest < TestCase # 1.. && 2 "ranges.txt", + # https://bugs.ruby-lang.org/issues/20478 + "3.4/circular_parameters.txt", + # Cannot yet handling leading logical operators. - "leading_logical.txt", + "3.5/leading_logical.txt", # Ruby >= 3.5 specific syntax - "endless_methods_command_call.txt", + "3.5/endless_methods_command_call.txt", # https://bugs.ruby-lang.org/issues/21168#note-5 "command_method_call_2.txt", @@ -165,9 +168,9 @@ def test_non_prism_builder_class_deprecated if RUBY_VERSION >= "3.3" def test_current_parser_for_current_ruby - major, minor, _patch = Gem::Version.new(RUBY_VERSION).segments + major, minor = current_major_minor.split(".") # Let's just hope there never is a Ruby 3.10 or similar - expected = major * 10 + minor + expected = major.to_i * 10 + minor.to_i assert_equal(expected, Translation::ParserCurrent.new.version) end end @@ -189,7 +192,7 @@ def test_invalid_syntax end def test_it_block_parameter_syntax - it_fixture_path = Pathname(__dir__).join("../../../test/prism/fixtures/it.txt") + it_fixture_path = Pathname(__dir__).join("../../../test/prism/fixtures/3.4/it.txt") buffer = Parser::Source::Buffer.new(it_fixture_path) buffer.source = it_fixture_path.read diff --git a/test/prism/ruby/ripper_test.rb b/test/prism/ruby/ripper_test.rb index 4916ec8d9d..12c854aea6 100644 --- a/test/prism/ruby/ripper_test.rb +++ b/test/prism/ruby/ripper_test.rb @@ -9,7 +9,7 @@ class RipperTest < TestCase # Skip these tests that Ripper is reporting the wrong results for. incorrect = [ # Not yet supported. - "leading_logical.txt", + "3.5/leading_logical.txt", # Ripper incorrectly attributes the block to the keyword. "seattlerb/block_break.txt", @@ -31,8 +31,16 @@ class RipperTest < TestCase # Ripper fails to understand some structures that span across heredocs. "spanning_heredoc.txt", + "3.3-3.3/block_args_in_array_assignment.txt", + "3.3-3.3/it_with_ordinary_parameter.txt", + "3.3-3.3/keyword_args_in_array_assignment.txt", + "3.3-3.3/return_in_sclass.txt", + + # https://bugs.ruby-lang.org/issues/20478 + "3.4/circular_parameters.txt", + # https://bugs.ruby-lang.org/issues/17398#note-12 - "endless_methods_command_call.txt", + "3.5/endless_methods_command_call.txt", # https://bugs.ruby-lang.org/issues/21168#note-5 "command_method_call_2.txt", diff --git a/test/prism/ruby/ruby_parser_test.rb b/test/prism/ruby/ruby_parser_test.rb index ec55e41967..7640ddaf1c 100644 --- a/test/prism/ruby/ruby_parser_test.rb +++ b/test/prism/ruby/ruby_parser_test.rb @@ -39,7 +39,6 @@ class RubyParserTest < TestCase "dos_endings.txt", "heredocs_with_fake_newlines.txt", "heredocs_with_ignored_newlines.txt", - "leading_logical.txt", "method_calls.txt", "methods.txt", "multi_write.txt", @@ -77,8 +76,15 @@ class RubyParserTest < TestCase "whitequark/ruby_bug_19281.txt", "whitequark/slash_newline_in_heredocs.txt", - # Ruby >= 3.5 specific syntax - "endless_methods_command_call.txt", + "3.3-3.3/block_args_in_array_assignment.txt", + "3.3-3.3/it_with_ordinary_parameter.txt", + "3.3-3.3/keyword_args_in_array_assignment.txt", + "3.3-3.3/return_in_sclass.txt", + + "3.4/circular_parameters.txt", + + "3.5/endless_methods_command_call.txt", + "3.5/leading_logical.txt", # https://bugs.ruby-lang.org/issues/21168#note-5 "command_method_call_2.txt", diff --git a/test/prism/snapshots_test.rb b/test/prism/snapshots_test.rb index 3fbda1f86e..20cdf44d90 100644 --- a/test/prism/snapshots_test.rb +++ b/test/prism/snapshots_test.rb @@ -36,16 +36,16 @@ def teardown ) end - Fixture.each(except: except) do |fixture| - define_method(fixture.test_name) { assert_snapshot(fixture) } + Fixture.each_with_version(except: except) do |fixture, version| + define_method(fixture.test_name(version)) { assert_snapshot(fixture, version) } end private - def assert_snapshot(fixture) + def assert_snapshot(fixture, version) source = fixture.read - result = Prism.parse(source, filepath: fixture.path) + result = Prism.parse(source, filepath: fixture.path, version: version) assert result.success? printed = PP.pp(result.value, +"", 79) @@ -57,8 +57,14 @@ def assert_snapshot(fixture) # If the snapshot file exists, but the printed value does not match the # snapshot, then update the snapshot file. if printed != saved - File.write(snapshot, printed) - warn("Updated snapshot at #{snapshot}.") + if ENV["UPDATE_SNAPSHOTS"] + File.write(snapshot, printed) + else + warn("Snapshot at #{snapshot} outdated for #{version}. Run with UPDATE_SNAPSHOTS=1 " \ + "to regenerate the files. If modifying behaviour for a subset of ruby versions, " \ + "instead move the fixture and snapshot into versioned directories. For more details, " \ + "see `Prism::TestCase.ruby_versions_for`.") + end end # If the snapshot file exists, then assert that the printed value diff --git a/test/prism/snippets_test.rb b/test/prism/snippets_test.rb index 66802c5dc3..3160442cc0 100644 --- a/test/prism/snippets_test.rb +++ b/test/prism/snippets_test.rb @@ -18,24 +18,24 @@ class SnippetsTest < TestCase "whitequark/multiple_pattern_matches.txt" ] - Fixture.each(except: except) do |fixture| - define_method(fixture.test_name) { assert_snippets(fixture) } + Fixture.each_with_version(except: except) do |fixture, version| + define_method(fixture.test_name(version)) { assert_snippets(fixture, version) } end private # We test every snippet (separated by \n\n) in isolation to ensure the # parser does not try to read bytes further than the end of each snippet. - def assert_snippets(fixture) + def assert_snippets(fixture, version) fixture.read.split(/(?<=\S)\n\n(?=\S)/).each do |snippet| snippet = snippet.rstrip - result = Prism.parse(snippet, filepath: fixture.path) + result = Prism.parse(snippet, filepath: fixture.path, version: version) assert result.success? if !ENV["PRISM_BUILD_MINIMAL"] - dumped = Prism.dump(snippet, filepath: fixture.path) - assert_equal_nodes(result.value, Prism.load(snippet, dumped).value) + dumped = Prism.dump(snippet, filepath: fixture.path, version: version) + assert_equal_nodes(result.value, Prism.load(snippet, dumped, version: version).value) end end end diff --git a/test/prism/test_helper.rb b/test/prism/test_helper.rb index 0be9d1e7da..84871722c9 100644 --- a/test/prism/test_helper.rb +++ b/test/prism/test_helper.rb @@ -58,8 +58,12 @@ def snapshot_path File.join(File.expand_path("../..", __dir__), "snapshots", path) end - def test_name - :"test_#{path}" + def test_name(version = nil) + if version + :"test_#{version}_#{path}" + else + :"test_#{path}" + end end def self.each(except: [], &block) @@ -68,6 +72,14 @@ def self.each(except: [], &block) paths.each { |path| yield Fixture.new(path) } end + def self.each_with_version(except: [], &block) + each(except: except) do |fixture| + TestCase.ruby_versions_for(fixture.path).each do |version| + yield fixture, version + end + end + end + def self.custom_base_path? ENV.key?("FIXTURE_BASE") end @@ -217,6 +229,37 @@ def self.windows? RbConfig::CONFIG["host_os"].match?(/bccwin|cygwin|djgpp|mingw|mswin|wince/i) end + # All versions that prism can parse + SYNTAX_VERSIONS = %w[3.3 3.4 3.5] + + # Returns an array of ruby versions that a given filepath should test against: + # test.txt # => all available versions + # 3.4/test.txt # => versions since 3.4 (inclusive) + # 3.4-4.2/test.txt # => verisions since 3.4 (inclusive) up to 4.2 (inclusive) + def self.ruby_versions_for(filepath) + return [ENV['SYNTAX_VERSION']] if ENV['SYNTAX_VERSION'] + + parts = filepath.split("/") + return SYNTAX_VERSIONS if parts.size == 1 + + version_start, version_stop = parts[0].split("-") + if version_stop + SYNTAX_VERSIONS[SYNTAX_VERSIONS.index(version_start)..SYNTAX_VERSIONS.index(version_stop)] + else + SYNTAX_VERSIONS[SYNTAX_VERSIONS.index(version_start)..] + end + end + + def current_major_minor + RUBY_VERSION.split(".")[0, 2].join(".") + end + + if RUBY_VERSION >= "3.3.0" + def test_all_syntax_versions_present + assert_include(SYNTAX_VERSIONS, current_major_minor) + end + end + private if RUBY_ENGINE == "ruby" && RubyVM::InstructionSequence.compile("").to_a[4][:parser] != :prism