Swift: Parse MAD enum content.

This commit is contained in:
Geoffrey White
2023-07-21 16:08:36 +01:00
parent 1cfb9bbf34
commit d9187c62fe
4 changed files with 34 additions and 3 deletions

View File

@@ -476,9 +476,15 @@ private predicate parseField(AccessPathToken c, Content::FieldContent f) {
)
}
private predicate parseEnum(AccessPathToken c, Content::EnumContent f) {
c.getName() = "Enum" and
c.getAnArgument() = f.getSignature()
}
/** Holds if the specification component parses as a `Content`. */
predicate parseContent(AccessPathToken component, Content content) {
parseField(component, content)
parseField(component, content) or
parseEnum(component, content)
}
cached

View File

@@ -202,9 +202,24 @@ module Content {
/** Gets the declaration of the enum parameter. */
ParamDecl getParam() { result = p }
override string toString() {
/**
* Gets a string describing this enum content, of the form: `EnumElementName:N` where `EnumElementName`
* is the name of the enum element declaration within the enum, and `N` is the 0-based index of the
* parameter that this content is for. For example in the following code there is only one `EnumContent`
* and it's signature is `myValue:0`:
* ```
* enum MyEnum {
* case myValue(Int)
* }
* ```
*/
string getSignature() {
exists(EnumElementDecl d, int pos | d.getParam(pos) = p | result = d.toString() + ":" + pos)
}
override string toString() {
result = this.getSignature()
}
}
}

View File

@@ -210,10 +210,14 @@ edges
| test.swift:490:14:490:32 | call to mkMyEnum1(_:) [mySingle:0] | test.swift:496:13:496:35 | .mySingle(...) [mySingle:0] |
| test.swift:490:24:490:31 | call to source() | test.swift:375:16:375:21 | v |
| test.swift:490:24:490:31 | call to source() | test.swift:490:14:490:32 | call to mkMyEnum1(_:) [mySingle:0] |
| test.swift:492:14:492:32 | call to mkMyEnum2(_:) [mySingle:0] | test.swift:498:13:498:35 | .mySingle(...) [mySingle:0] |
| test.swift:492:24:492:31 | call to source() | test.swift:492:14:492:32 | call to mkMyEnum2(_:) [mySingle:0] |
| test.swift:494:13:494:35 | .mySingle(...) [mySingle:0] | test.swift:494:33:494:33 | d2 |
| test.swift:494:33:494:33 | d2 | test.swift:494:54:494:54 | d2 |
| test.swift:496:13:496:35 | .mySingle(...) [mySingle:0] | test.swift:496:33:496:33 | d4 |
| test.swift:496:33:496:33 | d4 | test.swift:496:54:496:54 | d4 |
| test.swift:498:13:498:35 | .mySingle(...) [mySingle:0] | test.swift:498:33:498:33 | d6 |
| test.swift:498:33:498:33 | d6 | test.swift:498:54:498:54 | d6 |
| test.swift:517:13:517:28 | call to optionalSource() [some:0] | test.swift:519:8:519:12 | let ...? [some:0] |
| test.swift:517:13:517:28 | call to optionalSource() [some:0] | test.swift:524:19:524:19 | x [some:0] |
| test.swift:519:8:519:12 | let ...? [some:0] | test.swift:519:12:519:12 | a |
@@ -517,12 +521,17 @@ nodes
| test.swift:488:30:488:37 | call to source() | semmle.label | call to source() |
| test.swift:490:14:490:32 | call to mkMyEnum1(_:) [mySingle:0] | semmle.label | call to mkMyEnum1(_:) [mySingle:0] |
| test.swift:490:24:490:31 | call to source() | semmle.label | call to source() |
| test.swift:492:14:492:32 | call to mkMyEnum2(_:) [mySingle:0] | semmle.label | call to mkMyEnum2(_:) [mySingle:0] |
| test.swift:492:24:492:31 | call to source() | semmle.label | call to source() |
| test.swift:494:13:494:35 | .mySingle(...) [mySingle:0] | semmle.label | .mySingle(...) [mySingle:0] |
| test.swift:494:33:494:33 | d2 | semmle.label | d2 |
| test.swift:494:54:494:54 | d2 | semmle.label | d2 |
| test.swift:496:13:496:35 | .mySingle(...) [mySingle:0] | semmle.label | .mySingle(...) [mySingle:0] |
| test.swift:496:33:496:33 | d4 | semmle.label | d4 |
| test.swift:496:54:496:54 | d4 | semmle.label | d4 |
| test.swift:498:13:498:35 | .mySingle(...) [mySingle:0] | semmle.label | .mySingle(...) [mySingle:0] |
| test.swift:498:33:498:33 | d6 | semmle.label | d6 |
| test.swift:498:54:498:54 | d6 | semmle.label | d6 |
| test.swift:517:13:517:28 | call to optionalSource() [some:0] | semmle.label | call to optionalSource() [some:0] |
| test.swift:519:8:519:12 | let ...? [some:0] | semmle.label | let ...? [some:0] |
| test.swift:519:12:519:12 | a | semmle.label | a |
@@ -701,6 +710,7 @@ subpaths
| test.swift:482:19:482:19 | e | test.swift:425:26:425:33 | call to source() | test.swift:482:19:482:19 | e | result |
| test.swift:494:54:494:54 | d2 | test.swift:488:30:488:37 | call to source() | test.swift:494:54:494:54 | d2 | result |
| test.swift:496:54:496:54 | d4 | test.swift:490:24:490:31 | call to source() | test.swift:496:54:496:54 | d4 | result |
| test.swift:498:54:498:54 | d6 | test.swift:492:24:492:31 | call to source() | test.swift:498:54:498:54 | d6 | result |
| test.swift:520:19:520:19 | a | test.swift:259:12:259:19 | call to source() | test.swift:520:19:520:19 | a | result |
| test.swift:527:19:527:19 | a | test.swift:259:12:259:19 | call to source() | test.swift:527:19:527:19 | a | result |
| test.swift:551:15:551:15 | z1 | test.swift:259:12:259:19 | call to source() | test.swift:551:15:551:15 | z1 | result |

View File

@@ -495,7 +495,7 @@ func testEnums() {
if case MyEnum.mySingle(let d3) = c3 { sink(arg: d3) }
if case MyEnum.mySingle(let d4) = c4 { sink(arg: d4) } // $ flow=490
if case MyEnum.mySingle(let d5) = c5 { sink(arg: d5) }
if case MyEnum.mySingle(let d6) = c6 { sink(arg: d6) } // $ MISSING: flow=492
if case MyEnum.mySingle(let d6) = c6 { sink(arg: d6) } // $ flow=492
let e1 = Optional.some(0)
let e2 = Optional.some(source())