mirror of
https://github.com/github/codeql.git
synced 2026-04-21 23:14:03 +02:00
Swift: add NamedPattern.getVarDecl()
This commit is contained in:
@@ -222,19 +222,19 @@ predicate catchMatchingPattern(DoCatchStmt s, CaseStmt c, Pattern pattern) {
|
||||
|
||||
/** Holds if `sub` is a subpattern of `p`. */
|
||||
private predicate isSubPattern(Pattern p, Pattern sub) {
|
||||
sub = p.(BindingPattern).getResolveStep()
|
||||
sub = p.(BindingPattern).getImmediateSubPattern()
|
||||
or
|
||||
sub = p.(EnumElementPattern).getSubPattern().getFullyUnresolved()
|
||||
sub = p.(EnumElementPattern).getImmediateSubPattern()
|
||||
or
|
||||
sub = p.(IsPattern).getSubPattern().getFullyUnresolved()
|
||||
sub = p.(IsPattern).getImmediateSubPattern()
|
||||
or
|
||||
sub = p.(OptionalSomePattern).getFullyUnresolved()
|
||||
sub = p.(OptionalSomePattern).getImmediateSubPattern()
|
||||
or
|
||||
sub = p.(ParenPattern).getResolveStep()
|
||||
sub = p.(ParenPattern).getImmediateSubPattern()
|
||||
or
|
||||
sub = p.(TuplePattern).getAnElement().getFullyUnresolved()
|
||||
sub = p.(TuplePattern).getImmediateElement(_)
|
||||
or
|
||||
sub = p.(TypedPattern).getSubPattern().getFullyUnresolved()
|
||||
sub = p.(TypedPattern).getImmediateSubPattern()
|
||||
}
|
||||
|
||||
/** Gets the value of `e` if it is a constant value, disregarding conversions. */
|
||||
|
||||
@@ -1,5 +1,40 @@
|
||||
private import codeql.swift.generated.pattern.NamedPattern
|
||||
private import codeql.swift.elements.pattern.BindingPattern
|
||||
private import codeql.swift.elements.pattern.EnumElementPattern
|
||||
private import codeql.swift.elements.pattern.IsPattern
|
||||
private import codeql.swift.elements.pattern.OptionalSomePattern
|
||||
private import codeql.swift.elements.pattern.ParenPattern
|
||||
private import codeql.swift.elements.pattern.TuplePattern
|
||||
private import codeql.swift.elements.pattern.TypedPattern
|
||||
private import codeql.swift.elements.decl.VarDecl
|
||||
private import codeql.swift.elements.stmt.LabeledConditionalStmt
|
||||
private import codeql.swift.elements.stmt.ConditionElement
|
||||
|
||||
class NamedPattern extends Generated::NamedPattern {
|
||||
/** Holds if this named pattern has a corresponding `VarDecl` */
|
||||
predicate hasVarDecl() { exists(this.getVarDecl()) }
|
||||
|
||||
/** Gets the `VarDecl` bound by this named pattern, if any. */
|
||||
VarDecl getVarDecl() {
|
||||
isSubPattern*(result.getParentPattern().getFullyUnresolved(), this) and
|
||||
result.getName() = this.getName()
|
||||
}
|
||||
|
||||
override string toString() { result = this.getName() }
|
||||
}
|
||||
|
||||
private predicate isSubPattern(Pattern p, Pattern sub) {
|
||||
sub = p.(BindingPattern).getImmediateSubPattern()
|
||||
or
|
||||
sub = p.(EnumElementPattern).getImmediateSubPattern()
|
||||
or
|
||||
sub = p.(IsPattern).getImmediateSubPattern()
|
||||
or
|
||||
sub = p.(OptionalSomePattern).getImmediateSubPattern()
|
||||
or
|
||||
sub = p.(ParenPattern).getImmediateSubPattern()
|
||||
or
|
||||
sub = p.(TuplePattern).getImmediateElement(_)
|
||||
or
|
||||
sub = p.(TypedPattern).getImmediateSubPattern()
|
||||
}
|
||||
|
||||
@@ -39,3 +39,23 @@
|
||||
| patterns.swift:46:9:46:9 | b |
|
||||
| patterns.swift:49:10:49:10 | true |
|
||||
| patterns.swift:50:10:50:10 | false |
|
||||
| patterns.swift:55:9:55:9 | a |
|
||||
| patterns.swift:55:16:55:16 | b |
|
||||
| patterns.swift:55:23:55:23 | c |
|
||||
| patterns.swift:55:23:55:26 | ... as ... |
|
||||
| patterns.swift:57:8:57:20 | let ... |
|
||||
| patterns.swift:57:8:57:20 | let ...? |
|
||||
| patterns.swift:57:12:57:20 | (...) |
|
||||
| patterns.swift:57:13:57:13 | a |
|
||||
| patterns.swift:57:16:57:16 | b |
|
||||
| patterns.swift:57:19:57:19 | c |
|
||||
| patterns.swift:58:13:58:29 | (...) |
|
||||
| patterns.swift:58:14:58:14 | =~ ... |
|
||||
| patterns.swift:58:17:58:21 | let ... |
|
||||
| patterns.swift:58:21:58:21 | b |
|
||||
| patterns.swift:58:24:58:28 | let ... |
|
||||
| patterns.swift:58:28:58:28 | c |
|
||||
| patterns.swift:61:14:61:14 | =~ ... |
|
||||
| patterns.swift:62:14:62:18 | let ... |
|
||||
| patterns.swift:62:18:62:18 | c |
|
||||
| patterns.swift:63:9:63:9 | _ |
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
bound
|
||||
| patterns.swift:2:9:2:9 | an_int |
|
||||
| patterns.swift:3:9:3:9 | a_string |
|
||||
| patterns.swift:4:10:4:10 | x |
|
||||
| patterns.swift:4:13:4:13 | y |
|
||||
| patterns.swift:4:16:4:16 | z |
|
||||
| patterns.swift:10:9:10:9 | point |
|
||||
| patterns.swift:12:15:12:15 | xx |
|
||||
| patterns.swift:12:19:12:19 | yy |
|
||||
| patterns.swift:24:9:24:9 | v |
|
||||
| patterns.swift:28:19:28:19 | i |
|
||||
| patterns.swift:28:22:28:22 | s |
|
||||
| patterns.swift:31:9:31:9 | w |
|
||||
| patterns.swift:34:14:34:14 | n |
|
||||
| patterns.swift:38:9:38:9 | a |
|
||||
| patterns.swift:42:14:42:14 | x |
|
||||
| patterns.swift:46:9:46:9 | b |
|
||||
| patterns.swift:55:9:55:9 | a |
|
||||
| patterns.swift:55:16:55:16 | b |
|
||||
| patterns.swift:55:23:55:23 | c |
|
||||
| patterns.swift:57:13:57:13 | a |
|
||||
| patterns.swift:57:19:57:19 | c |
|
||||
| patterns.swift:58:21:58:21 | b |
|
||||
| patterns.swift:62:18:62:18 | c |
|
||||
unbound
|
||||
| patterns.swift:57:16:57:16 | b |
|
||||
| patterns.swift:58:28:58:28 | c |
|
||||
11
swift/ql/test/extractor-tests/patterns/bound_and_unbound.ql
Normal file
11
swift/ql/test/extractor-tests/patterns/bound_and_unbound.ql
Normal file
@@ -0,0 +1,11 @@
|
||||
import swift
|
||||
|
||||
query predicate bound(NamedPattern p) {
|
||||
p.getFile().getBaseName() = "patterns.swift" and
|
||||
p.hasVarDecl()
|
||||
}
|
||||
|
||||
query predicate unbound(NamedPattern p) {
|
||||
p.getFile().getBaseName() = "patterns.swift" and
|
||||
not p.hasVarDecl()
|
||||
}
|
||||
@@ -50,3 +50,16 @@ func switch_patterns() {
|
||||
case false: "false"
|
||||
}
|
||||
}
|
||||
|
||||
func bound_and_unbound() {
|
||||
let a = 1, b = 2, c: Int = 3
|
||||
|
||||
if let (a, b, c) = Optional.some((a, b, c)) { _ = (a, c) }
|
||||
if case (a, let b, let c) = (a, b, c) { _ = (b) }
|
||||
|
||||
switch a {
|
||||
case c: "equals c"
|
||||
case let c: "binds c"
|
||||
default: "default"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5509,6 +5509,95 @@ patterns.swift:
|
||||
# 34| Type = Int
|
||||
# 42| [ConcreteVarDecl] x
|
||||
# 42| Type = String
|
||||
# 54| [ConcreteFuncDecl] bound_and_unbound()
|
||||
# 54| InterfaceType = () -> ()
|
||||
# 54| getBody(): [BraceStmt] { ... }
|
||||
# 55| getElement(0): [PatternBindingDecl] var ... = ...
|
||||
# 55| getInit(0): [IntegerLiteralExpr] 1
|
||||
# 55| getInit(1): [IntegerLiteralExpr] 2
|
||||
# 55| getInit(2): [IntegerLiteralExpr] 3
|
||||
# 55| getPattern(0): [NamedPattern] a
|
||||
# 55| getPattern(1): [NamedPattern] b
|
||||
# 55| getPattern(2): [TypedPattern] ... as ...
|
||||
# 55| getSubPattern(): [NamedPattern] c
|
||||
# 55| getTypeRepr(): [TypeRepr] Int
|
||||
# 55| getElement(1): [ConcreteVarDecl] a
|
||||
# 55| Type = Int
|
||||
# 55| getElement(2): [ConcreteVarDecl] b
|
||||
# 55| Type = Int
|
||||
# 55| getElement(3): [ConcreteVarDecl] c
|
||||
# 55| Type = Int
|
||||
# 57| getElement(4): [IfStmt] if ... then { ... }
|
||||
# 57| getCondition(): [StmtCondition] StmtCondition
|
||||
# 57| getElement(0): [ConditionElement] let ...? = ...
|
||||
# 57| getPattern(): [OptionalSomePattern] let ...?
|
||||
# 57| getSubPattern(): [TuplePattern] (...)
|
||||
# 57| getElement(0): [NamedPattern] a
|
||||
# 57| getElement(1): [NamedPattern] b
|
||||
# 57| getElement(2): [NamedPattern] c
|
||||
# 57| getSubPattern().getFullyUnresolved(): [BindingPattern] let ...
|
||||
# 57| getInitializer(): [CallExpr] call to ...
|
||||
# 57| getFunction(): [MethodLookupExpr] .some
|
||||
# 57| getBase(): [TypeExpr] Optional<(Int, Int, Int)>.Type
|
||||
# 57| getTypeRepr(): [TypeRepr] Optional<(Int, Int, Int)>
|
||||
# 57| getMethodRef(): [DeclRefExpr] some
|
||||
# 57| getArgument(0): [Argument] : (...)
|
||||
# 57| getExpr(): [TupleExpr] (...)
|
||||
# 57| getElement(0): [DeclRefExpr] a
|
||||
# 57| getElement(1): [DeclRefExpr] b
|
||||
# 57| getElement(2): [DeclRefExpr] c
|
||||
# 57| getThen(): [BraceStmt] { ... }
|
||||
# 57| getElement(0): [AssignExpr] ... = ...
|
||||
# 57| getDest(): [DiscardAssignmentExpr] _
|
||||
# 57| getSource(): [TupleExpr] (...)
|
||||
# 57| getElement(0): [DeclRefExpr] a
|
||||
# 57| getElement(1): [DeclRefExpr] c
|
||||
# 58| getElement(5): [IfStmt] if ... then { ... }
|
||||
# 58| getCondition(): [StmtCondition] StmtCondition
|
||||
# 58| getElement(0): [ConditionElement] (...) = ...
|
||||
# 58| getPattern(): [TuplePattern] (...)
|
||||
# 58| getElement(0): [ExprPattern] =~ ...
|
||||
# 58| getSubExpr(): [DeclRefExpr] a
|
||||
# 58| getElement(1): [NamedPattern] b
|
||||
# 58| getElement(1).getFullyUnresolved(): [BindingPattern] let ...
|
||||
# 58| getElement(2): [NamedPattern] c
|
||||
# 58| getElement(2).getFullyUnresolved(): [BindingPattern] let ...
|
||||
# 58| getInitializer(): [TupleExpr] (...)
|
||||
# 58| getElement(0): [DeclRefExpr] a
|
||||
# 58| getElement(1): [DeclRefExpr] b
|
||||
# 58| getElement(2): [DeclRefExpr] c
|
||||
# 58| getThen(): [BraceStmt] { ... }
|
||||
# 58| getElement(0): [AssignExpr] ... = ...
|
||||
# 58| getDest(): [DiscardAssignmentExpr] _
|
||||
# 58| getSource(): [DeclRefExpr] b
|
||||
# 58| getSource().getFullyConverted(): [ParenExpr] (...)
|
||||
# 60| getElement(6): [SwitchStmt] switch a { ... }
|
||||
# 60| getExpr(): [DeclRefExpr] a
|
||||
# 61| getCase(0): [CaseStmt] case ...
|
||||
# 61| getBody(): [BraceStmt] { ... }
|
||||
# 61| getElement(0): [StringLiteralExpr] equals c
|
||||
# 61| getLabel(0): [CaseLabelItem] =~ ...
|
||||
# 61| getPattern(): [ExprPattern] =~ ...
|
||||
# 61| getSubExpr(): [DeclRefExpr] c
|
||||
# 62| getCase(1): [CaseStmt] case ...
|
||||
# 62| getBody(): [BraceStmt] { ... }
|
||||
# 62| getElement(0): [StringLiteralExpr] binds c
|
||||
# 62| getLabel(0): [CaseLabelItem] c
|
||||
# 62| getPattern(): [NamedPattern] c
|
||||
# 62| getPattern().getFullyUnresolved(): [BindingPattern] let ...
|
||||
# 63| getCase(2): [CaseStmt] case ...
|
||||
# 63| getBody(): [BraceStmt] { ... }
|
||||
# 63| getElement(0): [StringLiteralExpr] default
|
||||
# 63| getLabel(0): [CaseLabelItem] _
|
||||
# 63| getPattern(): [AnyPattern] _
|
||||
# 57| [ConcreteVarDecl] a
|
||||
# 57| Type = Int
|
||||
# 57| [ConcreteVarDecl] c
|
||||
# 57| Type = Int
|
||||
# 58| [ConcreteVarDecl] b
|
||||
# 58| Type = Int
|
||||
# 62| [ConcreteVarDecl] c
|
||||
# 62| Type = Int
|
||||
statements.swift:
|
||||
# 1| [ConcreteFuncDecl] loop()
|
||||
# 1| InterfaceType = () -> ()
|
||||
|
||||
@@ -50,3 +50,16 @@ func switch_patterns() {
|
||||
case false: "false"
|
||||
}
|
||||
}
|
||||
|
||||
func bound_and_unbound() {
|
||||
let a = 1, b = 2, c: Int = 3
|
||||
|
||||
if let (a, b, c) = Optional.some((a, b, c)) { _ = (a, c) }
|
||||
if case (a, let b, let c) = (a, b, c) { _ = (b) }
|
||||
|
||||
switch a {
|
||||
case c: "equals c"
|
||||
case let c: "binds c"
|
||||
default: "default"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user