mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Now `TypeRepr` is a final class in the AST, which is more or less just a type with a location in code. As the frontend does not provide a direct way to get a type from a type representation, this information must be provided when fetching the label of a type repr. This meant: * removing the type repr field from `EnumIsCaseExpr`: this is a virtual AST node introduced in place of some kinds of `IsEpxr`. The type repr is still available from the `ConditionalCheckedCastExpr` wrapped by this virtual node, and we will rebuild the original `IsExpr` with the IPA layer. * some logic to get the type of keypath roots has been added to `KeyPathExpr`. This was done to keep the `TypeRepr` to `Type` relation total in the DB, but goes against the design of a dumb extractor. The logic could be moved to QL in the future * in the control flow library, `TypeRepr` children are now ignored. As far as I can tell, there is no runtime evaluation going on in `TypeRepr`s, so it does not make much sense to have control flow through them.
92 lines
3.9 KiB
C++
92 lines
3.9 KiB
C++
#include "swift/extractor/visitors/PatternVisitor.h"
|
|
|
|
namespace codeql {
|
|
|
|
void PatternVisitor::visitNamedPattern(swift::NamedPattern* pattern) {
|
|
auto label = dispatcher_.assignNewLabel(pattern);
|
|
// TODO: in some (but not all) cases, this seems to introduce a duplicate entry
|
|
// for example the vars listed in a case stmt have a different pointer than then ones in
|
|
// patterns.
|
|
// assert(pattern->getDecl() && "expect NamedPattern to have Decl");
|
|
// dispatcher_.emit(NamedPatternsTrap{label, pattern->getNameStr().str(),
|
|
// dispatcher_.fetchLabel(pattern->getDecl())});
|
|
dispatcher_.emit(NamedPatternsTrap{label, pattern->getNameStr().str()});
|
|
}
|
|
|
|
void PatternVisitor::visitTypedPattern(swift::TypedPattern* pattern) {
|
|
auto label = dispatcher_.assignNewLabel(pattern);
|
|
assert(pattern->getSubPattern() && "expect TypedPattern to have a SubPattern");
|
|
dispatcher_.emit(TypedPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
|
|
if (auto typeRepr = pattern->getTypeRepr()) {
|
|
dispatcher_.emit(TypedPatternTypeReprsTrap{
|
|
label, dispatcher_.fetchLabel(pattern->getTypeRepr(), pattern->getType())});
|
|
}
|
|
}
|
|
|
|
void PatternVisitor::visitTuplePattern(swift::TuplePattern* pattern) {
|
|
auto label = dispatcher_.assignNewLabel(pattern);
|
|
dispatcher_.emit(TuplePatternsTrap{label});
|
|
auto i = 0u;
|
|
for (auto p : pattern->getElements()) {
|
|
dispatcher_.emit(TuplePatternElementsTrap{label, i++, dispatcher_.fetchLabel(p.getPattern())});
|
|
}
|
|
}
|
|
void PatternVisitor::visitAnyPattern(swift::AnyPattern* pattern) {
|
|
dispatcher_.emit(AnyPatternsTrap{dispatcher_.assignNewLabel(pattern)});
|
|
}
|
|
|
|
void PatternVisitor::visitBindingPattern(swift::BindingPattern* pattern) {
|
|
auto label = dispatcher_.assignNewLabel(pattern);
|
|
assert(pattern->getSubPattern() && "expect BindingPattern to have a SubPattern");
|
|
dispatcher_.emit(BindingPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
|
|
}
|
|
|
|
void PatternVisitor::visitEnumElementPattern(swift::EnumElementPattern* pattern) {
|
|
auto label = dispatcher_.assignNewLabel(pattern);
|
|
dispatcher_.emit(
|
|
EnumElementPatternsTrap{label, dispatcher_.fetchLabel(pattern->getElementDecl())});
|
|
if (auto subPattern = pattern->getSubPattern()) {
|
|
dispatcher_.emit(
|
|
EnumElementPatternSubPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
|
|
}
|
|
}
|
|
|
|
void PatternVisitor::visitOptionalSomePattern(swift::OptionalSomePattern* pattern) {
|
|
auto label = dispatcher_.assignNewLabel(pattern);
|
|
assert(pattern->getSubPattern() && "expect BindingPattern to have a SubPattern");
|
|
dispatcher_.emit(
|
|
OptionalSomePatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
|
|
}
|
|
|
|
void PatternVisitor::visitIsPattern(swift::IsPattern* pattern) {
|
|
auto label = dispatcher_.assignNewLabel(pattern);
|
|
dispatcher_.emit(IsPatternsTrap{label});
|
|
|
|
if (auto typeRepr = pattern->getCastTypeRepr()) {
|
|
dispatcher_.emit(IsPatternCastTypeReprsTrap{
|
|
label, dispatcher_.fetchLabel(typeRepr, pattern->getCastType())});
|
|
}
|
|
if (auto subPattern = pattern->getSubPattern()) {
|
|
dispatcher_.emit(IsPatternSubPatternsTrap{label, dispatcher_.fetchLabel(subPattern)});
|
|
}
|
|
}
|
|
|
|
void PatternVisitor::visitExprPattern(swift::ExprPattern* pattern) {
|
|
auto label = dispatcher_.assignNewLabel(pattern);
|
|
assert(pattern->getSubExpr() && "expect ExprPattern to have SubExpr");
|
|
dispatcher_.emit(ExprPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubExpr())});
|
|
}
|
|
|
|
void PatternVisitor::visitParenPattern(swift::ParenPattern* pattern) {
|
|
auto label = dispatcher_.assignNewLabel(pattern);
|
|
assert(pattern->getSubPattern() && "expect ParenPattern to have SubPattern");
|
|
dispatcher_.emit(ParenPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
|
|
}
|
|
|
|
void PatternVisitor::visitBoolPattern(swift::BoolPattern* pattern) {
|
|
auto label = dispatcher_.assignNewLabel(pattern);
|
|
dispatcher_.emit(BoolPatternsTrap{label, pattern->getValue()});
|
|
}
|
|
|
|
} // namespace codeql
|