зеркало из https://github.com/github/codeql.git
Swift: WIP upgrade script for for-each refactor
This commit is contained in:
Родитель
eddca7f3f6
Коммит
30b30695e4
|
@ -0,0 +1,171 @@
|
|||
class Element extends @element {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class ForEachStmt extends Element, @for_each_stmt {
|
||||
Element getSequence() { for_each_stmts(this, _, result, _) }
|
||||
|
||||
Pattern getPattern() { for_each_stmts(this, result, _, _) }
|
||||
}
|
||||
|
||||
class Pattern extends Element, @pattern {
|
||||
string getGeneratorString() { result = "$generator" }
|
||||
}
|
||||
|
||||
class NamedPattern extends Pattern, @named_pattern {
|
||||
override string getGeneratorString() {
|
||||
exists(string name |
|
||||
named_patterns(this, name) and
|
||||
result = "$" + name + "$generator"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
newtype TAddedElement =
|
||||
TIteratorVar(ForEachStmt stmt) or
|
||||
TIteratorVarPattern(ForEachStmt stmt) or
|
||||
TNextCall(ForEachStmt stmt) or
|
||||
TNextCallMethodLookup(ForEachStmt stmt) or
|
||||
TNextCallInOutConversion(ForEachStmt stmt) or
|
||||
TNextCallVarRef(ForEachStmt stmt) or
|
||||
TNextCallFuncRef(ForEachStmt stmt)
|
||||
|
||||
module Fresh = QlBuiltins::NewEntity<TAddedElement>;
|
||||
|
||||
class TNewElement = @element or Fresh::EntityId;
|
||||
|
||||
class NewElement extends TNewElement {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
query predicate new_for_each_stmts(ForEachStmt id, NamedPattern pattern, Element body) {
|
||||
for_each_stmts(id, pattern, _, body)
|
||||
}
|
||||
|
||||
query predicate for_each_stmt_iterator_vars(ForEachStmt id, NewElement iteratorVar) {
|
||||
Fresh::map(TIteratorVar(id)) = iteratorVar
|
||||
}
|
||||
|
||||
query predicate new_pattern_binding_decls(NewElement id) {
|
||||
pattern_binding_decls(id)
|
||||
or
|
||||
Fresh::map(TIteratorVar(_)) = id
|
||||
}
|
||||
|
||||
query predicate new_pattern_binding_decl_patterns(NewElement id, int index, NewElement pattern) {
|
||||
pattern_binding_decl_patterns(id, index, pattern)
|
||||
or
|
||||
exists(ForEachStmt foreach |
|
||||
Fresh::map(TIteratorVar(foreach)) = id and
|
||||
Fresh::map(TIteratorVarPattern(foreach)) = pattern and
|
||||
index = 0
|
||||
)
|
||||
}
|
||||
|
||||
query predicate new_named_patterns(NewElement id, string name) {
|
||||
named_patterns(id, name)
|
||||
or
|
||||
exists(ForEachStmt foreach |
|
||||
Fresh::map(TIteratorVarPattern(foreach)) = id and
|
||||
name = foreach.getPattern().getGeneratorString()
|
||||
)
|
||||
}
|
||||
|
||||
query predicate new_pattern_binding_decl_inits(NewElement id, int index, NewElement init) {
|
||||
pattern_binding_decl_inits(id, index, init)
|
||||
or
|
||||
exists(ForEachStmt foreach |
|
||||
Fresh::map(TIteratorVar(foreach)) = id and
|
||||
foreach.getSequence() = init and
|
||||
index = 0
|
||||
)
|
||||
}
|
||||
|
||||
query predicate for_each_stmt_next_calls(ForEachStmt id, NewElement nextCall) {
|
||||
Fresh::map(TNextCall(id)) = nextCall
|
||||
}
|
||||
|
||||
query predicate new_dot_syntax_call_exprs(NewElement id) {
|
||||
dot_syntax_call_exprs(id)
|
||||
or
|
||||
Fresh::map(TNextCallMethodLookup(_)) = id
|
||||
}
|
||||
|
||||
query predicate new_self_apply_exprs(NewElement id, NewElement base) {
|
||||
self_apply_exprs(id, base)
|
||||
or
|
||||
exists(ForEachStmt foreach |
|
||||
Fresh::map(TNextCallMethodLookup(foreach)) = id and
|
||||
Fresh::map(TNextCallInOutConversion(foreach)) = base
|
||||
)
|
||||
}
|
||||
|
||||
query predicate new_in_out_exprs(NewElement inOutExpr, NewElement subExpr) {
|
||||
in_out_exprs(inOutExpr, subExpr)
|
||||
or
|
||||
exists(ForEachStmt foreach |
|
||||
Fresh::map(TNextCallInOutConversion(foreach)) = inOutExpr and
|
||||
Fresh::map(TNextCallVarRef(foreach)) = subExpr
|
||||
)
|
||||
}
|
||||
|
||||
query predicate new_apply_exprs(NewElement id, NewElement func) {
|
||||
apply_exprs(id, func)
|
||||
or
|
||||
exists(ForEachStmt foreach |
|
||||
Fresh::map(TNextCall(foreach)) = id and
|
||||
Fresh::map(TNextCallMethodLookup(foreach)) = func
|
||||
)
|
||||
or
|
||||
exists(ForEachStmt foreach |
|
||||
Fresh::map(TNextCallMethodLookup(foreach)) = id and
|
||||
Fresh::map(TNextCallFuncRef(foreach)) = func
|
||||
)
|
||||
}
|
||||
|
||||
Element getParent(Element type) {
|
||||
any_generic_type_parents(type, result)
|
||||
or
|
||||
// there may be an extension that implements IteratorProtocol
|
||||
exists(@extension_decl extDecl, @nominal_type_decl typeDecl, @protocol_decl protocolDecl |
|
||||
any_generic_types(type, typeDecl) and
|
||||
extension_decls(extDecl, typeDecl) and
|
||||
extension_decl_protocols(extDecl, _, protocolDecl) and
|
||||
any_generic_types(result, protocolDecl)
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: do we need a new_apply_expr_arguments
|
||||
query predicate new_decl_ref_exprs(NewElement id, NewElement decl) {
|
||||
decl_ref_exprs(id, decl)
|
||||
or
|
||||
exists(ForEachStmt foreach |
|
||||
Fresh::map(TNextCallVarRef(foreach)) = id and
|
||||
Fresh::map(TIteratorVarPattern(foreach)) = decl
|
||||
)
|
||||
or
|
||||
exists(ForEachStmt foreach, @element sequence, @element exprType, @element parentType, @element typeDecl |
|
||||
Fresh::map(TNextCallFuncRef(foreach)) = id and
|
||||
// ForEachStmt.getSequence().getType().getMember(next)
|
||||
sequence = foreach.getSequence() and
|
||||
expr_types(sequence, exprType) and
|
||||
parentType = getParent*(exprType) and
|
||||
any_generic_types(parentType, typeDecl) and
|
||||
decl_members(typeDecl, _, decl) and
|
||||
callable_names(decl, "next()")
|
||||
)
|
||||
}
|
||||
|
||||
query predicate new_lookup_exprs(NewElement id, NewElement base) {
|
||||
lookup_exprs(id, base)
|
||||
or
|
||||
exists(ForEachStmt foreach |
|
||||
Fresh::map(TNextCallMethodLookup(foreach)) = id and
|
||||
Fresh::map(TNextCallVarRef(foreach)) = base
|
||||
)
|
||||
}
|
||||
|
||||
query predicate new_call_exprs(NewElement id) {
|
||||
call_exprs(id) or
|
||||
Fresh::map(TNextCall(_)) = id
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,16 @@
|
|||
description: <INSERT DESCRIPTION HERE>
|
||||
compatibility: full
|
||||
|
||||
for_each_stmts.rel: run for_in_upgrade.qlo new_for_each_stmts
|
||||
for_each_stmt_iterator_vars.rel: run for_in_upgrade.qlo for_each_stmt_iterator_vars
|
||||
pattern_binding_decls.rel: run for_in_upgrade.qlo new_pattern_binding_decls
|
||||
pattern_binding_decl_patterns.rel: run for_in_upgrade.qlo new_pattern_binding_decl_patterns
|
||||
named_patterns.rel: run for_in_upgrade.qlo new_named_patterns
|
||||
pattern_binding_decl_inits.rel: run for_in_upgrade.qlo new_pattern_binding_decl_inits
|
||||
for_each_stmt_next_calls.rel: run for_in_upgrade.qlo for_each_stmt_next_calls
|
||||
dot_syntax_call_exprs.rel: run for_in_upgrade.qlo new_dot_syntax_call_exprs
|
||||
self_apply_exprs.rel: run for_in_upgrade.qlo new_self_apply_exprs
|
||||
apply_exprs.rel: run for_in_upgrade.qlo new_apply_exprs
|
||||
decl_ref_exprs.rel: run for_in_upgrade.qlo new_decl_ref_exprs
|
||||
in_out_exprs.rel: run for_in_upgrade.qlo new_in_out_exprs
|
||||
call_exprs.rel: run for_in_upgrade.ql new_call_exprs
|
Загрузка…
Ссылка в новой задаче