Skip to content

Commit 62e58b5

Browse files
committed
Python: SubclassFinder: reorder + comment
1 parent f48ecb1 commit 62e58b5

File tree

1 file changed

+40
-27
lines changed

1 file changed

+40
-27
lines changed

python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,56 @@ private module NotExposed {
3838
)
3939
}
4040

41+
// ---------------------------------------------------------------------------
42+
// Implementation below
43+
// ---------------------------------------------------------------------------
44+
//
45+
// inherent problem with API graphs is that there doesn't need to exist a result for
46+
// all the stuff we have already modeled... as an example, the following query has no
47+
// results when evaluated against a django/django DB
48+
//
49+
// select API::moduleImport("django")
50+
// .getMember("contrib")
51+
// .getMember("admin")
52+
// .getMember("views")
53+
// .getMember("main")
54+
// .getMember("ChangeListSearchForm")
55+
//
56+
// therefore we use fully qualified names to capture new classes/new aliases.
57+
//
58+
// note that this implementation was originally created to help with automatically
59+
// modeling packages in mind, and was just copied for this purpose. See
60+
// https://github.com/github/codeql/pull/5632 for more discussion. I wanted to get
61+
// this into the codeql-repo, so it could be of use when modeling 3rd party libraries,
62+
// and save some manual effort.
63+
//
64+
//
4165
bindingset[fullyQaulified]
4266
string fullyQualifiedToAPIGraphPath(string fullyQaulified) {
4367
result = "moduleImport(\"" + fullyQaulified.replaceAll(".", "\").getMember(\"") + "\")"
4468
}
4569

46-
// -- Specs --
4770
bindingset[this]
4871
abstract class FindSubclassesSpec extends string {
4972
abstract API::Node getAlreadyModeledClass();
5073
}
5174

75+
/**
76+
* Holds if `newModelFullyQualified` describes either a new subclass, or a new alias, belonging to `spec` that we should include in our automated modeling.
77+
* This new element is defined by `ast`, which is defined at `loc` in the module `mod`.
78+
*/
79+
query predicate newModel(
80+
FindSubclassesSpec spec, string newModelFullyQualified, AstNode ast, Module mod, Location loc
81+
) {
82+
(
83+
newSubclass(spec, newModelFullyQualified, ast, mod, loc)
84+
or
85+
newDirectAlias(spec, newModelFullyQualified, ast, mod, loc)
86+
or
87+
newImportStar(spec, newModelFullyQualified, ast, mod, _, _, loc)
88+
)
89+
}
90+
5291
API::Node newOrExistingModeling(FindSubclassesSpec spec) {
5392
result = spec.getAlreadyModeledClass()
5493
or
@@ -161,30 +200,4 @@ private module NotExposed {
161200
not alreadyModeled(spec, newSubclassQualified) and
162201
isNonTestProjectCode(classExpr)
163202
}
164-
165-
/**
166-
* Holds if `newModelFullyQualified` describes either a new subclass, or a new alias, belonging to `spec` that we should include in our automated modeling.
167-
* This new element is defined by `ast`, which is defined at `loc` in the module `mod`.
168-
*/
169-
query predicate newModel(
170-
FindSubclassesSpec spec, string newModelFullyQualified, AstNode ast, Module mod, Location loc
171-
) {
172-
(
173-
newSubclass(spec, newModelFullyQualified, ast, mod, loc)
174-
or
175-
newDirectAlias(spec, newModelFullyQualified, ast, mod, loc)
176-
or
177-
newImportStar(spec, newModelFullyQualified, ast, mod, _, _, loc)
178-
)
179-
}
180-
// inherint problem with API graphs is that there doesn't need to exist a result for all
181-
// the stuff we have already modeled... as an example, the following query has no
182-
// results when evaluated against Django
183-
//
184-
// select API::moduleImport("django")
185-
// .getMember("contrib")
186-
// .getMember("admin")
187-
// .getMember("views")
188-
// .getMember("main")
189-
// .getMember("ChangeListSearchForm")
190203
}

0 commit comments

Comments
 (0)