mirror of
https://github.com/github/codeql.git
synced 2026-06-29 16:47:09 +02:00
Merge pull request #22080 from asgerf/unified/commonast-followups
unified: Add or_pattern and fix 'if case let' translation
This commit is contained in:
@@ -42,6 +42,7 @@ supertypes:
|
||||
- name_pattern
|
||||
- tuple_pattern
|
||||
- constructor_pattern
|
||||
- or_pattern
|
||||
- ignore_pattern
|
||||
- expr_equality_pattern
|
||||
- bulk_importing_pattern
|
||||
@@ -359,12 +360,12 @@ named:
|
||||
case*: switch_case
|
||||
|
||||
# A single `case ...:` (or `default:`) entry in a switch.
|
||||
# An entry with multiple `case p1, p2:` patterns has multiple `pattern`s.
|
||||
# A `default:` entry has no patterns.
|
||||
# An entry with multiple `case p1, p2:` patterns uses an `or_pattern`.
|
||||
# A `default:` entry has no pattern.
|
||||
# An optional `guard` corresponds to a `where`-clause on the case.
|
||||
switch_case:
|
||||
modifier*: modifier
|
||||
pattern*: pattern
|
||||
pattern?: pattern
|
||||
guard?: expr
|
||||
body: block
|
||||
|
||||
@@ -421,6 +422,11 @@ named:
|
||||
constructor: expr_or_type
|
||||
element*: pattern_element
|
||||
|
||||
# A disjunction pattern that matches if any of its sub-patterns match.
|
||||
or_pattern:
|
||||
modifier*: modifier
|
||||
pattern*: pattern
|
||||
|
||||
# A pattern with an optional associated name.
|
||||
pattern_element:
|
||||
modifier*: modifier
|
||||
|
||||
@@ -652,11 +652,20 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
|
||||
=>
|
||||
(switch_expr value: {val} case: {..cases})
|
||||
),
|
||||
// Switch entry with patterns and body
|
||||
// Switch entry with multiple patterns and body
|
||||
rule!(
|
||||
(switch_entry pattern: (switch_pattern pattern: @pats)* statement: _* @body)
|
||||
(switch_entry
|
||||
pattern: (switch_pattern pattern: @first)
|
||||
pattern: (switch_pattern pattern: @rest)+
|
||||
statement: _* @body)
|
||||
=>
|
||||
(switch_case pattern: {..pats} body: (block stmt: {..body}))
|
||||
(switch_case pattern: (or_pattern pattern: {first} pattern: {..rest}) body: (block stmt: {..body}))
|
||||
),
|
||||
// Switch entry with exactly one pattern and body
|
||||
rule!(
|
||||
(switch_entry pattern: (switch_pattern pattern: @pat) statement: _* @body)
|
||||
=>
|
||||
(switch_case pattern: {pat} body: (block stmt: {..body}))
|
||||
),
|
||||
// Switch entry: default case (no patterns)
|
||||
rule!(
|
||||
@@ -664,13 +673,13 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
|
||||
=>
|
||||
(switch_case body: (block stmt: {..body}))
|
||||
),
|
||||
// if case let x = expr — the pattern is taken as-is (no Optional wrapping)
|
||||
// if case PATTERN = expr — preserve the pattern directly (no Optional wrapping)
|
||||
rule!(
|
||||
(if_let_binding "case" (value_binding_pattern) bound_identifier: @name _ @val)
|
||||
(if_let_binding "case" pattern: @pat value: @val)
|
||||
=>
|
||||
(pattern_guard_expr
|
||||
value: {val}
|
||||
pattern: (name_pattern identifier: (identifier #{name})))
|
||||
pattern: {pat})
|
||||
),
|
||||
rule!(
|
||||
(if_let_binding
|
||||
|
||||
@@ -573,10 +573,12 @@ top_level
|
||||
name_expr
|
||||
identifier: identifier "print"
|
||||
pattern:
|
||||
expr_equality_pattern
|
||||
expr: int_literal "2"
|
||||
expr_equality_pattern
|
||||
expr: int_literal "3"
|
||||
or_pattern
|
||||
pattern:
|
||||
expr_equality_pattern
|
||||
expr: int_literal "2"
|
||||
expr_equality_pattern
|
||||
expr: int_literal "3"
|
||||
switch_case
|
||||
body:
|
||||
block
|
||||
@@ -592,6 +594,83 @@ top_level
|
||||
name_expr
|
||||
identifier: identifier "x"
|
||||
|
||||
===
|
||||
If-case-let with shadowing in condition value
|
||||
===
|
||||
|
||||
if case let x = x + 10 {
|
||||
print(x)
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
source_file
|
||||
statement:
|
||||
if_statement
|
||||
body:
|
||||
block
|
||||
statement:
|
||||
call_expression
|
||||
function: simple_identifier "print"
|
||||
suffix:
|
||||
call_suffix
|
||||
arguments:
|
||||
value_arguments
|
||||
argument:
|
||||
value_argument
|
||||
value: simple_identifier "x"
|
||||
condition:
|
||||
if_condition
|
||||
kind:
|
||||
if_let_binding
|
||||
pattern:
|
||||
pattern
|
||||
kind:
|
||||
binding_pattern
|
||||
binding:
|
||||
value_binding_pattern
|
||||
mutability: let
|
||||
pattern:
|
||||
pattern
|
||||
bound_identifier: simple_identifier "x"
|
||||
value:
|
||||
additive_expression
|
||||
lhs: simple_identifier "x"
|
||||
op: +
|
||||
rhs: integer_literal "10"
|
||||
|
||||
---
|
||||
|
||||
top_level
|
||||
body:
|
||||
block
|
||||
stmt:
|
||||
if_expr
|
||||
condition:
|
||||
pattern_guard_expr
|
||||
pattern:
|
||||
name_pattern
|
||||
identifier: identifier "x"
|
||||
value:
|
||||
binary_expr
|
||||
operator: infix_operator "+"
|
||||
left:
|
||||
name_expr
|
||||
identifier: identifier "x"
|
||||
right: int_literal "10"
|
||||
then:
|
||||
block
|
||||
stmt:
|
||||
call_expr
|
||||
argument:
|
||||
argument
|
||||
value:
|
||||
name_expr
|
||||
identifier: identifier "x"
|
||||
callee:
|
||||
name_expr
|
||||
identifier: identifier "print"
|
||||
|
||||
===
|
||||
Switch with binding pattern
|
||||
===
|
||||
|
||||
@@ -978,6 +978,23 @@ module Unified {
|
||||
}
|
||||
}
|
||||
|
||||
/** A class representing `or_pattern` nodes. */
|
||||
class OrPattern extends @unified_or_pattern, AstNode {
|
||||
/** Gets the name of the primary QL class for this element. */
|
||||
final override string getAPrimaryQlClass() { result = "OrPattern" }
|
||||
|
||||
/** Gets the node corresponding to the field `modifier`. */
|
||||
final Modifier getModifier(int i) { unified_or_pattern_modifier(this, i, result) }
|
||||
|
||||
/** Gets the node corresponding to the field `pattern`. */
|
||||
final Pattern getPattern(int i) { unified_or_pattern_pattern(this, i, result) }
|
||||
|
||||
/** Gets a field or child node of this node. */
|
||||
final override AstNode getAFieldOrChild() {
|
||||
unified_or_pattern_modifier(this, _, result) or unified_or_pattern_pattern(this, _, result)
|
||||
}
|
||||
}
|
||||
|
||||
/** A class representing `parameter` nodes. */
|
||||
class Parameter extends @unified_parameter, AstNode {
|
||||
/** Gets the name of the primary QL class for this element. */
|
||||
@@ -1109,14 +1126,14 @@ module Unified {
|
||||
final Modifier getModifier(int i) { unified_switch_case_modifier(this, i, result) }
|
||||
|
||||
/** Gets the node corresponding to the field `pattern`. */
|
||||
final Pattern getPattern(int i) { unified_switch_case_pattern(this, i, result) }
|
||||
final Pattern getPattern() { unified_switch_case_pattern(this, result) }
|
||||
|
||||
/** Gets a field or child node of this node. */
|
||||
final override AstNode getAFieldOrChild() {
|
||||
unified_switch_case_def(this, result) or
|
||||
unified_switch_case_guard(this, result) or
|
||||
unified_switch_case_modifier(this, _, result) or
|
||||
unified_switch_case_pattern(this, _, result)
|
||||
unified_switch_case_pattern(this, result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1654,6 +1671,10 @@ module Unified {
|
||||
i = -1 and
|
||||
name = "getPrecedence"
|
||||
or
|
||||
result = node.(OrPattern).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(OrPattern).getPattern(i) and name = "getPattern"
|
||||
or
|
||||
result = node.(Parameter).getDefault() and i = -1 and name = "getDefault"
|
||||
or
|
||||
result = node.(Parameter).getExternalName() and i = -1 and name = "getExternalName"
|
||||
@@ -1682,7 +1703,7 @@ module Unified {
|
||||
or
|
||||
result = node.(SwitchCase).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(SwitchCase).getPattern(i) and name = "getPattern"
|
||||
result = node.(SwitchCase).getPattern() and i = -1 and name = "getPattern"
|
||||
or
|
||||
result = node.(SwitchExpr).getCase(i) and name = "getCase"
|
||||
or
|
||||
|
||||
@@ -716,6 +716,24 @@ unified_operator_syntax_declaration_def(
|
||||
int name: @unified_token_identifier ref
|
||||
);
|
||||
|
||||
#keyset[unified_or_pattern, index]
|
||||
unified_or_pattern_modifier(
|
||||
int unified_or_pattern: @unified_or_pattern ref,
|
||||
int index: int ref,
|
||||
unique int modifier: @unified_token_modifier ref
|
||||
);
|
||||
|
||||
#keyset[unified_or_pattern, index]
|
||||
unified_or_pattern_pattern(
|
||||
int unified_or_pattern: @unified_or_pattern ref,
|
||||
int index: int ref,
|
||||
unique int pattern: @unified_pattern ref
|
||||
);
|
||||
|
||||
unified_or_pattern_def(
|
||||
unique int id: @unified_or_pattern
|
||||
);
|
||||
|
||||
unified_parameter_default(
|
||||
unique int unified_parameter: @unified_parameter ref,
|
||||
unique int default: @unified_expr ref
|
||||
@@ -747,7 +765,7 @@ unified_parameter_def(
|
||||
unique int id: @unified_parameter
|
||||
);
|
||||
|
||||
@unified_pattern = @unified_bulk_importing_pattern | @unified_constructor_pattern | @unified_expr_equality_pattern | @unified_name_pattern | @unified_token_ignore_pattern | @unified_token_unsupported_node | @unified_tuple_pattern
|
||||
@unified_pattern = @unified_bulk_importing_pattern | @unified_constructor_pattern | @unified_expr_equality_pattern | @unified_name_pattern | @unified_or_pattern | @unified_token_ignore_pattern | @unified_token_unsupported_node | @unified_tuple_pattern
|
||||
|
||||
unified_pattern_element_key(
|
||||
unique int unified_pattern_element: @unified_pattern_element ref,
|
||||
@@ -795,10 +813,8 @@ unified_switch_case_modifier(
|
||||
unique int modifier: @unified_token_modifier ref
|
||||
);
|
||||
|
||||
#keyset[unified_switch_case, index]
|
||||
unified_switch_case_pattern(
|
||||
int unified_switch_case: @unified_switch_case ref,
|
||||
int index: int ref,
|
||||
unique int unified_switch_case: @unified_switch_case ref,
|
||||
unique int pattern: @unified_pattern ref
|
||||
);
|
||||
|
||||
@@ -1056,7 +1072,7 @@ unified_trivia_tokeninfo(
|
||||
string value: string ref
|
||||
);
|
||||
|
||||
@unified_ast_node = @unified_accessor_declaration | @unified_argument | @unified_array_literal | @unified_assign_expr | @unified_associated_type_declaration | @unified_base_type | @unified_binary_expr | @unified_block | @unified_bound_type_constraint | @unified_break_expr | @unified_bulk_importing_pattern | @unified_call_expr | @unified_catch_clause | @unified_class_like_declaration | @unified_compound_assign_expr | @unified_constructor_declaration | @unified_constructor_pattern | @unified_continue_expr | @unified_destructor_declaration | @unified_do_while_stmt | @unified_equality_type_constraint | @unified_expr_equality_pattern | @unified_for_each_stmt | @unified_function_declaration | @unified_function_expr | @unified_function_type_expr | @unified_generic_type_expr | @unified_guard_if_stmt | @unified_if_expr | @unified_import_declaration | @unified_initializer_declaration | @unified_key_value_pair | @unified_labeled_stmt | @unified_map_literal | @unified_member_access_expr | @unified_name_expr | @unified_name_pattern | @unified_named_type_expr | @unified_operator_syntax_declaration | @unified_parameter | @unified_pattern_element | @unified_pattern_guard_expr | @unified_return_expr | @unified_switch_case | @unified_switch_expr | @unified_throw_expr | @unified_token | @unified_top_level | @unified_trivia_token | @unified_try_expr | @unified_tuple_expr | @unified_tuple_pattern | @unified_tuple_type_element | @unified_tuple_type_expr | @unified_type_alias_declaration | @unified_type_cast_expr | @unified_type_parameter | @unified_type_test_expr | @unified_type_test_pattern | @unified_unary_expr | @unified_variable_declaration | @unified_while_stmt
|
||||
@unified_ast_node = @unified_accessor_declaration | @unified_argument | @unified_array_literal | @unified_assign_expr | @unified_associated_type_declaration | @unified_base_type | @unified_binary_expr | @unified_block | @unified_bound_type_constraint | @unified_break_expr | @unified_bulk_importing_pattern | @unified_call_expr | @unified_catch_clause | @unified_class_like_declaration | @unified_compound_assign_expr | @unified_constructor_declaration | @unified_constructor_pattern | @unified_continue_expr | @unified_destructor_declaration | @unified_do_while_stmt | @unified_equality_type_constraint | @unified_expr_equality_pattern | @unified_for_each_stmt | @unified_function_declaration | @unified_function_expr | @unified_function_type_expr | @unified_generic_type_expr | @unified_guard_if_stmt | @unified_if_expr | @unified_import_declaration | @unified_initializer_declaration | @unified_key_value_pair | @unified_labeled_stmt | @unified_map_literal | @unified_member_access_expr | @unified_name_expr | @unified_name_pattern | @unified_named_type_expr | @unified_operator_syntax_declaration | @unified_or_pattern | @unified_parameter | @unified_pattern_element | @unified_pattern_guard_expr | @unified_return_expr | @unified_switch_case | @unified_switch_expr | @unified_throw_expr | @unified_token | @unified_top_level | @unified_trivia_token | @unified_try_expr | @unified_tuple_expr | @unified_tuple_pattern | @unified_tuple_type_element | @unified_tuple_type_expr | @unified_type_alias_declaration | @unified_type_cast_expr | @unified_type_parameter | @unified_type_test_expr | @unified_type_test_pattern | @unified_unary_expr | @unified_variable_declaration | @unified_while_stmt
|
||||
|
||||
unified_ast_node_location(
|
||||
unique int node: @unified_ast_node ref,
|
||||
|
||||
Reference in New Issue
Block a user