mirror of
https://github.com/github/codeql.git
synced 2026-04-20 22:44:52 +02:00
python: Allow dotted paths in type column
This commit is contained in:
@@ -29,7 +29,11 @@ import semmle.python.dataflow.new.DataFlow::DataFlow as DataFlow
|
||||
/**
|
||||
* Holds if models describing `type` may be relevant for the analysis of this database.
|
||||
*/
|
||||
predicate isTypeUsed(string type) { API::moduleImportExists(type) }
|
||||
bindingset[type]
|
||||
predicate isTypeUsed(string type) {
|
||||
// If `type` is a path, then it is the first component that should be imported.
|
||||
API::moduleImportExists(type.splitAt(".", 0))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `type` can be obtained from an instance of `otherType` due to
|
||||
@@ -41,8 +45,59 @@ predicate hasImplicitTypeModel(string type, string otherType) { none() }
|
||||
bindingset[type, path]
|
||||
API::Node getExtraNodeFromPath(string type, AccessPath path, int n) { none() }
|
||||
|
||||
/**
|
||||
* Holds if `type` = `typePath`+`suffix` and `suffix` is either empty or "!".
|
||||
*/
|
||||
bindingset[type]
|
||||
private predicate parseType(string type, string typePath, string suffix) {
|
||||
exists(string regexp |
|
||||
regexp = "([^!]+)(!|)" and
|
||||
typePath = type.regexpCapture(regexp, 1) and
|
||||
suffix = type.regexpCapture(regexp, 2)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate parseRelevantType(string type, string typePath, string suffix) {
|
||||
isRelevantType(type) and
|
||||
parseType(type, typePath, suffix)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private string getTypePathComponent(string typePath, int n) {
|
||||
parseRelevantType(_, typePath, _) and
|
||||
result = typePath.splitAt(".", n)
|
||||
}
|
||||
|
||||
private int getNumTypePathomponents(string typePath) {
|
||||
result = strictcount(int n | exists(getTypePathComponent(typePath, n)))
|
||||
}
|
||||
|
||||
private API::Node getNodeFromTypePath(string typePath, int n) {
|
||||
n = 1 and
|
||||
result = API::moduleImport(getTypePathComponent(typePath, 0))
|
||||
or
|
||||
result = getNodeFromTypePath(typePath, n - 1).getMember(getTypePathComponent(typePath, n - 1))
|
||||
}
|
||||
|
||||
private API::Node getNodeFromTypePath(string typePath) {
|
||||
result = getNodeFromTypePath(typePath, getNumTypePathomponents(typePath))
|
||||
}
|
||||
|
||||
/** Gets a Python-specific interpretation of the given `type`. */
|
||||
API::Node getExtraNodeFromType(string type) { result = API::moduleImport(type) }
|
||||
API::Node getExtraNodeFromType(string type) {
|
||||
result = API::moduleImport(type)
|
||||
or
|
||||
exists(string typePath, string suffix, API::Node node |
|
||||
parseRelevantType(type, typePath, suffix) and
|
||||
node = getNodeFromTypePath(typePath)
|
||||
|
|
||||
suffix = "!" and
|
||||
result = node
|
||||
or
|
||||
suffix = "" and
|
||||
result = node.getAnInstance()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Python-specific API graph successor of `node` reachable by resolving `token`.
|
||||
|
||||
Reference in New Issue
Block a user