Merge pull request #9911 from github/redsun82/swift-deduplicate-vardecls

Swift: deduplicate `VarDecl`
This commit is contained in:
Paolo Tranquilli
2022-07-28 14:31:59 +02:00
committed by GitHub
27 changed files with 191 additions and 21 deletions

View File

@@ -83,11 +83,13 @@ codeql::PrecedenceGroupDecl DeclVisitor::translatePrecedenceGroupDecl(
return entry;
}
codeql::ParamDecl DeclVisitor::translateParamDecl(const swift::ParamDecl& decl) {
// TODO: deduplicate
ParamDecl entry{dispatcher_.assignNewLabel(decl)};
fillVarDecl(decl, entry);
entry.is_inout = decl.isInOut();
std::optional<codeql::ParamDecl> DeclVisitor::translateParamDecl(const swift::ParamDecl& decl) {
auto entry = createNamedEntry(decl);
if (!entry) {
return std::nullopt;
}
fillVarDecl(decl, *entry);
entry->is_inout = decl.isInOut();
return entry;
}
@@ -111,11 +113,18 @@ codeql::PatternBindingDecl DeclVisitor::translatePatternBindingDecl(
return entry;
}
codeql::ConcreteVarDecl DeclVisitor::translateVarDecl(const swift::VarDecl& decl) {
// TODO: deduplicate all non-local variables
ConcreteVarDecl entry{dispatcher_.assignNewLabel(decl)};
entry.introducer_int = static_cast<uint8_t>(decl.getIntroducer());
fillVarDecl(decl, entry);
std::optional<codeql::ConcreteVarDecl> DeclVisitor::translateVarDecl(const swift::VarDecl& decl) {
std::optional<codeql::ConcreteVarDecl> entry;
if (decl.getDeclContext()->isLocalContext()) {
entry.emplace(dispatcher_.assignNewLabel(decl));
} else {
entry = createNamedEntry(decl);
if (!entry) {
return std::nullopt;
}
}
entry->introducer_int = static_cast<uint8_t>(decl.getIntroducer());
fillVarDecl(decl, *entry);
return entry;
}

View File

@@ -30,10 +30,10 @@ class DeclVisitor : public AstVisitorBase<DeclVisitor> {
codeql::PostfixOperatorDecl translatePostfixOperatorDecl(const swift::PostfixOperatorDecl& decl);
codeql::InfixOperatorDecl translateInfixOperatorDecl(const swift::InfixOperatorDecl& decl);
codeql::PrecedenceGroupDecl translatePrecedenceGroupDecl(const swift::PrecedenceGroupDecl& decl);
codeql::ParamDecl translateParamDecl(const swift::ParamDecl& decl);
std::optional<codeql::ParamDecl> translateParamDecl(const swift::ParamDecl& decl);
codeql::TopLevelCodeDecl translateTopLevelCodeDecl(const swift::TopLevelCodeDecl& decl);
codeql::PatternBindingDecl translatePatternBindingDecl(const swift::PatternBindingDecl& decl);
codeql::ConcreteVarDecl translateVarDecl(const swift::VarDecl& decl);
std::optional<codeql::ConcreteVarDecl> translateVarDecl(const swift::VarDecl& decl);
std::variant<codeql::StructDecl, codeql::StructDeclsTrap> translateStructDecl(
const swift::StructDecl& decl);
std::variant<codeql::ClassDecl, codeql::ClassDeclsTrap> translateClassDecl(

View File

@@ -1,5 +1,4 @@
| Sources/cross-references/lib.swift:10:5:10:5 | X |
| Sources/cross-references/lib.swift:10:5:10:5 | X |
| Sources/cross-references/lib.swift:17:16:17:19 | v |
| Sources/cross-references/lib.swift:22:16:22:19 | v |
| Sources/cross-references/lib.swift:27:8:27:13 | lhs |

View File

@@ -0,0 +1,7 @@
| var_decls.swift:4:7:4:7 | i | getInterfaceType: | Int | getName: | i | getType: | Int | getIntroducerInt: | 1 |
| var_decls.swift:7:5:7:5 | numbers | getInterfaceType: | [Int] | getName: | numbers | getType: | [Int] | getIntroducerInt: | 1 |
| var_decls.swift:10:12:10:12 | numbers | getInterfaceType: | [Int] | getName: | numbers | getType: | [Int] | getIntroducerInt: | 0 |
| var_decls.swift:15:7:15:7 | wrappedValue | getInterfaceType: | T | getName: | wrappedValue | getType: | T | getIntroducerInt: | 1 |
| var_decls.swift:20:7:20:7 | wrappedValue | getInterfaceType: | Int | getName: | wrappedValue | getType: | Int | getIntroducerInt: | 1 |
| var_decls.swift:24:15:24:15 | _wrapped | getInterfaceType: | X<Y> | getName: | _wrapped | getType: | X<Y> | getIntroducerInt: | 1 |
| var_decls.swift:24:15:24:15 | wrapped | getInterfaceType: | Int | getName: | wrapped | getType: | Int | getIntroducerInt: | 1 |

View File

@@ -0,0 +1,14 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from ConcreteVarDecl x, Type getInterfaceType, string getName, Type getType, int getIntroducerInt
where
toBeTested(x) and
not x.isUnknown() and
getInterfaceType = x.getInterfaceType() and
getName = x.getName() and
getType = x.getType() and
getIntroducerInt = x.getIntroducerInt()
select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "getType:", getType,
"getIntroducerInt:", getIntroducerInt

View File

@@ -0,0 +1,13 @@
| var_decls.swift:10:12:10:12 | numbers | 0 | var_decls.swift:10:12:10:12 | get |
| var_decls.swift:15:7:15:7 | wrappedValue | 0 | var_decls.swift:15:7:15:7 | get |
| var_decls.swift:15:7:15:7 | wrappedValue | 1 | var_decls.swift:15:7:15:7 | set |
| var_decls.swift:15:7:15:7 | wrappedValue | 2 | var_decls.swift:15:7:15:7 | (unnamed function decl) |
| var_decls.swift:20:7:20:7 | wrappedValue | 0 | var_decls.swift:20:7:20:7 | get |
| var_decls.swift:20:7:20:7 | wrappedValue | 1 | var_decls.swift:20:7:20:7 | set |
| var_decls.swift:20:7:20:7 | wrappedValue | 2 | var_decls.swift:20:7:20:7 | (unnamed function decl) |
| var_decls.swift:24:15:24:15 | _wrapped | 0 | var_decls.swift:24:15:24:15 | get |
| var_decls.swift:24:15:24:15 | _wrapped | 1 | var_decls.swift:24:15:24:15 | set |
| var_decls.swift:24:15:24:15 | _wrapped | 2 | var_decls.swift:24:15:24:15 | (unnamed function decl) |
| var_decls.swift:24:15:24:15 | wrapped | 0 | var_decls.swift:24:15:24:15 | get |
| var_decls.swift:24:15:24:15 | wrapped | 1 | var_decls.swift:24:15:24:15 | set |
| var_decls.swift:24:15:24:15 | wrapped | 2 | var_decls.swift:24:15:24:15 | (unnamed function decl) |

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from ConcreteVarDecl x, int index
where toBeTested(x) and not x.isUnknown()
select x, index, x.getAccessorDecl(index)

View File

@@ -0,0 +1 @@
| var_decls.swift:24:15:24:15 | wrapped | X<Y> |

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from ConcreteVarDecl x
where toBeTested(x) and not x.isUnknown()
select x, x.getAttachedPropertyWrapperType()

View File

@@ -0,0 +1,3 @@
| var_decls.swift:4:7:4:7 | i | var_decls.swift:4:11:4:11 | 0 |
| var_decls.swift:7:5:7:5 | numbers | var_decls.swift:7:15:7:18 | [...] |
| var_decls.swift:10:12:10:12 | numbers | var_decls.swift:10:22:10:35 | [...] |

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from ConcreteVarDecl x
where toBeTested(x) and not x.isUnknown()
select x, x.getParentInitializer()

View File

@@ -0,0 +1,7 @@
| var_decls.swift:4:7:4:7 | i | var_decls.swift:4:7:4:7 | i |
| var_decls.swift:7:5:7:5 | numbers | var_decls.swift:7:5:7:5 | numbers |
| var_decls.swift:10:12:10:12 | numbers | var_decls.swift:10:12:10:12 | numbers |
| var_decls.swift:15:7:15:7 | wrappedValue | var_decls.swift:15:7:15:21 | ... as ... |
| var_decls.swift:20:7:20:7 | wrappedValue | var_decls.swift:20:7:20:21 | ... as ... |
| var_decls.swift:24:15:24:15 | _wrapped | var_decls.swift:24:15:24:15 | ... as ... |
| var_decls.swift:24:15:24:15 | wrapped | var_decls.swift:24:15:24:25 | ... as ... |

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from ConcreteVarDecl x
where toBeTested(x) and not x.isUnknown()
select x, x.getParentPattern()

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py
After a swift source file is added in this directory and codegen/codegen.py is run again, test queries
will appear and this file will be deleted

View File

@@ -0,0 +1,25 @@
func loop() {
for i in 1...5 {
}
var i = 0
}
var numbers = [42]
struct S {
static let numbers = [42, 404, 101]
}
@propertyWrapper
struct X<T> {
var wrappedValue: T
}
@propertyWrapper
struct Y {
var wrappedValue: Int
}
struct Wrapped {
@X @Y var wrapped : Int
}

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py
After a swift source file is added in this directory and codegen/codegen.py is run again, test queries
will appear and this file will be deleted

View File

@@ -0,0 +1,15 @@
| param_decls.swift:1:10:1:13 | _ | getInterfaceType: | Int | getName: | _ | getType: | Int | isInout: | no |
| param_decls.swift:1:18:1:29 | y | getInterfaceType: | Double | getName: | y | getType: | Double | isInout: | yes |
| param_decls.swift:2:10:2:13 | _ | getInterfaceType: | Int | getName: | _ | getType: | Int | isInout: | no |
| param_decls.swift:2:18:2:29 | y | getInterfaceType: | Double | getName: | y | getType: | Double | isInout: | yes |
| param_decls.swift:5:5:5:5 | self | getInterfaceType: | S | getName: | self | getType: | S | isInout: | yes |
| param_decls.swift:5:15:5:15 | x | getInterfaceType: | Int | getName: | x | getType: | Int | isInout: | no |
| param_decls.swift:5:15:5:15 | x | getInterfaceType: | Int | getName: | x | getType: | Int | isInout: | no |
| param_decls.swift:5:15:5:18 | x | getInterfaceType: | Int | getName: | x | getType: | Int | isInout: | no |
| param_decls.swift:5:23:5:23 | y | getInterfaceType: | Int | getName: | y | getType: | Int | isInout: | no |
| param_decls.swift:5:23:5:23 | y | getInterfaceType: | Int | getName: | y | getType: | Int | isInout: | no |
| param_decls.swift:5:23:5:26 | y | getInterfaceType: | Int | getName: | y | getType: | Int | isInout: | no |
| param_decls.swift:7:9:7:9 | newValue | getInterfaceType: | Int? | getName: | newValue | getType: | Int? | isInout: | no |
| param_decls.swift:12:13:12:22 | s | getInterfaceType: | String | getName: | s | getType: | String | isInout: | yes |
| param_decls.swift:13:13:13:22 | s | getInterfaceType: | String | getName: | s | getType: | String | isInout: | yes |
| param_decls.swift:14:26:14:26 | $0 | getInterfaceType: | Int | getName: | $0 | getType: | Int | isInout: | no |

View File

@@ -0,0 +1,14 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from ParamDecl x, Type getInterfaceType, string getName, Type getType, string isInout
where
toBeTested(x) and
not x.isUnknown() and
getInterfaceType = x.getInterfaceType() and
getName = x.getName() and
getType = x.getType() and
if x.isInout() then isInout = "yes" else isInout = "no"
select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "getType:", getType,
"isInout:", isInout

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from ParamDecl x, int index
where toBeTested(x) and not x.isUnknown()
select x, index, x.getAccessorDecl(index)

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from ParamDecl x
where toBeTested(x) and not x.isUnknown()
select x, x.getAttachedPropertyWrapperType()

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from ParamDecl x
where toBeTested(x) and not x.isUnknown()
select x, x.getParentInitializer()

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from ParamDecl x
where toBeTested(x) and not x.isUnknown()
select x, x.getParentPattern()

View File

@@ -0,0 +1,15 @@
func foo(_: Int, x y: inout Double) {}
func bar(_: Int, x y: inout Double) {}
struct S {
subscript(x: Int, y: Int) -> Int? {
get { nil }
set {}
}
}
func closures() {
let x = {(s: inout String) -> String in s}
let y = {(s: inout String) -> String in ""}
let z : (Int) -> Int = { $0 + 1 }
}