mirror of
https://github.com/github/codeql.git
synced 2026-04-28 18:25:24 +02:00
Swift: Callable abstraction
This new class encompasses both `AbstractFunctionDecl` and `AbstractClosureExpr`, together with their common parts (namely parameters and the body). `ClosureExpr` and `AutoClosureExpr` got ported to structured C++ generated translation in the process.
This commit is contained in:
@@ -54,6 +54,11 @@ NominalTypeDecl:
|
||||
AstNode:
|
||||
_extends: Locatable
|
||||
|
||||
Callable:
|
||||
_children:
|
||||
params: ParamDecl*
|
||||
body: BraceStmt?
|
||||
|
||||
ConditionElement:
|
||||
_extends: Locatable
|
||||
_children:
|
||||
@@ -290,9 +295,9 @@ ValueDecl:
|
||||
interface_type: Type
|
||||
|
||||
AbstractClosureExpr:
|
||||
_extends: Expr
|
||||
_children:
|
||||
params: ParamDecl*
|
||||
_extends:
|
||||
- Expr
|
||||
- Callable
|
||||
|
||||
AnyTryExpr:
|
||||
_extends: Expr
|
||||
@@ -712,10 +717,8 @@ AbstractFunctionDecl:
|
||||
_extends:
|
||||
- GenericContext
|
||||
- ValueDecl
|
||||
- Callable
|
||||
name: string
|
||||
_children:
|
||||
body: BraceStmt?
|
||||
params: ParamDecl*
|
||||
|
||||
AbstractStorageDecl:
|
||||
_extends: ValueDecl
|
||||
@@ -735,13 +738,9 @@ TypeDecl:
|
||||
|
||||
AutoClosureExpr:
|
||||
_extends: AbstractClosureExpr
|
||||
_children:
|
||||
body: BraceStmt
|
||||
|
||||
ClosureExpr:
|
||||
_extends: AbstractClosureExpr
|
||||
_children:
|
||||
body: BraceStmt
|
||||
|
||||
ForceTryExpr:
|
||||
_extends: AnyTryExpr
|
||||
|
||||
@@ -363,20 +363,16 @@ class ExprVisitor : public AstVisitorBase<ExprVisitor> {
|
||||
dispatcher_.emit(DiscardAssignmentExprsTrap{label});
|
||||
}
|
||||
|
||||
void visitClosureExpr(swift::ClosureExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getBody() && "ClosureExpr has getBody()");
|
||||
auto bodyLabel = dispatcher_.fetchLabel(expr->getBody());
|
||||
dispatcher_.emit(ClosureExprsTrap{label, bodyLabel});
|
||||
emitAbstractClosureExpr(expr, label);
|
||||
codeql::ClosureExpr translateClosureExpr(const swift::ClosureExpr& expr) {
|
||||
ClosureExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
fillAbstractClosureExpr(expr, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
void visitAutoClosureExpr(swift::AutoClosureExpr* expr) {
|
||||
auto label = dispatcher_.assignNewLabel(expr);
|
||||
assert(expr->getBody() && "AutoClosureExpr has getBody()");
|
||||
auto bodyLabel = dispatcher_.fetchLabel(expr->getBody());
|
||||
dispatcher_.emit(AutoClosureExprsTrap{label, bodyLabel});
|
||||
emitAbstractClosureExpr(expr, label);
|
||||
codeql::AutoClosureExpr translateAutoClosureExpr(const swift::AutoClosureExpr& expr) {
|
||||
AutoClosureExpr entry{dispatcher_.assignNewLabel(expr)};
|
||||
fillAbstractClosureExpr(expr, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
void visitCoerceExpr(swift::CoerceExpr* expr) {
|
||||
@@ -536,14 +532,12 @@ class ExprVisitor : public AstVisitorBase<ExprVisitor> {
|
||||
}
|
||||
|
||||
private:
|
||||
void emitAbstractClosureExpr(swift::AbstractClosureExpr* expr,
|
||||
TrapLabel<AbstractClosureExprTag> label) {
|
||||
assert(expr->getParameters() && "AbstractClosureExpr has getParameters()");
|
||||
auto params = expr->getParameters();
|
||||
for (auto i = 0u; i < params->size(); ++i) {
|
||||
dispatcher_.emit(
|
||||
AbstractClosureExprParamsTrap{label, i, dispatcher_.fetchLabel(params->get(i))});
|
||||
}
|
||||
void fillAbstractClosureExpr(const swift::AbstractClosureExpr& expr,
|
||||
codeql::AbstractClosureExpr& entry) {
|
||||
assert(expr.getParameters() && "AbstractClosureExpr has getParameters()");
|
||||
assert(expr.getBody() && "AbstractClosureExpr has getBody()");
|
||||
entry.params = dispatcher_.fetchRepeatedLabels(*expr.getParameters());
|
||||
entry.body = dispatcher_.fetchLabel(expr.getBody());
|
||||
}
|
||||
|
||||
TrapLabel<ArgumentTag> emitArgument(const swift::Argument& arg) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.AstNode
|
||||
import codeql.swift.elements.Callable
|
||||
import codeql.swift.elements.Element
|
||||
import codeql.swift.elements.File
|
||||
import codeql.swift.elements.Locatable
|
||||
|
||||
4
swift/ql/lib/codeql/swift/elements/Callable.qll
Normal file
4
swift/ql/lib/codeql/swift/elements/Callable.qll
Normal file
@@ -0,0 +1,4 @@
|
||||
private import codeql.swift.generated.Callable
|
||||
private import codeql.swift.elements.AstNode
|
||||
|
||||
class Callable extends CallableBase, AstNode { }
|
||||
@@ -1,10 +1,10 @@
|
||||
private import codeql.swift.generated.decl.ParamDecl
|
||||
private import codeql.swift.elements.decl.AbstractFunctionDecl
|
||||
private import codeql.swift.elements.Callable
|
||||
|
||||
class ParamDecl extends ParamDeclBase {
|
||||
/** Gets the function which declares this parameter. */
|
||||
AbstractFunctionDecl getDeclaringFunction() { result.getAParam() = this }
|
||||
Callable getDeclaringFunction() { result.getAParam() = this }
|
||||
|
||||
/** Gets the index of this parameter in its declaring function's parameter list. */
|
||||
int getIndex() { exists(AbstractFunctionDecl func | func.getParam(result) = this) }
|
||||
int getIndex() { exists(Callable func | func.getParam(result) = this) }
|
||||
}
|
||||
|
||||
26
swift/ql/lib/codeql/swift/generated/Callable.qll
Normal file
26
swift/ql/lib/codeql/swift/generated/Callable.qll
Normal file
@@ -0,0 +1,26 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.stmt.BraceStmt
|
||||
import codeql.swift.elements.Element
|
||||
import codeql.swift.elements.decl.ParamDecl
|
||||
|
||||
class CallableBase extends @callable, Element {
|
||||
ParamDecl getParam(int index) {
|
||||
exists(ParamDecl x |
|
||||
callable_params(this, index, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
ParamDecl getAParam() { result = getParam(_) }
|
||||
|
||||
int getNumberOfParams() { result = count(getAParam()) }
|
||||
|
||||
BraceStmt getBody() {
|
||||
exists(BraceStmt x |
|
||||
callable_bodies(this, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasBody() { exists(getBody()) }
|
||||
}
|
||||
@@ -18,9 +18,9 @@ Element getAnImmediateChild(Element e) {
|
||||
(
|
||||
none()
|
||||
or
|
||||
abstract_function_decl_bodies(e, x)
|
||||
callable_params(e, _, x)
|
||||
or
|
||||
abstract_function_decl_params(e, _, x)
|
||||
callable_bodies(e, x)
|
||||
or
|
||||
abstract_storage_decl_accessor_decls(e, _, x)
|
||||
or
|
||||
@@ -36,8 +36,6 @@ Element getAnImmediateChild(Element e) {
|
||||
or
|
||||
top_level_code_decls(e, x)
|
||||
or
|
||||
abstract_closure_expr_params(e, _, x)
|
||||
or
|
||||
any_try_exprs(e, x)
|
||||
or
|
||||
apply_exprs(e, x)
|
||||
@@ -52,16 +50,12 @@ Element getAnImmediateChild(Element e) {
|
||||
or
|
||||
assign_exprs(e, _, x)
|
||||
or
|
||||
auto_closure_exprs(e, x)
|
||||
or
|
||||
bind_optional_exprs(e, x)
|
||||
or
|
||||
capture_list_expr_binding_decls(e, _, x)
|
||||
or
|
||||
capture_list_exprs(e, x)
|
||||
or
|
||||
closure_exprs(e, x)
|
||||
or
|
||||
dictionary_expr_elements(e, _, x)
|
||||
or
|
||||
dot_syntax_base_ignored_exprs(e, x, _)
|
||||
|
||||
@@ -1,29 +1,8 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.stmt.BraceStmt
|
||||
import codeql.swift.elements.Callable
|
||||
import codeql.swift.elements.decl.GenericContext
|
||||
import codeql.swift.elements.decl.ParamDecl
|
||||
import codeql.swift.elements.decl.ValueDecl
|
||||
|
||||
class AbstractFunctionDeclBase extends @abstract_function_decl, GenericContext, ValueDecl {
|
||||
class AbstractFunctionDeclBase extends @abstract_function_decl, Callable, GenericContext, ValueDecl {
|
||||
string getName() { abstract_function_decls(this, result) }
|
||||
|
||||
BraceStmt getBody() {
|
||||
exists(BraceStmt x |
|
||||
abstract_function_decl_bodies(this, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasBody() { exists(getBody()) }
|
||||
|
||||
ParamDecl getParam(int index) {
|
||||
exists(ParamDecl x |
|
||||
abstract_function_decl_params(this, index, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
ParamDecl getAParam() { result = getParam(_) }
|
||||
|
||||
int getNumberOfParams() { result = count(getAParam()) }
|
||||
}
|
||||
|
||||
@@ -1,16 +1,5 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.Callable
|
||||
import codeql.swift.elements.expr.Expr
|
||||
import codeql.swift.elements.decl.ParamDecl
|
||||
|
||||
class AbstractClosureExprBase extends @abstract_closure_expr, Expr {
|
||||
ParamDecl getParam(int index) {
|
||||
exists(ParamDecl x |
|
||||
abstract_closure_expr_params(this, index, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
|
||||
ParamDecl getAParam() { result = getParam(_) }
|
||||
|
||||
int getNumberOfParams() { result = count(getAParam()) }
|
||||
}
|
||||
class AbstractClosureExprBase extends @abstract_closure_expr, Callable, Expr { }
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.expr.AbstractClosureExpr
|
||||
import codeql.swift.elements.stmt.BraceStmt
|
||||
|
||||
class AutoClosureExprBase extends @auto_closure_expr, AbstractClosureExpr {
|
||||
override string getAPrimaryQlClass() { result = "AutoClosureExpr" }
|
||||
|
||||
BraceStmt getBody() {
|
||||
exists(BraceStmt x |
|
||||
auto_closure_exprs(this, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements.expr.AbstractClosureExpr
|
||||
import codeql.swift.elements.stmt.BraceStmt
|
||||
|
||||
class ClosureExprBase extends @closure_expr, AbstractClosureExpr {
|
||||
override string getAPrimaryQlClass() { result = "ClosureExpr" }
|
||||
|
||||
BraceStmt getBody() {
|
||||
exists(BraceStmt x |
|
||||
closure_exprs(this, x) and
|
||||
result = x.resolve()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ sourceLocationPrefix(
|
||||
|
||||
@element =
|
||||
@argument
|
||||
| @callable
|
||||
| @file
|
||||
| @generic_context
|
||||
| @iterable_decl_context
|
||||
@@ -125,6 +126,24 @@ nominal_type_decls(
|
||||
| @type_repr
|
||||
;
|
||||
|
||||
@callable =
|
||||
@abstract_closure_expr
|
||||
| @abstract_function_decl
|
||||
;
|
||||
|
||||
#keyset[id, index]
|
||||
callable_params(
|
||||
int id: @callable ref,
|
||||
int index: int ref,
|
||||
int param: @param_decl ref
|
||||
);
|
||||
|
||||
#keyset[id]
|
||||
callable_bodies(
|
||||
int id: @callable ref,
|
||||
int body: @brace_stmt ref
|
||||
);
|
||||
|
||||
condition_elements(
|
||||
unique int id: @condition_element
|
||||
);
|
||||
@@ -659,13 +678,6 @@ value_decls(
|
||||
| @closure_expr
|
||||
;
|
||||
|
||||
#keyset[id, index]
|
||||
abstract_closure_expr_params(
|
||||
int id: @abstract_closure_expr ref,
|
||||
int index: int ref,
|
||||
int param: @param_decl ref
|
||||
);
|
||||
|
||||
@any_try_expr =
|
||||
@force_try_expr
|
||||
| @optional_try_expr
|
||||
@@ -1392,19 +1404,6 @@ abstract_function_decls(
|
||||
string name: string ref
|
||||
);
|
||||
|
||||
#keyset[id]
|
||||
abstract_function_decl_bodies(
|
||||
int id: @abstract_function_decl ref,
|
||||
int body: @brace_stmt ref
|
||||
);
|
||||
|
||||
#keyset[id, index]
|
||||
abstract_function_decl_params(
|
||||
int id: @abstract_function_decl ref,
|
||||
int index: int ref,
|
||||
int param: @param_decl ref
|
||||
);
|
||||
|
||||
@abstract_storage_decl =
|
||||
@subscript_decl
|
||||
| @var_decl
|
||||
@@ -1449,13 +1448,11 @@ type_decl_base_types(
|
||||
);
|
||||
|
||||
auto_closure_exprs(
|
||||
unique int id: @auto_closure_expr,
|
||||
int body: @brace_stmt ref
|
||||
unique int id: @auto_closure_expr
|
||||
);
|
||||
|
||||
closure_exprs(
|
||||
unique int id: @closure_expr,
|
||||
int body: @brace_stmt ref
|
||||
unique int id: @closure_expr
|
||||
);
|
||||
|
||||
force_try_exprs(
|
||||
|
||||
Reference in New Issue
Block a user